DSPy.rb를 활용한 AI 챗 에이전트 구축은 다음과 같은 핵심 단계로 진행됩니다.
1. 기본적인 채팅 기능 구현 (메모리 없음)
-
DSPy::Signature: 입력(user_message)과 출력(reply)을 정의하는 계약입니다. -
DSPy::Predict: 정의된 시그니처를 사용하여 LLM 호출을 캡슐화합니다. -
초기 단계에서는 대화 기록을 유지하지 않아 매 턴마다 이전 내용을 잊어버립니다.
2. 임시 메모리 추가
-
@memory배열을 사용하여 사용자 메시지와 LLM 응답을 저장합니다. -
ResolveUserQuestion시그니처에history매개변수를 추가하여 LLM이 이전 대화를 참조할 수 있도록 합니다.
3. 컨텍스트 엔지니어링 (Two-Struct 패턴)
-
저장용 풍부한 구조체 (
ConversationMemoryEntry):role,message외에model_id,timestamp,token_count등 상세 메타데이터를 포함합니다. -
LLM 프롬프트용 경량 구조체 (
MemoryTurn):role과message만 포함하여 LLM에 불필요한 정보를 노출하지 않습니다. -
forward메서드 내에서@memory의 풍부한 구조체를 경량 구조체로 변환하고, 최근 N개의 턴으로 잘라내어 컨텍스트 길이를 최적화합니다.
4. 비용 기반 라우팅
-
복잡도 분류 시그니처 (
RouteChatRequest): 메시지 복잡도(ComplexityLevel- Routine, Detailed, Critical)를 예측하고, 신뢰도, 이유, 제안된 비용 등급을 출력합니다. -
챗 라우터 (
ChatRouter): 분류 결과를 기반으로 적절한 예측기(예: 저비용gpt-4o-mini또는 고비용gpt-4o + CoT)를 선택하여 메시지를 라우팅합니다. -
동일한
ResolveUserQuestion시그니처를 공유하여 모델 변경에도 계약을 유지합니다.
5. 라이프사이클 콜백을 통한 분리 (around 콜백)
-
DSPy::Module의around콜백(update_memory)을 활용하여 메모리 관리 로직을forward메서드로부터 분리합니다. -
forward실행 전 사용자 메시지를 기록하고,forward실행 후 LLM 응답을 기록하여 관심사를 명확히 분리합니다.
이러한 단계적 접근 방식을 통해, 개발자는 유연하고 확장 가능한 AI 챗 에이전트를 구축할 수 있으며, 향후 영구 메모리, 스마트한 컨텍스트 선택, 도구 사용, 심층 연구 기능 등으로 쉽게 확장할 수 있습니다.