Institution Mode: 운영자 참조
다중 에이전트 투자 위원회의 애널리스트 복구 계약과 정규 자산 preflight
minara_institution_analyze는 Minara의 기본 위원회 흐름 또는 웹 UI에서
세션에 저장한 Roundtable을 실행합니다. 이 문서는 기본 분석 경로가
사용하는 하위 수준 복구 및 자산 해석 동작을 설명합니다. 단계 구성,
Agent 설정, 템플릿, 변경 불가능한 실행 스냅샷은
Institution Mode를 참조하십시오.
기본 흐름에는 병렬 분석, 강세와 약세 토론, 조사 통합, 거래 계획, 위험 토론, 최종 포트폴리오 판단이 포함됩니다. 맞춤 Roundtable은 이 구성을 바꿔도 같은 읽기 전용 안전 경계를 유지합니다.
파이프라인 타임아웃과 벤치마크 설정은 환경 변수: Institution Mode를 참고하세요.
Roundtable 상태와 스냅샷
Builder는 Institution 세션마다 활성 파이프라인을 저장합니다. 저장할 때 예상 리비전을 확인하므로 다른 브라우저 창이 더 새로운 작업을 조용히 덮어쓰지 않고 충돌을 반환합니다. 저장된 파이프라인이 없으면 게이트웨이는 최근 실행 스냅샷을 사용하고, 그것도 없으면 기본 구성을 사용합니다.
Agent, 단계, Roundtable 템플릿은 별도로 저장하며 기본 템플릿은 변경할 수 없습니다. 실행을 시작하면 전체 파이프라인을 단계 결과, Agent 사용량, 최종 상태, 보고서 파일과 함께 변경 불가능한 스냅샷으로 복사합니다. 관련 API는 다음과 같습니다.
애널리스트 복구 : synthesis-and-parse
각 Phase-1 애널리스트 슬롯은 먼저 자유로운 tool 호출 루프에서
모델을 실행합니다(submit_analyst_report는 항상 역할의 데이터
도구들과 함께 노출됩니다). 메인 루프가 실제로 non-stub 리포트를
제출하면 슬롯은 캡처된 tool_outputs[]를 첨부하고 반환합니다.
메인 루프가 제출하지 않았거나(턴 상한 도달, 모델이 산문을 적고 제출을 잊음) 빈/플레이스홀더 인자를 제출했을 때, 오케스트레이터는 synthesis 턴을 한 번만 실행합니다.
-
도구도
tool_choice도 없습니다. thinking은 활성화됨 : 이는 이전에tool_choice: { type: "tool" }하에서 실패하던 호출입니다. Anthropic이 그 조합을 거부하므로 모델이 인자를 채울 추론 여유가 0이 되기 때문입니다. -
사용자 메시지는 엄격한 3 섹션 산문 형식을 요구합니다:
HEADLINE: <한 문장 결론> KEY FINDINGS: - <finding 1, 도구명 + 구체적 수치 인용> - <finding 2, ...> CONFIDENCE: <0.0에서 1.0 사이의 숫자>
오케스트레이터는 parseSynthesisProseToReport로 서버사이드에서
산문을 곧바로 AnalystReport로 파싱합니다. 파서는 혼합된
bullet 스타일, 섹션 마커 주변의 markdown 강조, 범위를 벗어난
confidence([0, 1]로 클램프)에 관대합니다.
synthesis 턴의 산문이 비어있거나, 형식이 깨졌거나, 모든 bullet이
플레이스홀더 형태("tried X: ok")일 경우 오케스트레이터는
buildSubagentSummaryReport : 보편적인 "항상 쓸만한 결과를
낸다" 빌더 : 로 폴백합니다. 두 가지 분기:
| 분기 | 트리거 | Headline | Confidence |
|---|---|---|---|
| 일부 tool 성공 | toolsTried.some(t => t.status === "ok") | "<ticker> (<role>): raw tool summary (model synthesis unavailable)" | 0.3 |
| 전부 tool 실패/tool 호출 없음 | toolsTried.every(t => t.status !== "ok") 또는 비어있음 | "<ticker> (<role>): no data gathered this session" / "... no tools available this session" | 0.1 |
일부 tool이 성공한 경우 리포트는 캡처된 tool 데이터(도구당 1
bullet, preview에서 파생)를 인용하므로 하류 단계가 무엇이
돌아왔는지 볼 수 있습니다. 전부 실패한 경우 리포트는 시도한
tool을 열거하고 끝에 역할의 도메인 기본 추론을 한 문장으로
첨가합니다(역할당 한 문장, roles.ts의 역할 정의 옆에 정의).
어느 분기든 슬롯의 ok 플래그는 true입니다 : 옛 "data-gap"
개념은 폐기되었습니다. 모든 Phase 1 슬롯은 이제 항상 메인
에이전트에 쓸만한 요약을 제공하므로 Phase 2-6은 항상 실행됩니다.
Tool outputs : 캡처된 반환값 표면
각 AnalystReport는 선택적 tool_outputs[]를 담으며,
오케스트레이터가 슬롯의 대화에서 채웁니다. tool 호출당 한
항목:
{
tool: string; // 도구명
ok: boolean; // 호출이 성공했을 때 true
preview: string; // 성공: 잘려진 JSON / 텍스트(~1500자)
// 실패: 에러 메시지 문자열
args_summary?: string; // 호출 입력의 한 줄 요약
error_code?: string; // 구조화된 실패 카테고리(있을 때)
}성공한 호출은 pretty-print된 JSON 미리보기를, 실패한 호출은
실패 사유를 그대로 preview에 담습니다. 운영자는 호출이 왜
데이터를 반환하지 않았는지를 직접 볼 수 있습니다(단순히
"안 돌아왔다"가 아닌). web-ui의 PersonaOutputRenderer는
이것을 구조화된 출력 팝업의 "Tool outputs" 섹션으로 렌더링
하며 각 행은 클릭으로 펼칠 수 있습니다.
정규 자산 preflight
Phase 1 디스패치 전, classifyAsset(ticker) === "unknown"인
경우(또는 INSTITUTION_FORCE_RESOLVER_PREFLIGHT=true),
오케스트레이터는 서버사이드 preflight를 실행합니다:
- SQLite 캐시(
canonical_asset_cache테이블)를 확인. - 캐시 미스 또는 만료 시: CoinGecko / CMC / DexScreener를
병렬 조회하고, chain+contract 아이덴티티(CAIP-19 스타일의
evm/native/solana/cosmos/polkadot/equitydiscriminated union)로 정규화. outcome별 TTL로 영속화. - outcome 라우팅:
resolved(유일한 chain+contract):meta.resolved_ticker를 보강, 애널리스트는 preamble에서 정규 아이덴티티를 볼 수 있음.multi(멀티체인 배포): 동일, 단 후보 배열이 모호성 해소 컨텍스트로 들어감.ambiguous(provider 간 불일치): 중앙집중적 모호성 해소 이벤트를 발생(병렬 4개의 "어느 토큰입니까?" 프롬프트가 아님).none: Phase 1 전에 중단, LLM 호출 0건. 오케스트레이터가 지금 유일하게 발생시키는 abort kind입니다.
정규 아이덴티티는 chain+contract이지 CoinGecko id가
아닙니다. CoinGecko의 내부 id는 그들의 큐레이션에 의존하는
중앙집중 인덱스이므로, 부트스트랩 출력으로 사용하면
에이전트를 단일 provider의 세계관에 묶어버립니다. on-chain
쿼리를 받는 하류 도구들은 CAIP-19를 직접 받습니다. provider
특화 도구(CoinGecko 가격 차트)는 정규 아이덴티티가 확립된
후에 sources에서 자기 id를 읽습니다.
outcome별 TTL
캐시는 outcome별로 다른 TTL을 사용합니다. outcome들의 노후화 속도가 다르기 때문입니다:
| outcome | 기본 TTL | 이유 |
|---|---|---|
resolved | 30일 | 안정적 chain+contract, 거의 안 변함 |
multi | 14일 | 사용자 모호성 해소가 체인을 pin할 수 있음 |
ambiguous | 7일 | provider 데이터가 수렴할 수 있음 |
none | 1일 | provider는 매일 갱신; 빠른 재시도 |
user_supplied | 365일 | 운영자 오버라이드; 사람을 신뢰 |
클래스별 TTL은 CANONICAL_ASSET_CACHE_TTL_*_DAYS 환경
변수로 설정합니다(env-vars 참조).
라이브 집계기가 실패할 때(provider 다운, rate limit),
CANONICAL_ASSET_CACHE_FALLBACK_TO_EXPIRED=true(기본)는
from_expired_fallback: true로 태그된 만료된 캐시 항목을
반환합니다. 배포가 어떤 드리프트도 허용할 수 없다면 false로
설정.
없는 ticker 추가하기
에이전트는 새 ticker를 처음 만났을 때 ticker → 정규 아이덴티티 매핑을 학습합니다. 새 토큰을 위한 코드 배포가 필요 없습니다. 두 경로:
- 라이브 해상도: 다음
/institution <ticker>호출이 preflight를 트리거하고, 결과가 캐시되며, 이후 모든 역할이 정규 아이덴티티를 볼 수 있습니다. - 운영자 오버라이드: CoinGecko / CMC / DexScreener에
토큰이 없을 때(예: 신규 출시), 운영자는 정규 아이덴티티를
직접 pin할 수 있습니다. UI: 중단 배너에 컨트랙트 주소
폼. CLI:
minara assets pin <ticker> --chain <chain> --contract <0x...>(배포에서 assets CLI가 활성화된 경우).
methodology-store의 TICKER_TO_CLASS 테이블은 그대로
있지만 용도가 달라졌습니다(리스크/포트폴리오 코드의
asset-class 조회). 정규 리졸버가 asset_class 필드가 새
정보를 줄 때 회신 기록하지만, TICKER_TO_CLASS는 더 이상
정규 아이덴티티의 진실의 원천이 아닙니다.
실제 운영에서 복구 검사
institution_role_outputs.data_gap 컬럼은 data-gap 개념
폐기 이전에 기록된 레거시 행을 위해 스키마에 그대로
남아있습니다. 새 쓰기는 항상 0입니다. 메트릭 집계기
InstitutionStore.getAnalystStubMetrics는 히스토리컬 보고를
위해 여전히 이 값을 읽지만, 현재 복구 경로에서는 더 이상
하중을 가지지 않습니다.
run별 감사:
# run의 모든 애널리스트 행(레거시 retry_count + data_gap 포함).
minara learning methodology cases --run-id <run_id>