iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0

前言

Day 27 我們分析了最終實驗結果。

走到這裡,原本分散的功能已經組成一個小型 Agent 測試驗證平台,包含:

  • Agent Runner
  • Tool Calling
  • Trace
  • SQLite storage
  • Trace Viewer
  • Eval dataset
  • Batch Evaluation Runner
  • Rule-based evaluator
  • Failure Dashboard
  • Prompt versioning
  • Retry
  • JSON schema guardrail
  • Tool guardrail
  • Cost / latency metrics
  • Reliability Dashboard
  • Final experiment

如果只看每天的文章,我們可以跟著一步一步做出功能。

但當功能累積到這個階段,只靠文章順序已經不夠了。

一個專案要能被持續使用和維護,需要有清楚的入口文件。

這份文件至少要回答三個問題:

這個專案在做什麼?
要怎麼跑起來?
結果要怎麼看?

所以 Day 28 要整理專案架構與 README。

Day 28 不加新功能,而是把現有內容整理成容易閱讀、能重現結果,也方便繼續擴充的工程專案。


這篇要完成什麼?

整理工作包括:

  1. 整理目前專案架構。
  2. 補上 README 的專案介紹。
  3. 說明如何設定 Gemini API key。
  4. 說明如何執行 Agent。
  5. 說明如何執行 eval runner。
  6. 說明如何啟動 Trace Viewer 和 Reliability Dashboard。
  7. 補上系統流程圖。
  8. 補上 final experiment 摘要。
  9. 補上目前限制與後續工作入口。

這次先不做:

  • 不新增新的 Agent 能力。
  • 不重新分析實驗。
  • 不重構整個專案。
  • 不把 README 寫成過度包裝的行銷頁。

整理後要達到:

讓專案能被讀懂、跑起來、重現結果。

目前專案架構

先把目前專案整理成一棵乾淨的 tree。

README 不需要列出 __pycache__、資料庫檔、舊 eval run 全部 JSON。

列出主要模組的位置就夠了。

可以在 README.md 放這段。

新增 README.md:

# Agent Testing Platform

這是一個簡化版 AI Agent 測試驗證平台。

它的目標不是打造最強的 Agent,而是建立一套流程,讓 Agent 的執行過程可以被記錄、測試、評分、分析與改善。

## Project Structure

```text
agent-testing-platform/
  app.py
  trace_viewer_app.py
  failure_dashboard_app.py

  agents/
    client_factory.py
    fake_llm.py
    gemini_llm.py
    prompts.py
    simple_agent.py

  tools/
    calculator.py

  tracing/
    models.py

  storage/
    database.py
    schema.sql

  evals/
    cases.json
    evaluators.py
    runner.py
    final_experiment_plan.json
    final_experiment_runs.md
    analyze_final_runs.py

  guardrails/
    json_schema.py
    tool_permissions.py

  metrics/
    cost.py

  ui/
    trace_viewer.py
    failure_dashboard.py

  tests/
    test_json_schema_guardrail.py
    test_tool_permissions_guardrail.py
```

這段 tree 的重點不是列出所有檔案。

而是讓人一眼看懂:

目錄 負責內容
agents/ Agent、LLM client、prompt version
tools/ Agent 可以呼叫的工具
tracing/ Trace 資料模型
storage/ SQLite 儲存
evals/ 測試案例、評分、批次 eval、最終實驗
guardrails/ JSON schema 與 tool permission guardrail
metrics/ token、cost、latency 相關 helper
ui/ Streamlit viewer 與 dashboard
tests/ guardrail 單元測試

補上專案目標

README 開頭要先回答:

這個專案解決什麼問題?

不是先放安裝指令。

可以這樣寫。

繼續修改 README.md:

## What This Project Does

這個專案示範一個 AI Agent 測試驗證流程:

1. 使用 `SimpleAgent` 執行任務。
2. 記錄每次 Agent 執行的 trace。
3. 使用 eval dataset 批次測試 Agent。
4. 用 rule-based evaluator 自動評分。
5. 將失敗案例分類成 `format_error`、`wrong_answer`、`tool_error` 等類型。
6. 使用 JSON schema guardrail 驗證結構化輸出。
7. 使用 tool guardrail 限制 Agent 可用工具。
8. 記錄 latency、LLM call count、token usage 與 estimated cost。
9. 用 Streamlit dashboard 分析可靠性與失敗原因。

這個專案適合用來理解:

- Agent 為什麼需要 trace。
- 如何建立最小 eval pipeline。
- prompt 改善與 retry 是否真的有效。
- guardrails 如何讓失敗變得可觀察。
- reliability 和 cost 之間如何取捨。

這段文字要務實。

不要寫成:

這是一個 production-ready AgentOps 平台。

因為目前它不是。

它是一個教學用、可重現的 MVP。


補上環境需求

接著寫執行環境。

修改 README.md:

## Requirements

- Python 3.12+
- Streamlit
- Pandas
- Pytest
- Gemini API key(如果要使用 Gemini provider)

本專案提供兩種 LLM provider:

| Provider | 說明 |
|---|---|
| `fake` | 本機測試用,不需要 API key |
| `gemini` | 使用 Gemini API,需要 `GEMINI_API_KEY` |

如果專案目前沒有 requirements.txt,可以先在 README 寫手動安裝方式。

例如:

## Installation

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install streamlit pandas pytest google-genai
```

這裡要注意。

如果只用 fake provider 和測試 guardrails,不一定需要 google-genai。

但如果要跑 Gemini,就需要安裝 Gemini SDK。


補上環境變數說明

這個專案已經使用不少環境變數。

README 裡一定要整理。

修改 README.md:

## Environment Variables

| Name | Required | Default | Description |
|---|---|---|---|
| `LLM_PROVIDER` | no | `fake` | `fake` or `gemini` |
| `GEMINI_API_KEY` | only for Gemini | none | Gemini API key |
| `GEMINI_MODEL` | no | project default | Gemini model name |
| `PROMPT_VERSION` | no | `baseline` | `baseline` or `json_strict` |
| `RETRY_ENABLED` | no | `0` | `1` enables retry for JSON format error |
| `EVAL_DELAY_SECONDS` | no | `0` | delay between eval cases |
| `INPUT_COST_PER_1K_TOKENS` | no | `0.0` | estimated input cost |
| `OUTPUT_COST_PER_1K_TOKENS` | no | `0.0` | estimated output cost |

如果要使用 Gemini:

```bash
export GEMINI_API_KEY="your-api-key"
```

如果只是要本機驗證流程,可以使用 fake provider:

```bash
LLM_PROVIDER=fake python3 -m evals.runner
```

這段很重要。

因為如果沒有說清楚,使用者很容易遇到:

ValueError: GEMINI_API_KEY is not set

README 應該讓這種錯誤變得可預期。


補上基本執行方式

接著寫最短路徑。

第一次看專案的人通常想知道:

我要打哪幾個指令才看得到成果?

修改 README.md:

## Quick Start

### 1. Run the Agent

使用 fake provider:

```bash
LLM_PROVIDER=fake python3 app.py
```

使用 Gemini:

```bash
export GEMINI_API_KEY="your-api-key"
LLM_PROVIDER=gemini PROMPT_VERSION=json_strict python3 app.py
```

### 2. Run Evaluation

本機流程驗證:

```bash
RETRY_ENABLED=0 LLM_PROVIDER=fake python3 -m evals.runner
```

使用 Gemini 執行 eval:

```bash
EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=0 \
PROMPT_VERSION=json_strict \
LLM_PROVIDER=gemini \
python3 -m evals.runner
```

### 3. Run Tests

```bash
python3 -m pytest tests/test_json_schema_guardrail.py
python3 -m pytest tests/test_tool_permissions_guardrail.py
```

這裡不要一次塞太多指令。

README 的目標是讓人能成功跑起第一輪。

更完整的實驗指令可以放在後面。


補上 Dashboard 執行方式

目前有兩個 Streamlit app:

  • Trace Viewer
  • Reliability Dashboard

README 要清楚分開。

修改 README.md:

## Dashboards

### Trace Viewer

Trace Viewer 用來查看單次 Agent 執行過程。

```bash
streamlit run trace_viewer_app.py
```

可以用來查看:

- user input
- LLM response
- tool call
- tool result
- final answer
- error

### Reliability Dashboard

Reliability Dashboard 用來分析 eval run。

```bash
streamlit run failure_dashboard_app.py
```

可以用來查看:

- success rate
- failed cases
- failure type distribution
- task type failure rate
- latency
- LLM call count
- token usage
- estimated cost
- prompt version comparison

這裡檔名仍然是 failure_dashboard_app.py。

雖然 Day 24 把它擴充成 Reliability Dashboard,但入口檔沿用 Day 17 的命名。

README 可以直接說明:

failure_dashboard_app.py now renders the Reliability Dashboard.

如果未來要整理得更漂亮,可以把檔案改名成 reliability_dashboard_app.py。

但 Day 28 先不做這個重構。


補上系統流程圖

README 可以用 Mermaid 畫簡單流程圖。

GitHub Markdown 支援 Mermaid,所以不需要另外產生圖片。

修改 README.md:

## System Flow

```mermaid
flowchart TD
    A[User Task] --> B[SimpleAgent]
    B --> C[LLM Client]
    C --> D{Tool Call?}
    D -- yes --> E[Tool Guardrail]
    E --> F[Tool Execution]
    F --> G[Trace Recorder]
    D -- no --> G
    G --> H[SQLite Storage]

    I[Eval Cases] --> J[Eval Runner]
    J --> B
    J --> K[JSON Schema Guardrail]
    K --> L[Rule-based Evaluator]
    L --> M[Eval Run JSON]
    M --> N[Reliability Dashboard]
```

這張圖說明兩條線:

  1. Agent 執行線:user task -> agent -> LLM/tool -> trace。
  2. Evaluation 線:cases -> runner -> guardrail/evaluator -> dashboard。

這比單純列檔案更容易讓讀者理解系統。


補上 final experiment 摘要

Day 26 和 Day 27 的結果也應該放進 README。

但 README 不需要貼所有 case output。

只要放摘要。

修改 README.md:

## Final Experiment Summary

Final experiment 使用同一份 `evals/cases.json`,比較 baseline prompt、`json_strict` prompt 和 retry。

| Experiment | Passed | Failed | Success Rate | LLM Calls | Total Latency |
|---|---:|---:|---:|---:|---:|
| baseline / no retry | 10 | 5 | 66.7% | 15 | 88262.05 ms |
| json_strict / no retry | 13 | 2 | 86.7% | 15 | 80131.38 ms |
| baseline / retry | 11 | 4 | 73.3% | 18 | 105118.41 ms |
| json_strict / retry | 12 | 3 | 80.0% | 15 | 79742.16 ms |

在目前這組 eval dataset 上,`json_strict / no retry` 是最值得保留的設定。

原因是:

- success rate 最高。
- JSON format error 從 3 降到 0。
- 沒有增加 LLM calls。

Retry 仍然有價值,但比較適合做為 JSON format error 的備援策略。

這段要延續 Day 27 的保守結論。

不要寫成:

json_strict 永遠最好。

而是:

在目前這組 eval dataset 上最值得保留。

補上分析指令

Day 27 新增了 evals/analyze_final_runs.py。

README 也要讓讀者知道怎麼用。

修改 README.md:

## Analyze Final Runs

```bash
python3 -m evals.analyze_final_runs
```

這個指令會讀取 final experiment 的 eval run JSON,輸出:

- success rate
- failure type counts
- LLM calls
- total tokens
- total latency
- average latency
- estimated cost

這樣 README 也能當成專案的操作入口。

它也變成重現實驗的入口。


補上測試說明

目前測試主要集中在 guardrails。

這要誠實寫。

修改 README.md:

## Tests

目前測試涵蓋:

- JSON schema guardrail
- Tool permission guardrail

執行:

```bash
python3 -m pytest tests/test_json_schema_guardrail.py
python3 -m pytest tests/test_tool_permissions_guardrail.py
```

目前尚未完整測試:

- Gemini API integration
- Streamlit UI
- SQLite persistence edge cases
- end-to-end eval runner

這樣寫比假裝測試完整更好。

清楚說明測試範圍,會讓後續維護者知道哪些地方已經被驗證,哪些地方還需要補測。


補上 limitations

Day 29 會完整談限制和未來工作。

但 README 可以先放短版。

修改 README.md:

## Limitations

這是一個 MVP,不是 production-ready AgentOps 平台。

目前限制包含:

- eval dataset 規模很小。
- rule-based evaluator 對語意等價答案不夠寬容。
- token usage 和 cost 是估算,不是真實 billing。
- Gemini API 可能受到 quota 和 429 影響。
- dashboard 主要用於觀察,不包含完整實驗管理功能。
- 目前沒有支援 resume failed cases。

更多限制與未來工作會在 Day 29 整理。

這段很重要。

README 不應該只寫專案做得到的事情。

能清楚說明限制,才能讓使用者知道系統邊界在哪裡。


可以補 .env.example

除了 README,也可以補一個 .env.example。

這不是必要,但很實用。

新增 .env.example:

LLM_PROVIDER=fake
GEMINI_API_KEY=
GEMINI_MODEL=
PROMPT_VERSION=baseline
RETRY_ENABLED=0
EVAL_DELAY_SECONDS=0
INPUT_COST_PER_1K_TOKENS=0.0
OUTPUT_COST_PER_1K_TOKENS=0.0

這個檔案不要放真的 API key。

它只是告訴使用者有哪些環境變數可以設定。

如果之後加入 .gitignore,也可以提醒:

.env

不要被 commit。


README 完整骨架

整理後,README.md 可以長這樣。

新增 README.md:

# Agent Testing Platform

這是一個簡化版 AI Agent 測試驗證平台。

它的目標不是打造最強的 Agent,而是建立一套流程,讓 Agent 的執行過程可以被記錄、測試、評分、分析與改善。

## What This Project Does

這個專案示範一個 AI Agent 測試驗證流程:

1. 使用 `SimpleAgent` 執行任務。
2. 記錄每次 Agent 執行的 trace。
3. 使用 eval dataset 批次測試 Agent。
4. 用 rule-based evaluator 自動評分。
5. 使用 guardrails 檢查 JSON schema 與 tool permission。
6. 記錄 latency、LLM call count、token usage 與 estimated cost。
7. 用 Streamlit dashboard 分析可靠性與失敗原因。

## Project Structure

```text
agent-testing-platform/
  app.py
  trace_viewer_app.py
  failure_dashboard_app.py
  agents/
  tools/
  tracing/
  storage/
  evals/
  guardrails/
  metrics/
  ui/
  tests/
```

## Requirements

- Python 3.12+
- Streamlit
- Pandas
- Pytest
- Gemini API key(如果使用 Gemini provider)

## Environment Variables

| Name | Required | Default | Description |
|---|---|---|---|
| `LLM_PROVIDER` | no | `fake` | `fake` or `gemini` |
| `GEMINI_API_KEY` | only for Gemini | none | Gemini API key |
| `PROMPT_VERSION` | no | `baseline` | `baseline` or `json_strict` |
| `RETRY_ENABLED` | no | `0` | `1` enables retry |
| `EVAL_DELAY_SECONDS` | no | `0` | delay between eval cases |
| `INPUT_COST_PER_1K_TOKENS` | no | `0.0` | estimated input cost |
| `OUTPUT_COST_PER_1K_TOKENS` | no | `0.0` | estimated output cost |

## Quick Start

```bash
RETRY_ENABLED=0 LLM_PROVIDER=fake python3 -m evals.runner
```

Use Gemini:

```bash
export GEMINI_API_KEY="your-api-key"

EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=0 \
PROMPT_VERSION=json_strict \
LLM_PROVIDER=gemini \
python3 -m evals.runner
```

## Dashboards

Trace Viewer:

```bash
streamlit run trace_viewer_app.py
```

Reliability Dashboard:

```bash
streamlit run failure_dashboard_app.py
```

## System Flow

```mermaid
flowchart TD
    A[User Task] --> B[SimpleAgent]
    B --> C[LLM Client]
    C --> D{Tool Call?}
    D -- yes --> E[Tool Guardrail]
    E --> F[Tool Execution]
    F --> G[Trace Recorder]
    D -- no --> G
    G --> H[SQLite Storage]

    I[Eval Cases] --> J[Eval Runner]
    J --> B
    J --> K[JSON Schema Guardrail]
    K --> L[Rule-based Evaluator]
    L --> M[Eval Run JSON]
    M --> N[Reliability Dashboard]
```

## Final Experiment Summary

| Experiment | Passed | Failed | Success Rate | LLM Calls | Total Latency |
|---|---:|---:|---:|---:|---:|
| baseline / no retry | 10 | 5 | 66.7% | 15 | 88262.05 ms |
| json_strict / no retry | 13 | 2 | 86.7% | 15 | 80131.38 ms |
| baseline / retry | 11 | 4 | 73.3% | 18 | 105118.41 ms |
| json_strict / retry | 12 | 3 | 80.0% | 15 | 79742.16 ms |

在目前這組 eval dataset 上,`json_strict / no retry` 是最值得保留的設定。

## Tests

```bash
python3 -m pytest tests/test_json_schema_guardrail.py
python3 -m pytest tests/test_tool_permissions_guardrail.py
```

## Limitations

- eval dataset 規模很小。
- rule-based evaluator 對語意等價答案不夠寬容。
- token usage 和 cost 是估算。
- Gemini API 可能受到 quota 和 429 影響。
- dashboard 主要用於觀察,不包含完整實驗管理功能。

這個版本已經足夠作為第一版 README。

它清楚交代:

  • 專案做什麼。
  • 怎麼跑。
  • 怎麼看結果。
  • 實驗結果是什麼。
  • 限制在哪裡。

整理結果

這一篇處理的是工程整理,沒有新增 Agent 能力。

完成內容包含:

  • 整理專案目錄結構。
  • 補上 README.md。
  • 說明環境變數。
  • 說明如何使用 fake provider 和 Gemini provider。
  • 說明如何執行 eval runner。
  • 說明如何啟動 Trace Viewer 和 Reliability Dashboard。
  • 補上 Mermaid 系統流程圖。
  • 放入 final experiment summary。
  • 補上測試指令。
  • 補上 limitations。
  • 建議新增 .env.example。

整理後可以做到:

讓專案從「功能已經做出來」變成「流程可以被理解與重現」。

如果專案沒有 README,即使功能完成,後續使用者仍然很難知道怎麼啟動、測試和判讀結果。


下一步

Day 29 會整理限制、風險與未來工作。

README 目前只放短版 limitations。

明天會更完整地討論:

  • rule-based evaluator 的限制。
  • eval dataset 太小的問題。
  • Gemini 單一模型實驗的限制。
  • token / cost estimation 的限制。
  • production-grade AgentOps 還缺哪些東西。
  • 未來可以如何延伸到 LLM-as-a-Judge、RAG evaluation 和多模型比較。

下一篇會補齊風險與限制,讓系統邊界交代得更清楚。


上一篇
Day 27|分析最終實驗結果
下一篇
Day 29|限制、風險與未來工作
系列文
從黑盒到可驗證:30 天打造 AI Agent 的 Trace、Eval 與 Guardrails 系統 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言