ReAct Prompting: How We Prompt for High-Quality Results from LLMs | Chatbots & Summarization
프롬프트 엔지니어링은 대규모 언어 모델(LLMs)로부터의 결과의 품질과 정확성을 향상시키는 방법을 찾는 것에 관한 것입니다. 최근 몇 개월 동안, 생각의 연쇄(chain-of-thought) 프롬프팅과 같은 발전은 프롬프트 엔지니어가 그들의 결과의 품질을 향상시키는 데 도움을 주었습니다. 이 글에서는 우리의 목표 상태 출력에 도달하는 방법을 정말로 이해하고 프롬프팅 지시사항의 이해를 더욱 깊게 하는 데 도움을 주는 ReAct 프롬프팅이라는 또 다른 프롬프팅 기술을 살펴보겠습니다.
ReAct 프롬프팅이 무엇인가요?
ReAct는 LLM의 프롬프팅 및 결과 처리 접근법으로, 추론, 행동 계획, 지식의 원천 통합을 결합하여 LLM이 언어 모델을 넘어서 실제 세계의 정보를 예측에 사용하게 합니다. ReAct는 추론과 행동의 결합입니다.
ReAct를 소개한 논문은 이것이 생각의 연쇄(chain-of-thought) 프롬프팅보다 더 나은 것으로 보였습니다. 후자와 달리 ReAct는 사실을 그렇게 많이 환영하지 않습니다. 그러나 최상의 결과를 위해 논문은 ReAct와 생각의 연쇄 프롬프팅을 자체 일관성 검사와 결합하는 것을 제안합니다.
How to Use ReAct Prompting for Your Use Cases
ReAct 프롬프팅을 구현하려면 추론, 의사 결정, 행동 계획 및 외부 지식을 포함하는 모든 LLM 워크플로우에 적용할 수 있습니다. ReAct에는 다음과 같은 핵심 구성 요소가 필요합니다.
1.추론 및 행동 계획을 위한 ReAct 지시 프롬프트 제공
아래에는 그 구성 요소와 함께 ReAct 프롬프트의 예가 나와 있습니다.
LLM에게 필요한 네 가지 핵심 정보를 포함하는 프롬프트:
- 기본 프롬프트 지시(Primary prompt instruction): 프롬프트는 LLM에게 주요 지시를 제공해야 합니다. 이것은 거의 모든 프롬프팅 프레임워크에서 사용됩니다. 목표는 모델이 우리가 실제로 원하는 작업을 이해하게 시작하는 것입니다.
- ReAct 단계(ReAct steps): 추론 및 행동 계획을 위한 단계를 지정합니다. “생각, 행동, 관찰 단계를 교차로”는 모든 ReAct 프롬프트에서 사용할 수 있는 표준 순서입니다. 이 중 일부는 작업과 주요 정보에 대해 어떻게 생각할지 완전히 개요를 제공하는 훨씬 더 구체적인 생각 섹션을 사용합니다. 이것은 거의 모든 다른 지시 중심의 프롬프트에 대해 개요를 제공하는 시스템 프롬프트와 유사합니다. 또한 특정 생각 섹션에 대해 다양한 입력에 대한 교환 가능한 프롬프트를 가지도록 측면 기반의 프롬프트 접근법을 구현할 수도 있습니다. 이에 대한 최고의 버전은 이 대화 요약 기사에서 개요를 제공합니다.
- 추론(Reasoning): 모델이 주어진 상황이나 문제에 대해 어떻게 생각해야 하는지를 안내합니다. 이는 모델이 문제를 단계별로 분석하도록 도와줍니다. “현재 상황에 대해 생각할 수 있다”와 같은 일반적인 지시나 “이것을 단계별로 생각해보자”와 같은 생각의 연쇄 프롬프트로 추론을 가능하게 합니다. 이것은 몇 번의 샷 프롬프팅 프레임워크에 연결되어 이유를 행동에 연결하는 방법에 대한 정확한 예를 제공합니다.
- 행동(Actions): 모델이 추론을 바탕으로 취해야 할 행동을 지시합니다. 예를 들어, 특정 정보를 검색하거나 키워드를 찾는 등의 명령을 포함할 수 있습니다. 마지막 핵심 정보는 추론 생각에 대한 응답으로 LLM이 선택할 수 있는 일련의 행동 명령입니다. 위의 예에서 “Search[entity]”, “Lookup[keyword]”, “Finish[answer]”는 행동 명령입니다. 몇 번의 샷 예제 덕분에 LLM은 “entity”, “keyword”, “answer”를 런타임에 적절하게 대체되어야 할 플레이스홀더로 취급해야 한다는 것을 압니다.
LLMs는 분류 작업에 매우 뛰어나며, 특히 주어진 문맥에 대한 “태그”로 사용될 수 있는 단일 토큰을 생성하는 데 탁월하다는 아이디어에서 크게 영향을 받았습니다. 이 시스템은 동적 데이터 챗봇에서 자주 사용되며, 이를 통해 기존 지식을 활용하여 질의에 응답하고 필요할 때 API로부터 동적 데이터를 포함시킬 수 있습니다. 기본적인 프롬프트 지시와 목표 상태 출력 정의 시스템 대신에, 이 프롬프트를 매우 높은 정확도를 가진 분류 시스템에 의해 주도되는 프롬프트 시스템으로 바꾸고 있습니다.
즉, LLMs의 분류 능력을 최대한 활용하여, 동적 데이터와 기존 지식을 결합하여 사용자의 질문에 더 정확하게 응답하는 새로운 프롬프트 시스템을 구축하려는 것입니다.
2. 프롬프트에 Few-Shot 예제 제공
LLM에게 생각, 행동, 관찰 단계를 보여주기 위해 프롬프트에 몇 가지 작업 특정의 문맥 내 예제를 포함시킵니다.
질문-응답 작업에 대한 몇 가지 샷 예제는 아래와 같습니다.
예제의 행동에서 “[Colorado orogeny]”나 “[eastern sector]”와 같은 값들이 플레이스홀더 대신에 지정되어 있는 것에 주목하세요. 이것이 LLM이 행동 명령의 플레이스홀더를 문맥에 관련된 값으로 대체하는 방법을 배우는 방법입니다.
사실 확인 작업에 대한 몇 가지 샷 예제는 아래와 같습니다.
최적의 예제 수는 작업 및 데이터셋에 따라 다르며 실험적으로 결정되어야 합니다. 그러나 실제로는 몇 개만 필요합니다. 우리가 특정 도메인에 대한 새로운 지식을 모델에 추가하려는 것이 아니라 목표 상태 출력 정의를 정의하려고 하기 때문에, 3-6개만 있어도 완벽하게 괜찮습니다.
간단히 말하면, LLM을 가이드하기 위해 많은 예제를 제공할 필요는 없습니다. 몇 가지 적절한 예제만으로도 모델에 원하는 출력을 정의하는 데 충분합니다.
3.지식 원천 참조하기
마지막으로, LLM에 의해 발행된 행동 명령에 응답하여 애플리케이션이 참조할 수 있는 관련 지식 원천 및 응용 프로그래밍 인터페이스(API)를 설정해야 합니다.
이러한 원천은 세계에 대한 일반적인 정보나 고객 특정 정보를 사용하여 LLM의 추론 및 행동 계획에 영향을 줄 수 있게 해줍니다 — 이 정보는 매우 동적이고 변동성이 클 수 있습니다.
예를 들어, 위의 예제 프롬프트에서 LLM이 생각에 응답하여 “Search[entity]” 행동을 생성할 때(“entity”는 문맥 특정 값으로 대체됨), 애플리케이션은 해당 엔터티에 대한 위키백과 검색 API를 쿼리하고 그 위키백과 페이지의 처음 몇 단락을 반환합니다.
그러나 지속적으로 변경되는 내부 제품 및 가격 데이터베이스에서 정보를 가져올 수도 있습니다.
지정된 엔터티가 그 지식 원천에 존재하지 않는 경우, LLM이 작업을 다양한 각도에서 접근하도록 의미론적으로 유사한 값을 제공할 수 있습니다. 아래의 예제에서 이를 보여줍니다:
이미 추출한 지식으로 쉽게 쿼리할 수 있는 벡터 데이터베이스를 주로 사용합니다. 내장된 벡터 생성 서비스를 사용하여 입력 작업을 기반으로 가장 관련 있는 정보를 검색하기 때문에 외부 서비스로의 복잡한 동적 API 호출을 다룰 필요가 없습니다. 이 방식은 데이터베이스를 모든 입력(예: 챗봇)에 대해 쿼리하는 일반적인 시스템보다 훨씬 더 잘 작동합니다. 왜냐하면 생각 단계를 사용하여 검색된 문맥이 실제로 입력과 관련이 있는지 확인할 수 있기 때문입니다. 또한 모델에게 무작정 반환된 정보를 사용하도록 요청하지 않습니다. 벡터 데이터베이스에 저장된 문서들이 모두 의미론적으로 매우 유사한 경우 잘못된 문서를 끌어오게 되어 재앙스러운 결과를 초래할 수 있습니다. 예를 들어, 데이터베이스에 NDA 조항만 있고 사용자가 잘못된 조항과 의미론적으로 일치하는 매우 혼란스러운 입력을 넣는다고 상상해보십시오. ReAct 프롬프팅은 입력과 반환된 내용을 문맥화하고 문맥이 실제로 일치하는지 이해하는 데 도움을 줄 수 있습니다.
다음 섹션에서는 여러 LLM 지원 비즈니스 워크플로우에 대해 이러한 단계를 시연합니다.
은행 고객 서비스 챗봇을 위한 ReAct 프롬프팅 시스템:
첫 번째 파이프라인은 고객으로부터의 복잡한 지원 및 서비스 문의를 처리하는 챗봇 프레임워크를 살펴봅니다. 은행 챗봇은 주택 담보 대출 계산기와 같은 것들에 대한 외부 API 서비스와 고객 데이터베이스와 같은 내부 지식 기반을 많이 사용하기 때문에 좋은 예시 사례입니다. 사용자의 쿼리는 종종 모호하기 때문에 의도를 분류하는 것이 중요합니다.
이러한 챗봇 프레임워크는 다음과 같은 방식으로 작동합니다:
- 사용자 쿼리 수신: 사용자로부터의 질문이나 요청을 받습니다.
- 의도 분류: ReAct 프롬프팅을 사용하여 사용자의 의도를 정확하게 분류합니다.
- 외부 API 및 내부 지식 기반 조회: 사용자의 요청에 따라 필요한 정보를 검색하기 위해 외부 서비스나 내부 데이터베이스를 조회합니다.
- 적절한 응답 생성: 검색된 정보를 기반으로 사용자의 질문에 대한 적절한 응답을 생성합니다.
이러한 방식으로, 은행 챗봇은 고객의 다양한 요청에 신속하고 정확하게 응답할 수 있습니다.
작동 원리
챗봇 프레임워크는 ReAct 프롬프팅, 피드백 루프, 외부 데이터 원천의 복잡한 시스템을 사용하여 고객의 질문을 처리합니다. 이 과정에서 우리가 사용하는 문맥 내 정보가 최종 고객 목표에 도달하는 데 관련이 있는지에 대한 이해도를 가지고 있습니다. 그래픽의 복잡성으로 인해 언급되지 않은 주요 단계 중 하나는 대화 응답 생성과 임베디드 벡터 생성을 위한 세밀하게 조정된 모델입니다.
의도 분류(Intent Classification)
더 복잡한 챗봇에서 의도 분류를 사용하여 다양한 의도에 대해 동적으로 프롬프트를 제공할 수 있게 합니다. 이는 대화가 진행되어야 할 특정 방향에 기반하여 모델에 다른 지시와 목표 상태 출력을 제공할 수 있음을 의미합니다. 이로 인해 우리는 덜 일반적인 작업 특정 프롬프트를 가질 수 있어 정확도가 크게 향상됩니다. 전체 대화를 고려하여 의도를 생성할 때 전체 대화에 대해 이 모델을 세밀하게 조정할 수 있습니다.
ReAct Framework for response generation and context management
LLM 위의 ReAct 프레임워크는 사용자의 의도와 일치하는 최종 결과를 향해 대화를 안내하는 데 있어 주요한 원동력입니다. 우리의 생각 파이프라인은 지금까지의 쿼리나 대화를 기반으로 관련 데이터와 정보를 얻기 위해 어떤 행동을 취해야 하는지 관리합니다. 생각 파이프라인은 우리가 필요한 작업을 어떻게 배열했는지를 기반으로 모든 하류 작업을 안내하기 때문에 ReAct 프레임워크에서 가장 중요한 부분입니다. 우리는 특정 형식을 따르도록 생각 생성에 대한 맞춤형 LLM을 훈련시켰습니다. 이 형식의 목표는 생성 과정 전반에 걸쳐 필요한 모든 작업을 다단계 대화에서 쉽게 파싱할 수 있는 형식으로 upfront에 개요를 제공하는 것입니다.
우리가 생성하는 ‘생각’ 응답은 다음 형식으로 작업을 개요화합니다:
- 지금 해야 할 것: 현재 진행해야 할 주요 작업을 설명합니다.
- 데이터 반환 또는 생성 시 발생하는 일: 항상 동적 함수를 호출하는 것은 아닙니다. 때로는 단순히 응답을 생성하기도 합니다. 이것이 우리가 이 프레임워크를 사용하는 주요 이유 중 하나입니다. 대부분의 챗봇은 둘 중 하나만 수행합니다.
- 결과가 의미 없을 경우 해야 할 것: 이것이 프롬프트의 일부로 포함되어 있으면 다음 ‘생각’ 생성에 도움이 됩니다.
‘행동’ 단계는 우리의 원천에서 데이터를 추출하는 과정을 실행합니다. 이를 시작하기 위해 코드와 함께 사용되는 태그를 생성합니다. 은행 챗봇에서 이것은 외부 API 서비스 또는 데이터베이스 조회를 의미합니다. 행동 단계는 데이터를 어디서 가져와야 하는지 이해하기 위한 문맥 내 분류자 역할을 합니다. 이것의 더 복잡한 버전은 ToolFormer와 조금 더 유사하게 작동하여 동적 데이터를 채우기 위해 사용되는 키와 함께 응답을 생성합니다. 이를 통해 응답을 생성하고 필요한 동적 데이터를 동일한 단계에서 가져올 수 있습니다.