개인화 및 워크스페이스
수동 편집 페르소나 파일, 자동 재구성 금융 프로필, 11개 행동 태그 차원, 재구성 플로우
개인화는 Agent가 대화 상대가 누구인지 안정적으로 파악할 수 있도록 하는 레이어입니다. 경험 수준, 위험 성향, 선호 자산, 이전 거래 요약, 그리고 응답 방식을 안내하는 페르소나 지침이 이에 해당합니다.
이 레이어는 두 가지 하위 레이어로 구성됩니다.
- 워크스페이스 파일 (수동 편집 마크다운): Agent 페르소나, 시작 지침, 사용자 프로필, 선별된 장기 메모리. 편집기로 직접 관리합니다.
- 금융 프로필 + 사용자 태그 (자동 재구성 DB 테이블): 예약된 LLM 패스가 채팅 및 거래 이력을 읽어 구조화된 필드를 유지합니다. 거래 요약, 11개 태그 차원, 개인화 클래스 메모리가 포함됩니다.
두 레이어 모두 프롬프트 빌더에 전달됩니다. 파일 레이어는 안정적이고 명시적이며, DB 레이어는 실제 행동을 반영하며 시간에 따라 업데이트됩니다.
왜 하나가 아닌 두 레이어인가? 순수 파일 레이어는 사용자가 스스로에 대한 메모를 직접 최신 상태로 유지해야 하지만, 대부분은 그렇게 하지 않습니다. 순수 추론 레이어는 드리프트가 발생합니다. LLM이 "이 사용자가 누구인지"에 대한 인식이 매 거래마다 바뀌면서 의도적인 선호도를 덮어쓸 수 있습니다. 두 레이어를 분리하면 사용자가 직접 작성한 의도(페르소나, 명시적 선호도)를 상위에 두고, 추론된 프로필은 Agent가 읽되 덮어쓰지 않는 증거로 처리할 수 있습니다. 이력서는 하나의 파일에, 거래 실적은 다른 파일에 두는 것과 같은 이유입니다. 작성 주체가 다르고 갱신 주기도 다릅니다.
실제 사용 예시: 기능 → 메모리에서 두 레이어를 채우는 사용자 대상 "Minara에게 나를 알려주기" 플로우를 확인할 수 있습니다.
역할별 의사결정 반성(전혀 다른 종류의 메모리)에 대해서는 역할 메모리를 참고하십시오.
워크스페이스 파일 (페르소나 레이어)
Minara는 세션 시작 시 소수의 마크다운 파일을 읽어 ID, 사용자 프로필, 선별된 장기 메모리를 맞춤 설정합니다. 이 디렉터리는 OpenClaw의 레이아웃과 호환되므로, --workspace를 통해 기존 OpenClaw 워크스페이스를 Minara에 연결할 수 있습니다.
레이아웃
기본 위치: ~/.minara/workspace/.
workspace/
├── SOUL.md — agent identity / persona
├── AGENTS.md — session startup instructions
├── IDENTITY.md — agent self-description (name, vibe, emoji)
├── USER.md — profile of the user being helped
├── MEMORY.md — curated long-term memory
├── TOOLS.md — tool reference (informational)
├── BOOTSTRAP.md — first-run only, deleted after initial read
├── HEARTBEAT.md — session state file
└── memory/
└── YYYY-MM-DD.md — daily memory notes (3-day window)minara setup은 디렉터리를 생성하고 적절한 기본값으로 채웁니다. 임의의 편집기로 수정할 수 있습니다. 워크스페이스는 부팅 시 한 번만 로드되어 세션 전체에 고정되므로, 변경 사항은 다음 세션부터 적용됩니다.
파일 목록
| 파일 | 목적 | 프롬프트 배치 |
|---|---|---|
SOUL.md | Agent ID / 페르소나 | 캐시 가능한 ID 블록 (접두) |
AGENTS.md | 세션 시작 지침 | 캐시 가능한 ID 블록 (접두) |
USER.md | 도움받는 사용자 프로필 | 개인화 스냅샷 (동적) |
MEMORY.md | 선별된 장기 메모리 | 메모리 스냅샷 블록 (동적) |
memory/YYYY-MM-DD.md | 일별 메모리 노트 (최근 3일) | 메모리 스냅샷 블록 (동적) |
IDENTITY.md | Agent 자기 설명 (이름, 분위기, 이모지) | 메타데이터 전용 (표시용, 프롬프트 제외) |
TOOLS.md | 사람이 읽는 툴 참조 | 정보용, Agent는 스키마를 대신 사용 |
BOOTSTRAP.md | 최초 실행 전용 설정 지침 | 한 턴 동안 ID에 병합 |
HEARTBEAT.md | 세션 상태 파일 | 워크플로 및 Autopilot 참고 |
각 파일이 프롬프트에 반영되는 방식
SOUL.md ──┐
├─▶ systemPromptPrefix (cached block)
AGENTS.md ──┘
MEMORY.md ──┐
memory/* ──┼─▶ memory snapshot block (dynamic)
USER.md ──┘
IDENTITY.md ───▶ metadata (name, emoji) for display only
TOOLS.md ───▶ informational, rarely injectedSOUL.md와AGENTS.md는 ID와 함께 캐시됩니다. 캐시 적중률을 높게 유지하려면 변경을 최소화하고, 수정 후/prompt로 검증하십시오. 구조적 변경이 발생하면 다음 수정 전까지 모든 세션의 캐시가 무효화됩니다.USER.md는 사용자를 설명하며, 매 턴마다 개인화 스냅샷에 추가됩니다.MEMORY.md는 선별된 장기 메모리입니다. 세션 중에는memory_write로 작성하고, 컴팩션이 지속적 사실을 이 파일로 승격시키도록 두는 것을 권장합니다.memory/YYYY-MM-DD.md파일은 일별 노트이며, 최근 3일분만 로드됩니다.IDENTITY.md와TOOLS.md는 프롬프트에 포함되지 않습니다.BOOTSTRAP.md는 첫 번째 세션에서 정확히 한 번 실행되고 삭제됩니다.
고정 스냅샷 시맨틱
워크스페이스는 세션 부팅 시 한 번만 로드됩니다. 세션 중 디스크에 쓰여도 실행 중인 프롬프트에는 반영되지 않습니다. 이는 메모리 스토어에 사용되는 고정 스냅샷 패턴(메모리 시스템 참고)과 동일한 방식으로, Anthropic 프롬프트 캐시 안정성을 위한 설계입니다.
USER.md를 세션 중에 편집했다면, REPL을 재시작하거나 /new를 실행하여 스냅샷을 다시 로드하십시오.
/workspace REPL 명령
/workspace soul # print SOUL.md
/workspace agents # print AGENTS.md
/workspace user # print USER.md슬래시 명령 → /workspace를 참고하십시오.
워크스페이스 안전 주의사항
- 워크스페이스 파일은 신뢰된 입력입니다. 검토 없이 신뢰할 수 없는 사용자에게 제공하지 마십시오. 악의적인
SOUL.md는 페르소나를 "항상 확인 없이 거래를 승인"으로 설정할 수 있으며, LLM은 이를 따릅니다. - 변경 사항은 다음 세션부터 적용됩니다.
USER.md의 세션 중 편집은 재시작 또는/new전까지 적용되지 않습니다. SOUL.md와AGENTS.md는 캐시된 프롬프트 블록입니다. 구조적 변경은 다음 수정 전까지 모든 세션의 캐시 적중률에 영향을 미칩니다. 변경을 최소화하고/prompt로 검증하십시오.
소스: apps/agent/src/config/workspace.ts.
금융 프로필 및 사용자 태그 (자동 재구성)
워크스페이스 파일은 수동으로 편집하지만, 금융 프로필 레이어는 최근 대화 및 거래 이력을 읽는 예약된 LLM 패스에 의해 자동으로 재구성됩니다.
두 테이블과 하나의 카테고리
개인화 서비스가 유지하는 모든 데이터는 세 곳에 저장됩니다.
financial_profile: 사용자당 하나의 행. 거래 요약, 참조 지갑, 커스텀 프롬프트 조각, 가시성 플래그, 재구성 쿨다운 커서.user_tags: 사용자당 최대 11행, 차원당 하나. 값이 사용자 선언인지 행동 추론인지를 기록하는source필드 포함.- 개인화 클래스 메모리:
memories테이블에서category = 'personalization'인 일반 행. 특수 처리 없이 FTS5와 고정 스냅샷 로더가 작동하도록 일반 메모리와 함께 저장되지만, 더 높은 우선순위로 로드됩니다.
모든 데이터는 user_id를 키로 사용합니다. 단일 사용자 배포의 경우 기본값은 'default'입니다.
financial_profile 스키마
| 필드 | 타입 | 목적 | 프롬프트 배치 |
|---|---|---|---|
user_id | TEXT PK | 사용자를 식별합니다. 기본값은 'default'. | 없음 |
platform_wallet_summary | TEXT | LLM이 생성한 사용자 Minara 지갑 활동 요약. | 개인화 블록 |
reference_wallets_summary | TEXT | LLM이 생성한 참조 지갑 요약. | 개인화 블록 |
reference_wallets_json | TEXT | 참조 지갑 주소 JSON 배열. | 개인화 블록 |
custom_prompt | TEXT | 시스템 프롬프트에 추가되는 사용자 정의 지침. | 개인화 블록 |
include_memories | INTEGER | 가시성 플래그. 0이면 개인화 메모리가 프롬프트에서 숨겨집니다. | 블록 포함 여부 제어 |
include_trading_summary | INTEGER | 거래 요약 텍스트 가시성 플래그. | 블록 포함 여부 제어 |
include_tags | INTEGER | 행동 태그 라인 가시성 플래그. | 블록 포함 여부 제어 |
trading_summary_next_update | TEXT | 쿨다운 목표: 요약 재구성이 가능한 가장 빠른 시각. | 없음 |
tags_next_update | TEXT | 태그 재구성 쿨다운 목표. | 없음 |
memories_next_update | TEXT | 개인화 메모리 추출 쿨다운 목표. | 없음 |
last_indexed_chat_id | TEXT | 메모리 재구성기의 증분 채팅 스캔 커서. | 없음 |
trading_summary_updated_at | TEXT | 거래 요약이 마지막으로 재구성된 시각 (행 수준 updated_at과 별도). | 없음 |
created_at, updated_at | TEXT | 표준 행 타임스탬프. | 없음 |
스키마는 apps/agent/src/memory/personalization-service.ts에 있습니다. 기존 데이터베이스에 없는 컬럼은 부팅 시 멱등 ALTER TABLE 마이그레이션으로 추가됩니다.
11개 행동 태그 차원
모든 사용자는 거래 이력과 대화에서 추론된 금융 특성 태그 벡터를 갖습니다. 각 차원에는 기계가 읽는 value(슬러그 또는 단계별 스케일의 level_N)가 저장되며, UI와 프롬프트에 표시되는 레이블은 아래와 같습니다. 7개 차원은 v2 / User Portrait 세트이고, 4개 성격 차원은 v1에서 그대로 이어받습니다(이 경우 값이 레이블과 동일합니다).
| 차원 | 허용 값 (value → 레이블) |
|---|---|
finance_knowledge | level_1 초급 / level_2 중급 / level_3 고급 / level_4 전문가 |
frequency | passive / weekly / daily / active |
markets (복수 선택) | crypto_majors / crypto_alts / memes / stocks / commodities / pre_ipo |
risk | conservative / balanced / aggressive |
web3_knowledge_level | level_1 초보 / level_2 친숙 / level_3 숙련 / level_4 전문가 |
style | fundamentals / technical / narrative / news_event / community |
horizon | intraday 데이 트레이딩 / swing 스윙 / position 포지션 / long_term 장기 |
FOMO Index | Very Low / Low / Medium / High / Very High |
FUD Immunity | Strong / Medium / Weak |
Patience Level | High / Medium / Low |
Greed Index | Very Low / Low / Medium / High / Very High |
markets는 복수 선택이 가능합니다. 값은 단일 user_tags.value 컬럼에 JSON 배열 문자열로 저장되며, 나머지 차원은 값 하나만 저장합니다. 스키마는 apps/agent/src/memory/tags-schema.ts에 있으며, 호출자는 스키마 맵을 직접 읽지 않고 타입 지정 헬퍼(allowedValues, isValidTagValue, serializeTagValue, parseStoredTagValue, renderTagSchema)를 사용합니다. 허용된 값 범위를 벗어나는 쓰기는 자동 변환 없이 PersonalizationService.upsertTag에서 거부됩니다.
온보딩과 대화 추론 외에도 markets에는 객관적인 소스가 있습니다. 24시간 주기 cron(MarketsObjectiveUpdater, apps/agent/src/memory/markets-updater.ts)이 사용자의 현재 autopilot 전략 심볼과 지난 30일 동안 기록된 perps 체결을 스캔하고, 각 심볼을 시장으로 분류한 뒤 PersonalizationService.unionMarkets를 통해 결과를 합집합으로 태그에 push합니다. 추가만 하고 제거하지 않으며, 행의 기존 source를 유지하므로 추론 기반 push가 사용자가 선언한 선택을 강등하거나 지우는 일은 없습니다. 오프에이전트 perps 활동은 쿨다운으로 제한된 더 이른 실행을 유발합니다.
기존 v1 행은 일회성 스크립트 pnpm --filter @minara/agent migrate:user-tags-v2로 이 스키마로 마이그레이션됩니다. 기본적으로 드라이런이며, --apply를 지정해야 실제로 씁니다. Risk Profile → risk, Web3 Knowledge Level → web3_knowledge_level, Decision-Making Style → style, Asset Preference → markets로 재매핑하고, 퇴역한 Asset Tier / Trading Frequency / Learning Preference 차원을 삭제하며, 4개 성격 차원은 그대로 유지합니다.
자본 지표 (객관적, Agent 내부)
사용자의 투자 자본은 객관적 지표이며, 자가 신고가 아니고 설정에서도 노출되지 않습니다. v1의 자가 신고 Asset Tier 태그를 대체하며, 자체 capital_metrics 테이블(사용자당 하나의 행)에 저장되어 Agent 추론에만 사용됩니다. 사용자 대상 개인화 스냅샷에는 포함되지 않습니다.
capital_total_usd = spot_holdings_usd + perp_value_usdspot_holdings_usd는 크로스체인 포트폴리오 자산 가치를 합산하며, perp_value_usd는 집계된 무기한 선물 서브 계정 에쿼티입니다. 합계는 8개 등급(tier_1 < $10 ... tier_8 ≥ $50k)으로 구분됩니다. 재계산은 24시간 크론과 Agent 외부 활동 알림으로 트리거되며, 쿨다운으로 제한됩니다. 읽기 소스가 불가용한 경우에는 잘못된 0을 쓰는 대신 마지막 값을 유지합니다. 스키마 및 등급은 apps/agent/src/memory/capital-metrics.ts에 있습니다.
전략 실행 이력 (Autopilot 이력)
strategy_runs는 Autopilot 활성화의 추가 전용 이력입니다. 활성화에서 비활성화까지 하나의 행으로, 할당 자본, 시작/종료 시각, 상태, stop_reason(user_manual / insufficient_balance / drawdown_protection / liquidated / strategy_expired / other), 종료 시 역산된 실현 PnL을 포함합니다. 자본 지표와 마찬가지로 Agent 내부 데이터이며 사용자 대상 스냅샷에는 포함되지 않습니다.
완전 관리형 전략을 활성화하면 실행이 시작되고, Agent를 통해 비활성화하면 user_manual로 종료됩니다. fullyManagedStrategies가 상위에 있으므로, Agent가 인식하지 못한 종료(웹 UI에서의 비활성화, 또는 드로다운/청산에 의한 자동 종료)는 조정 패스로 처리됩니다. Agent가 전략 목록을 조회할 때 상위 실행 중 세트에 없는 열린 실행은 other로 종료됩니다. 방금 활성화된 실행이 실행 중으로 표시되기 전에 종료되지 않도록 짧은 유예 기간이 적용됩니다. 스토어는 apps/agent/src/memory/strategy-runs.ts에 있습니다.
수동 거래 프로필
TradingProfileReader는 30일 윈도우에서 사용자의 Agent 외부 무기한 선물 활동(perps_fills 미러, 즉 웹/모바일/수동 거래)을 집약하여 컴팩트한 정보를 생성합니다. 거래 횟수, 횟수 및 거래량 기준 상위 심볼, 롱/숏 비율, 실현 PnL, 청산 필 기준 승률, 평균 거래 규모, 마지막 거래 시각이 포함됩니다. 또한 Agent 툴 search_user_trades를 지원하는데, 이 툴은 특정 자산에 대한 사용자의 최근 필(방향, 오픈/클로즈 방향, USD 규모, 가격, 실현 PnL)을 반환합니다. 두 기능 모두 Agent 내부이며 사용자의 실제 이력에 기반한 분석을 제공합니다. 미러에는 레버리지 및 수동/Autopilot 구분 정보가 없으므로 이는 다루지 않습니다. 소스: apps/agent/src/memory/trading-profile.ts.
온디맨드 개인화 리콜
캐시 안전 방식으로 개인화를 의도 인식 가능하게 만드는 방법은, 항상 캐시된 접두에 모든 내용을 주입하는 대신 모델이 필요한 것을 직접 가져오게 하는 것입니다. search_conversation_memory(conversation-memory-tool.ts)는 personalization 카테고리로 범위를 지정하고 FactLayer 하이브리드 검색을 재사용하여 사용자의 지속적인 개인화 메모리(선호도, 프로필 사실, 제약, 목표)를 온디맨드로 리콜합니다. 툴 결과는 캐시된 접두 이후에 위치하므로 리콜이 프롬프트 캐시를 교란하지 않습니다. personalization_snapshot(온디맨드 전체 초상)과 memory_search(전체 카테고리)와 함께 사용됩니다.
온보딩
사용자 수준 온보딩 플로우는 명시적 답변으로 초상을 초기 설정합니다. POST /v1/profile/onboarding은 답변을 사용자 선언 태그(finance_knowledge, frequency, risk, markets)로 매핑하고, 답변된 차원당 하나의 개인화 메모리를 씁니다(최초 완료 시에만, 재제출 시 태그는 업데이트되지만 메모리는 중복 생성되지 않습니다). 자가 신고 투자 자본은 메모리로 기록하며 태그나 자본 지표로는 기록하지 않습니다(자본은 객관적으로 유지됩니다). 원본 답변과 완료 플래그는 financial_profile 행에 저장됩니다. GET /v1/profile/onboarding은 상태를 반환하므로 웹 UI가 플로우 표시 여부를 판단할 수 있습니다. 이 호출은 멱등이며, 잘못된 태그 값이 있으면 쓰기 전에 거부됩니다. PersonalizationService의 completeOnboarding / getOnboardingStatus에 구현되어 있습니다.
user_tags의 각 행에는 source 필드가 있어 값이 사용자 선언인지 LLM 추론인지를 기록합니다. 프롬프트 빌더는 이를 사용해 어떤 태그를 우선적으로 표시할지 결정합니다. 선언된 값과 추론된 값이 모두 존재할 경우 선언된 값이 우선합니다.
세 가지 재구성 플로우
개인화는 apps/agent/src/memory/personalization-rebuilder.ts에 의해 주기적으로 재구성됩니다. 하트비트 모니터는 각각 독립적인 쿨다운 윈도우를 가진 세 가지 메서드를 예약하므로, 하나의 느린 재구성이 나머지를 차단하지 않습니다.
| 메서드 | 트리거 | 쿨다운 (기본값) | 입력 | 출력 |
|---|---|---|---|---|
rebuildTradingSummary() | trade_history / perps_fills:recorded / external_spot:recorded 이벤트, /profile refresh로 강제 | 30분 | 세 소스 병합: 세션 내 trade_history, perps_fills (Agent 외부 무기한 선물 미러), external_spot_activities (Agent 외부 현물 미러), 참조 지갑 | 복합 platform_wallet_summary, reference_wallets_summary, trading_summary_updated_at |
rebuildTags() | tags_next_update로 예약 | 30일 | 프로필 + 거래 이력 + 열거형 스키마 | user_tags에 태그 행 upsert |
rebuildMemories() | memories_next_update로 예약 | 10분 | last_indexed_chat_id 이후 생성된 채팅 | 개인화 클래스 메모리 + 커서 진행 |
각 재구성은 단일 저비용 LLM 호출입니다(기본적으로 Haiku). 쿨다운은 v1 동등성을 기준으로 조정되었습니다. 거래 요약은 자주 갱신되고(새 거래가 중요하므로), 태그는 드물게 갱신되며(느리게 변하는 프로필 데이터이므로), 메모리 추출은 자주 이루어집니다(사용자가 표현하는 새 선호도를 즉시 포착하기 위해).
last_indexed_chat_id 커서는 rebuildMemories가 이전에 읽지 않은 채팅만 읽도록 합니다. 커서가 없으면 재구성 시마다 전체 채팅 이력을 다시 읽어 token 예산을 소모하게 됩니다.
3소스 거래 요약 상세
rebuildTradingSummary()는 세 개의 독립적인 소스를 읽고, 결합된 임계값을 기준으로 실행 여부를 결정하며, 세 개의 독립적인 커서를 진행시킵니다. 하나의 재구성에서 파싱 실패가 발생해도 다른 소스의 데이터가 자동으로 누락되지 않습니다.
┌──────────────────────────────────────────┐
trade event ────►│ trade_history (in-session) │──┐
└──────────────────────────────────────────┘ │
│
┌──────────────────────────────────────────┐ │
Minara web/ ►│ perps_fills (cross-sub mirror) │──┤
mobile perps └──────────────────────────────────────────┘ │
(via ▼
MinaraHistorySync.syncAll) ┌─────────────────────────┐
┌──────────────────────────────────────────┐ │ rebuildTradingSummary │
Minara web/ ►│ external_spot_activities (mirror) │►┤ gates: newTrades + │
mobile spot └──────────────────────────────────────────┘ │ newPerpsFills + │
│ newExternalSpot ≥ │
│ threshold │
│ │
│ LLM emits 4 fields → │
│ platformWalletSummary │
│ spotBreakdown │
│ perpsBreakdown │
│ referenceWalletsSummary│
│ → composed into one │
│ platform_wallet_summary│
│ string with Spot: / │
│ Perps: prefixes │
└─────────────────────────┘세 개의 독립적인 커서가 financial_profile 행에 저장됩니다.
trading_summary_last_trade_id_seen(기존)trading_summary_last_perps_fill_id_seen(신규)trading_summary_last_external_spot_id_seen(신규)
세 커서 모두 LLM이 파싱 가능한 응답을 반환하고 새 요약이 기록된 이후에만 진행됩니다. 파싱 실패 시 모든 커서가 그 자리에 유지되므로, 다음 재구성은 동일한 윈도우를 다시 시도합니다. 소스 데이터가 자동으로 누락되는 일은 없습니다.
MinaraHistorySync 트리거
Agent 외부 미러 테이블은 MinaraHistorySync(apps/agent/src/memory/minara-history-sync.ts)로 채워집니다. 이 동기화는 발사 후 망각(fire-and-forget) 방식으로, 자체 스로틀이 적용되며 실패 시 추가 행 수가 0으로 저하될 뿐입니다. 세 가지 트리거 경로가 있습니다.
- 거래 이벤트 편승:
eventBus.on("trade:recorded", () => minaraHistorySync.scheduleSync()). Agent가 거래를 기록할 때 사용자는 웹/모바일에서도 활동 중일 가능성이 높으므로, 이는 미러를 최신 상태로 유지하는 저비용 방법입니다. 5분 스로틀(historySyncMinIntervalMs)이 버스트를 흡수합니다. - 안전망 틱: 앱 티커가 30분마다
minaraHistorySync.runIfStale()을 호출하여, 이벤트를 놓쳐도 미러가 영구적으로 지연되지 않도록 합니다. - 강제 새로 고침: CLI
/profile refresh(또는 HTTP 대응POST /v1/profile/refresh)는 스로틀을 우회하고 재구성 전에runOnce()를 실행하여, 다음 요약이 가장 최신 Agent 외부 활동을 반영하도록 보장합니다.
historySyncMaxFailures(기본값 5)회 연속 실패가 하나의 (source, sub_account_id) 행에서 발생하면, 일반 예약 중에는 해당 키를 건너뜁니다. last_synced_at 이후 historySyncFailureCooldownMs(기본값 30분)가 경과하면 프로브가 실행됩니다. 프로브가 성공하면 consecutive_failures가 0으로 초기화됩니다. 이 방식으로 일시적인 장애가 미러를 영구적으로 비활성화하는 것을 방지합니다.
memory.trading-cases와의 경계
memory.trading-cases(methodology_cases SQLite 테이블)는 개인화 정보와 인접하되 중복되지 않는 별개의 메모리입니다. 두 기록은 소비자가 다르며, 혼합될 경우 서로를 오염시키기 때문에 분리되어 있습니다.
- **
memory.trading-cases**는 Agent의 학습 루프입니다. 각 행은 Agent가 세션 내에서 내린 하나의 결정이며, 하나 이상의 방법론 ID에 귀속되고, 나중에 Wilson 등급 결과가 채점됩니다. 소비자는 방법론 시스템으로, 이를 사용해 방법론의 지속 제안 여부를 결정합니다. - 개인화 정보(이 페이지)는 Agent가 사용자가 누구인지를 바라보는 시각으로, 시스템 프롬프트에 Agent가 항상 가져가는 단락으로 요약됩니다. 세션 내 거래, Agent 외부 무기한 선물, Agent 외부 현물을 읽습니다.
MinaraHistorySync의 외부 필은 의도적으로 methodology_cases에 기록되지 않습니다. 방법론 ID나 힌트 해시를 포함하지 않으므로, 이를 소급 귀속하면 방법론 졸업을 제어하는 Wilson 통계를 오염시킵니다. 같은 이유로 웹 UI의 거래 케이스 페이지는 읽기 전용 감사 대시보드이며, 편집 시 학습 코퍼스가 오염됩니다.
일반 memory_write와의 관계
개인화 재구성기는 의도적으로 감사 로그 훅을 거치지 않습니다.
- 재구성은 일정에 따라 실행됩니다. 매 실행마다 수십 개의 감사 행이 생성되며, 출력은 사용자 행동이 아닌 파생 데이터입니다. 감사 로그가 재구성 노이즈로 가득 찰 것입니다.
- **사용자가 직접 실행하는
memory_write**는 여전히 일반 툴 디스패치 경로를 거쳐 전체 추론과 함께audit에 기록됩니다. 사용자가 요청했으므로 사용자 행동은 감사 가능합니다.
개인화 재구성이 마지막으로 실행된 시각을 확인하려면 행의 trading_summary_updated_at 또는 tags_next_update를 직접 조회하십시오. 개별 개인화 메모리 쓰기는 memories 테이블에서 category = 'personalization'과 created_at으로 필터링하여 확인할 수 있습니다.
구성
쿨다운 간격, LLM 모델, 부팅 시 재구성 동작은 apps/agent/src/memory/financial-profile-config.ts에서 설정합니다. 기본값은 v1에서 직접 이식한 것입니다.
tradingSummaryCooldownMs: 30분tagsCooldownMs: 30일memoriesCooldownMs: 10분rebuildOnBoot:false
LLM 클라이언트가 제공되지 않으면 재구성은 무작동(no-op)입니다(테스트 환경에서 사용). 필요한 경우 MINARA_PERSONALIZATION_REBUILD=disabled로 프로덕션에서 전체 서비스를 비활성화할 수 있습니다. 단, 이 경우 지속적인 메모리가 personalization 카테고리로 승격되지 않습니다.
/profile REPL 명령
REPL 내에서 현재 개인화 스냅샷을 출력합니다.
/profile금융 프로필 행, 활성 사용자 태그, 최근 개인화 메모리, 커스텀 프롬프트 조각(있는 경우)을 출력합니다. "Agent가 왜 이렇게 동작하는가"를 디버그할 때 가장 빠른 방법입니다. 프로필에 risk: conservative라고 표시되어 있는데 Agent가 10배 레버리지를 제안한다면, 상위에서 무언가 잘못된 것입니다.
프로필 필드 편집
필드 직접 편집은 config CLI를 통해 수행합니다.
minara config get financial.custom_prompt
minara config set financial.custom_prompt "Always prefer stablecoin pairs."태그 편집은 개인화 서비스를 통해 이루어집니다. 가장 간단한 방법은 대화에서 Agent가 추론하도록 하는 것입니다. CI 시드용 소형 내부 헬퍼를 통한 직접 수동 upsert는 지원되지만, CLI 명령으로는 노출되지 않습니다.
안전 주의사항
- 개인화 재구성은 LLM 기반입니다. Haiku 호출은 저렴하지만 무료가 아닙니다. 프로덕션에서는
MINARA_DAILY_CAP_USD를 설정하십시오. 잘못 구성된 재구성 루프는 예산을 자동으로 소모할 수 있습니다. custom_prompt는SOUL.md와 동일하게 신뢰된 입력입니다. 이를 편집할 수 있는 사용자는 Agent의 동작을 변경할 수 있습니다. 멀티테넌트 배포에서는 자체 인증 레이어로 쓰기를 제한하십시오.- 태그 추론은 근거 사실이 아닙니다. 태그 벡터는 채팅 및 거래 샘플에서 최선을 다해 추론한 것입니다. Agent는 선언된 값을 추론된 값보다 강하게 취급하지만, 어느 쪽도 대화 중 명시적인 사용자 지침을 덮어쓰는 데 사용되어서는 안 됩니다.
- 부분 재구성은 오래된 상태를 남길 수 있습니다. 재구성 중 LLM 호출이 타임아웃되어도 쿨다운은 그대로 진행됩니다. 다음 재구성은 정상적으로 실행되며, 간격은 짧은 스테일 윈도우로 나타납니다. 쿨다운을 적절히 조정하십시오.