본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 28. 04:05

Hindsight를 사용하여 분석 에이전트에게 장기 기억(Long-Term Memory) 부여하기

요약

에이전트 파이프라인의 고질적인 문제인 '건망증'을 해결하기 위해 Hindsight를 활용하여 장기 기억(Long-Term Memory)을 부여하는 방법을 다룹니다. 4개의 에이전트로 구성된 시장 정보 시스템 구축 사례를 통해 상태 관리와 메모리 유지의 중요성을 설명합니다.

핵심 포인트

  • Hindsight를 사용하여 에이전트에게 지속적인 장기 기억 부여 가능
  • 시장 정보, 트렌드, 인사이트, 비판 에이전트로 구성된 4단계 파이프라인 구조
  • 결정론적이고 디버깅이 용이한 CascadeFlow 오케스트레이션 활용
  • 이전 실행 결과와 오류를 기억하여 분석의 연속성 확보

대부분의 에이전트 파이프라인(Agent pipelines)은 설계 단계부터 건망증이 있습니다. 매 실행은 새롭게 시작됩니다. 웹 검색이 수행되고, LLM이 무언가를 합성하며, 당신은 보고서를 받지만, 그 후 모든 컨텍스트(Context)는 증발해 버립니다. 다음에 당신이 동일한 시장에 대해 질문할 때, 에이전트는 6일 전에 이미 유사한 내용을 말했었다는 사실이나, 당시 내놓았던 권장 사항이 틀렸었다는 사실을 전혀 알지 못합니다.

이것은 제가 [전략적 시장 정보 시스템(strategic market intelligence system)]을 구축하는 동안 계속해서 마주쳤던 문제였습니다. 이 포스트는 제가 Hindsight를 통해 이 문제를 어떻게 해결했는지, 그리고 제가 해결하기 전에 무엇이 망가졌었는지에 관한 이야기입니다.

시스템이 하는 일

이 시스템은 4개의 에이전트로 구성된 연구 파이프라인입니다. 당신이 "동남아시아의 EV 배터리 공급망 리스크"와 같은 쿼리(Query)를 입력하면, 시스템은 다음과 같은 구조화된 시퀀스(Sequence)를 실행합니다:

  1. 시장 정보 에이전트 (Market Intelligence Agent) — Tavily를 통해 최신 신호를 찾기 위해 라이브 웹을 검색하고, 출처가 명시된 5개의 결과를 반환합니다.
  2. 트렌드 에이전트 (Trend Agent) — 각 결과의 전체 텍텍스트를 스크래핑(Scraping)하고 정제한 다음, 방향성 신호와 패턴을 추출합니다.
  3. 인사이트 및 권장 에이전트 (Insights & Recommendation Agent) — 신호들을 실행 가능한 권장 사항으로 합성하며, 이전 실행에서 관련된 내용이 있는지 메모리(Memory)를 확인합니다.
  4. 비판 에이전트 (Critic Agent) — 논리적 공백, 최신성 편향(Recency bias) 또는 누락된 컨텍스트가 있는지 권장 사항에 이의를 제기한 후, 검증된 인사이트를 다시 메모리에 기록합니다.

파이프라인은 순차적으로 실행됩니다. 에이전트 라우팅(Agentic routing)이나 다음에 어떤 도구를 호출할지 결정하는 LLM은 없습니다. 상태(State)는 일반적인 Python 딕셔너리(dict) 형태로 전달됩니다. CascadeFlow 오케스트레이션(Orchestration) 레이어가 시퀀싱을 관리하며, 각 에이전트는 상태를 다음 단계로 넘기기 전에 상태를 변경(Mutate)합니다.

단순하고, 결정론적(Deterministic)이며, 디버깅(Debuggable)이 가능합니다. 무언가 잘못되었을 때 실제로 추적할 수 있는 종류의 파이프라인입니다.

메모리 문제

지속적인 메모리(Persistent Memory)가 없는 시장 정보 시스템(Market Intelligence System)에서 어떤 일이 발생하는지 살펴보겠습니다. 이는 결코 사소한 문제가 아닙니다.

첫 번째 실행: 탄산리튬(Lithium Carbonate) 가격 압박에 대해 질문합니다. 에이전트는 검색, 스크래핑(Scraping), 합성(Synthesizing)을 수행한 후 다음과 같은 권장 사항을 반환합니다: "칠레의 공급업체들이 계약 재협상 압박을 받고 있습니다. 현재 3분기 가격을 확정할 것을 권장합니다." 합리적인 답변입니다.

4일 후의 두 번째 실행: 동일한 질문을 합니다. 에이전트는 다시 검색하고, 중복되는 소스를 찾고, 다시 합성하여 거의 동일한 권장 사항을 반환합니다. 이 내용이 이미 보고되었거나, 조치가 취해졌거나, 혹은 틀렸다는 사실을 전혀 인지하지 못한 채 말입니다.

열 번째 실행: 이제 당신은 동일한 통찰(Insight)을 아홉 번이나 생성했습니다. 실행 사이에 무엇이 변했는지에 대한 기록도 없고, "이 권장 사항이 여전히 유효한가?"라고 물을 방법도 없으며, 에이전트가 세션(Session)을 거치며 스스로 모순되는 말을 하기 시작할 때 이를 잡아낼 능력도 없습니다.

메모리가 없다면 각 실행은 에피소드적(Episodic)입니다. 에이전트는 지능적이지만 경험이 없습니다. 학습할 수 없습니다.

이것이 바로 Hindsight가 해결하고자 설계된 정확한 실패 모드(Failure Mode)입니다. Hindsight는 사용자가 직접 커스텀 벡터 데이터베이스(Vector Database)를 구축하거나, 임베딩(Embedding)을 관리하거나, 검색 로직(Retrieval Logic)을 연결할 필요 없이, 에이전트가 쓰고, 의미론적으로 쿼리(Query)하고, 반추(Reflect)할 수 있는 구조화된 저장소인 지속적인 에이전트 메모리(Persistent Agent Memory)를 제공합니다.

Hindsight가 파이프라인에 통합되는 방식

메모리 계층은 tools.py에 존재하며, Hindsight가 지원하는 세 가지 메모리 작업에 깔끔하게 매핑되는 세 가지 함수로 노출됩니다.

세 가지 작업은 각각 서로 다른 역할을 수행합니다:

  • retain은 선택적인 태그와 컨텍스트 메타데이터(context metadata)와 함께 구조화된 통찰(insight)을 메모리 뱅크(memory bank)에 기록합니다.
  • recall은 의미론적 검색(semantic retrieval)을 수행합니다. 쿼리 문자열(query string)을 입력하면 관련성 순으로 정렬된 가장 관련 있는 과거의 통찰들을 반환합니다.
  • reflect는 진정한 가치를 발휘하는 기능입니다. 개별 결과를 반환하는 대신, 전체 메모리 뱅크를 가로질러 종합(synthesize)함으로써 메타 질문(meta-question)에 답합니다.

세 번째 기능은 시스템이 단순한 조회 테이블(lookup table)을 벗어나 조직적 지식(institutional knowledge)을 가진 존재처럼 행동하기 시작하는 지점입니다.

각 작업의 사용처

**인사이트 및 추천 에이전트 (Insights & Recommendation Agent)**는 무언가를 생성하기 전에 recall_past_insights를 호출합니다. 검색된 메모리는 사전 컨텍스트(prior context)로서 프롬프트(prompt)에 직접 주입됩니다. 만약 시스템이 지난주에 이미 불확실하다고 표시했던 내용을 추천하려고 한다면, 그 사실이 추천 내용이 작성된 후가 아니라 작성되기 전에 드러나게 됩니다.

**비평 에이전트 (Critic Agent)**는 현재의 추천 사항을 평가한 후 reflect_on_findings를 호출합니다. 이는 더 어려운 질문을 던집니다.

모순 탐지 불가 (No contradiction detection). reflect가 없다면, Critic은 "우리가 이전에 이런 판단을 내렸다가 틀린 적이 있었나?"라고 물을 방법이 없습니다. Critic은 오직 현재의 소스(sources)를 바탕으로 현재의 추천 사항을 평가할 수만 있습니다. 자신의 판단이 변질(drift)되는 것을 포착할 수 없습니다.

조직적 기억 부재 (No institutional memory). 시스템은 "X에 대해 우리가 알고 있는 것은 무엇인가?"라는 질문에 답할 수 없으며, 오직 "최신 검색 결과가 X에 대해 무엇을 반환했는가?"에만 답할 수 있습니다. 지속적인 경쟁사 또는 시장 모니터링을 수행할 때, 이 둘은 매우 다른 문제입니다.

추천 사항에 대한 감사 추적(audit trail) 부재. retain_insight를 통해 유지되는 모든 통찰(insight)은 컨텍스트(context), 태그(tags), 타임스탬프(timestamp)를 포함합니다. 이것이 없다면 시스템이 무엇을 언제 결론지었는지에 대한 기록이 남지 않습니다. 시장 정보(market intelligence) 맥락에서 이는 사소한 불편함이 아니라, 분석 도구와 연구 기록을 가르는 결정적인 차이입니다.

Hindsight 문서는 이를 잘 설명하고 있습니다. 목표는 단순한 검색(retrieval)이 아니라 _에이전트 연속성(agent continuity)_입니다. 즉, 에이전트가 세션 전반에 걸쳐 자신이 무엇을 보았고, 무엇을 결론지었으며, 그 결론이 유효했는지를 알 수 있는 능력입니다.

구체적인 예시

쿼리: "자동차 부문 반도체 재고 조정, 4분기 전망"

첫 번째 실행 (이전 기억 없음):
에이전트가 검색을 수행하여 Tier 1 공급업체의 과잉 공급을 논의하는 5개의 소스를 찾고, 트렌드를 추출하여 다음과 같은 추천 사항을 생성합니다: "4분기까지 레거시 노드(legacy node) 칩에 대한 가격 압박이 예상됩니다. 구매 팀은 현물 구매(spot purchases)를 연기해야 합니다."

Critic은 현재 소스를 바탕으로 이를 평가하여 타당하다고 판단하고, 이를 메모리에 기록합니다:

6주 후, 세 번째 실행:
Insights Agent는 무언가를 생성하기 전에 recall_past_insights("automotive semiconductor Q4 procurement")를 호출합니다. 저장된 인사이트가 나타납니다. 이제 에이전트는 자신이 이미 이 호출을 수행했다는 것과, 당시 권장 사항이 지연(delay)이었다는 사실을 알게 됩니다.

그 다음 Critic은 reflect_on_findings("Has the automotive semiconductor oversupply recommendation proven accurate or been contradicted?")를 호출합니다. 만약 이후의 실행 과정에서 상충하는 신호가 저장되었다면, reflection(성찰) 과정에서 그 긴장 상태를 합성하여 플래그(flag)를 표시합니다. 만약 상충하는 내용이 없다면, 현재의 권장 사항은 "이는 [날짜]에 저장된 이전 조사 결과와 일치합니다."라는 명시적인 연속성을 통해 강화됩니다.

이것은 마법이 아닙니다. 그저 메모리(memory)일 뿐입니다. 하지만 호출 사이에 모든 것을 잊어버릴 수 있는 파이프라인의 적절한 지점에 적용된 메모리입니다.

Lessons Learned (교훈)

1. 순차적 파이프라인(Sequential pipelines)은 에이전트 방식(agentic)보다 디버깅하기 쉽습니다 — 시스템이 망가지기 전까지는 말이죠.
고정된 4단계 시퀀스는 깔끔한 콜 스택(call stack)을 제공합니다. Critic이 쓰레기(garbage)를 생성할 때, 무엇을 받았고 무엇을 해야 했는지 정확히 알 수 있습니다. 저는 어떤 멀티 에이전트 시스템(multi-agent system)을 구축하든 초기에는 이 패턴을 사용할 것이며, 구체적인 이유가 생겼을 때만 동적 라우팅(dynamic routing)을 추가할 것입니다.

2. 메모리는 사후 고려 사항이 아니라, 일급 시민(first-class)으로서의 설계 결정이어야 합니다.
저는 작업 중간에 메모리를 덧붙였습니다. 파이프라인은 메모리 없이도 작동했기에 구현을 미루기 쉬웠습니다. 하지만 "작동하는 것"과 "시간이 지남에 따라 유용해지는 것"은 기준이 다릅니다. 만약 처음부터 다시 시작한다면, 저는 retainrecall을 세 번째 에이전트가 아닌 첫 번째 에이전트부터 연결할 것입니다.

3. reflect는 시스템의 동작을 변화시키는 연산입니다.
retainrecall은 시스템을 상태 유지(stateful)하게 만듭니다. reflect는 시스템을 시간이 지남에 따라 진정으로 더 나아지게 만듭니다. 그 차이는 recall은 결과를 반환하지만, reflect는 그 결과들을 하나의 판단(judgment)으로 합성한다는 점에 있습니다. 하위 소비자(downstream consumer)가 권장 사항을 생성하려는 LLM(대규모 언어 모델)일 때, 이 차이는 매우 중요합니다.

4. Hindsight의 budget 파라미터는 튜닝할 가치가 있습니다.
recallreflect 모두 메모리 뱅크(memory bank)에서 얼마나 많은 정보를 가져올지를 제어하는 budget 파라미터를 허용합니다. "mid"는 안전한 기본값이며, "high"는 최대 범위를 원하는 광범위한 전략적 쿼리(strategic queries)에 유용합니다. 저는 모든 곳에 "mid"를 기본값으로 설정했는데, 이로 인해 일부 쿼리에서 성능을 충분히 끌어내지 못했습니다.

5. 태그(Tags)는 추가하기는 쉽지만, 나중에 소급 적용하기는 고통스럽습니다.
모든 retain_insight 호출은 태그 리스트를 허용합니다. 저는 처음에 태그를 느슨하게 달기 시작했습니다. 6주가 지난 시점에서, 전체 리콜(recall)과 후처리(post-processing)를 수행하지 않고서는 섹터(sector)나 시간 지평(time horizon)별로 메모리를 필터링할 수 없었습니다. 초기에 태그를 달고, 일관되게 다세요.

향후 방향

현재의 파이프라인은 지속적인 시장 모니터링을 위한 견고한 기반이 됩니다. 즉, 동일한 유형의 쿼리를 매주 실행하며, 같은 내용을 다시 발견하는 대신 무엇이 변했는지를 시스템이 추적해야 하는 경우에 적합합니다. CascadeFlow 오케스트레이션(orchestration) 레이어를 사용하면 실행 일정을 예약하고, 에이전트 상태(agent state)를 관리하며, 처음부터 다시 아키텍처를 설계할 필요 없이 파이프라인을 확장하는 것이 매우 간단해집니다.

다음으로 의미 있는 추가 사항은 시간적 추론(temporal reasoning)입니다. 단순히 "X에 대해 무엇을 알고 있는가?"가 아니라, "8월에 X에 대해 알고 있었지만 10월에는 더 이상 믿지 않는 것은 무엇이며, 그 이유는 무엇인가?"를 묻는 것입니다. 이는 더 어려운 문제이며, 보존된 인사이트(retained insights)에 구조화된 타임스탬프(timestamps)를 결합하고, 에이전트에게 변화(drift)를 찾도록 명시적으로 요청하는 reflect 쿼리가 필요합니다. 인프라는 이미 Hindsight의 메모리 시스템을 통해 갖춰져 있습니다. 이를 안정적으로 작동하게 만들기 위한 프롬프트 엔지니어링(prompt engineering)이 남은 과제입니다.

만약 여러분이 어떤 종류의 반복적인 리서치나 모니터링 파이프라인을 구축하고 있다면, 여기서 제시한 패턴을 그대로 적용할 수 있습니다: 시퀀스(sequence)를 고정하고, 상태(state)를 일반 딕셔너리(dict)로 전달하며, 메모리를 기능(feature)이 아닌 인프라(infrastructure)로 취급하십시오. 지난번에 내린 결론을 기억하는 에이전트는 그렇지 않은 에이전트보다 훨씬 더 큰 가치를 지닙니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0