프롬프트 엔지니어링 실제 적용 사례

crowdworks
크라우드웍스 Tech Blog
9 min readSep 11, 2024

case1_

A사 LLM을 활용한 16개국어 번역앱

프로젝트 개요

요즘 건설 현장에는 다양한 국가, 인종들이 모여 일을 하곤 합니다. 또 다양한 사람들이 모이는 자리인 만큼 당연히 의사소통에 어려움을 많이 겪습니다.

특히나 건설현장에선 실시간으로 의사소통이 계속 필요한 현장이기 때문에, 이러한 문제가 현장에서 근무하시는 분들의 능률에 치명적으로 다가가기도 합니다.

번역을 위한 스마트폰 어플리케이션들은 현재 시중에 많이 나와있습니다. 하지만 모든 근로자를 수용할 정도의 다양한 언어를 지원하지 않기도 하며, 또 건설현장에서 사용되는 특수한 용어들을 번역할 때 품질이 생각보다 낮습니다.

때문에 여러 언어를 번역할 수 있으면서, 특수한 용어들을 인지하여 번역할 수 있는 어플리케이션이 있다면 현장의 능률을 상당히 제고할 수 있습니다.

이러한 배경에서 저희는 AI 기술을 사용하여 특수한 용어들의 번역은 물론, 음성 인식(Speech To Text)과 음성 생성(Text To Speech) 기능이 합쳐진 번역 어플리케이션을 기획하게 되었습니다.

프롬프트 엔지니어링 적용 사례

저희가 프롬프트를 작성할 때 먼저 중요하게 생각하는 것은 합리적인 가정을 하는 것입니다.

본 프로젝트에서 프롬프트를 통해 원하는 결과는 특정 언어로부터 또 다른 언어로의 번역 결과입니다. 이 때 특정 언어를 다른 언어로 번역할 때 LLM에게 바로 번역을 요구하는 것 보단, 영어로 번역을 거친 뒤 목표한 언어로 번역을 요구하는 것이 더 정확한 답변을 얻을 것이라고 가정했습니다.

아무래도 LLM을 학습한 Dataset에는 영어가 가장 많은 지분을 차지할 것이고, 같은 의미의 단어들이라면 영어를 중심으로 벡터가 모여있을 가능성이 높기 때문입니다.

저희는 16개국어를 번역할 때 LLM이 영어를 먼저 거쳐서 다음 번역 결과를 내보내도록 유도하는 프롬프트를 사용했습니다.

위의 예시는 한국어에서 베트남어로 번역을 할 때의 예시입니다.

다음과 같이 특정 언어로 번역을 하기 전에 영어로 번역을 먼저 한번 거치는 단계를 추가하는 방식을 사용했습니다.

또한 프롬프트 내에 특정 건설 용어에 대한 설명을 영어로 넣어 용어들을 이해할 수 있도록 유도하였습니다.

The term “{kor_word}” means “{eng_word}” in English.

유저가 쿼리를 날리면, 먼저 단어 사전에서 관련된 단어들을 가져옵니다.

그리고 발견된 단어들이 번역될 언어에서는 어떤 단어인지 의미를 매핑하여 프롬프트에 추가하게 됩니다.

아래는 예시입니다.

case2_

B사 보험 인수여부 판별 챗봇

프로젝트 개요

보험 상품은 특성상 상품마다 여러 조건들에 따라 가입 여부나 특약, 금액 등이 다르게 책정됩니다. 대표적인 조건들로는 나이, 성별, 질병 이력 등이 있습니다.

때문에 보험 상품을 전문적으로 다루는 사람들이 아니라면 이러한 다양한 조건들을 판별하며 상품의 특성을 파악하기는 쉽지 않습니다.

본 프로젝트는 보험 상품에 대한 다양한 조건들을 인식하고, 질문에 응답할 수 있는 챗봇을 만드는 프로젝트 입니다.

프롬프트 엔지니어링 적용 사례

해당 프로젝트에서 가장 핵심적인 부분 중 하나는 특정 키워드들을 추출해야 하는 부분이었습니다.

보험을 가입하고 싶을 땐 질문을 하는 사람의 나이와 성별을 파악할 수 있어야 하며, 또 특정 질병과 관련된 보험 상품을 찾고 싶으면 어떤 질병인지 인식하는 것이 우선적으로 되어야 하기 때문입니다.

LLM을 이용하면 자연어 속에서 키워드를 추출해낼 수 있습니다.

LLM을 통해 특정 데이터를 추출하고 싶을 땐 형식을 정확하게 명시하는 것이 가장 중요합니다. 형식이 정확하지 못하면 LLM이 응답한 내용에서 어느 부분을 추출해야 하는지 알 수가 없기 때문이죠.

일반적으로 개발하기 가장 쉽고 범용적으로 사용되는 양식은 json이기 때문에 저희는 LLM이 json 형식으로 대답하도록 유도하는 방식을 사용했습니다.

이 때 key와 이에 들어가는 value의 datatype을 명시하고, 때에 따라 few shot을 주어 프롬프트를 사용하면 LLM이 해당 형식에 맞춰서 대답하여 줍니다.

아래는 json 형식으로 특정 키워드를 추출했던 예시입니다.

###### system prompt
~~~
문장 내용 중에서 질병명을 추출하고 담보명은 <list>에서 고르시고 답변을 아래 <output> JSON 형식으로 출력하시오.
<output>
{
"질병명" : "",
"담보명" : ""
}
<\output>
담보명 : ['질병수술', '뇌질환', …]
~~~

위와 같이 system prompt를 작성하고, 실제로 들어오는 질문은 user prompt에 넣어서 LLM에 보내는 형식입니다.

이 때 중요한 부분 중 하나는 json 안에 기본값을 주어(“”) 데이터가 출력되지 않아도 json을 읽을 수 있도록 만드는 것입니다.

{“질병명”: string // disease name} 과 같은 형식으로 string 형식을 지정할 수도 있지만, 저희는 불확실한 정보에 대해선 최대한 답변이 나오지 않도록 유도하기 위해 위처럼 기본값을 주는 사용했습니다.

그리고 “담보명 : […] “ 처럼 리스트 형식으로 예시를 주어 해당 리스트 내에서만 답변을 찾도록 유도하는 방법도 있습니다.

또 few shot을 주어 답변을 유도하는 방법도 사용하였습니다.

Rule base의 챗봇을 만들 때에는, 어떤 룰로 분기할 것인지 선택하는 과정이 필요합니다. Rule 별로 few shot을 주어 유저가 보낸 자연어가 어느 질문에 가장 가까운지 의도 분석을 해볼 수 있습니다.

~~~
아래의 Case 정보를 참고 하여 적절한 case 숫자를 JSON 형식으로 리턴하시오.
답변 예시) {"case":1}
case 1:
1. 51세 남성이 90세만기 보험 가입 가능해?

case 2:
1. 암진단특약의 최소 가입 금액을 알려줘

case 3:
1. 브루셀라병 관련 보험 가입시 필요한 서류는?

case …:
~~~

위와 같은 방법으로 유저가 입력하는 쿼리를 여러 케이스로 분기하는 방법을 사용했습니다.

case3_

C사 약물 정보 챗봇

프로젝트 개요

의사가 약물을 처방할 때 약물마다 특정 조건들에 따라 투여 방법이나 투여 용량이 완전히 달라집니다. 아무리 의사라 하더라도 모든 약물에 대해서, 어떤 조건에 용법과 용량이 어떻게 되는지 기억하고 있긴 어렵습니다.

때문에 저희는 약물에 대한 정보들을 통하여 용법용량을 응답해주는 챗봇을 개발하게 되었습니다.

프롬프트 엔지니어링 적용 사례

본 프로젝트에서 프롬프트 엔지니어링을 적용한 부분은 데이터 전처리에 있습니다.

일반적으로 데이터는 양으로 가치를 많이 평가받지만, 그것이 사용 가능한 데이터인지에 대한 여부, 그리고 얼마나 정확한 데이터인지를 결정하는 데이터의 품질 또한 매우 중요한 요소들입니다.

해당 프로젝트를 시작할 때 주어진 약물에 대한 데이터는 정확한 데이터이지만, 사용하기엔 어려운 형식의 데이터였습니다. 특히 용법용량에 대한 정보가 모두 문자열로 이루어져 있었고, 이러한 형식의 데이터는 원하는 부분을 추출해내기가 어렵습니다.

저희는 먼저 이 문자열 데이터들을 구조화 시키는 작업이 필요했습니다.

먼저 EDA를 진행하면서 발견한 점은, 문자열 안에는 일관된 규칙은 아니지만 특정 대상들을 기준으로 나누어지는 형태가 있었습니다.

하지만 사람은 이런 규칙을 인지할 수 있지만, 코드로 짜려면 정확하고 일관된 규칙이 필요하기 때문에 코드로 나눌 순 없는 형태였습니다.

데이터가 전부 문자열이기 때문에, 저희는 LLM을 통해 이 문자열들을 json으로 구조화 시키는 방법을 시도해보게 됩니다.

이 때 최대한 많은 데이터들이 인식될 수 있도록 json 구조를 구상하여 LLM에게 제시하는 것이 아주 중요합니다.

해당 프로젝트 데이터 전처리에서 사용한 프롬프트는 아래와 같습니다.

~~~
제시된 정보를 유형별로 분류하여 아래와 같은 json 형식으로 채워주세요. 용량에 계산식이 있다면 계산식을 포함하여 주세요.
{
"약물 이름": string // drug name
"유형": dict //
{
"연령대": {
"용법용량": string // specific usage and dosage
"계산식": string // calculation formula
}
"질병": {
"용법용량": string // specific usage and dosage
"계산식": string // calculation formula
},

}
"용법용량": string // usage and dosage for all
"기타": string // remaining contents
}
정보가 부족할 땐 ""으로 처리해주세요.
~~~

EDA를 통해 약물의 용법이 사람의 연령대, 혹은 질병 유무에 따라 구분되어 있음을 발견하였고, 이를 구조화 시켜서 json 형식을 제시하였습니다.

이 때 각 key, value 라인에 data type과 주석을 간단하게 달아 어떤 정보를 입력해야 하는지 명확하게 명시해줍니다.

그리고 간혹 값을 찾지 못하였을 때 빈값으로 두어 json 형식으로 불러오는 것이 안되는 경우들이 있습니다.

자신이 json을 불러오는 형식에 맞추어 해당 상황을 방지해줍니다. (저같은 경우엔 정보가 없을 시 “”(빈 문자열)으로 값을 처리해달라는 문구를 넣었습니다.)

저는 이러한 방식으로 수 만개의 데이터가 오류없이 json화가 될 수 있도록 하였습니다. (물론 정확하게 되었는지는 추후 검수가 필요합니다.)

위에서 “크녹산주(에녹사파린나트륨)”에 대한 예시를 보시면, 용법용량 안에 간단한 계산식이 있는 경우 계산식을 다음과 같이 추출하는 것도 가능합니다.

또 계산식이 없으면 위에서 유도한 것처럼 “”(빈 문자열)을 출력해 줍니다.

위와 같이 모든 것을 사람 손으로 데이터를 전처리하는 것 보다, AI를 통해 선행적으로 전처리를 시도하고, 그 이후 데이터를 사람이 검수하며 수정해 나간다면 훨씬 더 효율적으로 데이터 자산화가 가능합니다.

--

--