잠재 고객을 실제로 기억하는 영업 에이전트를 구축한 방법
요약
세션 간 지속적인 메모리를 유지하여 잠재 고객의 정보를 기억하는 영업 에이전트 구축 방법을 소개합니다. Hindsight를 통한 메모리 관리와 cascadeflow를 이용한 지능형 모델 라우팅을 통해 비용 효율성과 성능을 동시에 확보하는 구조를 다룹니다.
핵심 포인트
- Hindsight를 활용해 세션 및 서버 재시작 후에도 지속되는 에이전트 메모리 구현
- cascadeflow를 통한 쿼리 복잡도 기반의 지능형 모델 라우팅 및 비용 최적화
- FastAPI와 React를 결합한 백엔드 및 UI 아키텍처 구성
- 데이터 파싱 시 원시 응답의 형태(shape)를 먼저 확인하는 디버깅 팁
이 블록 전체를 복사하여 Dev.to에 붙여넣으세요:
제가 사용해 본 모든 영업 도구는 동일한 문제를 가지고 있었습니다. 탭을 닫는 순간 모든 것을 잊어버린다는 점입니다.
CRM에 메모가 있긴 하겠죠. 하지만 AI 어시스턴트는 어떤가요? 매 대화마다 백지 상태입니다. 3개월 동안 공을 들여온 잠재 고객에 대해 물어보면, 마치 처음 보는 사람처럼 대합니다.
저는 다른 것을 만들었습니다. 모든 반대 의견(objection), 모든 논의, 모든 약속을 세션 간, 재시작 간, 그리고 며칠의 시간 간격을 넘어 기억하는 영업 에이전트입니다.
기능
Deal Intelligence Agent는 세 가지 레이어로 구축된 영업 어시스턴트입니다:
- Hindsight: 세션 간 지속적인 메모리(persistent memory)를 위한 기능
- cascadeflow: 지능적인 모델 라우팅(model routing) 및 비용 제어를 위한 기능
- FastAPI + React: 백엔드(backend) 및 UI를 위한 기능
영업 담당자가 잠재 고객을 열고, 대화를 나누고, 세션을 종료합니다. 다음 날, 다른 서버 인스턴스에서
핵심 교훈: Hindsight는 리스트(list)나 딕셔너리(dict)가 아닌 RecallResult 객체를 반환합니다. 저는 파서(parser)에서 항상 실패하는 isinstance(results, list) 체크를 수행하느라 두 시간 동안 디버깅을 했습니다. 파서를 작성하기 전에 항상 원시 응답(raw response)의 형태(shape)를 출력해 보세요.
전과 후 (The Before and After)
세션 1 — 이전 컨텍스트 없음:
영업 담당자: "그들이 5만 달러 가격에 대해 이의를 제기했습니다."
에이전트: "이 잠재 고객에 대한 이전 컨텍스트가 없습니다.
그들의 우려 사항에 대해 더 자세히 말씀해 주시겠습니까?"
...
세션 2 — 서버 재시작 후, 완전히 새로운 세션:
영업 담당자: "Acme가 어떤 이의를 제기했었죠?"
에이전트: "Acme는 지난 논의에서
50,000달러의 가격 이의를 제기했습니다..."
...
이러한 차이 — 일반적인 상태에서 구체적인 상태로의 변화 — 가 바로 전체 가치 제안(value proposition)입니다. Hindsight의 에이전트 메모리 (agent memory)가 없다면 세션 2는 세션 1과 동일할 것입니다. 하지만 메모리가 있다면, 에이전트는 시간이 지남에 따라 지식을 축적합니다.
cascadeflow를 이용한 지능형 라우팅 (Intelligent Routing)
모든 쿼리를 70B 모델로 실행하는 것은 비용이 많이 들고 불필요합니다.
cascadeflow는 라우팅(routing)을 자동으로 처리합니다:
route_result = await self.router.route_query(
messages=messages,
complexity_hint=self._estimate_complexity(message),
...
- 단순 쿼리 → 호출당 $0.00005인
llama-3.1-8b-instant - 복잡한 분석 → 호출당 $0.00032인
llama-3.3-70b-versatile
선택된 모델, 비용, 복잡도, 추론 과정 등 모든 결정 사항이 로그에 기록됩니다. 대부분의 영업 대화는 단순한 상태 확인입니다. 전략적 분석만이 비용이 많이 드는 모델을 필요로 합니다. 100개의 쿼리를 기준으로 할 때 비용 차이는 상당합니다.
Hindsight reflect()를 통한 세션 요약 (Session Summaries)
각 대화가 끝난 후, 에이전트는 모든 내용을 종합합니다:
result = client.reflect(
bank_id=bank_id,
query="주요 사항, 제기된 이의 사항을 요약하세요, "
...
출력물은 논의 사항, 잠재 고객의 감정 (sentiment), 이의 사항 (objections), 그리고 구체적인 다음 조치 사항 (next action)을 포함하는 구조화된 요약입니다. 이것은 세션 간의 인수인계 문서 (handoff document)가 됩니다.
내가 다르게 했을 세 가지 작업
- 첫날부터 실제 응답 객체(response object)를 대상으로 회상 파서(recall parser)를 테스트하세요. 데이터의 형태 (shape)를 당연하게 가정하지 마세요. 먼저 가공되지 않은 응답 (raw response)을 출력해 보세요.
- 상태 확인 엔드포인트 (health check endpoint)를 추가하세요. 저는 Hindsight가 아무런 알림 없이 몇 시간 동안 로컬 메모리 (local memory)로 조용히 폴백 (fallback)되는 것을 인지하지 못했습니다. 시작 시점에 간단한 '저장 후 회상 (retain-then-recall)' 테스트를 수행했다면 이를 즉시 잡아낼 수 있었을 것입니다.
- 단어 수를 세는 대신 의도 (intent)를 분류하세요. 저의 복잡도 휴리스틱 (complexity heuristic)은 단어 수를 사용합니다. 요청 유형 — 질문 vs 분석 vs 초안 작성 — 을 분류하는 것이 더 신뢰할 수 있습니다.
다음 단계
현재 버전은 단일 영업 담당자 (single-rep)의 대화를 처리합니다. 명백한 다음 단계는 다중 영업 담당자 공유 메모리 (multi-rep shared memory)입니다. 즉, 잠재 고객의 이력이 영업 팀 전체에 공유되는 방식입니다.
코드: github.com/dpkpaswan/deal-intelligence-agent
Hindsight 문서: hindsight.vectorize.io
cascadeflow 문서: docs.cascadeflow.ai
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기