본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 1. · 68 Views
Context Engineering 완벽 가이드
AI 에이전트의 성능을 좌우하는 컨텍스트 엔지니어링의 핵심 개념과 실전 패턴을 다룹니다. 동적 시스템 프롬프트부터 요약 미들웨어까지, LLM 기반 애플리케이션의 품질을 높이는 기법을 배워봅니다.
목차
1. 컨텍스트 엔지니어링 개념
김개발 씨는 최근 회사에서 AI 챗봇 프로젝트를 맡게 되었습니다. GPT API를 연동해서 간단한 고객 상담 봇을 만들었는데, 답변 품질이 들쭉날쭉했습니다.
어떨 때는 완벽한 답변을, 어떨 때는 엉뚱한 답변을 내놓았습니다.
컨텍스트 엔지니어링은 LLM에게 전달하는 정보를 체계적으로 설계하고 관리하는 기법입니다. 마치 훌륭한 비서에게 업무를 맡길 때, 필요한 배경 정보와 지침을 명확히 전달하는 것과 같습니다.
이것을 제대로 이해하면 AI 에이전트의 응답 품질을 획기적으로 높일 수 있습니다.
다음 코드를 살펴봅시다.
from langchain.schema import SystemMessage, HumanMessage
# 컨텍스트 엔지니어링의 기본 구조
context = {
"system_prompt": "당신은 친절한 고객 상담 전문가입니다.",
"user_profile": {"name": "홍길동", "tier": "VIP"},
"conversation_history": [],
"available_tools": ["search_faq", "create_ticket"],
"constraints": {"max_response_length": 500}
}
# 컨텍스트를 메시지로 변환
def build_messages(context, user_input):
messages = [SystemMessage(content=context["system_prompt"])]
messages.append(HumanMessage(content=user_input))
return messages
김개발 씨는 입사 2년 차 백엔드 개발자입니다. 최근 회사에서 AI 기반 고객 상담 챗봇 프로젝트를 맡게 되었습니다.
OpenAI API 문서를 읽고 간단한 챗봇을 만들었는데, 결과가 만족스럽지 않았습니다. "왜 같은 질문인데 답변이 매번 다르지?" 김개발 씨는 고개를 갸웃거렸습니다.
그때 AI 프로젝트 경험이 많은 박시니어 씨가 다가왔습니다. "혹시 컨텍스트 엔지니어링에 대해 들어봤어요?" 컨텍스트 엔지니어링이란 정확히 무엇일까요?
쉽게 비유하자면, 컨텍스트 엔지니어링은 마치 신입 직원에게 업무를 인수인계하는 것과 같습니다. 아무런 설명 없이 "이 일 해주세요"라고 하면 결과가 엉망이 됩니다.
하지만 회사의 업무 방침, 이전 담당자의 노하우, 고객의 성향, 주의할 점 등을 꼼꼼히 전달하면 훨씬 나은 결과를 얻을 수 있습니다. LLM도 마찬가지입니다.
단순히 사용자 질문만 전달하면 LLM은 어떤 맥락에서 답변해야 할지 모릅니다. 하지만 시스템 프롬프트, 사용자 정보, 대화 이력, 사용 가능한 도구 등을 체계적으로 전달하면 훨씬 정확하고 일관된 응답을 얻을 수 있습니다.
프롬프트 엔지니어링이라는 용어를 많이 들어보셨을 겁니다. 컨텍스트 엔지니어링은 프롬프트 엔지니어링을 포함하는 더 넓은 개념입니다.
프롬프트 엔지니어링이 "어떻게 질문할까"에 집중한다면, 컨텍스트 엔지니어링은 "어떤 정보를 어떤 순서로 전달할까"까지 고려합니다. 위의 코드를 살펴보겠습니다.
context 딕셔너리에는 시스템 프롬프트, 사용자 프로필, 대화 이력, 사용 가능한 도구, 제약 조건이 담겨 있습니다. 이 모든 정보가 LLM의 응답 품질을 결정합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 VIP 고객이 문의를 하면, 일반 고객과는 다른 톤으로 응대해야 합니다.
고객의 등급 정보를 컨텍스트에 포함시키면 LLM이 알아서 적절한 어조로 답변합니다. 주의할 점도 있습니다.
컨텍스트에 너무 많은 정보를 담으면 오히려 역효과가 납니다. LLM의 토큰 한도를 초과하거나, 중요한 정보가 묻힐 수 있습니다.
필요한 정보를 선별하고 우선순위를 정하는 것이 핵심입니다. 박시니어 씨의 설명을 들은 김개발 씨는 무릎을 쳤습니다.
"아, 그래서 답변이 들쭉날쭉했군요! 저는 사용자 질문만 던졌거든요." 컨텍스트 엔지니어링을 제대로 이해하면 AI 에이전트의 성능을 한 단계 끌어올릴 수 있습니다.
이것은 단순히 기술이 아니라, LLM과 효과적으로 소통하는 방법론입니다.
실전 팁
💡 - 컨텍스트는 항상 구조화하여 관리하세요. 딕셔너리나 클래스로 정리하면 유지보수가 쉬워집니다.
- 토큰 비용을 고려해서 꼭 필요한 정보만 포함시키세요.
2. 모델 도구 라이프사이클 컨텍스트
김개발 씨는 컨텍스트 엔지니어링의 기본 개념을 이해했습니다. 하지만 막상 적용하려니 막막했습니다.
"도대체 어떤 종류의 컨텍스트가 있는 거지?" 박시니어 씨가 화이트보드에 세 가지 원을 그리기 시작했습니다.
컨텍스트는 크게 모델 컨텍스트, 도구 컨텍스트, 라이프사이클 컨텍스트 세 가지로 분류됩니다. 마치 요리사에게 레시피, 조리도구 설명서, 주방 운영 매뉴얼을 각각 제공하는 것과 같습니다.
각 컨텍스트는 LLM이 다른 측면의 정보를 이해하도록 돕습니다.
다음 코드를 살펴봅시다.
from dataclasses import dataclass
from typing import List, Dict, Any
@dataclass
class ContextBundle:
# 모델 컨텍스트: LLM의 역할과 행동 지침
model_context: Dict[str, Any] = None
# 도구 컨텍스트: 사용 가능한 함수와 API 정보
tool_context: Dict[str, Any] = None
# 라이프사이클 컨텍스트: 대화 상태와 세션 정보
lifecycle_context: Dict[str, Any] = None
# 실제 사용 예시
bundle = ContextBundle(
model_context={"role": "상담사", "tone": "친근함"},
tool_context={"functions": ["search", "book"], "api_limits": 100},
lifecycle_context={"session_id": "abc123", "turn_count": 5}
)
박시니어 씨가 화이트보드에 그린 세 개의 원에는 각각 이름이 적혀 있었습니다. 모델, 도구, 라이프사이클.
김개발 씨는 펜을 들고 메모할 준비를 했습니다. "첫 번째는 모델 컨텍스트예요." 박시니어 씨가 설명을 시작했습니다.
모델 컨텍스트는 LLM이 어떤 역할을 맡고, 어떻게 행동해야 하는지를 정의합니다. 마치 배우에게 배역을 설명하는 것과 같습니다.
"당신은 친절한 상담사입니다", "전문적이지만 쉬운 언어를 사용하세요" 같은 지침이 여기에 해당합니다. "두 번째는 도구 컨텍스트입니다." 도구 컨텍스트는 LLM이 사용할 수 있는 함수나 API에 대한 정보입니다.
마치 목수에게 어떤 연장이 있는지 알려주는 것과 같습니다. 검색 기능, 예약 기능, 결제 기능 등 각 도구가 무엇을 하는지, 어떤 매개변수가 필요한지 설명합니다.
"마지막은 라이프사이클 컨텍스트예요." 라이프사이클 컨텍스트는 현재 대화의 상태와 흐름에 대한 정보입니다. 몇 번째 대화인지, 이전에 어떤 이야기를 나눴는지, 사용자가 어떤 단계에 있는지 등을 포함합니다.
마치 진료 기록을 보고 환자의 상태를 파악하는 의사와 같습니다. 위의 코드에서 ContextBundle 클래스가 바로 이 세 가지를 담고 있습니다.
dataclass를 사용하면 간결하게 정의할 수 있습니다. 실무에서 이 구분이 왜 중요할까요?
예를 들어 챗봇의 역할을 바꾸고 싶을 때는 모델 컨텍스트만 수정하면 됩니다. 새로운 기능을 추가할 때는 도구 컨텍스트를 업데이트합니다.
대화 히스토리 관리 로직을 변경할 때는 라이프사이클 컨텍스트를 손봅니다. 관심사가 분리되어 있으니 유지보수가 훨씬 쉬워집니다.
초보 개발자들이 흔히 하는 실수는 모든 정보를 하나의 프롬프트에 뒤섞어 넣는 것입니다. 이렇게 하면 나중에 특정 부분만 수정하기가 어렵습니다.
처음부터 세 가지 영역을 분리해서 관리하는 습관을 들이세요. 김개발 씨는 고개를 끄덕였습니다.
"마치 프로그래밍의 관심사 분리 원칙과 같네요!" "맞아요. 좋은 소프트웨어 설계 원칙은 AI 시스템에도 그대로 적용됩니다."
실전 팁
💡 - 세 가지 컨텍스트를 별도의 파일이나 클래스로 관리하면 팀 협업이 수월해집니다.
- 도구 컨텍스트는 OpenAPI 스펙 형식으로 작성하면 문서화와 코드 생성에 유리합니다.
3. 동적 시스템 프롬프트
며칠 후, 김개발 씨는 새로운 문제에 부딪혔습니다. 챗봇이 낮에는 활발하게, 밤에는 차분하게 응대했으면 좋겠는데, 시스템 프롬프트를 매번 수동으로 바꿀 수는 없었습니다.
고민하던 중 문득 아이디어가 떠올랐습니다.
동적 시스템 프롬프트는 상황에 따라 실시간으로 변경되는 시스템 프롬프트입니다. 마치 상황에 맞게 매뉴얼을 자동으로 업데이트해주는 스마트한 비서와 같습니다.
시간대, 사용자 특성, 대화 맥락 등에 따라 LLM의 행동 지침을 유연하게 조절할 수 있습니다.
다음 코드를 살펴봅시다.
from datetime import datetime
from typing import Dict
def generate_dynamic_prompt(user: Dict, context: Dict) -> str:
# 시간대에 따른 인사말 조정
hour = datetime.now().hour
greeting_style = "활기찬" if 9 <= hour < 18 else "차분한"
# 사용자 등급에 따른 톤 조정
tone = "정중하고 격식있는" if user.get("tier") == "VIP" else "친근한"
# 이전 대화에서 불만 표시 여부 확인
if context.get("sentiment") == "negative":
extra = "고객의 불편함에 깊이 공감하며 응대하세요."
else:
extra = ""
return f"""당신은 {greeting_style} 분위기의 고객 상담 전문가입니다.
{tone} 말투로 응대하세요. {extra}"""
김개발 씨의 아이디어는 간단했습니다. 시스템 프롬프트를 고정된 문자열이 아니라, 함수가 생성하도록 만드는 것이었습니다.
"시스템 프롬프트도 코드처럼 조건문을 넣을 수 있지 않을까?" 이것이 바로 동적 시스템 프롬프트의 핵심 아이디어입니다. 정적인 텍스트 대신, 상황을 분석해서 그때그때 적절한 프롬프트를 생성하는 것입니다.
비유하자면, 콜센터 상담사의 응대 매뉴얼이 시간대별, 고객별로 자동으로 바뀌는 것과 같습니다. 아침에는 "좋은 아침입니다!"로 시작하고, 밤에는 "늦은 시간에 연락 주셨네요"로 시작하는 식입니다.
위의 코드를 살펴보겠습니다. generate_dynamic_prompt 함수는 세 가지 요소를 고려합니다.
첫째, 현재 시간입니다. 업무 시간에는 활기찬 분위기로, 야간에는 차분한 분위기로 응대합니다.
datetime.now().hour로 현재 시각을 확인합니다. 둘째, 사용자 등급입니다.
VIP 고객에게는 정중하고 격식 있게, 일반 고객에게는 친근하게 응대합니다. 같은 질문이라도 고객에 따라 다른 경험을 제공할 수 있습니다.
셋째, 대화 맥락입니다. 고객이 불만을 표시했다면 더욱 공감하는 자세로 응대해야 합니다.
이전 대화의 감정 분석 결과를 활용합니다. 실무에서 동적 프롬프트가 빛을 발하는 경우는 많습니다.
A/B 테스트로 어떤 톤이 더 효과적인지 실험할 수 있습니다. 특정 이벤트 기간에만 프로모션 안내를 추가할 수 있습니다.
고객의 언어 설정에 따라 다국어 응대도 가능합니다. 주의할 점은 프롬프트 생성 로직이 복잡해지면 디버깅이 어려워진다는 것입니다.
어떤 조건에서 어떤 프롬프트가 생성되었는지 로깅하는 것이 중요합니다. 문제가 생겼을 때 원인을 추적할 수 있어야 합니다.
김개발 씨는 이 기법을 적용한 후 고객 만족도가 눈에 띄게 올랐습니다. 같은 AI라도 상황에 맞는 응대를 하니 훨씬 자연스러워졌기 때문입니다.
실전 팁
💡 - 동적 프롬프트 생성 시 항상 로깅을 남겨서 어떤 프롬프트가 사용되었는지 추적하세요.
- 프롬프트 템플릿을 별도 파일로 관리하면 비개발자도 쉽게 수정할 수 있습니다.
4. 메시지 주입 패턴
컨텍스트 엔지니어링을 공부하던 김개발 씨는 새로운 고민에 빠졌습니다. 대화 중간에 중요한 정보를 LLM에게 알려줘야 하는데, 시스템 프롬프트에 넣기엔 타이밍이 맞지 않았습니다.
대화 흐름 중간에 정보를 끼워 넣을 방법이 없을까요?
메시지 주입 패턴은 대화 히스토리 중간에 시스템 메시지나 컨텍스트 정보를 삽입하는 기법입니다. 마치 비서가 회의 중간에 슬쩍 쪽지를 전달해 중요한 정보를 알려주는 것과 같습니다.
이를 통해 대화 맥락에 맞는 실시간 정보를 LLM에게 전달할 수 있습니다.
다음 코드를 살펴봅시다.
from langchain.schema import SystemMessage, HumanMessage, AIMessage
def inject_context_message(messages: list, injection: str, position: int = -1):
"""대화 히스토리에 컨텍스트 메시지를 주입합니다."""
context_msg = SystemMessage(content=f"[컨텍스트 업데이트] {injection}")
if position == -1:
# 마지막 사용자 메시지 직전에 삽입
messages.insert(len(messages) - 1, context_msg)
else:
messages.insert(position, context_msg)
return messages
# 사용 예시
messages = [
SystemMessage(content="당신은 상담사입니다."),
HumanMessage(content="주문 상태 알려주세요"),
AIMessage(content="주문번호를 알려주시겠어요?"),
HumanMessage(content="12345입니다")
]
# DB 조회 결과를 주입
messages = inject_context_message(messages, "주문 12345: 배송중, 내일 도착 예정")
박시니어 씨가 김개발 씨의 고민을 듣고 해결책을 제시했습니다. "시스템 프롬프트는 대화 시작 전에 설정하는 거잖아요.
대화 도중에 필요한 정보는 메시지 주입을 사용하면 됩니다." 메시지 주입은 대화 히스토리라는 배열 중간에 새로운 메시지를 끼워 넣는 것입니다. 마치 대화 녹취록 중간에 편집자 주석을 다는 것과 비슷합니다.
왜 이런 기법이 필요할까요? 실제 서비스에서는 대화 도중에 데이터베이스를 조회하거나 외부 API를 호출해야 하는 경우가 많습니다.
고객이 주문번호를 말하면 DB에서 주문 정보를 가져와야 합니다. 이 정보를 LLM에게 어떻게 전달할까요?
가장 단순한 방법은 사용자 메시지에 붙이는 것입니다. 하지만 이렇게 하면 LLM이 정보의 출처를 혼동할 수 있습니다.
시스템이 제공한 정보인지, 사용자가 말한 정보인지 구분하기 어렵습니다. 메시지 주입 패턴은 SystemMessage 타입으로 정보를 삽입합니다.
LLM은 이것이 시스템에서 제공한 신뢰할 수 있는 정보임을 인식합니다. 위의 코드에서 inject_context_message 함수는 messages 리스트의 특정 위치에 새로운 SystemMessage를 삽입합니다.
position이 -1이면 마지막 사용자 메시지 직전에 삽입됩니다. 이렇게 하면 LLM이 응답을 생성하기 직전에 최신 정보를 참고할 수 있습니다.
주입 위치도 중요합니다. 너무 앞에 넣으면 LLM이 해당 정보를 잊어버릴 수 있습니다.
너무 뒤에 넣으면 맥락이 어색해질 수 있습니다. 일반적으로 관련 질문 직후, 응답 생성 직전이 가장 효과적입니다.
주의할 점은 너무 많은 정보를 주입하면 대화 흐름이 끊긴다는 것입니다. 꼭 필요한 정보만 간결하게 주입하세요.
또한 주입된 메시지도 토큰 수에 포함되므로 비용을 고려해야 합니다. 김개발 씨는 이 패턴을 적용해 주문 조회, 재고 확인, 배송 추적 등의 기능을 자연스럽게 챗봇에 통합할 수 있었습니다.
실전 팁
💡 - 주입하는 메시지는 명확한 포맷을 정해두세요. 예: "[DB 조회 결과]", "[API 응답]" 등의 접두사 사용
- 민감한 정보는 주입 전에 마스킹 처리하는 것을 잊지 마세요.
5. 도구 선택 제한
김개발 씨의 챗봇은 점점 기능이 많아졌습니다. 검색, 예약, 결제, 환불까지 10개가 넘는 도구가 연결되었습니다.
그런데 이상한 일이 벌어졌습니다. 단순한 인사에도 LLM이 불필요한 도구를 호출하려고 했습니다.
"안녕하세요"라고 했는데 검색 API를 호출하다니요!
도구 선택 제한은 특정 상황에서 LLM이 사용할 수 있는 도구를 제한하는 기법입니다. 마치 수술실에서 의사에게 해당 수술에 필요한 도구만 준비해주는 것과 같습니다.
불필요한 도구 호출을 방지하고, 비용을 절감하며, 보안을 강화할 수 있습니다.
다음 코드를 살펴봅시다.
from typing import List, Dict, Callable
class ToolManager:
def __init__(self, all_tools: Dict[str, Callable]):
self.all_tools = all_tools
def get_allowed_tools(self, context: Dict) -> List[str]:
"""상황에 따라 허용할 도구 목록을 반환합니다."""
user_tier = context.get("user_tier", "basic")
conversation_stage = context.get("stage", "greeting")
# 단계별 도구 제한
stage_tools = {
"greeting": [], # 인사 단계: 도구 불필요
"inquiry": ["search_faq", "get_product_info"],
"purchase": ["search_faq", "check_inventory", "create_order"],
"support": ["search_faq", "create_ticket", "get_order_status"]
}
allowed = stage_tools.get(conversation_stage, [])
# VIP만 환불 도구 사용 가능
if user_tier == "VIP" and "refund" in self.all_tools:
allowed.append("process_refund")
return allowed
박시니어 씨가 김개발 씨의 화면을 보더니 고개를 저었습니다. "도구가 너무 많으면 LLM이 혼란스러워해요.
지금 상황에 필요한 도구만 보여줘야 합니다." 이것이 도구 선택 제한의 핵심입니다. LLM에게 모든 도구를 다 보여주는 대신, 현재 맥락에 맞는 도구만 선별해서 제공하는 것입니다.
비유하자면, 레스토랑 주방을 생각해보세요. 디저트를 만들 때는 오븐과 믹서기가 필요하지, 프라이팬은 필요 없습니다.
모든 조리도구를 한꺼번에 꺼내놓으면 오히려 작업 효율이 떨어집니다. 도구 선택 제한이 필요한 이유는 여러 가지입니다.
첫째, 정확도 향상입니다. 선택지가 적으면 LLM이 더 정확한 판단을 합니다.
10개 중에서 고르는 것보다 3개 중에서 고르는 게 실수가 적습니다. 둘째, 비용 절감입니다.
도구 정의도 토큰으로 계산됩니다. 불필요한 도구를 제외하면 API 호출 비용이 줄어듭니다.
셋째, 보안 강화입니다. 민감한 도구는 특정 조건에서만 노출해야 합니다.
예를 들어 환불 처리 도구는 인증된 상담사 세션에서만 사용 가능하도록 제한할 수 있습니다. 위의 코드에서 ToolManager 클래스는 대화 단계와 사용자 등급에 따라 허용할 도구를 결정합니다.
greeting 단계에서는 어떤 도구도 필요 없습니다. inquiry 단계에서는 FAQ 검색과 상품 정보 조회만 허용합니다.
특히 주목할 부분은 VIP 고객에게만 환불 도구를 허용하는 로직입니다. 이런 식으로 권한 기반 도구 제한을 구현할 수 있습니다.
실무에서는 이 패턴을 확장해서 사용합니다. 시간대별 제한도 가능합니다.
업무 시간에만 상담원 연결 도구를 활성화할 수 있습니다. 또는 특정 에러가 발생했을 때만 디버깅 도구를 노출할 수도 있습니다.
김개발 씨는 이 패턴을 적용한 후 불필요한 API 호출이 80% 줄었다고 보고했습니다. 월말 청구서를 보고 팀장님이 흐뭇해했습니다.
실전 팁
💡 - 대화 단계를 명확히 정의하고 각 단계에서 필요한 도구를 문서화하세요.
- 도구 제한 로직에도 로깅을 추가해서 어떤 도구가 허용/차단되었는지 추적하세요.
6. 요약 미들웨어 활용
서비스가 성장하면서 김개발 씨는 새로운 문제에 직면했습니다. 긴 대화가 계속되면 컨텍스트 윈도우를 초과해 에러가 발생했습니다.
그렇다고 오래된 대화를 그냥 잘라내면 중요한 맥락이 사라집니다. 긴 대화를 효율적으로 관리할 방법이 필요했습니다.
요약 미들웨어는 긴 대화 히스토리를 자동으로 압축해서 토큰 사용량을 줄이는 기법입니다. 마치 회의록을 작성할 때 모든 발언을 기록하는 대신 핵심 내용만 정리하는 것과 같습니다.
중요한 맥락은 유지하면서도 토큰 비용을 크게 절감할 수 있습니다.
다음 코드를 살펴봅시다.
from typing import List
from langchain.schema import BaseMessage, SystemMessage
class SummarizationMiddleware:
def __init__(self, llm, max_messages: int = 10):
self.llm = llm
self.max_messages = max_messages
def process(self, messages: List[BaseMessage]) -> List[BaseMessage]:
"""메시지가 임계치를 넘으면 이전 대화를 요약합니다."""
if len(messages) <= self.max_messages:
return messages
# 요약할 메시지와 유지할 메시지 분리
to_summarize = messages[1:-self.max_messages] # 시스템 프롬프트 제외
to_keep = messages[-self.max_messages:]
# 요약 생성
summary = self._generate_summary(to_summarize)
# 새 메시지 리스트 구성
return [
messages[0], # 원본 시스템 프롬프트
SystemMessage(content=f"[이전 대화 요약] {summary}"),
*to_keep
]
def _generate_summary(self, messages: List[BaseMessage]) -> str:
prompt = "다음 대화의 핵심 내용을 3문장으로 요약하세요:\n"
prompt += "\n".join([f"{m.type}: {m.content}" for m in messages])
return self.llm.invoke(prompt).content
박시니어 씨가 화이트보드에 긴 막대를 그렸습니다. "이게 전체 대화 히스토리라고 생각해봐요." 그리고 막대의 앞부분을 작은 상자로 압축해서 표시했습니다.
"요약 미들웨어는 이렇게 과거 대화를 압축합니다." 요약 미들웨어는 LLM 호출 전에 대화 히스토리를 전처리하는 계층입니다. 미들웨어라는 이름처럼, 요청이 LLM에 도달하기 전에 중간에서 가공 작업을 수행합니다.
왜 이것이 필요할까요? LLM에는 컨텍스트 윈도우라는 한계가 있습니다.
GPT-4의 경우 최대 128K 토큰, Claude의 경우 200K 토큰까지 처리할 수 있습니다. 하지만 토큰이 많아질수록 비용도 올라가고, 응답 속도도 느려집니다.
긴 대화에서 모든 메시지가 똑같이 중요한 것은 아닙니다. 30분 전에 나눈 인사말보다 방금 언급한 주문번호가 훨씬 중요합니다.
요약 미들웨어는 이 점을 활용합니다. 위의 코드를 살펴보겠습니다.
SummarizationMiddleware 클래스는 메시지 수가 max_messages를 초과하면 이전 대화를 요약합니다. process 메서드의 동작을 단계별로 보겠습니다.
먼저 메시지 수가 임계치 이하면 그대로 반환합니다. 임계치를 초과하면 요약할 메시지와 유지할 메시지를 분리합니다.
시스템 프롬프트는 항상 유지하고, 최근 N개의 메시지도 원본 그대로 유지합니다. 나머지 오래된 메시지는 요약본으로 대체합니다.
요약 생성에도 LLM을 사용한다는 점을 주목하세요. 이것이 바로 LLM을 활용해서 LLM 입력을 최적화하는 기법입니다.
요약용 API 호출 비용보다 절감되는 토큰 비용이 더 크기 때문에 충분히 가치가 있습니다. 실무에서 요약 미들웨어를 적용할 때 몇 가지 고려사항이 있습니다.
요약의 품질이 중요합니다. 핵심 정보가 누락되면 대화 맥락이 끊어집니다.
따라서 요약 프롬프트를 신중하게 작성해야 합니다. 또한 요약 타이밍도 중요합니다.
매 메시지마다 요약하면 비용이 늘어납니다. 일정 임계치를 넘었을 때만 요약하는 것이 효율적입니다.
김개발 씨는 이 미들웨어를 도입한 후 긴 상담 세션에서도 에러 없이 대화를 이어갈 수 있게 되었습니다. 동시에 API 비용도 40% 절감되었습니다.
실전 팁
💡 - 요약 프롬프트에 "핵심 정보와 고객의 요청사항을 반드시 포함하세요"라는 지침을 추가하세요.
- 요약 전후의 토큰 수를 로깅해서 실제 절감 효과를 측정하세요.
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
vLLM 통합 완벽 가이드
대규모 언어 모델 추론을 획기적으로 가속화하는 vLLM의 설치부터 실전 서비스 구축까지 다룹니다. PagedAttention과 연속 배칭 기술로 GPU 메모리를 효율적으로 활용하는 방법을 배웁니다.
Web UI Demo 구축 완벽 가이드
Gradio를 활용하여 머신러닝 모델과 AI 서비스를 위한 웹 인터페이스를 구축하는 방법을 다룹니다. 코드 몇 줄만으로 전문적인 데모 페이지를 만들고 배포하는 과정을 초급자도 쉽게 따라할 수 있도록 설명합니다.
Sandboxing & Execution Control 완벽 가이드
AI 에이전트가 코드를 실행할 때 반드시 필요한 보안 기술인 샌드박싱과 실행 제어에 대해 알아봅니다. 격리된 환경에서 안전하게 코드를 실행하고, 악성 동작을 탐지하는 방법을 단계별로 설명합니다.
Voice Design then Clone 워크플로우 완벽 가이드
AI 음성 합성에서 일관된 캐릭터 음성을 만드는 Voice Design then Clone 워크플로우를 설명합니다. 참조 음성 생성부터 재사용 가능한 캐릭터 구축까지 실무 활용법을 다룹니다.
Tool Use 완벽 가이드 - Shell, Browser, DB 실전 활용
AI 에이전트가 외부 도구를 활용하여 셸 명령어 실행, 브라우저 자동화, 데이터베이스 접근 등을 수행하는 방법을 배웁니다. 실무에서 바로 적용할 수 있는 패턴과 베스트 프랙티스를 담았습니다.