두 개의 TypeScript 에이전트 세션에 공유 메모리를 부여하다 (Hindsight 사용 및 LLM 키 없이)
요약
Hindsight는 에이전트들이 여러 세션에 걸쳐 공유하고 읽을 수 있는 오픈 소스 메모리 서버입니다. LLM API 키 없이도 작동하는 기능을 테스트하며, Node/TypeScript 클라이언트와 함께 실제 프로젝트에서 활용 가능함을 보여줍니다. 이는 코드만으로는 알기 어려운 '맥락'을 에이전트에게 제공합니다.
핵심 포인트
- Hindsight는 세션 간 공유 메모리를 제공하여 에이전트의 맥락 이해도를 높입니다.
- LLM API 키 없이도 작동하는 기능을 테스트할 수 있어 범용성이 뛰어납니다.
- Node/TypeScript 클라이언트와 함께 사용하며, 실제 개발 환경에 적용 가능합니다.
제가 진행하는 코딩 에이전트 세션 대부분은 비슷하게 시작합니다. 에이전트는 레포지토리가 pnpm을 사용한다는 것을 재발견하고, 레거시 결제 파일(legacy payment file)을 건드리지 말라는 말을 다시 듣고, UTC에서만 통과되는 테스트에 걸립니다. 이 중 어느 것도 코드에는 없습니다. 그것은 누군가의 머릿속이나 사라진 이전 세션 속에 존재합니다.
Vectorize의 Hindsight는 바로 그러한 간극을 위해 만들어졌습니다. 이는 에이전트들이 여러 세션에 걸쳐 쓰고 읽을 수 있는 오픈 소스 에이전트 메모리 서버(MIT)입니다. 제가 2026년 10월 3일에 확인했을 때, GitHub 저장소는 44,886개의 스타를 보유하고 있었고, 그 주에 16,183개 스타로 GitHub의 주간 트렌딩 페이지에서 2위를 차지했으며, 최신 릴리스는 9월 29일자 v0.10.2였습니다.
저는 이것이 실제 어떻게 작동하는지 보고 싶어서 리눅스 박스에 설치하고 작은 Node/TypeScript 프로젝트에서 호출해 보았습니다. 전체 테스트를 규정하는 하나의 제약 조건이 있었습니다. 바로 그 기계에는 LLM API 키가 없었다는 것입니다. Hindsight 문서는 정확히 그러한 상황을 위한 모드를 문서화하고 있으므로, 이것은 그것이 할 수 있는 모든 것을 테스트하는 것이 아니라 'LLM이 없는' 기능을 테스트하는 것입니다. 제가 실행한 부분과 단순히 읽기만 한 부분을 명확하게 표시했습니다.
설정 (The setup)
박스는 8 vCPU, 약 15GB RAM을 가진 Linux x86_64였고 Node 20이 설치되어 있었습니다. Docker가 없었기 때문에 README에서 제시된 베어 메탈(bare-metal) 경로를 사용했습니다 (pip install hindsight-api)를 통해 uv를 거쳤습니다:
uv venv .venv-hs --python 3.12
uv pip install hindsight-api==0.10.2
이는 PyTorch 다운로드를 포함하여 총 227개의 패키지를 해결했고 11.6초 만에 완료되었습니다. 주의할 점은 크기입니다. 가상 환경이 주로 torch와 CUDA wheels 때문에 6.3 GB에 달했습니다. 디스크 공간을 그에 맞춰 계획하세요.
설정 문서는 HINDSIGHT_API_LLM_PROVIDER=none을
스타트업 배너에는 임베디드 PostgreSQL(pg0, 자동 시작), LLM none / none, 로컬 임베딩(BAAI/bge-small-en-v1.5), 로컬 리랭커(cross-encoder/ms-marco-MiniLM-L-6-v2), 그리고 /mcp에서 활성화된 MCP가 적용된 v0.10.2 버전이 표시되었습니다.
- 첫 시작은 Hugging Face로부터 모델 다운로드를 포함하여 "Uvicorn running" 상태에 도달하는 데 약 38초가 걸렸습니다.
- 웜 재시작(warm restart)은 건강한
/health상태에 도달하는 데 약 19초가 걸렸습니다. - 워커 프로세스는 대략 1.35 GB의 상주 메모리(resident memory)를 사용했습니다.
세션 1: 한 에이전트가 학습한 내용을 기록하다
Node/TypeScript 측에서는 공식 클라이언트(버전 0.10.2)를 설치하고 tsx로 스크립트를 실행했습니다:
npm install @vectorize-io/hindsight-client typescript tsx @types/node
시나리오는 가상의 shop-api 리포지토리였습니다. 첫 번째 스크립트는 세션 끝에서 "에이전트 A" 역할을 수행합니다. 이 에이전트는 Hindsight의 격리된 메모리 저장소인 은행(bank)을 생성하고, 코드만으로는 명확하지 않은 다섯 가지 프로젝트 사실(project facts)을 보존합니다.
// src/agentA.ts
import { HindsightClient } from '@vectorize-io/hindsight-client';
...
다섯 개의 보존 작업은 각각 184, 42, 46, 56, 그리고 41ms가 걸렸습니다. 모든 응답에서 LLM 토큰이 0으로 보고되었는데, 이는 모델이 없기 때문에 예상된 결과입니다. listMemories는 다섯 개의 메모리를 보여주었으며, 모두 fact_type: "world"를 가지고 있었습니다. 청크(chunks) 모드에서는 텍스트가 작성된 그대로 저장된다는 의미로, 추출된 개체나 재구조화는 없습니다.
세션 2: 새로운 프로세스가 알아야 할 것을 질문하다
두 번째 스크립트는 새 클라이언트와 공유 상태(shared state)가 없는 별도의 프로세스입니다. 이 에이전트는 첫날에 에이전트가 그럴듯하게 할 네 가지 질문을 던진 다음, reflect를 시도합니다.
// src/agentB.ts
import { HindsightClient } from '@vectorize-io/hindsight-client';
...
결과는 다음과 같았습니다:
| Query | Latency | Top result |
|---|---|---|
| How do I run the tests in this repo? | 227 ms | the pnpm / Vitest note ✅ |
| ... | ||
네 가지 질문 모두에서 가장 적절한 메모리가 먼저 나왔습니다. 하지만 이 비율을 유지하는 두 가지 주의사항이 있습니다. 은행에는 다섯 개의 항목이 있었기 때문에 모든 쿼리에서 다섯 개가 반환되었고, 제가 실제로 본 것은 필터링이 아니라 순위(ranking)였습니다. 두 번째 결과는 때때로 관련성이 없었습니다. 가격 질문에서는 TZ 노트가 두 번째 자리에 있었습니다. 장난감용으로는 괜찮지만, 실제 은행이라면 클라이언트가 노출하는 maxTokens 예산이나 minScores 바닥값이 필요할 것입니다. |
reflect는 문서화된 대로 실패했습니다:
Reflect requires an LLM provider. Current provider is set to 'none'.
Set HINDSIGHT_API_LLM_PROVIDER to a real provider (e.g., openai, anthropic, gemini).
다음으로 서버를 중지하고 다시 시작한 다음 Agent B를 재실행했습니다. 가장 적절한 결과는 변하지 않았습니다(첫 두 쿼리에서 각각 201ms와 91ms). 따라서 메모리는 프로세스 내에만 있는 것이 아니라 임베디드 Postgres에 디스크에 저장됩니다.
MCP를 통한 세 번째 클라이언트
모든 Hindsight 서버는 은행별로 /mcp/{bank_id}/ 엔드포인트에서 Model Context Protocol(MCP)을 노출합니다. 저는 일반 curl로 이와 통신했습니다. initialize 요청을 보내고, 반환된 mcp-session-id 헤더를 읽은 다음, 이후 모든 호출에 이 헤더를 포함하여 보냅니다:
curl -s -D hdr.txt -X POST http://localhost:8888/mcp/shop-api-repo/ \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
...
서버는 자신을 `hindsight-mcp-server 0.10.2`로 식별했으며, `tools/list`를 통해 36개의 도구를 반환했습니다. 이 도구들은 보존(retain) 및 회상(recall), 반영(reflect), 정신 모델(mental models), 지시사항(directives), 메모리 및 문서 관리, 작업 수행(operations), 태그(tags), 은행 설정(bank settings), 그리고 지식 페이지 CRUD를 포괄합니다. `recall` 호출은 Agent A가 TypeScript SDK를 통해 작성했던 pnpm/Vitest 메모리를 반환했습니다. SDK와 MCP 모두 동일한 은행을 대상으로 작동하므로, TypeScript 서비스와 모든 MCP 지원 에이전트는 하나의 메모리를 공유할 수 있습니다.
### 코딩 에이전트 설치 프로그램이 실제로 연결하는 것
코딩 에이전트가 주요 사용 사례입니다. Vectorize는 `@vectorize-io/hindsight-coding-agents`를 배포하며, 제가 시도한 버전(0.8.0)은 설치 프로그램에서 20개의 하네스 목록을 보여줍니다: Claude Code, Codex, Cursor CLI, GitHub Copilot CLI, opencode, Grok Build, Cline CLI, Devin CLI, Antigravity CLI, Qwen Code, Kimi Code, DeepSeek Harness 등.
저는 실제 코딩 에이전트 세션을 실행하지 않았습니다. 설치 프로그램이 이 장치에서 감지한 유일한 에이전트는 다른 도구들이 공유하는 Cursor CLI 설치였고, 저는 그 설정을 변경하고 싶지 않았습니다. 대신 임시 홈 디렉터리에 통합을 설치하여 이것이 무엇을 작성하는지 검사했습니다:
HOME=./fakehome npx -y @vectorize-io/hindsight-coding-agents install cursor-cli
--server self-hosted --api-url http://localhost:8888
이것은 `~/.cursor/hooks.json`에 후크(hook)가 병합되었고, MCP 서버가 `~/.cursor/mcp.json`에 추가되었으며, `~/.cursor/skills/hindsight-coding-agent` 아래에 스킬이 설치되었다고 보고했습니다. 이것이 작성한 후크는 다음과 같습니다 (경로 축약):
{
MCP 엔트리는 로컬 stdio 서버를 실행하며, node ~/.hindsight/coding-agents/dist/mcp-server.js ${workspaceFolder}를 사용합니다. 저는 이 서버를 제 Node 프로젝트를 작업 공간으로 지정하여 직접 시작했고, 그 도구 목록을 나열했습니다. 여기에는 여덟 가지가 있습니다: hindsight_sync_status, hindsight_diagnose, hindsight_search_knowledge_pages, hindsight_list_knowledge_pages, hindsight_read_knowledge_page, hindsight_reflect, hindsight_capture_initiative 그리고 hindsight_ingest_document입니다.
hindsight_diagnose는 프로젝트를 로컬 서버의 coding-agent::node-agents라는 은행(bank)으로 해결했습니다. hindsight_sync_status는 synced: false, git 로그 없음, 그리고 지식 페이지가 0개라고 보고했습니다. 이는 문서에 나와 있는 내용과 일치하는데, 문서에는 git 히스토리 및 과거 세션의 수집(ingestion)이 session-start hook에서 시작된다고 되어 있고, 저는 실제 에이전트를 사용하면서 이 후크를 발동시킨 적이 없기 때문입니다. 따라서 배선(wiring)은 보여드릴 수 있지만, 에이전트 내부에서 어떻게 작동하는지는 보여드릴 수 없습니다.
테스트할 수 없었던 것들
다음 항목들은 모두 LLM을 필요로 하므로, 저는 Vectorize의 문서를 통해 설명할 수만 있습니다:
- Retain에서의 사실 추출(Fact extraction). 모델을 사용하면 retain은 원시 청크를 저장하는 대신 사실(facts), 개체(entities), 관계(relationships) 및 날짜를 추출합니다.
- 관찰(Observations). 관련 사실들은 백그라운드에서 중복 제거된 믿음(deduplicated beliefs)으로 통합되며, 이 믿음들은 이를 뒷받침하는 증거(supporting evidence)를 유지합니다.
- Reflect. 조회(lookup) 방식이 아니라 은행 전체에 걸친 느린 추론 과정(reasoning pass)입니다.
- 정신 모델 및 지식 페이지(Mental models and knowledge pages). 은행이 학습함에 따라 재작성하는, 준비된 답변과 위키 같은 페이지입니다. coding-agent 통합은 이들을 기반으로 구축됩니다.
- LLM 래퍼(
hindsight-litellm). 각 모델 호출 주변에서 자동으로 회상하고 유지(recalls and retains)해주는 기능입니다. - 벤치마크(Benchmarks). README에 따르면 Hindsight는 LongMemEval에서 최첨단(state of the art)이며, Virginia Tech의 Sanghani Center와 The Washington Post가 독립적으로 그 결과를 재현했다고 합니다. 저는 아무것도 벤치마킹하지 않았으며, 다섯 개의 메모리가 대규모에서의 정확성에 대해 아무것도 증명하지 못합니다.
시도해 볼 가치가 있을까요?
제가 실행해 본 내용을 바탕으로 말씀드릴 수 있는 것은 이렇습니다. 설치는 빠르지만 용량이 큽니다. 서버는 외부 서비스나 API 키 없이 시작하며, TypeScript 클라이언트는 간단합니다. 메모리는 재시작에도 지속됩니다. 하나의 은행(bank)이 SDK 호출과 MCP 도구 호출을 모두 처리하며, 제가 의도적으로 쉬운 작은 질문 세트를 사용했을 때 recall은 매번 올바른 노트를 가장 먼저 제시했습니다.
다만 모델 없이 Hindsight는 MCP 프론트엔드를 갖춘 잘 패키징된 로컬 벡터-플러스-키워드 스토어입니다. 태그라인의 '학습(learning)' 부분(추출, 관찰, 성찰, 지식 페이지)은 LLM이 필요한 부분이며, 이 부분은 제가 아직 검증하지 못했습니다. 만약 키가 있거나 Ollama 또는 LM Studio를 통해 로컬 모델을 사용할 수 있다면(두 가지 모두 지원되는 제공업체입니다), 다음 테스트는 그쪽으로 진행할 것을 권장합니다. 그렇지 않다면, none 모드는 토큰을 소모하기 전에 API와 은행 모델이 에이전트 설정에 적합한지 확인하는 정직하고 빠른 방법입니다.
혹시 Hindsight나 다른 메모리 계층(memory layer)을 코딩 에이전트 뒤에 배치해 보신 경험이 있나요? 세션 간에 실제로 어떤 것이 유지되었는지 댓글로 알려주시면 좋겠습니다.
원래 Medium에 게시되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기