본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 28. 19:57

지속성 메모리를 갖춘 멀티 페르소나 금융 에이전트 구축하기: Vorniq 내부 살펴보기

요약

지속성 메모리 계층을 공유하는 멀티 페르소나 금융 에이전트 시스템 Vorniq의 기술적 구조를 분석합니다. 개별 에이전트 간의 정보 연속성을 보장하기 위해 Vectorize의 Hindsight를 활용한 메모리 회상 및 저장 메커니즘을 설명합니다.

핵심 포인트

  • 세션 간 정보 유실 문제를 해결하는 지속성 메모리 계층 구축
  • 다섯 명의 특화된 금융 전문가 페르소나 간 컨텍스트 공유
  • Hindsight를 통한 금융 컨텍스트 회상 및 새로운 사실 저장 프로세스
  • Next.js와 Express/TypeScript 기반의 에이전트 아키텍처

지속성 메모리(Persistent Memory)를 갖춘 멀티 페르소나 금융 에이전트 구축하기: Vorniq 내부 살펴보기

다섯 명의 전문가 AI 에이전트, 하나의 공유 메모리 계층, 그리고 이들이 어떻게 하나의 일관된 금융 어드바이저처럼 느껴지게 만드는지에 대한 기술적 심층 분석입니다.

문제점: 전문가의 건망증 (Expert Amnesia)
대부분의 AI 금융 도구에는 아무도 말하지 않는 사각지대가 있습니다. 바로 개별적으로는 뛰어나지만, 세션(Session) 간에는 건망증을 앓는다는 점입니다. 투자 어시스턴트에게 당신의 위험 선호도가 중간 정도이며 5년의 투자 기간을 가지고 있다고 말해도, 3일 후 세금 관련 질문으로 전환하면 해당 에이전트는 당신이 누구인지 전혀 알지 못합니다. 전문 지식은 존재하지만, 연속성(Continuity)이 없습니다.

그것이 바로 제가 Vorniq를 구축하여 메우고자 했던 간극입니다. Vorniq는 장부 관리자(Bookkeeper), 재무 분석가(Financial Analyst), FP&A 분석가(FP&A Analyst), 투자 연구원(Investment Researcher), 세무 전략가(Tax Strategist)라는 다섯 명의 특화된 전문가 페르소나를 중심으로 구축된 개인 금융 지능 시스템입니다. 이들은 모두 Vectorize의 Hindsight를 통해 구동되는 단일 지속성 메모리 계층(Persistent Memory Layer)을 공유합니다. 투자 연구원인 Quinn이 당신에게 중간 정도의 위험 감수 성향을 가진 50만 루피(five-lakh)의 자산이 있다는 것을 학습하면, 세무 전략가인 Cassandra는 당신이 단 한 마디도 반복하지 않아도 다음 세션에서 바로 그 사실을 알게 됩니다.

Vorniq의 기능 및 구조

핵심적으로 Vorniq는 Express/TypeScript 백엔드와 통신하는 Next.js 14 프론트엔드입니다. 백엔드는 세 가지 작업을 처리합니다: 각 LLM 호출 전에 Hindsight로부터 금융 컨텍스트(Financial context)를 회상(Recalling)하고, 메시지를 올바른 페르소나(Persona)의 시스템 프롬프트(System prompt)로 라우팅하며, 응답이 생성된 후 새로운 사실을 메모리에 다시 저장(Retaining)하는 것입니다. LLM 자체는 qwen/qwen3-32b를 실행하는 Groq이며, 회상-생성-저장(Recall-generate-retain) 루프가 체감할 수 있는 지연 시간(Latency)을 유발하지 않을 만큼 충분히 빠릅니다.

다섯 가지 페르소나는 동일한 프롬프트에 대한 단순한 미적 별칭이 아닙니다. 각 페르소나는 해당 도메인에 맞춰 조정된 고유한 시스템 지침(System instruction)을 가지고 있습니다:
• Controller (관리자): 월말 결산, GAAP 조정, 내부 통제, 감사 준비
• Financial Analyst (재무 분석가): DCF 모델링, 시나리오 분석, 가치 평가, 자본 구조
• FP&A Analyst (재무 계획 및 분석가): 롤링 예측(Rolling forecasts), 차이 분석, 드라이버 기반 예산 편성
• Investment Researcher (투자 연구원): 포트폴리오 실사, 주식 리서치, 리스크 평가
• Tax Strategist (세무 전략가): Section 80C 공제, LTCG(장기 자본 이득) 최적화, 다중 관할권 준수

사용자는 사이드바의 커맨드 팔레트(Command palette)를 통해 세션당 하나의 페르소나를 선택합니다. 대화 도중에 페르소나를 전환하는 것은 임시방편이 아닌 핵심 기능(First-class action)입니다. 또한 Hindsight 메모리가 다섯 가지 페르소나 모두에 걸쳐 지속되기 때문에, 분석가(Analyst)에서 세무 전략가(Tax Strategist)로 전환하는 것은 새로운 앱을 여는 것이 아니라 같은 건물 내에서 한 전문가의 사무실에서 다른 전문가의 사무실로 걸어가는 것에 더 가깝습니다.

핵심 기술적 이야기: 일급 인프라로서의 메모리

다른 모든 것을 가능하게 만든 단 하나의 아키텍처 결정은 메모리를 채팅 레이어에 덧붙여진 기능(feature)이 아니라, 단 하나의 생성 토큰이 시작되기 전에 해결되어야 하는 핵심 인프라 문제(infrastructure concern)로 취급한 것이었습니다.

모든 요청 시 backend/src/agent/core.ts 내부에서 실행되는 시퀀스는 다음과 같습니다:

try {
// 메모리는 선택 사항입니다 — Hindsight가 다운되어도 채팅은 여전히 작동합니다
try {
await ensureBank(bankId);
} catch (bankErr: unknown) {
console.warn([core] ensureBank failed (Hindsight may be offline): ${(bankErr as Error).message});
}
const memories = await recall(bankId, message);
const systemPrompt = getPersonaPrompt(persona, formatMemories(memories));
const completion = await groq.chat.completions.create({
model: settings.GROQ_MODEL,
messages: [
{ role: "system", content: systemPrompt },
...history.slice(-10),
{ role: "user", content: message },
],
temperature: 0.7,
max_tokens: 1024,
});

Recall(회상) 단계는 Hindsight가 제 역할을 다하는 지점입니다. 이 단계에서는 TEMPR 검색을 실행하는데, 이는 의미론적 벡터 유사도(semantic vector similarity), BM25 키워드 검색(keyword retrieval), 관련 사실 간의 그래프 탐색(graph traversal), 그리고 최근 정보에 더 높은 순위를 부여하는 시간적 가중치(temporal weighting)를 결합한 방식입니다. "무엇에 투자해야 할까요?"라는 단일 쿼리 하나만으로 투자 선호도뿐만 아니라, 완전히 별개의 세션에 저장되었던 연결된 부채 의무, 소득 제약, 그리고 세율 구간(tax-bracket) 문맥까지 모두 반환됩니다.

Retain(유지) 단계 또한 매우 의도적으로 설계되었습니다. 대화 전체를 메모리 저장소에 다시 쏟아붓는 대신, 시스템은 소득 수치, 부채 잔액, 위험 감수 성향, 명시된 목표와 같은 개별적인 금융 사실(financial facts)을 추출하여 사용자의 bankId를 키(key)로 하는 구조화된 항목으로 저장합니다. 이를 통해 검색을 깔끔하게 유지하고 메모리 저장소가 소음이 많은 대화 기록 보관소(transcript archive)가 되는 것을 방지합니다.

실전에서의 페르소나 간 메모리 교차(Cross-Persona Memory)

이 시스템을 가장 극명하게 보여주는 테스트는 워크플로 중간에 페르소나를 전환할 때 어떤 일이 발생하는가입니다.

다음은 실제 세션 시퀀스입니다:

// 세션 1 — 투자 연구원 (Investment Researcher)
사용자: "투자할 금액은 50만 루피(₹5L)이고, 위험 선호도는 중간(moderate), 투자 기간은 5년입니다."
투자 연구원: [주식, 채권, 하이브리드 펀드에 대한 자산 배분안을 제공함]
// 유지된 정보: investable_capital=₹5L, risk=moderate, horizon=5yr

// 세션 2 — 세무 전략가 (Tax Strategist)
사용자: "가장 세금 효율적인 투자 방법은 무엇인가요?"
세무 전략가: "Quinn이 언급한 50만 루피(₹5L)의 자산 규모와 5년의 투자 기간을 고려할 때,
ELSS 펀드를 이용하면 15만 루피(₹1.5L)까지 Sec 80C 공제를 받을 수 있으며
1년 후에는 장기 자본 이득(LTCG) 면제 혜택을 받을 수 있습니다."

세무 전략가는 투자 연구원에게 사용자의 상황이 어떠한지 다시 묻지 않았습니다. 메모리 시스템이 두 세션 사이를 보이지 않게 연결했기 때문입니다. 이것이 바로 이 아키텍처가 구현하도록 설계된 동작이며, 실제로 이 시스템은 세션 횟수가 두 자릿수를 넘어가는 상황에서도 잘 작동하며, 단일 사용자의 뱅크(bank)에 최대 105개의 유지된 메모리를 축적합니다.

Hindsight를 선택한 이유와 실제 기능

Hindsight를 최종 선택하기 전 몇 가지 메모리 백엔드(memory backends)를 평가했습니다. 결정적인 요인은 TEMPR, 즉 하이브리드 검색 전략(hybrid retrieval strategy)이었습니다. 순수 시맨틱 검색(semantic search)은 정확한 수치를 놓칠 수 있습니다 ("5L"과 "five lakh"는 의미론적으로는 가깝지만, 숫자가 많은 금융 데이터에서는 키워드 검색(keyword retrieval)이 더 신뢰할 수 있습니다). 반면 순수 BM25는 개념적으로 관련된 사실을 놓칩니다. Hindsight는 이 두 가지를 모두 실행한 다음, 그래프 탐색(graph traversal)을 적용하여 연결된 엔티티(entities)를 가져오고, 시간적 가중치(temporal weighting)를 적용하여 오래된 항목보다 최근 업데이트된 내용을 우선적으로 노출합니다.

Reflect 엔드포인트는 세션 위생(session hygiene)을 위한 유용한 추가 기능입니다. 세션 종료 시 POST /reflect를 호출하면 Hindsight가 세션에서 유지된 사실들을 일관된 프로필 업데이트로 통합합니다. 이 과정에서 중복을 제거하고, 충돌을 해결하며, 대체된 데이터를 정리(pruning)합니다. 이 기능이 없다면, 세 번의 세션에 걸쳐 소득 수치를 업데이트하는 사용자의 경우 하나의 현재 값 대신 세 개의 별도 소득 항목이 쌓이게 될 것입니다.

메모리는 지정된 bankId 내에서 사용자별로 저장됩니다. backend/.env에서는 로컬 개발을 위해 이를 HINDSIGHT_BANK_ID=finsight-bank로 설정하지만, 프로덕션 환경에서는 금융 데이터가 적절히 범위가 지정되고 격리될 수 있도록 사용자별 식별자로 사용됩니다.

페르소나 프롬프트(Persona Prompts): 도메인 전문성이 살아있는 곳

backend/src/agent/personas.ts에 정의된 각 페르소나의 시스템 프롬프트(system prompt)는 두 가지 역할을 수행합니다.

첫째, GAAP 준수 및 직무 분리(segregation of duties)를 중시하는 전문가 정체성인 Controller, DCF(현금흐름할인법) 및 시나리오 분석을 기본으로 하는 Financial analyst 등의 전문가 정체성을 확립합니다. 둘째, 회상된 메모리가 응답에 어떻게 통합되어야 하는지를 지정합니다.

메모리 주입(memory injection)은 단순한 결합(concatenation)이 아닙니다. 시스템 프롬프트는 각 페르소나가 현재 쿼리와 관련이 있을 때만 회상된 컨텍스트를 드러내고, "이전 세션에서 언급하셨듯이" 또는 "Investment Researcher가 기록한 소득 수치에 근거하여"와 같이 출처를 인용하도록 지시합니다. 이를 통해 모든 답변이 시스템이 기억하는 모든 내용을 읊는 식이 되지 않도록 하면서도, 응답의 근거를 명확히 유지할 수 있습니다.

제가 초기에 내린 결정 중 만족스러운 것은 백엔드에서 페르소나 전환을 상태 비저장(stateless)으로 유지한 것입니다. 프론트엔드는 요청마다 { persona, bankId, message, history }를 전송합니다. 백엔드는 호출 간에 세션 상태를 유지하지 않습니다. 이는 프론트엔드가 서버 측 조정 없이 대화 중간에 페르소나를 전환할 수 있음을 의미하며, 올바른 페르소나 프롬프트는 맵에서 선택되어 매번의 호출 시점에 새로 주입될 뿐입니다.

결과: 시스템이 실제로 생성하는 것들

가장 중요한 것은 구체적인 결과물입니다. 시스템이 실제로 어떤 결과를 내는지 보여드리겠습니다. 월 소득 ₹1,20,000, 뮤추얼 펀드 ₹5L, 자동차 대출 ₹5L, 월 예산 ₹50,000의 재정 프로필을 가진 사용자가 '재무 분석가(Financial Analyst)'에게 문의하면, 총소득, 명시된 잉여금 ₹70,000, 현재 투자액, 부채 의무를 상세히 분류한 구조화된 간편 요약본을 받습니다. 이 보고서에는 자동차 대출 이자율과 같은 알 수 없는 정보에 대한 주석이 포함됩니다.

같은 사용자가 나중에 '세금 전략가(Tax Strategist)'로 전환하여 세션을 진행할 경우, ELSS와 균형 펀드 배분(balanced fund allocation)을 다루는 네 개의 열로 된 표를 받습니다. 각 항목별 공제액, 장기 자본 이득세(LTCG tax treatment), 그리고 각각 10–12% 및 7–9%의 세후 CAGR 예측치가 포함됩니다. 이때 시스템은 사용자가 별도로 요청하지 않았음에도 불구하고 '투자 연구원(Investment Researcher)' 세션에서 언급된 ₹5L 원금과 5년 기간을 참조합니다.

'컨트롤러(Controller)'는 완전히 다른 영역의 요청을 처리합니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0