학습 시스템
Agent가 반복 작업을 시간이 지날수록 더 잘 수행하게 되는 방식
Minara Agent에는 성공한 도구 시퀀스를 기록하고, 이후 턴에서 제안으로 표시하는 학습 루프가 내장되어 있습니다. 모델 파인튜닝과 달리, 이 모든 것은 SQLite 행으로 처리됩니다. 학습 작업도, 모델 업데이트도, 오프라인 파이프라인도 없습니다. 이 페이지에서는 각 구성 요소와 스킬 시스템과의 협력 방식을 설명합니다.
여기서 "학습"의 의미. Minara에서 "학습"은 파인튜닝이나 가중치 업데이트를 의미하지 않습니다. 모델은 그대로 유지됩니다. 변하는 것은 매 턴 전에 Agent가 SQLite에서 검색하는 내용입니다. 즉, 성공한
{tool_name, args}시퀀스의 라이브러리, 자유 형식의 안내 노트, 구조화된 방법론이 변합니다. 과거의 성공 사례와 유사한 새 턴에는 해당 시퀀스가 제안으로 제공됩니다. 설계는 정교함 대신 감사 가능성을 택합니다. 모든 "학습된" 동작은 읽고, 수정하고, 삭제할 수 있는 행이며, 운영자가 검사할 수 없는 동작은 유지되지 않습니다.
실제 사용 사례: 기능 → 자가 개선에서는 사용자가 Agent에 교훈을 저장하도록 유도하는 방법과, 이후 세션에서 해당 교훈이 표시되는 방식 등 사용자 관점의 인터페이스를 다룹니다.
특정 스킬 호출이 올바른지 그른지에 대한 2단계 LLM 분류를 포함하는 병렬 의사결정-반성 루프(역할별로 범위 지정)에 대해서는 역할 메모리를 참조하십시오. 해당 시스템은 이 시스템과 병렬로 실행되며 다른 질문에 답합니다. "어떻게 성공했는가"가 아니라 "이 특정 결정이 옳았는가, 그 이유는 무엇인가"를 묻습니다.
학습 대상
세 가지 고유한 아티팩트가 learnings 테이블과 apps/agent/src/learning/ 아래의 관련 테이블에 저장됩니다.
- 도구 시퀀스. Agent가 작업을 성공적으로 완료하기 위해 실행한
{tool_name, args}쌍의 순서 있는 목록. 턴 종료 시 Agent가 명시적으로skill_learn을 호출할 때 기록됩니다. - 안내 노트. "Polymarket 가격은 특정 시장 URL에서
web_extract를 사용하십시오. API 요청 제한은 10rpm입니다."와 같은 짧은 자유 형식 메모. 도구 시퀀스와 함께 저장됩니다. - 방법론. 성공 기준이 포함된 구조화된 다단계 계획으로,
learning/structured-methodology.ts에 의해 저장됩니다. 단순한 도구 시퀀스만으로는 표현하기 어려운 딥 리서치 워크플로에 사용됩니다.
피드백 루프
review-engine
learning/review-engine.ts는 턴 종료 시 실행되는 경량 LLM 패스입니다(app.ts에 설치된 review-engine-hook.ts를 통해). 다음을 수행합니다.
- 턴의 도구 호출 시퀀스를 검사합니다.
- N회 미만의 호출이 있거나 명백히 실패한 턴을 필터링합니다.
- "이 작업이 완료되었는가? 얼마나 새로운가? 얼마나 재사용 가능한가?"를 묻는 구조화된 프롬프트로 저렴한 모델(빠른 등급)을 호출합니다.
{score, summary, suggested_trigger, suggested_tool_sequence}를 포함한ReviewResult를 생성합니다.
점수가 임계값을 넘으면 결과가 스킬 매니저로 전달됩니다.
skill-manager
learning/skill-manager.ts는 learnings 테이블을 관리합니다. 적격한 리뷰 시 다음을 기록합니다.
{
id: uuid,
name: "hyperliquid_open_long_with_tp_sl",
trigger: "open long on hyperliquid with tp/sl",
tool_sequence: [...],
guidance: "always set TP before SL; Hyperliquid's 'reduce_only' flag...",
created_at,
success_count: 1,
failure_count: 0,
last_used_at: null,
}중복 제거도 수행합니다. 유사한 트리거가 이미 존재하는 경우(learning/similarity.ts의 코사인 유사도 및 learning/tfidf.ts의 TF-IDF 사용), 새 항목을 생성하는 대신 기존 행의 카운터를 업데이트합니다.
evaluation-loop
learning/evaluation-loop.ts는 매 턴 시작 시 실행됩니다. 다음을 수행합니다.
- 사용자 메시지와 라우터 컨텍스트로 TF-IDF 쿼리를 생성합니다.
- 모든 학습 항목을 쿼리에 대해 점수를 매깁니다.
- 상위 K개 일치 항목(기본값 3)을 반환합니다.
- 프롬프트 빌더로 전달하며, 트리거, 도구 시퀀스 요약, 안내 텍스트가 포함된
<learnings>블록을 시스템 프롬프트에 추가합니다.
LLM은 자유롭게 제안을 채택하거나 무시할 수 있습니다. 어떤 선택이든 학습 항목의 카운터를 업데이트합니다. 성공한 턴으로 이어진 채택은 success_count를 증가시키고, 무시된 학습은 점차 감소합니다.
방법론: 구조화된 계획
딥 리서치 턴은 다른 아티팩트인 방법론을 생성합니다. 도구 시퀀스가 평면 목록인 반면, 방법론은 성공 기준이 있는 단계들의 트리입니다.
{
id, name,
phases: [
{name: "Gather", criteria: [...], tools_used: [...]},
{name: "Synthesize", criteria: [...], depends_on: ["Gather"]},
{name: "Verify", criteria: [...], depends_on: ["Synthesize"]},
],
asset_class: "crypto_alt",
...
}저장소는 learning/methodology-store.ts이며, 딥 리서치 스킬은 이를 읽어 다단계 리서치 계획을 초기화합니다. 방법론은 "어떤 도구를 호출할 것인가"보다 "어떤 중간 근거를 수집할 것인가"가 더 중요한 작업을 위한 세분화된 학습 아티팩트입니다.
벡터 메모리와의 차이점
단순 벡터 메모리는 사실을 저장하고 검색합니다. 학습 시스템은 절차, 즉 "이 유형의 작업을 어떻게 수행할 것인가"를 저장합니다. 그런 다음 이를 실행 가능한 제안으로 표시합니다. 이 구분이 중요합니다.
- 벡터 메모리는 "BTC에 대해 내가 아는 것은 무엇인가?"에 답합니다.
- 학습 시스템은 "Hyperliquid에서 TP/SL로 BTC 롱 포지션을 여는 요청을 보통 어떻게 처리하는가?"에 답합니다.
두 시스템은 상호 보완적이며, Agent는 두 가지 모두를 사용합니다. 메모리 조회는 memory_search를 통해 스킬 레이어에서 이루어지고, 학습 조회는 첫 LLM 호출 전 프롬프트 어셈블리의 일부로 에이전트 루프에서 이루어집니다.
안전 속성
학습 항목은 제안입니다. 결코 강제 사항이 아닙니다. 구체적으로 다음과 같습니다.
- 학습 항목은 권한 등급 훅을 우회할 수 없습니다. 4등급 도구가 포함된 제안
tool_sequence는 해당 턴 소스가 허용하지 않으면 여전히 차단됩니다. - 학습 항목은 L3 위험 게이트를 우회할 수 없습니다. 제안된 시퀀스가
requires_user_confirmation스킬 활성화를 요구하는 경우 일반적인 확인 절차가 적용됩니다. - 학습 항목은 비밀을 저장할 수 없습니다. 도구 시퀀스에 기록된
args는 감사 로그와 동일한 리댁터를 통과합니다. - 실패한 턴은 학습 항목이 되지 않습니다. 리뷰 엔진이 스킬 매니저에 전달되기 전에 필터링합니다.
검사 및 관리
# 성공률 기준 상위 학습 항목
sqlite3 $dataDir/minara.db \
"SELECT name, success_count, failure_count
FROM learnings
ORDER BY success_count - failure_count DESC LIMIT 20;"
# 최근 사용된 항목
sqlite3 $dataDir/minara.db \
"SELECT name, last_used_at FROM learnings
WHERE last_used_at IS NOT NULL
ORDER BY last_used_at DESC LIMIT 10;"
# 잘못된 학습 항목 삭제
sqlite3 $dataDir/minara.db "DELETE FROM learnings WHERE id = '...'""강등" 작업은 없습니다. 학습 항목이 잘못되었다면 삭제하십시오. 진정으로 유용했다면 Agent가 다시 도출할 것입니다.
구성
관련 환경 변수(환경 변수 참조):
MINARA_LEARNING_ENABLED은 마스터 스위치입니다(기본값true).MINARA_LEARNING_MIN_CALLS은 리뷰를 고려하기 전 턴당 최소 도구 호출 횟수입니다(기본값3).MINARA_LEARNING_SCORE_THRESHOLD는 학습 항목을 기록하는 데 필요한 리뷰 점수입니다(0–10, 기본값7).MINARA_LEARNING_TOP_K는 턴당 표시할 학습 항목 수입니다(기본값3).
MINARA_LEARNING_ENABLED=false로 설정하면 루프가 완전히 비활성화됩니다. 쓰기도, 제안도, 리뷰 패스도 없습니다. Agent는 여전히 작동하지만 시간이 지나도 빨라지지 않습니다.
예산 추적
학습 시스템이 수행하는 모든 LLM 호출은 learning/budget-tracker.ts를 통과합니다. 이는 카테고리별, 윈도우별 하드 상한을 적용합니다. 2단계 판정 패스와 사후 프로브가 버그나 적대적 프롬프트로 인해 무한 반성을 유발할 경우 LLM 비용이 10배로 증가할 수 있다는 리뷰 경고 이후 추가되었습니다. 하드 예산은 회로 차단기 역할을 합니다.
각각 독립적인 일별 및 월별 상한을 가진 네 가지 카테고리:
| 카테고리 | 목적 |
|---|---|
learning | 리뷰 엔진, 방법론 추출, 역할 반성, 스킬 학습 |
agent | 메인 에이전트 루프 턴 자체 |
workflow | 워크플로 및 Autopilot 턴 |
experiment | 오프라인 실험, 백테스트, A/B 테스트, 프로덕션에서는 사용되지 않음 |
상태는 llm_usage SQLite 테이블에 유지됩니다.
CREATE TABLE llm_usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category TEXT NOT NULL,
task TEXT NOT NULL,
model TEXT NOT NULL,
input_tokens INTEGER NOT NULL,
output_tokens INTEGER NOT NULL,
cost_usd REAL NOT NULL,
date TEXT NOT NULL,
ts TEXT NOT NULL
);모든 LLM 호출 시 트래커는 다음을 수행합니다.
- 카테고리의 현재 일별 및 월별 합계에 대해 예상 비용을 계산합니다.
- 예상 합계가 하드 상한을 초과하면 호출 전에
BudgetExceededError를 던집니다. - 예상 합계가 소프트 임계값(하드 상한 이하)을 넘으면 경고 수준 구조화 로그를 생성하되 호출은 허용합니다.
- 호출 완료 후 실제 token 수와 비용을
llm_usage에 기록합니다.
상태가 SQLite에 저장되므로 예산은 재시작 후에도 유지됩니다. 재설정될 인메모리 카운터가 없습니다.
Agent를 실행하지 않고 지출을 확인하려면:
sqlite3 $dataDir/minara.db \
"SELECT category, SUM(cost_usd) FROM llm_usage
WHERE date = date('now') GROUP BY 1;"REPL의 /budget 명령은 동일한 뷰를 대화형으로 표시합니다.
방법론 저장소
learning/methodology-store.ts는 2단계의 핵심입니다. Agent는 어떤 분석 방법이 어떤 자산 클래스에서 수익성 있는 신호를 생성하는지를 학습하고, 향후 유사한 분석에 이를 검색합니다.
각 방법론은 다음과 함께 저장됩니다.
| 필드 | 의미 |
|---|---|
id | UUID |
asset_class | 알려진 자산 클래스 중 하나(major_crypto, layer_1, defi_blue_chip, meme_coin, stock, …) |
methodology | 방법에 대한 자유 형식 텍스트 설명 |
evidence | 지원 근거 텍스트 |
confidence | [0, 1] 범위의 Wilson 하한 신뢰도 점수 |
times_used | 성공적인 적용 횟수 |
times_correct | 결과 검증을 통과한 적용 횟수 |
quarantine | 이상 감지 없이 N번 성공적으로 사용될 때까지 1로 유지 |
dedup_key | O(1) 의미론적 중복 제거를 위한 구조화된 필드의 해시 |
structured_json | 정규화된 StructuredMethodology(아래 참조) |
격리 및 주입 방어
새 방법론은 confidence: 0.1로 격리 상태에서 시작됩니다. 충분한 성공적인 사용 횟수를 통과할 때까지 프롬프트에 주입되지 않습니다. scanMethodologyForInjection을 통해 모든 쓰기 시 방법론 텍스트에 대해 이상 감지가 실행되어, 저장소에 저장되기 전 프롬프트 주입 패턴을 감지합니다.
신뢰도 상향 조정
방법론이 적용되고 결과가 검증될 때마다:
- 성공:
times_correct와times_used를 증가시키고, 이항 분포의 Wilson 하한으로confidence를 재계산합니다(작은 표본에 불이익을 줍니다). - 실패:
times_used만 증가시키고 신뢰도를 재계산합니다. 자주 실패하는 방법론은 주입 임계값 이하로 신뢰도가 떨어집니다. - 졸업:
confidence >= INJECTION_THRESHOLD이고times_used >= MIN_USES가 되면quarantine = 0으로 전환됩니다. 이 방법론은 이제 프롬프트 주입 대상이 됩니다.
Wilson 하한은 단순 times_correct / times_used보다 우수합니다. 1회 중 1회의 운 좋은 성공이 30회 중 15회의 일관된 성공보다 높게 평가되는 것을 방지하기 때문입니다.
기관 모드: 반성 사다리
기관 모드(Institution Mode)는 방법론 저장소에 가장 많이 쓰는 작성자입니다. 각 실행은 여러 LLM 역할(애널리스트, 강세/약세 토론, 리스크 위원회, 포트폴리오 매니저)을 소집하고 그 결정을 기록합니다. 이 결정들은 지연된 반성 루프로 들어가 각 판단을 실제 결과와 대조해 점수를 매기고, 교훈을 위에서 설명한 저장소로 승격시킵니다.
결정 역할이 강제 구조화 도구 호출을 사용하는 이유
결정을 생성하는 각 역할은 Zod 스키마(AnalystReportSchema, TraderProposalSchema, PortfolioDecisionSchema 등)에 일치하는 도구 호출을 발행해야 합니다. 호출과 함께 있는 자유 형식 산문은 폐기됩니다. 이유는 두 가지이며 모두 반성 루프와 관련됩니다.
- 결정성. 반성 점수는 실행 간에 동일한 필드를 비교합니다. 자유 텍스트에 대한 구제 파싱은 모델 업그레이드에서 흔들리지만 고정 스키마는 그렇지 않습니다.
- 비교 가능성. 오늘 신뢰도 0.71의
Buy가 지난주 신뢰도 0.62의Buy와 직접 비교 가능한 것은 스키마가 일정할 때뿐입니다.
INSTITUTION_LEARNING_ENABLED=1이면 캡처 훅이 각 실행 후 institution_runs(실행 메타데이터)와 institution_role_outputs(각 역할의 구조화 출력)를 기록합니다. 반성 사다리는 각 윈도가 기한이 되면 institution_reflections를 나중에 기록합니다.
사다리
learning/institution/reflect.ts의 러너는 각 실행을 고정 일정으로 다시 방문합니다.
| 윈도 | 트리거 | 질문 |
|---|---|---|
| 1d | 실행 24시간 후 | 트리거가 타당했는가? |
| 7d | 실행 7일 후 | 기본 시나리오가 실현되었는가? |
| 30d | 실행 30일 후 | 기간 추정이 옳았는가? |
| 90d / 180d / 365d | 더 길게 | 논지가 지속되었는가? |
lazy | 다음에 해당 ticker를 조회할 때 | 해당 실행의 Phase 0 회고로 재사용 |
각 표준 윈도는 실행을 실현된 가격 움직임(price-source.ts)과 대조해 점수를 매기고, 실행의 역할 출력에서 인용된 각 방법론에 대해 그 결과를 methodologyStore.recordOutcome()에 전달합니다. 방법론은 자신의 Wilson 신뢰 경계(>= 0.55에서 표면화)에서 승격되며, 이는 위의 신뢰도 상향 조정 경로가 적용하는 것과 동일한 게이트이므로, 소수의 실행으로 불안정한 규칙이 승격될 수 없습니다. lazy 및 수동 반성은 스냅샷이며 이 루프에 관여하지 않습니다.
구조화된 방법론 중복 제거
자유 형식 텍스트는 중복 제거가 어렵습니다. "RSI 하락 시 BTC 매수"와 "RSI 과매도 시 롱 진입"은 동일한 개념이지만 공통 token이 거의 없습니다. 더 나쁜 경우, Jaccard 유사도는 "지지선에서 BTC 매수"와 "지지선에서 BTC 매도"를 병합할 수 있습니다(동일한 token, 반대되는 행동).
learning/structured-methodology.ts는 판정 LLM이 유한한 어휘를 가진 정규화된 필드를 출력하도록 강제하여 이 문제를 해결합니다.
| 필드 | 허용 값 |
|---|---|
direction | bullish / bearish / neutral |
primary_signal | momentum / mean_reversion / technical / fundamental / on_chain / sentiment / macro / event |
timeframe | intraday / short / medium / long |
indicators | 알려진 지표의 배열(rsi, macd, funding_rate, …) |
중복 제거는 구조화된 필드의 해시(direction + primary_signal + timeframe + sorted indicators + asset_class)를 사용합니다. 동일한 해시를 가진 두 방법론은 중복으로 간주되며, 저장소는 새 행을 삽입하는 대신 기존 행의 카운터를 증가시킵니다.
자유 형식 설명은 사람이 읽을 수 있게 하고 프롬프트 주입을 위해 여전히 저장됩니다. 구조화된 필드는 순수하게 중복 제거 키로만 사용됩니다.
유사도: Jaccard(레거시) vs TF-IDF
구조화된 중복 제거 이전에는 텍스트 유사도가 폴백이었습니다. 두 가지 구현이 존재합니다.
- Jaccard 4-gram (
learning/similarity.ts)은 v1 레거시입니다. 계산이 저렴하고 언어에 독립적이지만, 의역 시 불안정하고 의미론적 반전("BTC 매수 / BTC 매도" 함정)에서 오류가 발생합니다. - TF-IDF 코사인 (
learning/tfidf.ts)은 권장 대체제입니다. 단어 수준이고 불용어를 인식하며, 여전히 언어에 독립적이고 의역 처리가 더 우수합니다.findMostSimilarTfidf가 방법론 저장소의 기본 경로입니다.
저장소는 TF-IDF가 실패할 경우(드문 경우: 빈 코퍼스, 비정상적인 토큰화)에만 Jaccard로 폴백합니다. 두 방법 모두 구조화된 중복 제거 해시가 실패할 때만 사용되므로, v1에 비해 호출 횟수가 훨씬 적습니다.
새로운 학습 아티팩트를 작성하는 경우 findMostSimilarTfidf를 직접 사용하십시오. 세 번째 유사도 함수를 새로 만들지 마십시오.
감사 서브시스템
학습 루프는 행 단위 포렌식 데이터(methodology_lifecycle_events, methodology_cases, methodology_cron_runs)를 많이 기록하지만, 이 테이블들은 한 번에 하나의 질문만 답할 수 있습니다. 감사 서브시스템(learning/methodology-audit.ts)은 집계 뷰로, 포렌식 행을 읽고 6개 차원에서 0-100 복합 건강도 점수를 계산하며, 구조화된 findings와 운영자용 advisory action을 포함한 한 행을 매 패스마다 methodology_audit_reports에 영속화합니다.
서브시스템은 학습 상태를 절대 변경하지 않습니다. 쓰기 동작은 감사 보고서 행과, 학습 cron이 직접 기록하는 하트비트 행뿐입니다(아래 격리 불변 조건 참조).
6개 채점 차원
각 차원은 learning/methodology-audit-scoring.ts 내의 순수 함수입니다. 함수는 { score: number | null, findings, advisory_actions }를 반환합니다. null 점수는 "정직하게 채점하기에 샘플이 부족하다"는 뜻이며 복합 점수에서 빠지고 가중치는 다른 차원으로 재분배됩니다.
| 차원 | 읽기 대상 | 측정 내용 |
|---|---|---|
synthesis_quality | reflection_adjusted.reason_text 파싱 | flag 측과 recovery 측 판정 사이의 급격한 진동에 패널티. 한 방향으로의 안정적인 flag 또는 recovery 추이는 만점. 저샘플 윈도우에서도 market_stress_freeze와 synthesis_auto_demote를 표면화. |
graduation_fp_rate | graduated 이후 30일 내 demoted/requantized_by_judge | FP 비율의 Wilson 하한. 졸업 후 관측 윈도우를 완주하지 못했고 아직 반전하지 않은 졸업은 카운트하지 않습니다. 일괄 신규 졸업이 점수를 거짓으로 끌어올리지 못하게 막습니다. |
attribution_integrity | 윈도우 내 methodology_cases.outcome_state | (0.7 × resolve_rate + 0.3 × (1 − backlog_share)) × 100. closed가 0이고 14일 초과 pending 백로그가 0일 때 null을 반환합니다(건강한 신규 설치, 아직 채점 대상 없음). attribution_model drift 검사는 하지 않습니다. 기록된 값은 의도적인 스냅샷이기 때문입니다. |
coverage_health | graduated이고 times_used ≥ 10인 methodologies | CLAUDE.md §13 자산 클래스 표준에 따라 5개 최상위 그룹(crypto / stock / index / commodity / forex) 커버리지 평가. 5개 그룹 모두에 활성 방법론이 3개 이상 있으면 만점, 3그룹 하한을 밑돌면 선형으로 감점. |
quarantine_churn | methodology_lifecycle_events의 상태 변경 kind | reflection_adjusted를 제외합니다(6시간 synthesis 주기에서 하루 4회까지 정당하게 발생). 윈도우 내 한 방법론에 상태 변경이 3회 이상이면 high churn으로 판정. |
cron_health | methodology_cron_runs 하트비트 + pending 백로그 | 예상 주기의 2배에 대한 지연 + 백로그 패널티. 지연 7일 초과 시 점수 0(loop가 죽은 것으로 간주). 하트비트 테이블이 비어 있고 pending 백로그가 0이 아닐 때도 0(loop가 작업을 처리하지 않고 있음이 분명함). |
복합 점수와 밴드
기본 가중치 및 밴드:
composite = 0.22·synthesis_quality + 0.22·graduation_fp_rate + 0.22·attribution_integrity
+ 0.14·coverage_health + 0.08·quarantine_churn + 0.12·cron_health
밴드: ≥ 80 healthy · 60-79 watch · 40-59 degraded · < 40 alarm · disabled(off switch)null 차원은 드롭되고 남은 가중치는 합이 1이 되도록 재정규화됩니다. 영속화된 보고서는 dimension_weights_used를 기록하므로 JSON을 읽는 운영자가 정확히 어떤 차원이 기여했는지 확인할 수 있습니다.
격리 불변 조건
감사는 4개의 학습 테이블(methodologies, methodology_lifecycle_events, methodology_cases, methodology_case_hints)을 읽으며, 어느 것에도 쓰지 않습니다. 3개 계층의 보장이 누적됩니다:
- 협력적 유휴 스케줄링. 감사 cron(
learning/methodology-audit-cron.ts)은AgentLoop.run()과BusyTracker(core/busy-tracker.ts)를 공유합니다. 매 tick은inFlight > 0(스킵)과 idle 시간(부족 시 연기)을 확인하고, 오케스트레이터는 각 SQL 단계 사이에서yieldIfBusy로 양보하며, 사용자 턴이 패스 중 도착하면 일시 중지합니다. 연속 N회 연기 후에는 starvation 가드가 강제 실행해 항상 바쁜 에이전트가 감사 커버리지를 잃지 않게 합니다. - 순수 함수 채점 경계.
methodology-audit-scoring.ts의 차원 채점기는Methodology/MethodologyLifecycleEvent/MethodologyCase형식의 순수 배열만 받습니다.MemoryStore핸들을 전혀 보지 않으므로 실수로라도.prepare(...).run(...)을 호출할 수 없습니다. - 종단 간 테이블 해시 불변 조건.
tests/e2e/methodology-audit.test.ts는 매 감사 패스 전후로 각 학습 테이블을 SHA-256으로 해시하고 바이트 단위 동일성을 단언합니다. 검사는 행 수 비교를 넘어섭니다.updated_at을 건드리는UPDATE는 행 수 검사는 통과하지만 해시 검사는 통과하지 못합니다.
유일한 역방향 접촉점은 학습 cron tick 끝에 기록되는 methodology_cron_runs 하트비트 행입니다. in-process 스케줄러(learning/methodology-cron.ts)와 CLI cron 경로(gateway/learning-cli.ts의 runFullCronCli) 모두 이 행을 쓰므로, 문서화된 system-cron 배포에서 감사의 cron_health 차원이 정상 동작합니다.
감사 운영
cron은 opt-in입니다. 기본값은 일일 수동 모니터링에 맞춰져 있습니다. 학습 루프가 채점 가능한 데이터를 충분히 축적한 후(보통 1-2주 후) METHODOLOGY_AUDIT_CRON_ENABLED=1을 켜십시오. 전체 env 참조는 환경 변수 → 방법론 감사 서브시스템을 보십시오.
4개의 CLI 명령이 운영자 워크플로우를 다룹니다:
minara learning audit run [--window-days N] # 1회 인라인 패스
minara learning audit show [--latest|--pass <id>] # 보고서 확인
minara learning audit trend [--days N] # 복합 점수 이력 + sparkline
minara learning audit findings [--severity high|medium|low] # findings 드릴다운전체 CLI 인터페이스는 CLI 서브커맨드 → audit를 참조하십시오.
보류 항목: 능동 프로브
초기 설계는 무작위로 과거의 "확실한 오답" trading case에 대해 에이전트를 다시 실행하여 학습 루프가 이제 다른 결정을 내리는지 테스트하는 7번째 차원을 제안했습니다. 이 작업은 보류되었습니다. 정직한 재생을 위해서는 과거 결정 컨텍스트(가격, 뉴스, sentiment, 당시 활성 방법론, 도구 출력)의 동결 스냅샷이 필요합니다. 그렇지 않으면 새 실행은 원래 결정이 본 것과 동일한 정보를 보지 못합니다. 스냅샷 없이 에이전트에게 "지금 ETH를 사야 하는가"를 물으면 현재의 판단을 측정하게 되며, 학습이 과거의 오답을 교정했는지를 측정하지 못합니다. 두 가지 전제 조건이 작업을 막고 있습니다: (a) hint / case 시점에 case-recorder가 기록하는 스냅샷 테이블, (b) createApp()을 거치지 않는 독립적인 ProbeAgentLoop. 이렇게 하면 재생이 라이브 에이전트와 0의 상태(skill session, tool registry, hooks) 공유를 갖습니다.