멀티에이전트 팀을 벤치마크로 평가하고, 모든 실행 과정을 PostgreSQL trace DB에 기록해 팀 구성 변경의 효과를 데이터로 검증하는 시스템 — 동작·설정·워크플로우·DB 메트릭 수집·Grafana 연동을 한 페이지로.
SelectorGroupChat — 역할 다른 AI들의 협업benchmark — 정답 있는 문제집events — 실행 중 일어난 모든 일의 기록runs.run_id — 문제 1개를 1번 푼 시도mv_batch_summary.pass_at_1 — 한 번에 맞힌 비율p95_latency — 느린 쪽 5% 응답시간(꼬리 지연)research_grounding — 인용 정확도(precision·recall 조화평균)v_analysis_grounded — 답이 실제 근거에 뿌리내렸는지failure_stage·root_cause — 실패 원인 2축 분류mv_* — 미리 계산해 둔 집계 표runs(실행 1회의 결과/조건) + events(그 안의 모든 메시지).team_id를 강제합니다 (재현성 가드 — 해시 불일치 시 즉시 중단).cli.py run) → 태스크 선택 → 팀 실행 → 전부 기록 → 채점 → 집계 뷰 → Grafana. 이 한 줄이 페이지 전체의 뼈대입니다.한 줄 요약(식별자 버전): CLI가 러너를 부르고 → 러너가 팀을 돌리고 → 로거가 모든 메시지를 events에, 채점기가 결과를 runs에 적고 → 집계 뷰를 거쳐 Grafana 패널이 읽는다.
flowchart TB
classDef cli fill:#eaf0fd,stroke:#2f5bd0,color:#16202c;
classDef orch fill:#efeaff,stroke:#6b4fc4,color:#16202c;
classDef cap fill:#fdf4e3,stroke:#b07400,color:#16202c;
classDef db fill:#e9f6ee,stroke:#1f8a4c,color:#16202c;
classDef viz fill:#eaf0fd,stroke:#2f5bd0,color:#16202c;
CLI["🧑🔬 cli.py · run / report / compare"]:::cli
subgraph ORCH["② 오케스트레이션 · runner.py"]
RB["runner.run_batch<br/>async · Semaphore · asyncpg pool"]:::orch
REG["teams.registry<br/>build + 재현성 가드"]:::orch
TEAM["SelectorGroupChat · run_stream<br/>Planner → Executor → Critic · Selector"]:::orch
end
subgraph CAP["③ 기록 · 채점"]
LOG["TraceLogger<br/>event→message_type · 마스킹"]:::cap
SC["scorer<br/>success · format_valid"]:::cap
end
subgraph DBP["④ PostgreSQL · schema eval_ph1"]
T1[(tasks)]:::db
T2[(teams)]:::db
RUNS[(runs ★)]:::db
EV[(events ★)]:::db
MV["mv_batch_summary · mv_passk · mv_tool_summary"]:::db
VW["v_research / v_analysis / v_cppx grounding"]:::db
end
GRAF["📊 Grafana ①–⑥ · MAST"]:::viz
CLI -->|"run_batch(TaskFilter)"| RB
RB --> REG --> TEAM
RB -.->|select| T1
REG -.->|upsert| T2
TEAM -->|AutoGen events| LOG
TEAM -->|final_answer| SC
LOG -->|INSERT seq| EV
SC -->|UPDATE success| RUNS
RB -.->|refresh_views| MV
RUNS --> MV
EV --> MV
MV -->|postgres SQL| GRAF
VW -->|live view| GRAF
runs = 실행 1회의 결과/조건(성공·토큰·지연·temperature/seed), events = 그 run 안에서 일어난 모든 메시지(seq 순서). 메트릭은 거의 전부 이 둘에서 파생된다.run_batch()runner.py run_batch() 가 (task × attempts)개의 run을 세마포어로 동시 실행한다. 각 run의 단계:
db.create_pool(min=1, max=max(concurrency+1,2))teams 행 upsert(ensure_team_record). 재현성 가드 작동(§4).--exclude-web) · (task_id=ANY) · LIMIT · ORDER BY task_idEVAL_LLM_MODEL, temperature=EVAL_DEFAULT_TEMPERATURE(기본 0.2), seed=EVAL_DEFAULT_SEED, max_messages. 이미 completed면 skip / crashed면 --retry-crashed 여부로 분기.TraceLogger(conn).log_stream(run_id, team.run_stream(task=msg)). 매 이벤트를 events에 적재(§5). 반환: final_answer(한 줄)·final_answer_full·stop_reason·turns·tokens(in/out)·latency_ms.db.refresh_views() → mv_batch_summary · mv_passk · mv_tool_summary REFRESH (안 하면 report/Grafana가 stale).
sequenceDiagram
autonumber
actor OP as 평가자
participant R as runner
participant DR as runs(DB)
participant TM as Team P–E–C
participant LG as TraceLogger
participant DE as events(DB)
OP->>R: cli.py run --batch --team --attempts
R->>DR: INSERT status=running (temp·seed·model 박제)
R->>TM: build + run_stream(task)
loop 매 이벤트
TM->>LG: AutoGen 이벤트
LG->>DE: INSERT (seq · 마스킹 · 절단+해시)
end
TM-->>R: trace_result(final_answer, tokens, latency)
R->>R: score_fn(answer, gold)
R->>DR: UPDATE completed (success, format_valid)
Note over R,DR: 예외→crashed · 배치끝→refresh_views()
R-->>OP: BatchSummary
stateDiagram-v2
[*] --> running: INSERT
running --> completed: 채점·UPDATE
running --> crashed: 예외
running --> timeout: max_messages
crashed --> running: --retry-crashed
completed --> [*]
timeout --> [*]
asyncio.Semaphore(concurrency) + asyncpg 풀(max=concurrency+1). 크래시는 run 단위로 흡수돼 배치 요약에 집계될 뿐 전체를 멈추지 않는다(--retry-crashed로 재실행, --task-ids로 1개씩 독립 실행 가능).python cli.py <cmd>Typer 앱. 기본 팀 v1-baseline. 평가/적재/리포트/실험 분석 + 개인화(fleet/propose/learn) 명령.
| 명령 | 역할 | 주요 플래그 (기본값) |
|---|---|---|
init-db | migrations 001+ 멱등 적용(000_provision은 DBA 수동) | — |
load-gaia | GAIA metadata.jsonl → tasks 적재 | — |
load-research | 리서치 벤치 tasks.jsonl 적재 | --dir, --benchmark research|research_hard |
load-cppx | 전문가 코딩 문제셋 적재(benchmark='cppx') | --dir, --level-dir L5_full |
run | 평가 배치 실행(태스크 필터 → run → 채점) | 아래 표 참조 |
report | 배치 요약(level별 pass@1·fmt_err·loop·turns·p95) | --batch(필수) |
compare | 배치 ≥2개 A/B 비교(level별 pass@1·p95) | --batches a,b(필수) |
failures | 실패/크래시 run 트랜스크립트 요약 | --batch, --limit 10 |
grounding-score | 리서치 인용 F1 채점 → research_grounding | --batch(필수) |
cppx-grounding | 코딩 보고서 사실 인용 채점 → cppx_grounding | --batch(필수) |
export-team | 팀을 AutoGen Studio JSON 컴포넌트로 직렬화 | --team, --out, --baseline-tool |
fleet-run | 야간 플릿 사이클(상시의도→실패triage→모닝브리프) | --date, --domains, --dry-run/--commit |
propose | 이상/반복 신호 → 개선 제안(personal_proposals) | --domains, --dry-run/--commit, --git-lookback 30 |
load-learn / learn-next | 학습 동반자 태스크 적재 / 다음 커리큘럼 선택 | — |
| 플래그 | 타입 | 기본 | 의미 |
|---|---|---|---|
--batch | str | 필수 | 배치 ID(실험 단위 식별자) |
--team | str | v1-baseline | 인스턴스화할 팀 ID(registry 키) |
--benchmark | str | gaia | 태스크 벤치(gaia|research|cppx…) |
--level | int? | None | GAIA level / research hops 필터 |
--exclude-web | bool | False | requires_web=false 태스크만 |
--task-ids | str? | None | 콤마구분 특정 task만(크래시 격리에 유용) |
--limit | int? | None | 선택 태스크 수 상한 |
--attempts | int | 1 | 태스크당 반복(pass@k 측정용) |
--concurrency | int? | EVAL_CONCURRENCY | 동시 실행 워커 수 |
--retry-crashed | bool | False | crashed run 삭제 후 재실행 |
config.py (env, 하드코딩 금지)pydantic-settings BaseSettings. 모든 키 EVAL_* 접두사, .env에서 로드. 비밀정보는 로그/예외/커밋에 노출 금지.
| env | 필드 | 기본 | 의미 |
|---|---|---|---|
EVAL_PG_DSN | pg_dsn | 필수 | PostgreSQL 접속 DSN |
EVAL_LLM_BASE_URL | llm_base_url | None | 내부 vLLM(OpenAI 호환) 엔드포인트 |
EVAL_LLM_MODEL | llm_model | None | 모델명(예: glm-4.7) → runs.model_name |
EVAL_LLM_API_KEY | llm_api_key | None | LLM API 키 |
EVAL_DEFAULT_TEMPERATURE | default_temperature | 0.2 | 샘플링 temperature → runs.temperature |
EVAL_DEFAULT_SEED | default_seed | None | seed → runs.seed (비교 가능성용) |
EVAL_MAX_MESSAGES | max_messages | 20 | run당 최대 메시지(루프 종료 한계) |
EVAL_CONCURRENCY | concurrency | 1 | 기본 동시 워커 수 |
EVAL_GAIA_DIR | gaia_dir | data/gaia/validation | GAIA 태스크 디렉토리 |
EVAL_RESEARCH_DIR / EVAL_CPP_DIR | research_dir / cpp_dir | 경로 | 리서치 / 코딩 문제 디렉토리 |
EVAL_FIRECRAWL_BASE_URL | firecrawl_base_url | api.firecrawl.dev | 웹검색 백엔드 |
EVAL_FIRECRAWL_API_KEY | firecrawl_api_key | None | 있으면 Firecrawl, 없으면 DuckDuckGo 폴백 |
EVAL_CLOSED_NET | closed_net | True | 폐쇄망 안전 토글 |
팀은 SelectorGroupChat(셀렉터가 다음 발화자를 라우팅). 베이스라인은 P–E–C 3-에이전트.
| 에이전트 | 역할 | 도구 |
|---|---|---|
| planner 🤖 | 계획 수립 + FINAL ANSWER 초안 | 없음 |
| executor 🛠 | 도구 실행(파일/산술) | read_attached_file, python_calc(AST allowlist, eval 금지) |
| critic 🧐 | 형식·정답 검증 → APPROVE 또는 수정요구 | 없음 |
셀렉터는 JSON 출력 {"next","reason_code","summary"} — reason_code ∈ {NEEDS_PLANNING, NEEDS_EXECUTION, NEEDS_VERIFICATION, NEEDS_REVISION, READY_TO_FINAL}. 종료조건: TextMentionTermination("APPROVE", sources=["critic"]) | MaxMessageTermination(max_messages).
등록 팀 ~44개, 네이밍 패턴: v1~v6-baselineanalyst-solo/deep/webhq-research/content/coding/investresearch-pipeline/grounded/xverifysql-solo/executed/groundedcppx-solo/panelmetric-format/loop/groundingextract-solo/validated
flowchart LR
classDef sel fill:#efeaff,stroke:#6b4fc4;
classDef p fill:#eaf0fd,stroke:#2f5bd0;
classDef e fill:#e9f6ee,stroke:#1f8a4c;
classDef c fill:#fdf4e3,stroke:#b07400;
classDef fin fill:#e9f6ee,stroke:#1f8a4c;
SEL{{"🚦 Selector<br/>next + reason_code (JSON)"}}:::sel
P["🤖 Planner<br/>계획 · FINAL ANSWER 초안"]:::p
E["🛠 Executor<br/>read_attached_file · python_calc"]:::e
C["🧐 Critic<br/>형식 · 정답 검증"]:::c
F["🏁 종료<br/>APPROVE | max_messages"]:::fin
SEL -->|NEEDS_PLANNING| P
P -.->|발화| SEL
SEL -->|NEEDS_EXECUTION| E
E -.->|결과| SEL
SEL -->|NEEDS_VERIFICATION| C
C -.->|NEEDS_REVISION| SEL
C -->|APPROVE| F
allow_repeated_speaker=false · max_selector_attempts=3 · 종료는 critic의 APPROVE 또는 max_messages# 팀 빌드 시 프롬프트 번들 해시 계산 (v1_baseline.py) joined = "\n---\n".join([PLANNER_PROMPT, EXECUTOR_PROMPT, CRITIC_PROMPT, SELECTOR_PROMPT]) prompt_bundle_hash = sha256(joined.encode()).hexdigest() # registry.ensure_team_record(): 같은 team_id인데 해시가 다르면 즉시 중단 if existing_hash is not None and existing_hash != new_hash: raise TeamConfigMismatchError("구성이 바뀌었으면 새 team_id를 쓰세요")
flowchart LR
classDef ok fill:#e9f6ee,stroke:#1f8a4c;
classDef bad fill:#fbecea,stroke:#c0392b;
B["팀 빌드"] --> H["prompt_bundle_hash<br/>sha256(planner+executor+critic+selector)"]
H --> Q{"기존 team_id 행과<br/>해시 불일치?"}
Q -->|YES| X["raise TeamConfigMismatchError<br/>즉시 중단"]:::bad
Q -->|NO| K["ensure_team_record<br/>runs 진행"]:::ok
team_id. 기존 team_id + 다른 prompt_bundle_hash 조합은 즉시 에러로 중단 — "좋아졌다"는 비교가 오염되는 걸 DB 레벨에서 막는다.config_capture.py는 빌드 시점의 전체 구성을 teams.config_full(JSONB)에 스냅샷한다 — 에이전트별 system_prompt+sha, 도구별 impl_sha, selector_prompt, termination, allow_repeated_speaker, max_selector_attempts. git 없이도 Grafana ⑥ 대시보드에서 팀 구성을 추적할 수 있다.
tracing/logger.pyAutoGen 이벤트 스트림을 받아 message_type으로 매핑하고 events 테이블에 seq 순서로 적재.
flowchart LR
classDef ev fill:#eef2f8,stroke:#9aa7b6;
classDef map fill:#efeaff,stroke:#6b4fc4;
classDef db fill:#e9f6ee,stroke:#1f8a4c;
subgraph S["AutoGen 이벤트 스트림"]
A1["TextMessage / ToolCallSummary"]:::ev
A2["ToolCallRequestEvent"]:::ev
A3["ToolCallExecutionEvent"]:::ev
A4["SelectorEvent"]:::ev
A5["TaskResult"]:::ev
end
M["mapping → message_type<br/>seq+1 · 비밀 *** 마스킹<br/>content/result 절단+해시<br/>INSERT 실패→경고 후 계속"]:::map
subgraph EVS["events 행 (run_id, seq 순)"]
R1["agent_message"]:::db
R2["tool_call (id·name)"]:::db
R3["tool_result / tool_error"]:::db
R4["selector_decision"]:::db
R5["final_answer"]:::db
end
A1 --> M
A2 --> M
A3 --> M
A4 --> M
A5 --> M
M --> R1
M --> R2
M --> R3
M --> R4
M --> R5
R2 -.->|"응답 짝 필수 (CHECK)"| R3
| AutoGen 이벤트 | message_type | 비고 |
|---|---|---|
| TextMessage / ToolCallSummaryMessage | agent_message | 일반 에이전트 발화 |
| ToolCallRequestEvent | tool_call | FunctionCall당 1행 |
| ToolCallExecutionEvent | tool_result / tool_error | 결과 항목별 분기 |
| SelectorEvent / SelectSpeakerEvent | selector_decision | 라우팅 결정 |
| HandoffMessage | handoff | 에이전트 핸드오프 |
| TaskResult (종료) | final_answer | run 종료 |
| EvaluatorScoreEvent | evaluator_score | 교차검증 판정(FabricMAS) |
| 그 외(streaming chunk, thought…) | None → skip | 조용히 무시 |
_safe_insert()가 경고 로그 + missed_inserts 카운트만 올리고 평가는 계속. 배치를 멈추는 건 DB 연결 자체의 소실뿐.tool_args 저장 전 키가 (password|token|secret|api_key|authorization)(대소문자 무시)에 매치되면 값을 "***"로 치환. 구현은 logger.py 한 곳.events 주요 컬럼: run_id, seq, agent_name, message_type, content(+truncated), tool_call_id, tool_name, tool_args(JSONB·마스킹), tool_result(JSONB·해시), tool_error(JSONB), selected_next_agent, selector_reason(JSONB), tokens/input/output, latency_ms, ts, eval_meta(JSONB·009)
FINAL ANSWER: 패턴 추출(마지막 매치 — 자기수정 허용) → format_validabs(a-b) < 1e-6 허용오차, 문자열은 정규화 후 정확일치success = format_valid AND 정규화(pred)==정규화(gold)
flowchart LR
classDef io fill:#eef2f8,stroke:#9aa7b6;
classDef sc fill:#fdf4e3,stroke:#b07400;
classDef out fill:#e9f6ee,stroke:#1f8a4c;
IN["final_answer<br/>(open-ended: _full)"]:::io
RT{"benchmark?"}
IN --> RT
RT -->|gaia| G["gaia.score<br/>정규화 · 리스트 순서보존 · 1e-6"]:::sc
RT -->|sql| SQ["sql.score<br/>실행결과 멀티셋"]:::sc
RT -->|research| RE["research.grounding<br/>인용 F1"]:::sc
RT -->|analysis| AN["analysis.score<br/>형식만 (정답 비교 없음)"]:::sc
RT -->|extract| EX["extract.score<br/>field_accuracy"]:::sc
RT -->|cppx · roles| CP["fact-ratio · coverage · CER"]:::sc
G --> O1["runs.success / format_valid"]:::out
SQ --> O1
AN --> O1
EX --> O1
RE --> O2["도메인 테이블<br/>research_ / cppx_grounding"]:::out
CP --> O2
runs에, 인용·사실 grounding은 도메인 테이블에 적힌다.| 도메인 | 측정 | 판정 규칙 | 저장 |
|---|---|---|---|
| gaia | 정답 정확일치 | 정규화 후 일치 | runs.success/format_valid |
| extract | 필드 추출 정확도 | 모든 gold 필드 일치 / field_accuracy=일치/전체 | runs + 산출 |
| sql | 실행 결과 일치 | pred·gold SQL 실행 후 멀티셋 비교(순서무관, 부동소수 4자리) | runs |
| analysis | 보고서 형식 유효성 | FINAL ANSWER 추출 성공(정답 비교 없음) | runs + grounding 뷰 |
| research | 인용 정확도 | precision/recall/F1(cited∩gold) | research_grounding |
| roles(meeting) | 액션아이템 커버리지 | 키워드 60%↑ 매치, coverage≥0.5 통과 | runs |
| roles(ocr) | 문자오류율 CER | Levenshtein/gold_len ≤0.15 통과 | runs |
| cppx | 사실 인용 비율 | gold 사실 등장 비율 + objective 방향 일치 | cppx_grounding |
v_analysis_grounded: n_search_ok > 0) — "호출 횟수" 기반의 옛 정의는 검색 100% 실패인데 grounded 100%로 보이던 환각을 잡지 못해, 성공한 검색 기준으로 교정됨.report는 mv_batch_summary(pass@1·format_invalid_rate·loop_rate·tokens_per_success·p95)·mv_passk(pass_any/all·k)·mv_tool_summary를 읽어 표로 출력. experiments 테이블은 단일변수 개선을 기록: title·hypothesis·intervention·team_before/after·batch_before/after·verdict(promoted/rejected/inconclusive)·key_evidence(JSONB)·lesson — Grafana 시계열에 실험 마커(annotation)로 겹쳐 보인다.
스키마가 SSOT. 변경은 번호 증가 SQL 파일로만(기존 수정 금지). DB invariant는 애플리케이션 검증이 아니라 CHECK 제약으로 강제.
erDiagram
tasks ||--o{ runs : "task_id"
teams ||--o{ runs : "team_id"
runs ||--o{ events : "run_id · CASCADE"
runs ||--o| research_grounding : "run_id"
runs ||--o| cppx_grounding : "run_id"
teams ||--o{ experiments : "before/after"
tasks {
text task_id PK
text benchmark
text gold_answer
bool requires_web
}
runs {
uuid run_id PK
text batch_id
real temperature
bool success
text status
}
events {
uuid run_id FK
int seq PK
text message_type
jsonb tool_args
}
| 테이블 | PK | 핵심 컬럼 |
|---|---|---|
| tasks | task_id | benchmark, level, question, gold_answer, file_name, requires_web, annotator_meta(JSONB) |
| teams | team_id | agents(JSONB), topology, prompt_bundle_hash, config_full(JSONB·004) |
| runs | run_id(UUID) | team_id, task_id, attempt, batch_id, model_name, temperature, seed, status, terminated_by, success, format_valid, total/input/output_tokens, latency_ms, judge_meta, failure_stage, root_cause |
| events | (run_id, seq) | message_type, content, tool_*, selector_reason, tokens, latency_ms, ts, eval_meta(009) |
| # | 추가 객체 | 용도 |
|---|---|---|
| 003 | experiments + v_experiment_annotations | 단일변수 실험 원장 / Grafana 마커 |
| 004 | teams.config_full + v_team_config/v_team_orchestration | git 없이 팀 구성 관측 |
| 005 | v_team_graph_nodes/edges | Grafana Node Graph(셀렉터 허브) |
| 006 | research_grounding + 요약뷰 | 인용 F1/precision/recall |
| 007 | research_corpus | 코퍼스 문서(real vs decoy) |
| 008 | cppx_grounding + 요약뷰 | 코딩 보고서 사실 인용 |
| 009 | events.eval_meta | 교차검증 판정 메타 |
| 010 | v_analysis_grounded + 요약뷰 | 분석 grounding(성공검색 기준 재정의) |
| 011 | failure_stages·root_causes seed | MAST 통제어휘(2축 실패분류) |
| 012 | personal_proposals | 개선 제안(promoted엔 exp_id 필수) |
| 013 | runs.escalated·learner_skill·topology 확장 | 학습 슬라이스(SM-2 간격반복) |
| 014 | standing_intentions·fleet_briefs | 야간 플릿 상시의도/모닝브리프 |
claims·evidence 테이블, failure_stage/root_cause 자동 라벨링, LLM-judge는 스키마만 존재, 코드 구현 금지(Tier 1~2 범위).002_views.sql (배치 종료 시 REFRESH)원천 runs/events를 배치별로 미리 계산. report와 Grafana 대부분이 이 3개를 읽는다.
CREATE MATERIALIZED VIEW mv_batch_summary AS SELECT batch_id, team_id, level, COUNT(*) AS n_runs, AVG(success::int) AS pass_at_1, -- 1회 성공률 AVG((NOT format_valid)::int) FILTER(...) AS format_invalid_rate, AVG((terminated_by='max_messages')::int) AS loop_rate, -- 루프 소진 SUM(total_tokens)::float/NULLIF(SUM(success::int),0) AS tokens_per_success, PERCENTILE_CONT(0.95) WITHIN GROUP(ORDER BY latency_ms) AS p95_latency FROM runs r JOIN tasks t USING(task_id) WHERE status='completed' GROUP BY 1,2,3;
| 뷰 | 그룹 | 핵심 산출 |
|---|---|---|
mv_batch_summary | batch×team×level | pass@1, format_invalid_rate, loop_rate, avg_turns/tokens, tokens_per_success, p95_latency |
mv_passk | batch×team×task | k(시도수), pass_any(BOOL_OR), pass_all(BOOL_AND) |
mv_tool_summary | batch×tool | calls, errors, avg_latency |
run_batch() 끝에서 db.refresh_views()가 자동 호출되지만, 수동 적재 후엔 직접 갱신 필요. (도메인 뷰 v_research_grounding 등은 live view라 갱신 불필요)Grafana 컨테이너가 PostgreSQL에 직접 붙어(같은 docker 네트워크) SQL 패널로 뷰/테이블을 읽는다. 코드 배포 없이 데이터가 즉시 그래프가 된다.
flowchart LR
classDef src fill:#e9f6ee,stroke:#1f8a4c;
classDef dash fill:#eaf0fd,stroke:#2f5bd0;
MBS["mv_batch_summary"]:::src
MPK["mv_passk"]:::src
MTS["mv_tool_summary"]:::src
VAG["v_analysis_grounded"]:::src
VRG["v_research_grounding"]:::src
VTC["v_team_config / graph"]:::src
RUN["runs (failure_stage)"]:::src
EXP["experiments"]:::src
D1["① 총괄 개요"]:::dash
D2["② 실험 메트릭"]:::dash
D3["③ 분석 grounding"]:::dash
D4["④ 리서치 grounding"]:::dash
D6["⑥ 팀 구성"]:::dash
DM["MAST 실패분류"]:::dash
MBS --> D2
MPK --> D2
MTS --> D2
EXP --> D2
EXP --> D1
VAG --> D3
VRG --> D4
VTC --> D6
RUN --> DM
RUN --> D1
eval_ph1_pg→evaldb)에서 SQL로 읽는다.| 항목 | 값 |
|---|---|
| name / type | eval_ph1 / postgres (isDefault) |
| uid | eval_ph1_pg |
| url | eval_ph1_pg:5432 (컨테이너명 직접 접근) |
| database / user | evaldb / eval_ph1 |
| searchPath | eval_ph1 (모든 테이블이 사는 스키마) |
| network | eval-system-stack_evals-internal (PG와 공유 내부망) |
| postgresVersion / ssl | 1600 (PG 16) / disable |
json/*.json을 file provider로 등록, updateIntervalSeconds: 30 — JSON 변경은 30초마다 자동 반영(재시작 불필요). MAST 대시보드는 json-mast/ 별도 폴더("MAST 논문 따라가기" 메뉴). 단, provider yaml 자체를 처음 추가/수정하면 Grafana 1회 재시작 필요.
| 대시보드 | uid | 읽는 소스 |
|---|---|---|
| ① 총괄 개요 | eval_ph1_overview | experiments, runs(completed), events |
| ② 실험 메트릭 | (8407…) | mv_batch_summary, mv_tool_summary, mv_passk + 실험 annotation |
| ③ 분석 Grounding | eval_ph1_analysis_grounding | v_analysis_grounded(_summary) |
| ④ 리서치 Grounding | eval_ph1_research_grounding | v_research_grounding(_summary) |
| ⑤ 리서치 Corpus | eval_ph1_research_corpus | v_research_corpus(🔴decoy/🟢real) |
| ⑥ 팀 구성 | eval_ph1_team_config | v_team_config, v_team_orchestration, v_team_graph_* |
| HQ Teams | hq_teams | runs(HQ), mv_batch_summary |
| 발표용 메트릭 변화 | eval_pres_trends | runs, n_search vs n_search_ok |
| MAST 실패 분류 | eval_ph1_mast | runs(failure_stage, root_cause), events 프록시 |
runs+events → refresh_views() → mv_* → Grafana postgres datasource → SQL 패널. 도메인 grounding은 라이브 뷰(v_*)로 즉시 반영. 패널 정의 원본은 dashboards/grafana_panels.sql(10패널)·team_config_panels.sql(4패널)./home/hm/vps-srv/grafana-stack. 대시보드 추가 시 레포와 라이브 양쪽 동기화 필요.-- 완료 run에 success 누락 SELECT run_id FROM runs WHERE status='completed' AND success IS NULL; -- tool_call인데 응답(result/error) 짝이 없는 이벤트 SELECT e.run_id, e.seq FROM events e WHERE e.message_type='tool_call' AND NOT EXISTS ( SELECT 1 FROM events r WHERE r.run_id=e.run_id AND r.tool_call_id=e.tool_call_id AND r.message_type IN ('tool_result','tool_error'));
EVAL_LLM_BASE_URL)만.