跳转至

Experiment 5-8: Production Log Diagnosis / 实验 5-8:生产日志的智能诊断系统

Companion lab for AI Agents in Depth, Chapter 5 — diagnose trajectories + architecture + PRD → structured report → regression tests → real replay → GitHub Issues through the official MCP server. 《深入理解 AI Agent》第 5 章:诊断 Agent 读轨迹/架构/PRD,定位根因、生成回归测试、真实重放验证,并通过官方 GitHub MCP 创建 Issue。

Chapter 5 index / 返回第 5 章目录


Canonical manuscript experiment / 正文正式实验

The manuscript contract is satisfied by validation/runs/exp5-8-live-http-mcp-20260730-053403/manifest.json, not by the smaller deterministic demo described later in this README. The canonical campaign:

  • recorded two trajectories from a real local HTTP subprocess, including raw HTTP results and measured latency;
  • made two live doubao-seed-1-6-250615 calls to diagnose the failures and generate executable tests tied to trajectory IDs and turn numbers;
  • executed all three generated tests against both HTTP implementations: every test failed on the buggy service and passed after the fix; and
  • called issue_write(method=create) on the official github/github-mcp-server, creating Issue #502.

All nine acceptance gates are true and the manifest SHA-256 is 68e09e7c8b4fc100e0612a6f81978079c393a822025bfa794b6dda85134a5813. Raw provider calls, live replays, the generated tests, and the credential-free MCP receipt are retained beside the manifest.

正文合同由 validation/runs/exp5-8-live-http-mcp-20260730-053403/manifest.json 中的正式活动满足,而不是下文较小的确定性演示。该活动从真实本地 HTTP 子进程采集带原始响应和实测延迟的轨迹;用真实 doubao-seed-1-6-250615 调用完成诊断和可执行测试生成;让三个测试在有 缺陷实现上全部失败、修复实现上全部通过;最后通过官方 github/github-mcp-serverissue_write(method=create) 创建了 Issue #502。九项验收门禁全部为 true,原始模型回执、重放、测试与去凭据 MCP 回执均随 manifest 保留。

The sections below document the compact teaching/CI implementation. Its default GitHub sink is intentionally a mock; --create-issue selects its live MCP branch. Running that legacy path alone is not evidence for the canonical experiment.

下文记录的是适合教学和 CI 的小型实现;其 GitHub 默认输出有意采用 mock, --create-issue 才进入真实 MCP 分支。只运行该旧路径不能作为正式实验完成证据。


English

Purpose

Production Agents emit large trajectory logs. Finding issues, root causes, and building regression tests is expensive. This lab automates:

Read trajectory set + architecture + PRD → locate issues, structured report → generate regression cases → replay framework executes for real → (mock) GitHub Issues via MCP.

Diagnosis pipeline

data/trajectories.jsonl  (production trajectories with known issues)
data/architecture.md     (system architecture)          ┐
data/PRD.md              (product requirements)          ├─► [LLM] diagnose()      structured issue report
                                             ┘        │
                                            [LLM] gen_test_cases()   regression cases (trajectory IDs + turns)
                                            replay.py replay framework
                                              (A) unfixed SUT → FAIL (reproduce bug)
                                              (B) fixed SUT → PASS (verify fix)
                                            github_mcp.py  (mock) print/write GitHub Issues
  • diagnoser.py: diagnosis Agent; two real OpenAI calls (default gpt-5.6-luna, JSON mode).
  • sut.py: deterministic system-under-test simulator. fixed=False reproduces bugs; fixed=True fixed behavior.
  • replay.py: regression replay. Trajectory input → replay sut → evaluate asserts on new trajectory (4 built-in assert DSL kinds).
  • github_mcp.py: GitHub Issue create; default mock (print + output/github_issues.json).

Seeded known issues (Agent should find)

Trajectory Issue PRD violated Module
T-1001 / T-1002 Skipped mandatory verify_refund_eligibility before refund R1 (P0) order_service
T-1002 process_refund repeated failures, no backoff, false success R2 (P0) payment_service
T-1003 check_stock latency 8300ms timeout without degrade R3 (P1) inventory_service
T-1004 Healthy trajectory (control)

Run

# From the repository root: use the shared Chapter 5 environment
uv sync --locked --python 3.12 --extra ch5

# Activate it before changing directories:
# macOS/Linux:
source .venv/bin/activate
# Windows PowerShell: .\.venv\Scripts\Activate.ps1
# Windows cmd: .venv\Scripts\activate.bat

# pip fallback when uv is not installed:
# python -m pip install -e ".[ch5]"

cd chapter5/log-diagnosis

# Single-project compatibility path, still supported during migration:
# python -m pip install -r requirements.txt

cp env.example .env      # OPENAI_API_KEY (default gpt-5.6-luna); or OPENROUTER_API_KEY
python demo.py           # full pipeline (two real LLM calls)

demo.py once: read trajectories → diagnosis report → regression cases → replay pass/fail → (mock) GitHub Issue.

Common flags (python demo.py -h):

  • --smoke: no-API smoke—skip LLM; built-in diagnosis + replay + GitHub mock only (exit 0 if green). CI / no key.
  • --model gpt-5.6: override model (same as OPENAI_MODEL).
  • --data-dir DIR: input dir with trajectories.jsonl + architecture.md + PRD.md (default data/).
  • --output FILE: mock Issue write path (default output/github_issues.json).
  • --create-issue: real Issues via MCP (GITHUB_TOKEN + GITHUB_REPO; falls back to mock if missing).
  • --no-github: skip step 4.

Sample real output (excerpt)

Diagnosis found all 3 seeded issue classes:

[问题 1] 未进行退款资格校验
  优先级 : P0    模块: order_service    PRD: R1
  轨迹   : ['T-1001', 'T-1002']  关键轮次: [3]
[问题 2] 支付重试机制未正确实现
  优先级 : P0    模块: payment_service    PRD: R2
[问题 3] 库存查询延迟未降级处理
  优先级 : P1    模块: inventory_service    PRD: R3

Replay actually runs cases (reproduce then verify fix):

(A) 对『线上未修复』系统重放 —— 期望复现 bug(FAIL)
    [FAIL] RT-001 (T-1001)  工具 verify_refund_eligibility 缺失
    [FAIL] RT-002 (T-1002)  process_refund 调用 3 次, 失败 3 次, 末次失败
    [FAIL] RT-003 (T-1003)  check_stock 最大延迟 8300ms, 阈值 5000ms
(B) 对『修复后』系统重放 —— 期望修复被验证(PASS)
    [PASS] RT-001 (T-1001)  工具 verify_refund_eligibility 出现
    [PASS] RT-002 (T-1002)  process_refund 调用 2 次, 失败 1 次, 末次成功
    [PASS] RT-003 (T-1003)  check_stock 最大延迟 400ms, 阈值 5000ms
  小结:复现 bug 3/3 条;修复后通过 3/3 条。

Mock Issue example written to output/github_issues.json:

title  : [P0][order_service] 未进行退款资格校验
labels : ['module:order_service', 'priority:critical', 'auto-diagnosis']
body   : ## 问题描述 ... ## 关联回归测试用例 - RT-001 (轨迹 T-1001 第 3 轮) ...

Regression assert DSL (built into replay)

Generated cases must use one of:

  • step_present {tool}: tool must appear (e.g. mandatory pre-check).
  • tool_succeeds {tool}: tool eventually succeeds; no “many fails then fake success”.
  • latency_under {tool, threshold_ms}: single-call latency under threshold.
  • final_status_is {value}: final task status equals value.

Adapt / extend

  • Model: OPENAI_MODEL or python demo.py --model <name>. Default gpt-5.6-luna, JSON mode.
  • Provider: official openai SDK + OPENAI_BASE_URL + provider key/model, e.g.:
export OPENAI_BASE_URL=https://api.moonshot.cn/v1
export OPENAI_API_KEY=your-openai-api-key
export OPENAI_MODEL=kimi-k3
python demo.py
  • Logs: replace data/trajectories.jsonl (trajectory_id / task / task_input / turns[] / final_status; turns with module/tool/input/output/status/latency_ms); update architecture.md / PRD.md. Adjust sut.py / replay.py if fields differ.
  • Real GitHub MCP: next section; GITHUB_TOKEN + GITHUB_REPO + --create-issue.

Real GitHub MCP (token required; default mock)

Default is mock; --create-issue goes live. Implementation in github_mcp._create_issues_via_mcp(): MCP client (mcp SDK, stdio) to official GitHub MCP Server, create_issue with build_issue() fields.

  1. GitHub PAT with repo.env GITHUB_TOKEN; set GITHUB_REPO=owner/repo.
  2. Machine can start official GitHub MCP Server (default Docker ghcr.io/github/github-mcp-server); override with GITHUB_MCP_COMMAND (token as GITHUB_PERSONAL_ACCESS_TOKEN).
  3. The root ch5 extra includes the MCP SDK; the compatibility path above also keeps the old project-local install available.
  4. python demo.py --create-issue. Missing token/repo → tip + mock fallback.

Limitations

  • sut.py is a deterministic sim so replay can truly pass/fail; real systems need real stubs/replay.
  • Diagnosis quality depends on LLM. gpt-5.6-luna stably finds R1/R2/R3 on this data; it often splits R1 across T-1001 and T-1002 (4 issues vs 3 merged). For payment retry asserts it may choose final_status_is:failed instead of tool_succeeds (fixed SUT ends success → FAIL after fix, e.g. 3/4). Tool names sometimes get module prefixes incompatible with bare-name matching (further fails). --smoke built-in cases are deterministic 3/3.
  • GitHub create is mock unless --create-issue with token + repo + MCP server.
  • Trajectory schema is simplified vs production (tokens, sub-agent trees, etc.).

中文

目的

生产环境的 Agent 会产生大量轨迹日志(trajectory)。从中识别问题、定位根因、构建回归测试成本很高。 本实验让一个诊断 Agent 自动完成这条流水线:

读轨迹集合 + 架构文档 + PRD → 定位问题、生成结构化报告 → 生成回归测试用例 → 重放框架真正执行验证 → (mock) 通过 MCP 对接 GitHub 创建 Issue。

诊断流水线

data/trajectories.jsonl  (含已知问题的生产轨迹)
data/architecture.md     (系统架构)          ┐
data/PRD.md              (产品需求)          ├─► [LLM] diagnose()      结构化问题报告(优先级/模块/描述/建议)
                                             ┘        │
                                            [LLM] gen_test_cases()   回归测试用例(引用轨迹ID+交互轮次)
                                            replay.py 重放框架  ── 对同一输入重放被测系统并断言
                                              (A) 未修复系统 → FAIL(复现bug)
                                              (B) 修复后系统 → PASS(验证修复)
                                            github_mcp.py  (mock) 渲染并打印/落盘 GitHub Issue
  • diagnoser.py:诊断 Agent,两次真实调用 OpenAI(默认 gpt-5.6-luna,JSON 模式)。
  • sut.py:被测系统的确定性仿真器fixed=False 复现线上 bug,fixed=True 模拟修复后行为。
  • replay.py:回归测试重放框架。取轨迹输入 → 重放 sut → 在新轨迹上求值断言(内置 4 种断言 DSL)。
  • github_mcp.py:GitHub Issue 创建,默认 mock(打印 + 写 output/github_issues.json)。

预置的已知问题(Agent 应能定位)

轨迹 问题 违反 PRD 定位模块
T-1001 / T-1002 退款前跳过了强制的 verify_refund_eligibility 校验 R1 (P0) order_service
T-1002 process_refund 反复失败、无退避、且最终误报成功 R2 (P0) payment_service
T-1003 check_stock 延迟 8300ms 超时未降级 R3 (P1) inventory_service
T-1004 正常轨迹(对照组,无问题)

运行

# 在仓库根目录使用统一的第 5 章环境
uv sync --locked --python 3.12 --extra ch5

# 切换目录前先激活环境:
# macOS/Linux:
source .venv/bin/activate
# Windows PowerShell:.\.venv\Scripts\Activate.ps1
# Windows cmd:.venv\Scripts\activate.bat

# 未安装 uv 时可用 pip 兜底:
# python -m pip install -e ".[ch5]"

cd chapter5/log-diagnosis

# 迁移期间仍支持单项目兼容路径:
# python -m pip install -r requirements.txt

cp env.example .env      # 填入 OPENAI_API_KEY(模型默认 gpt-5.6-luna);未配置时设 OPENROUTER_API_KEY 自动改走 OpenRouter
python demo.py           # 完整流程(两次真实 LLM 调用)

demo.py 一次跑完:读轨迹 → 诊断报告 → 回归测试用例 → 重放执行(通过/失败) → (mock) GitHub Issue。

常用参数(python demo.py -h 查看全部):

  • --smoke免 API 快速自检,跳过 LLM,用内置诊断结果仅跑重放框架 + GitHub mock,验证管道是否端到端连通(全绿退出码 0)。适合无 Key 环境或 CI。
  • --model gpt-5.6:临时覆盖模型(等价于设置 OPENAI_MODEL)。
  • --data-dir DIR:换用自己的输入目录(需含 trajectories.jsonl + architecture.md + PRD.md,默认 data/)。
  • --output FILE:mock GitHub Issue 的落盘路径(默认 output/github_issues.json)。
  • --create-issue经 MCP 在真实仓库创建 Issue(需 GITHUB_TOKEN + GITHUB_REPO,见下节;缺失时自动回退 mock)。
  • --no-github:跳过步骤 4,不生成 GitHub Issue。

真实运行输出(节选)

诊断阶段,Agent 定位到全部 3 个预置问题:

[问题 1] 未进行退款资格校验
  优先级 : P0    模块: order_service    PRD: R1
  轨迹   : ['T-1001', 'T-1002']  关键轮次: [3]
[问题 2] 支付重试机制未正确实现
  优先级 : P0    模块: payment_service    PRD: R2
[问题 3] 库存查询延迟未降级处理
  优先级 : P1    模块: inventory_service    PRD: R3

回归测试用例被重放框架真正执行(先复现 bug、再验证修复):

(A) 对『线上未修复』系统重放 —— 期望复现 bug(FAIL)
    [FAIL] RT-001 (T-1001)  工具 verify_refund_eligibility 缺失
    [FAIL] RT-002 (T-1002)  process_refund 调用 3 次, 失败 3 次, 末次失败
    [FAIL] RT-003 (T-1003)  check_stock 最大延迟 8300ms, 阈值 5000ms
(B) 对『修复后』系统重放 —— 期望修复被验证(PASS)
    [PASS] RT-001 (T-1001)  工具 verify_refund_eligibility 出现
    [PASS] RT-002 (T-1002)  process_refund 调用 2 次, 失败 1 次, 末次成功
    [PASS] RT-003 (T-1003)  check_stock 最大延迟 400ms, 阈值 5000ms
  小结:复现 bug 3/3 条;修复后通过 3/3 条。

mock GitHub Issue 打印并写入 output/github_issues.json,示例:

title  : [P0][order_service] 未进行退款资格校验
labels : ['module:order_service', 'priority:critical', 'auto-diagnosis']
body   : ## 问题描述 ... ## 关联回归测试用例 - RT-001 (轨迹 T-1001 第 3 轮) ...

回归测试断言 DSL(replay 框架内置)

Agent 生成的测试用例须使用以下断言之一,框架可自动求值:

  • step_present {tool}:某工具必须出现(如强制前置校验)。
  • tool_succeeds {tool}:某工具最终成功、且不存在"多次失败后误报成功"。
  • latency_under {tool, threshold_ms}:某工具单次延迟低于阈值。
  • final_status_is {value}:任务最终状态等于给定值。

如何适配/扩展

  • 换模型:设置 OPENAI_MODEL(或 python demo.py --model <名称>)。diagnoser.py 默认 gpt-5.6-luna,均走 JSON 模式;更强模型对复杂/隐性问题更稳。
  • 换供应商:本项目用官方 openai SDK,只需再设 OPENAI_BASE_URL 指向兼容 OpenAI 接口的服务(如 Moonshot / 火山方舟 / 本地 vLLM),配合该供应商的 OPENAI_API_KEYOPENAI_MODEL 即可,无需改代码。例如:
    export OPENAI_BASE_URL=https://api.moonshot.cn/v1
    export OPENAI_API_KEY=your-openai-api-key          # 该供应商的 Key
    export OPENAI_MODEL=kimi-k3
    python demo.py
    
  • 换日志:把你自己的生产轨迹按 data/trajectories.jsonl 的结构(trajectory_id / task / task_input / turns[] / final_statusturns 内含 module/tool/input/output/status/latency_ms)落盘替换即可;同时更新 data/architecture.mddata/PRD.md 作为诊断依据。若轨迹字段不同,sut.py(重放桩)与 replay.py(断言求值)按新字段小幅调整。
  • 接入真实 GitHub MCP:见下一节,通过 GITHUB_TOKEN + GITHUB_REPO + --create-issuemock=False 接通。

接入真实 GitHub MCP(需 token,默认 mock)

本实验默认 mock,--create-issue 才会真正联网。真实创建的实现已内置在 github_mcp._create_issues_via_mcp():通过 MCP 客户端(mcp SDK,stdio)连接官方 GitHub MCP Server,逐个调用其 create_issue 工具,传入 build_issue() 生成的 title / body / labels / assignees。启用步骤:

  1. 准备一个 GitHub Personal Access Token(repo 权限),写入 .envGITHUB_TOKEN; 并设置目标仓库 GITHUB_REPO=owner/repo
  2. 确保本机可启动官方 GitHub MCP Server。默认启动命令用官方 Docker 镜像 ghcr.io/github/github-mcp-server;可用 GITHUB_MCP_COMMAND 覆盖为任意暴露 create_issue 工具的 MCP Server(token 经 GITHUB_PERSONAL_ACCESS_TOKEN 注入其环境)。
  3. 根目录 ch5 extra 已包含 MCP SDK;上方兼容路径仍保留旧版单项目安装。
  4. 运行 python demo.py --create-issue。缺少 GITHUB_TOKEN / GITHUB_REPO 时会打印提示并 自动回退 mock,避免误联网。

局限

  • 被测系统 sut.py确定性仿真,用于让回归测试可真正重放、给出稳定的通过/失败;真实场景下重放需对接实际系统或录制/回放的依赖桩。
  • 诊断质量取决于 LLM;gpt-5.6-luna 在本数据集能稳定定位全部 3 类预置问题(R1 校验缺失 / R2 重试误报 / R3 延迟未降级),步骤 1 诊断稳定;但它倾向把 R1「校验缺失」按 T-1001、T-1002 各报一条,故常输出 4 条问题(而非上文示例合并成的 3 条)。步骤 2 生成断言时,它稳定地为「支付重试」问题选用 final_status_is:failed(两次实跑均如此)而非上文示例的 tool_succeeds——因修复后的被测系统会重试成功(final_status=success),该断言在修复后重放中判 FAIL,使修复后通过数降为 3/4 而非满绿。此外它偶尔给 step_present/latency_under 的工具名加上模块前缀(如 order_service.verify_refund_eligibility),与重放框架按裸工具名匹配不符,会进一步压低修复后通过数(两次实跑分别得到 3/4 与 0/4)。--smoke 内置用例则确定性给出 3/3。
  • GitHub 创建默认 mock,不联网;--create-issue 才经真实 MCP Server 联网创建(需 token + repo + 可用的 GitHub MCP Server)。
  • 轨迹格式为简化示意,生产环境轨迹字段更丰富(token 用量、子 Agent 调用树等)。

Notes / 说明

  • Prefer --smoke without a key. / 无 Key 优先 --smoke
  • Commands/code/paths/env vars are identical in both language sections. / 命令、代码、路径与环境变量在中英文两侧保持一致。