소개
LLM(대규모 언어 모델)을 프로덕션 환경에 배포하는 과정은 전통적인 소프트웨어와는 상당히 다릅니다. 소프트웨어에서는 애플리케이션을 생성하는 코드가 결과물인 반면, LLM(ML과 마찬가지로)에서는 시도한 모든 것들 - 데이터(data), 프롬프트(prompt), 파이프라인(pipeline), 평가 지표(evaluation metrics) 등이 결과물입니다. ML 엔지니어는 실험적 사고방식을 채택하고 프로세스의 기본 구성 요소들이 실제로 생성되는 지적 재산임을 인식해야 합니다.
LLM은 오늘날 기업들이 다양한 기능에 배포하고 있습니다: 고객 지원 티켓(customer support tickets) 자동화, 영업 데이터 정리/매칭, 내부 문서화, 자동 마케팅 카피 생성 등이 그것입니다.
이 시리즈에서는 이러한 사용 사례 중 하나를 단계별로 안내합니다: GPT-4의 도움을 받아 자체 고객 성공 티켓을 분류하는 것입니다. 이유는 매우 간단합니다. 우리는 문의하는 모든 분들에게 진정성 있는 피드백을 제공하기 위해 최선을 다하지만, 서로 다른 티켓에는 다양한 응답이 필요합니다. 본질적인 문제를 다루는 메시지는 로그인 문제를 겪는 사람과는 다르게 처리되어야 합니다. 분류(triage) 외에도, 지원 질문의 전체 데이터세트를 이해하면 테마를 찾아내고, 개선할 수 있는 영역, 심지어 우선순위를 두어야 할 제품 기능까지 파악할 수 있습니다. 또한 많은 지원 티켓이 단순히 우리 제품에 관한 것이 아니라는 사실도 있습니다. 이를 프로그래밍 방식으로 식별할 수 있다면 고객 성공 조직이 더 효율적으로 일하고 실행 불가능한 메시지를 읽는 데 시간을 낭비하지 않도록 도울 수 있습니다.
여기서 핵심은 이러한 메시지를 개별적으로 그리고 전체적으로 더 잘 이해할수록 사용자를 더 잘 도울 수 있다는 것입니다.
오늘은 처음부터 시작하여 몇 가지 평가 하네스(evaluation harnesses)를 시도하고 프롬프트를 다듬어 얼마나 잘 할 수 있는지 확인할 것입니다. 시리즈 후반부에서는 fine-tuning(파인 튜닝)부터 RAG(검색 증강 생성), deployment(배포)까지 모든 것을 다룰 예정이지만, 그 전에 기초를 구축해야 합니다.
오늘 그 기초를 만들어봅시다! 아래 Colab 링크를 통해 이 프로젝트의 코드를 따라할 수 있습니다:
데이터 검토
고객 성공 팀원들(Frida와 Artsiom 감사합니다!)이 약 26,000개의 메시지로 구성된 데이터세트를 보내주었습니다. 무작위로 하나를 선택하여 살펴보고 무엇을 할 수 있을지 확인해봅시다(가독성을 위해 메시지 텍스트를 추출하겠습니다):
“Hi, I’ve noticed that when I run a training script through `wandb agent`, a fatal exception in the code is not printed out to the console. While when I run the same code directly with `python train.py` I see the exception in the command output. Looks like if the agent was suppressing the exception printout to the console. Have you heard about something like that?”
전체 JSON:
{ "description": "Hi, I've noticed that when I run a training script through \`wandb agent\` , a fatal exception in the code is not printed out to the console. While when I run the same code directly with \`python train.py\` I see the exception in the command output. Looks like if the agent was suppressing the exception printout to the console. Have you heard about something like that?", "raw_subject": "[SDK] wandb agent fatal exception not printed", "subject": "[SDK] wandb agent fatal exception not printed", "priority": "urgent", "problem_id": null, "tags": [ "component_cli", "enterprise_customer", "halp", "p0", "question", "sweeps" ], "id": 36380, "question": "question", "360042457771": [ "enterprise_customer" ], "360042775872": [ "component_cli" ], "360042457751": "sweeps", "360044019192": null, "360041678631": "https://weightsandbiases.slack.com/archives/C01L79NKX5L/p1669025253633279?thread_ts=1669007664.253479&cid=C01L79NKX5L", "360041794452": null, "4419373106452": null, "4419370133012": null, "4419373051540": null, "4419370299284": null, "4419380461716": null, "4417243931028": false, "4419380411796": null}
메시지 자체 외에 몇 가지 유용한 필드가 있음을 즉시 확인할 수 있습니다. Question, tags, priority는 유망한 시작점인 반면 일부 후속 필드는 그렇지 않습니다. 이를 제거하고 데이터를 정리하면 다음과 같이 됩니다:
{ "description": "Hi, I've noticed that when I run a training script through \`wandb agent\` , a fatal exception in the code is not printed out to the console. While when I run the same code directly with \`python train.py\` I see the exception in the command output. Looks like if the agent was suppressing the exception printout to the console. Have you heard about something like that?", "question": "question", "priority": "urgent", "tags": [ "component_cli", "enterprise_customer", "halp", "p0", "question", "sweeps" ]}
여기서는 우리가 관심 있는 네 가지 필드만 남기고 불필요한 노이즈를 제거했습니다. 이제 본격적으로 시작할 시간입니다.
범위 정의
궁극적으로는 이러한 티켓을 다양한 방식으로 분류하고 싶지만, 처음에는 태그(tags)를 예측하려는 직관을 따랐습니다. 알고 보니 이 직관은 틀렸습니다.
이에 대해 너무 길게 다루지는 않겠지만, 이것이 모델링 초기 단계에서 전형적인 행동이라는 점을 지적하는 것이 좋다고 생각합니다. machine learning(머신 러닝)은 실험 과학이며 처음부터 항상 성공하지는 않습니다. 첫 시도가 기대만큼 결실을 맺지 못한다면 기꺼이 방향을 전환하고 새로운 접근 방식을 시도해야 합니다.
태그의 문제는 너무 많았다는 것입니다. 실제로 500개가 넘었습니다. 여러 기법을 시도했지만 40% accuracy(정확도) 이상을 달성할 수 없었습니다. 주요 문제는 티켓 텍스트가 태그를 예측하는 데 그다지 유용하지 않았고 일부 태그가 잘못 적용되었다는 것입니다. 다시 말해, 처음부터 범위가 너무 넓었습니다.
Goal: Given the support text, predict if 'question' is one of the following:
'type_feature_request'
'type_bug'
'none'
'question'
교훈: 복잡성을 추가하기 전에 더 간단한 문제로 성공하는 것이 지나치게 야심적인 것보다 더 나은 접근 방식입니다. 더 까다로운 문제를 다루기 전에 작동하는 것을 만드세요.
성능 평가
prompting(프롬프팅) 기법을 시도하기 전에 성능을 평가할 방법이 필요합니다. 결국, 모델의 성능을 평가할 좋은 방법이 없다면 배울 수 있는 귀중한 교훈을 놓치게 되고 수행하는 실험이 헛수고가 됩니다. 즉, 이 단계에서 실제 모델링은 하지 않지만 구축할 수 있는 baseline(기준선)이 필요합니다.
우리가 할 일은 간단한 프롬프트를 사용하고 무작위로 선택된 고객 성공 티켓을 처리하는 방식을 평가하는 것입니다. 기본 프롬프트는 다음과 같습니다:
"""Classify the text delimited by triple backticks into one of the following classes.
Classes: 'type_bug', 'none', 'type_feature_request', 'question' Text: ```{ticket_text}```
Class:
"""
다시 강조하자면 - 그리고 위 코드에서 볼 수 있듯이 - 우리 모델은 특정 정답으로 얼마나 잘 수행하는지 평가할 수 있습니다. 텍스트에서 버그(bugs), 기능 요청(feature requests), 질문(questions)을 올바르게 식별하기를 바랍니다. 다른 많은 LLM use cases(사용 사례)(요약이나 카피라이팅과 같은 텍스트 생성 작업을 생각해보세요)에서는 이러한 사치를 누릴 수 없다는 점을 주목할 가치가 있습니다.
다음 섹션에서는 우리의 경우 - 즉, 정답이거나 오답일 수 있는 출력 - 에 대해 LLM을 평가하는 방법을 다룹니다.
수동 평가
먼저, 간단한 프롬프트로 고객 성공 티켓을 테스트하고 결과를 수동으로 확인하고 싶습니다. 아직 클래스 균형에 대해 걱정하지 말고 모델을 평가할 무작위 예제를 자유롭게 선택하세요.
모델이 특정 예제에서 실패하면 해당 예제를 프롬프트에 추가하는 것을 고려하세요. 프롬프트를 수정할 때 새 프롬프트가 이전 예제에서도 작동하는지 확인하기 위해 간단한 regression testing(회귀 테스트)을 수행하는 것이 좋습니다.
기능적으로, 성능이 이상적이지 않더라도 모델이 수행되고 모든 것이 작동하는지 확인하고 있습니다. 실제로 prompt engineering(프롬프트 엔지니어링)에 들어가기 전까지는 성능이 좋지 않을 수 있지만, 프롬프트는 최소한 일부 예제 데이터를 올바르게 예측하도록 모델을 이끌어야 합니다.
기준선에 대한 성공률을 계산하고 자동화된 평가로 넘어가세요.
자동화된 평가
모델을 영원히 수동으로 평가해서는 안 되므로 어느 시점에는 자동화된 평가를 설정하는 것이 현명합니다. 여기서는 예제 데이터를 늘리고 클래스 균형에 주의를 기울이고 싶습니다. 세 가지 클래스(버그, 기능 요청, 질문)만 예측하려고 하므로 100개의 예제로 구성된 평가 세트에 각각 적절한 양이 있는지 확인해야 합니다.
제가 한 일은 사용자 메시지와 정답으로 구성된 Python dictionary(딕셔너리)를 만드는 것이었습니다. dictionary의 예제를 반복하여 해당 메시지/답변 쌍으로 LLM을 호출하고 점수를 계산했습니다(여기서는 모델 출력이 이상적인 답변과 일치하는 평균 횟수).
앱을 평가하기 위해 간단한 평균 accuracy score(정확도 점수)를 사용하고 미리 정의된 100개 예제의 evaluation set(평가 세트)에서 프롬프트를 평가할 것입니다. 다음은 사용할 코드입니다:
def basic_prompt(evalset_start=400, evalset_end=500):
count, score_tags = 0, 0
for element in filtered_data[evalset_start:evalset_end]:
# print(element)
ticket_text = element['description']
# Prompt – Classify Class
prompt = f"""
Classify the text delimited by triple backticks into one of the following classes.
Classes: {desired_tags}
Text: ```{ticket_text}```
Class: """
response = get_completion(prompt)
print("Prediction: "+response)
if(response == element['question']):
score_tags += 1
print("Correct. Actual: "+element['question'])
else:
print("Incorrect. Actual: "+element['question'])
count += 1
print()
print("__________________")
print(f"Priority Accuracy: {score_tags/count}")
return score_tags/count
acc['basic_prompt'] = basic_prompt(evalset_start_all, evalset_end_all)
교훈: 첫 번째 metrics(지표)는 상당히 실망스러울 수 있지만, evaluation harness(평가 하네스)를 조기에 설정하면 파이프라인이 예상대로 작동하는지 확인하고 prompt engineering(프롬프트 엔지니어링) 실험이 전반에 걸쳐 동일한 rubric(기준)으로 평가되도록 할 수 있습니다.
이제 재미있는 부분으로 넘어가겠습니다:
프롬프트 엔지니어링
범위를 정했고 예비 평가 하네스도 준비했습니다. 다음 단계는 프롬프트를 다듬는 것입니다.
이러한 실험에서 저는 프롬프트 변경만으로 이 프롬프트를 17% 정확도에서 90% 이상으로 향상시켰습니다. 아래 표와 그래프에서 일반적인 접근 방식을 볼 수 있지만 걱정하지 마세요. 중요한 변경 사항을 자세히 살펴보겠습니다!

각 실험과 그 결과 정확도

Delimiters(구분 기호)를 사용하여 모델 돕기 - 그리고 Prompt Injections(프롬프트 주입) 방지
delimiters(구분 기호)를 사용하여 프롬프트에 사용자 입력을 삽입하는 위치를 지정할 수 있습니다. 이는 모델이 사용자 입력의 시작과 끝을 식별하는 데 도움이 됩니다(특히 수십 줄에서 수백 줄이 될 수 있는 지원 티켓과 같은 것에 좋습니다).
이는 또한 악의적인 사용자가 LLM을 조작하여 해서는 안 되는 작업을 수행하도록 시도하는 prompt injections(프롬프트 주입)을 방지하는 데 도움이 될 수 있습니다. 구분 기호는 다음과 같이 무엇이든 될 수 있습니다: ```, """, < >,
다음은 기본 프롬프트를 구조화한 방법입니다(실제로 이것은 평가 하네스를 설정하는 데 사용한 프롬프트입니다):
"""Classify the text delimited by triple backticks into one of the following classes.
Classes: 'type_bug', 'none', 'type_feature_request', 'question'
Text: ```{ticket_text}```
Class:
"""
기본 프롬프트는 17% 정확도에 불과했습니다. 시작은 했지만 훨씬 더 잘해야 합니다. 몇 가지 예제를 추가해봅시다:
Prompt Context Window(프롬프트 컨텍스트 윈도우) 내부에 예제 추가
모델에 프롬프트와 예상되는 생성 출력의 구체적인 예제를 제공하는 것은 성능을 빠르게 개선하는 가장 좋은 방법 중 하나입니다. 우리는 LLM이 문제뿐만 아니라 예제(이 경우 고객 성공 티켓)의 복잡성, 톤, 간결성에 대해 더 많이 학습하도록 미묘하게 돕고 있습니다.
또한 모델이 올바른 형태의 출력을 생성하도록 안내하고 있습니다. 예를 들어, 간단한 변경이 원하는 출력을 형성하는 데 어떻게 도움이 되는지 보여주는 toy problem(장난감 문제)이 있습니다. 예제를 볼 수 있습니다 - 프롬프트를 아래 A:와 같은 것으로 끝내면 모델이 자연스럽게 답변으로 채웁니다. 예제 답변을 구조화하는 방식에 따라 모델의 응답 복잡성을 지정할 수 있습니다.

LLM은 일반적으로 예제가 없는 zero-shot learning(제로샷 학습)에서 훌륭하지만, 더 작은 모델을 선택하면 one-shot learning(원샷 학습) 또는 few-shot learning(퓨샷 학습)을 사용하고 예상 답변의 예제를 포함하여 성능을 크게 향상시킬 수 있습니다.
실험을 위해 동일한 일반 프롬프트 골격에 다양한 양의 예제를 추가했습니다:
"""Classify the text delimited by triple backticks into one of the following classes.
Classes: {desired_tags}
Text: ```{ticket_text1}```
Class: question
Text: ```{ticket_text2}```
Class: type_bug
<...more examples here>
Text: ```{ticket_text}```
Class:
"""
5개의 예제를 추가하면 정확도가 25%에서 30%로 향상되었고, 프롬프트에 20개의 무작위 예제를 추가하면 정확도가 70%로 증가했습니다.
교훈: 우리와 같은 문제의 경우, 더 세밀한 프롬프트 엔지니어링을 수행하기 전에 예제를 추가하는 것을 고려하세요. 인간과 마찬가지로 기계도 문제에 대한 화려한 설명보다 실제 예제에서 더 잘 학습하는 경우가 많습니다.
클래스가 의미하는 바 설명
Though “bug,” “feature request,” and “question” are common terms, defining each term can be a simple but effective approach. In our case, this led to a 5% uptick in accuracy:
"""
Given the following description for each class:
type_feature_request: A request for a feature by a user of Weights & Biases.
type_bug: A bug report by a user of Weights & Biases.
question: If the request is not related to Weights & Biases; or doesn't fit the above 2 categories.
Classify the text delimited by triple backticks into one of the following classes.
Classes: {desired_tags}
{examples}
Text: ```{ticket_text}```
Class:
"""
모델의 Configuration Parameters(구성 매개변수) 변경
프롬프트를 변경하는 것 외에 할 수 있는 또 다른 일은 모델 구성을 조정하는 것입니다. 각 parameter(매개변수)는 모델이 다음 단어를 생성하는 방법에 대한 결정에 영향을 미칠 수 있습니다. Together.ai와 같은 LLM playground는 이러한 inference time parameters(추론 시간 매개변수)를 조작할 수 있게 해줍니다.
-
Max Tokens(최대 토큰): 모델이 생성할 토큰 수를 제한합니다. 이는 모델이 다음 단어를 선택하는 선택 프로세스를 거치는 횟수에 상한을 두어 시간과 컴퓨팅을 절약합니다.
-
Random Sampling(무작위 샘플링): 항상 가장 확률이 높은 단어를 선택하는 대신 모델이 무작위로 단어를 선택합니다. 이는 약간의 변동성을 도입하고 단어가 반복되지 않도록 합니다.
-
Top K and Top P Sampling(Top K 및 Top P 샘플링): 무작위 샘플링을 사용하면 모델이 너무 창의적이 되어 단어를 무작위로 선택할 수 있습니다. Top P 및 Top K 샘플링을 사용하면 변동성을 도입하면서도 모델이 선택할 수 있는 단어의 공간을 제한합니다. Top K는 확률이 가장 높은 k개의 토큰만 선택합니다. Top P는 결합된 확률이 p를 초과하지 않는 예측을 선택합니다. Top K를 사용하면 모델이 선택할 토큰의 수를 지정하지만 Top P를 사용하면 총 확률을 선택합니다.
-
Temperature(온도): 출력의 무작위성을 제어하는 데에도 도움이 됩니다. 온도가 높을수록 무작위성이 높아지고 모델이 더 창의적입니다. 반대로 온도가 낮을수록 모델이 더 예측 가능합니다. 온도를 변경하면 실제로 모델의 예측이 변경되는 반면 다른 샘플링 기법은 모델이 선택하는 예측만 변경합니다.
저는 모델 매개변수를 조정하여 temperature(온도)를 조정함으로써 약간의 향상을 얻을 수 있었습니다. 20개의 예제를 추가하고 온도를 변경하여 90% 정확도를 달성했습니다.
JSON 또는 HTML과 같은 Structured Output(구조화된 출력) 요청
모델에게 매우 구체적인 구문으로 응답하도록 요청할 수 있습니다. 이는 사람이 모델 출력을 파싱하는 것을 더 쉽게 만들 수 있지만, 프롬프트를 연결하려는 경우 특히 유용합니다. 다음 LLM 호출에 필요한 특정 형식의 출력을 모델에 요청할 수 있습니다.
예제:
"""
Given the text delimited by triple backticks, perform the following actions:
1 - Summarize what the user wants in 1-2 lines.
2 - Recommend a next action based on the user' request.
3 - Determine if the request is related to the product or company 'Weights & Biases'
4 - Classify the into one of the following classes. Classes: {desired_tags}
5 - Output a json object that contains the following keys: summary, recommended_action, is_wb, class
Here's the text ```{ticket_text}```
Make sure the output is only a json object.
"""
단계 지정
One interesting prompting technique that worked for me was specifying the steps I wanted the model to take and use that to generate the final output. Instead of allowing the model to approach the problem however it wanted, I asked it to first summarize what the user wants, determine if the request is related to W&B, then predict the class. Doing this gave me a small bump in performance.
"""
Given the text delimited by triple backticks, perform the following actions:
1 - Summarize what the user wants in 1-2 lines.
2 - Recommend a next action based on the user' request.
3 - Determine if the request is related to the product or company 'Weights & Biases'
4 - Classify the into one of the following classes. Classes: {desired_tags}
5 - Output a json object that contains the following keys: summary, recommended_action, is_wb, class
Here are some examples help you with the classification step.
{examples}
And here's the text ```{ticket_text}```
"""
각 단계의 추론 요청
완전히 공개하자면, 모든 기법이 모든 문제에 효과가 있는 것은 아닙니다. 이것이 그러한 예입니다. 각 단계의 추론을 제공하도록 모델에 요청해보았습니다. 이것은 실제로 모델의 성능을 20% 감소시켰으므로 폐기했습니다.
"""
Given the text delimited by triple backticks, perform the following actions:
1 - summary: Summarize what the user wants in 1-2 lines.
2 - summary_reasoning: Explain your reasoning for the summary.
3 - recommended_action: Recommend a next action based on the user' request.
4 - recommended_action_reasoning: Explain your reasoning for the recommended next action.
5 - is_wb: Determine if the request is related to the product or company 'Weights & Biases'.
6 - is_wb_reasoning: Explain your reasoning for detemining if the request is W&B related.
7 - class: Classify the into one of the following classes. Classes: {desired_tags}
8 - Output a json object that contains the following keys: summary, summary_reasoning, recommended_action, recommended_action_reasoning, is_wb, is_wb_reasoning, class
Here are some examples help you with the classification step.
{examples}
And here's the text ```{ticket_text}```.
Make sure the output is only a json object.
"""
Chain Of Thought Prompting(사고 연쇄 프롬프팅)
마지막 프롬프트에서 모델이 수행하기를 원하는 몇 가지 단계를 지정했습니다. 하지만 출력을 생성하기 전에 모델이 자체적으로 중간 reasoning steps(추론 단계), 즉 chain of thought(사고 연쇄)를 생성하도록 지시할 수도 있습니다. 이는 모델이 복잡한 추론 작업을 더 잘 수행하는 데 도움이 됩니다.

정형적인 사고 연쇄 예제
Prompt Chaining(프롬프트 체이닝)
Prompt chaining(프롬프트 체이닝)은 chain of thought prompting(사고 연쇄 프롬프팅)과 유사하지만, 하나의 프롬프트에서 모두 수행하는 대신 문제를 여러 프롬프트로 나누어 한 프롬프트의 생성이 다음 프롬프트의 컨텍스트에 추가되도록 할 수 있습니다. 이렇게 하면 각 프롬프트가 더 집중되어 성능이 향상될 가능성이 높아지고, 각 단계가 전체 context window(컨텍스트 윈도우)를 사용할 수 있기 때문에 컨텍스트 제한을 피할 수 있으며, 비용이 절감되고 코드를 읽기가 훨씬 쉬워집니다.
또한 각 단계를 자체 프롬프트로 나누면 각 단계에 대해 custom evaluations(사용자 정의 평가)를 작성할 수 있어 평가하기가 훨씬 쉬워집니다.
마지막으로, 1단계의 결과가 2단계에서 매우 다른 workflow를 선택하는 복잡한 workflow(워크플로)가 있는 경우, 프롬프트를 분해하면 다음에 호출할 프롬프트 세트를 동적으로 선택하는 데 도움이 될 수 있습니다.
이것은 특히 복잡한 문제에 매우 강력한 기법입니다. 여기 우리 작업의 경우에는? 그다지 잘 되지 않았습니다. 하지만 모델을 구축하고 태그 분류보다 더 미묘한 작업을 요청함에 따라 프롬프트 체이닝에 크게 의존할 것입니다. 다음은 제가 사용한 코드입니다:
# Prompt – Classify Class
prompt = f"""
Given the text delimited by triple backticks, perform the following actions:
1 - summary: Summarize what the user wants in 1-2 lines.
2 - summary_reasoning: Explain your reasoning for the summary.
3 - recommended_action: Recommend a next action based on the user' request.
4 - recommended_action_reasoning: Explain your reasoning for the recommended next action.
5 - is_wb: Determine if the request is related to the product or company 'Weights & Biases'.
6 - is_wb_reasoning: Explain your reasoning for detemining if the request is W&B related.
7 - Output a json object that contains the following keys: summary, summary_reasoning, recommended_action, recommended_action_reasoning, is_wb, is_wb_reasoning, class
And here's the text ```{ticket_text}```.
Make sure the output is only a json object.
"""
response_json = get_completion(prompt)
# print("Prompt: "+prompt)
print("Prediction: ")
response = json.loads(response_json)
print("Summary: "+response['summary'])
print("Summary Reasoning: "+response['summary_reasoning'])
print("Recommended Action: "+response['recommended_action'])
print("Recommended Reasoning: "+response['recommended_action_reasoning'])
print("Is W&B Related: "+str(response['is_wb']))
print("Is W&B Related Reasoning: "+response['is_wb_reasoning'])
prompt_2 = f"""
Given the following info about a user request:
1 - text delimited by triple backticks: ```{ticket_text}```
2 - summary of what the user wants: {response['summary']}
3 - recommended next action based on the user' request: {response['recommended_action']}
4 - whether the request is related to the product or company 'Weights & Biases': {response['is_wb']}
Classify the text into one of the following classes. Classes: {desired_tags}
Here are some examples help you with the classification step.
{examples}
Only print the name of the class"""
프롬프트에 대한 사용자 정의 평가
프롬프트를 더 복잡하게 만들면 evaluation prompts(평가 프롬프트)를 개선할 수 있습니다. LLM에게 모든 조건이 충족되는지 확인하도록 요청하는 추가 호출을 추가할 수 있습니다 - 예: 모든 중간 단계에 대해 합리적인 출력을 생성하고 있습니까? 추론이 건전합니까? W&B 문서를 기반으로 제안된 다음 작업입니까? 코드가 실행 가능합니까?
이 모든 것이 성능을 높일 수 있지만 우리의 간단한 시작 문제의 경우,
이 프로젝트에서 시도할 기회가 없었지만 다음에 기대하고 있는 두 가지 다른 고급 prompting techniques(프롬프팅 기법)이 있습니다: tree of thought prompting(생각 트리 프롬프팅)과 ReAct입니다. 이 시리즈의 후속 게시물에서 이를 더 자세히 다룰 예정이지만, 더 고급 프롬프팅 기법에 대해 배우고 싶다면 이 가이드를 추천합니다.
결론
이 실험에서 가장 크게 깨달은 것은 프롬프트에 대한 간단한 반복과 모델 매개변수에 대한 직접적인 조정이 모델 출력에 엄청난 긍정적 효과를 미친다는 것입니다. 실제로 우리는 그렇게 함으로써 17% 정확도에서 90% 이상으로 향상시킬 수 있었습니다.
가장 효과적이었던 것은 프롬프트에 다양한 예제와 해당 태그를 추가하는 것과 모델이 문제를 단계별로 해결하도록 돕기 위한 chain-of-thought prompting(사고 연쇄 프롬프팅)이었습니다.
이것은 실제 LLM 앱 구축에 관해 게시할 일련의 기사 중 첫 번째입니다. fine-tuning(파인 튜닝)부터 고급 프롬프팅 기법, deployment(배포)까지 모든 것을 다룰 예정이며 다음 편에서 여러분을 만나기를 바랍니다! 그 동안 LLM 앱 구축에 대한 무료 대화형 과정을 보려면 강좌 페이지를 방문하세요.
다음에 또 만나요!