[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -1,80 +1,231 @@
|
||||
---
|
||||
id: wiki-2026-0508-v-component-evaluation-interface
|
||||
title: V component (Evaluation Interface)
|
||||
title: V-component (Evaluation Interface)
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [Eval UI Component, V-component]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [uncategorized]
|
||||
source_trust_level: B
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [llm-eval, ui, component, dashboard, observability]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-08
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: React-19
|
||||
---
|
||||
|
||||
# [[V-component (Evaluation Interface)|V-component (Evaluation Interface)]]
|
||||
# V-component (Evaluation Interface)
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
V-component(Evaluation Interface)는 에이전트 하네스의 '눈'에 해당하는 구성 요소로, 에이전트의 출력물이나 도구 실행 결과를 객관적으로 평가하고 피드백을 생성하는 책임을 진다. 작업이 성공적으로 완료되었는지, 결과물이 제약 사항을 준수했는지, 혹은 오류가 발생했는지를 판단하여 실행 루프(E-component)에 다음 행동을 결정할 근거를 제공한다.
|
||||
## 매 한 줄
|
||||
> **"매 LLM eval result 의 매 inspect · compare · annotate 위한 매 reusable UI primitive."** Braintrust · Langfuse · Phoenix (Arize) 같은 매 eval platform 의 핵심 building block — 매 trace tree + 매 score panel + 매 diff view 의 통합. 매 custom dashboard 의 build 시 매 in-house V-component 의 생성 이 매 일반 패턴.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
* **결과 검증 (Output Verification)**: 모델이 생성한 코드, 문서, 데이터 형식이 사전에 정의된 스펙(Schema, Linter, Test Case)에 부합하는지 자동 검사한다.
|
||||
* **자기 비판 (Self-Correction Feedback)**: 검증 실패 시 단순히 "에러 발생"이라고 알리는 대신, 무엇이 틀렸고 어떻게 고쳐야 하는지에 대한 구체적인 피드백 프롬프트를 생성하여 에이전트에게 전달한다.
|
||||
* **벤치마킹 및 채점 (Scoring)**: 작업의 품질을 정량화된 점수로 환산하여, 여러 번의 시도 중 가장 우수한 결과물을 선택하거나 에이전트의 성능 추이를 모니터링한다.
|
||||
* **환각 탐지 (Hallucination Detection)**: 에이전트의 답변이 실제 근거(Evidence Memory)와 일치하는지, 혹은 논리적 모순이 없는지 검토한다.
|
||||
* **인간 피드백 통합 (HITL Evaluation)**: 자동화된 평가가 어려운 경우 인간 사용자의 승인이나 점수를 입력받아 평가 프로세스에 반영한다.
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
* **평가자 모델의 한계**: 평가를 위해 또 다른 LLM을 사용할 경우, 평가자 자체가 환각을 일으키거나 편향된 판단을 내릴 리스크가 있다.
|
||||
* **검증 오버헤드**: 모든 단계에서 엄격한 검증을 수행하면 전체 작업 시간이 길어지고 비용이 증가한다.
|
||||
* **평가 기준의 모호성**: 주관적인 디자인이나 문구 작성 등의 작업에 대해서는 객관적인 평가 지표를 설정하기 어렵다.
|
||||
### 매 V-component 의 구성
|
||||
- **Trace viewer**: 매 LLM call chain 의 tree (input → tool calls → output).
|
||||
- **Score panel**: 매 metric (accuracy, faithfulness, latency, cost) 의 numeric + sparkline.
|
||||
- **Diff view**: 매 two run 의 side-by-side comparison.
|
||||
- **Annotation**: 매 human reviewer 의 매 label · comment.
|
||||
- **Filter / search**: 매 trace 의 fail · slow · expensive 만 isolation.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
### Related Concepts
|
||||
* [[Agent Harness|Agent Harness]]
|
||||
* 연결 이유: V-component는 하네스의 품질 보증 계층이다.
|
||||
* [[Self-verification|Self-verification]]
|
||||
* 연결 이유: V-component가 수행하는 핵심 활동 중 하나이다.
|
||||
* Agent Evaluation Benchmarks
|
||||
* 연결 이유: V-component가 사용하는 표준화된 평가 기준과 도구 모음이다.
|
||||
### 매 data shape
|
||||
- **Trace**: { id, name, input, output, children: Span[], metadata }.
|
||||
- **Score**: { name, value, type: "numeric" | "categorical", confidence }.
|
||||
- **Annotation**: { author, label, comment, ts }.
|
||||
|
||||
### Deeper Research Questions
|
||||
* '평가자의 평가자(Meta-evaluator)'를 두어 평가 시스템 자체의 신뢰성을 지속적으로 모니터링하는 아키텍처는 어떻게 설계해야 하는가?
|
||||
* 실패한 작업의 원인을 분석하여 V-component가 자동으로 '성공 가이드라인'을 생성하고 다음 루프에 반영하게 만드는 방법은 무엇인가?
|
||||
* 정적 분석(Linter)과 동적 추론(LLM)을 결합하여 최소한의 비용으로 최대의 검증 효과를 내는 '하이브리드 평가 전략'은 무엇인가?
|
||||
### 매 design 결정
|
||||
- **Virtualization**: 매 1000+ trace 의 render — react-virtuoso · TanStack Virtual.
|
||||
- **Streaming**: 매 in-progress trace 의 real-time update — SSE · WebSocket.
|
||||
- **Diff algorithm**: 매 string-level (diff-match-patch) + 매 structural (json-diff).
|
||||
|
||||
### Practical Application Contexts
|
||||
* **Implementation:** 코딩 에이전트에서 작성된 코드를 테스트 코드를 통해 실행해보고, 실패 시 스택 트레이스를 V-component에 입력하여 수정 전략을 세우게 한다.
|
||||
* **System Design:** 프로덕션 환경에서 에이전트의 답변을 실시간으로 채점하여, 일정 점수 미만의 답변은 사용자에게 보여주지 않고 즉시 재시도(Retry)하도록 설계한다.
|
||||
### 매 응용
|
||||
1. **Internal eval dashboard**: 매 ML team 의 매 model regression 의 detect.
|
||||
2. **PR review**: 매 prompt change 의 매 before/after diff.
|
||||
3. **Production monitoring**: 매 live trace 의 매 anomaly detection.
|
||||
|
||||
---
|
||||
*Last updated: 2026-05-01*
|
||||
## 💻 패턴
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
### 매 Trace tree component (React)
|
||||
```tsx
|
||||
type Span = {
|
||||
id: string;
|
||||
name: string;
|
||||
input: unknown;
|
||||
output: unknown;
|
||||
durationMs: number;
|
||||
children: Span[];
|
||||
};
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
function TraceTree({ root }: { root: Span }) {
|
||||
return (
|
||||
<ul className="font-mono text-sm">
|
||||
<SpanNode span={root} depth={0} />
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
function SpanNode({ span, depth }: { span: Span; depth: number }) {
|
||||
const [open, setOpen] = useState(depth < 2);
|
||||
return (
|
||||
<li style={{ paddingLeft: depth * 16 }}>
|
||||
<button onClick={() => setOpen(o => !o)}>
|
||||
{open ? "▼" : "▶"} {span.name} <span className="text-gray-500">{span.durationMs}ms</span>
|
||||
</button>
|
||||
{open && (
|
||||
<>
|
||||
<pre className="text-xs">{JSON.stringify(span.input, null, 2)}</pre>
|
||||
{span.children.map(c => <SpanNode key={c.id} span={c} depth={depth + 1} />)}
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
### 매 Score panel
|
||||
```tsx
|
||||
type Score = { name: string; value: number; series?: number[] };
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
function ScorePanel({ scores }: { scores: Score[] }) {
|
||||
return (
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{scores.map(s => (
|
||||
<div key={s.name} className="rounded border p-2">
|
||||
<div className="text-xs text-gray-500">{s.name}</div>
|
||||
<div className="text-2xl font-bold">{s.value.toFixed(3)}</div>
|
||||
{s.series && <Sparkline data={s.series} />}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
### 매 Diff view (two runs)
|
||||
```tsx
|
||||
import { diffLines } from "diff";
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
function DiffView({ a, b }: { a: string; b: string }) {
|
||||
const parts = diffLines(a, b);
|
||||
return (
|
||||
<pre className="text-xs">
|
||||
{parts.map((p, i) => (
|
||||
<span key={i} className={
|
||||
p.added ? "bg-green-100" : p.removed ? "bg-red-100" : ""
|
||||
}>{p.value}</span>
|
||||
))}
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
### 매 Virtualized trace list (1000+ items)
|
||||
```tsx
|
||||
import { Virtuoso } from "react-virtuoso";
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
function TraceList({ traces }: { traces: Trace[] }) {
|
||||
return (
|
||||
<Virtuoso
|
||||
data={traces}
|
||||
itemContent={(_, t) => (
|
||||
<TraceRow trace={t} status={t.scores.faithfulness < 0.7 ? "fail" : "ok"} />
|
||||
)}
|
||||
style={{ height: "100vh" }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 매 Streaming trace (SSE)
|
||||
```tsx
|
||||
function useLiveTraces(runId: string) {
|
||||
const [traces, setTraces] = useState<Trace[]>([]);
|
||||
useEffect(() => {
|
||||
const es = new EventSource(`/api/runs/${runId}/stream`);
|
||||
es.onmessage = e => {
|
||||
const span: Span = JSON.parse(e.data);
|
||||
setTraces(prev => mergeSpan(prev, span));
|
||||
};
|
||||
return () => es.close();
|
||||
}, [runId]);
|
||||
return traces;
|
||||
}
|
||||
```
|
||||
|
||||
### 매 Annotation (human-in-the-loop)
|
||||
```tsx
|
||||
function AnnotationPanel({ traceId }: { traceId: string }) {
|
||||
const [label, setLabel] = useState<"good" | "bad" | "unsure">();
|
||||
const [comment, setComment] = useState("");
|
||||
|
||||
const submit = async () => {
|
||||
await fetch(`/api/traces/${traceId}/annotations`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ label, comment, author: currentUser.id }),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<RadioGroup value={label} onChange={setLabel} options={["good", "bad", "unsure"]} />
|
||||
<textarea value={comment} onChange={e => setComment(e.target.value)} />
|
||||
<button onClick={submit}>Save</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 매 Filter / query (Braintrust-style)
|
||||
```typescript
|
||||
type FilterExpr = {
|
||||
field: "score.faithfulness" | "duration_ms" | "model";
|
||||
op: "<" | ">" | "==" | "contains";
|
||||
value: number | string;
|
||||
};
|
||||
|
||||
function applyFilters(traces: Trace[], filters: FilterExpr[]) {
|
||||
return traces.filter(t => filters.every(f => evalExpr(t, f)));
|
||||
}
|
||||
|
||||
// 매 UI: 매 query builder + 매 saved filter
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 hosted eval platform 가능 | 매 Braintrust / Langfuse / Phoenix (build X) |
|
||||
| 매 internal-only, 매 specific domain | 매 custom V-component (Tailwind + TanStack) |
|
||||
| 매 small team | 매 hosted — 매 build cost 의 prohibitive |
|
||||
| 매 1000+ traces / day | 매 virtualization 필수 |
|
||||
|
||||
**기본값**: 매 startup 은 매 Langfuse self-host, 매 enterprise 는 매 Braintrust / Arize.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[LLM Eval]] · [[Observability]] · [[UI Component]]
|
||||
- 변형: [[Trace Viewer]] · [[Score Panel]] · [[Diff View]]
|
||||
- 응용: [[Braintrust]] · [[Langfuse]] · [[Arize Phoenix]] · [[Weights and Biases Weave]]
|
||||
- Adjacent: [[OpenTelemetry]] · [[LLM Tracing]] · [[Annotation Tool]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 V-component 의 boilerplate (trace tree, virtualized list) 의 generation — 매 well-typed React + TanStack 패턴.
|
||||
**언제 X**: 매 domain-specific scoring logic — 매 hand-author.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 No virtualization**: 매 5000 trace 의 매 single render — 매 browser freeze.
|
||||
- **매 Score 의 raw number 만**: 매 sparkline · histogram 부재 — 매 trend 의 invisible.
|
||||
- **매 Mixed run units**: 매 different prompt versions 의 매 scores 의 average — 매 misleading.
|
||||
- **매 No annotation persistence**: 매 reviewer label 의 매 lost — 매 future training data 의 source 의 X.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Braintrust docs 2025; Langfuse v3 docs; Arize Phoenix 2024).
|
||||
- 신뢰도 B (매 design pattern — 매 standardized spec 부재).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — trace tree, score panel, diff, streaming 패턴 추가 |
|
||||
|
||||
Reference in New Issue
Block a user