关于 agent-experience
Audit Agent Experience 从简短提示开始,评估 AI Agent 如何上手产品或 SDK 并尝试真实任务。它并行运行多个子 Agent、记录工具调用轨迹,并按五个维度评分。
主要功能
- 01并行运行多个子 Agent
- 02从简短且不引导的提示开始
- 03捕获 Agent 工具调用轨迹
- 04评估五项 Agent 体验指标
- 05支持配置模型和执行模式
适用场景
- 01评估 SDK 的入门文档
- 02测试 Agent 能否完成产品任务
- 03比较不同模型的文档体验
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ browserbase/ skills --skill agent-experience安装后在 Claude Code 中输入/agent-experience确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtassets/report-template.htmlreferences/evaluation-rubric.mdprompt-variants.mdsubagent-brief.md详细介绍
审核 Agent 体验
评估 AI Agent 实际尝试入门并完成真实任务时,产品/SDK/文档界面的表现如何——从一句简短提示词开始,不预先粘贴任何内容。Agent 必须自行查找文档、安装所需内容并尝试完成实际工作。这才是检验 Agent 开发者体验的唯一可靠方法。
此技能会并行启动多个子 Agent,记录每个子 Agent 的工具调用轨迹,并按照 Skill Test Arena 仪表板的相同维度对体验评分:设置阻力、速度、效率、错误恢复、文档质量。
核心原则
不要过度提示。 子 Agent 只会收到类似 “开始使用 {product} 并完成 {它的主要工作}” 的简短提示词。它必须自行查找文档、选择路径并遇到真实故障。好的文档经得住这样的考验;差的文档则不行。
工作流
按顺序执行以下步骤。不要跳步。
步骤 1 — 确定目标并定义抽象目标
弄清楚用户要求审核什么。目标可能以以下三种形式之一提供:
- URL — 文档网站或产品页面(例如
https://docs.example.com)。这是子代理开始工作的起点。 - 仓库 / 文件路径 — 用于审核 SKILL.md 或 SDK 仓库。
- 产品名称 — 如果用户描述得很含糊(“测试我的产品”),请通过
AskUserQuestion询问 URL 或仓库。
此技能与具体产品无关。绝不要假设用户想审核什么。 不要根据环境信号(操作者的电子邮件域名、git 远程地址、仓库名称、最近使用的文件、记忆、CLAUDE.md)推断目标。即使上下文强烈暗示某家公司,面向用户的问题也绝不能预先填入或默认任何特定产品、URL 或公司名称。使用中立选项开放式提问,例如:“粘贴 URL”“粘贴本地路径”“输入产品名称”。如果用户在调用时没有指定目标,就询问他们——从头开始,不带任何预设。
用户指定目标之后,再进行少量调查。最多使用 1 次 WebFetch,足以确认:这是什么产品?它是否有入门指南?你的目的是确认存在一条可遵循的流程,而不是提取具体步骤。关键是让文档决定路径。
定义一个抽象目标,而非逐步检查清单。 目标应是“完成入门流程”或“让产品成功完成一次主要功能”这一层级,而不是一系列具体操作。
原因:过于具体的检查清单会引导 Agent。如果你告诉它们“访问 example.com”,而文档中的快速入门指南指向另一个 URL,Agent 就会在你的指示和文档之间左右为难,从而污染测试。
好的抽象目标示例(目标产品由用户提供——以下示例仅供说明,不能作为默认值):
- 搜索 API → “完成入门指南。成功标准 = 代码成功调用 API,并打印文档视为有意义的结果。”
- 支付 API → “完成创建测试扣款的入门流程。成功标准 = 获得扣款 ID 或等效确认信息。”
- 浏览器自动化 SDK → “从头到尾完成入门指南。成功标准 = 编写出能够使用文档推荐的任意方式运行云端浏览器会话的代码。”
- SKILL.md → “遵循技能的说明,并成功完成其所宣称的任务。”
不好的目标示例(过于具体——不要这样做):
- ~~“访问 https://example.com”~~(会造成引导——文档可能会选择其他 URL)
“使用 Playwright”(文档可能推荐 Stagehand 或 Selenium)“打印页面标题”(文档可能会打印会话 ID、响应正文或其他内容)
子代理会根据抽象目标自行报告:我是否按照文档所述完成了入门流程?(是 / 否 / 部分完成)。Agent实际达成的具体结果应记录在其轨迹的 primary_outcome_achieved 下,而不是预先定义为检查清单。
如果目标没有明确的入门流程(这种情况很少见——即使是 README 也会提供流程),继续之前先询问用户“完成”意味着什么。
步骤 2 — 通过 AskUserQuestion 收集审计配置
使用 AskUserQuestion,在一次调用中提出 4 个问题。每个问题最多提供 4 个选项。
-
测试深度(单选,标题:
"Depth"):5 agents (Recommended)— 覆盖均衡3 agents— 快速健全性检查10 agents— 全面审计,成本较高
-
编程语言(多选,标题:
"Languages"):最多选择 4 项 —Python、TypeScript、Go、Shell/Bash(允许用户取消选择)。 -
Persona(多选,标题:
"Personas"):Standard (Recommended)— 中立基线,不添加行为倾向。只需“完成任务”。最适合进行无偏测量。Pragmatic— 只要能跑通即可,选择最快的路径Thorough— 编码前从头到尾阅读文档Skeptical— 核实文档中的说法
-
执行模式(单选,标题:
"Exec mode"):Allow Bash (Recommended)— 子 Agent 可以在你的机器上运行npm install、curl等命令。最贴近实际情况。Draft-only— 子 Agent 可以获取文档并编写代码,但不会执行任何操作。更安全。
用户回答后,再收集一个关于模型选择的问题:
- 模型(单选,标题:
"Model"):Sonnet (Recommended)— 成本与质量均衡,适用于大多数审计的默认选项Opus— 推理能力最强,成本最高;适合内容密集或含糊不清的文档Haiku— 成本最低、速度最快;适合检查文档是否便于 Agent 使用较小模型Mixed comparison— 将 Agent 分配到 Opus、Sonnet 和 Haiku 上,以比较文档质量随模型规模的变化。适合评估“我的文档对较弱的模型是否也足够完善?”
通过 model 参数,将选定的模型传递给每次 Agent 调用。如果选择 Mixed,将 N 个 Agent 大致均分到 3 个模型上(按槽位索引轮流分配),并在追踪记录和报告中记录每个 Agent 使用的模型。
用户回答后,你将获得:depth(N)、languages[]、personas[]、exec_mode、model。
如果 exec_mode = "Allow Bash",则使用 AskUserQuestion 追问凭据:
- 凭据(单选,标题:
"Credentials"):Auto-discover (Recommended)— 技能会检查用户的环境变量、常见的点文件和凭据管理器;只有在没有找到凭据时才会提示用户粘贴。最适合重复使用,以及由其他操作者运行审计的情况。None — let agents block (friction test)— 让 Agent 遇到凭据障碍,并将其计为设置摩擦。最适合纯文档审计。Paste manually— 由你直接粘贴密钥;技能会将其注入环境。适用于尚未在本地保存密钥的情况。
如果用户选择 Auto-discover,请在继续之前运行下面的步骤 2.5。如果选择 Paste manually(或自动发现时未找到凭据),AskUserQuestion 会询问凭据的值,而不是名称。随后,技能会使用通用且与产品无关的名称将凭据写入每个工作区的 .env:
- 主要凭据 →
API_KEY - 次要凭据(例如项目/组织 ID)→
PROJECT_ID - 第三项凭据(例如 webhook 密钥)→
SECRET
不要使用产品专属名称,例如 BROWSERBASE_API_KEY、EXA_API_KEY、STRIPE_SECRET_KEY。这些名称会引导 Agent——它们在环境变量中看到 BROWSERBASE_API_KEY 后,就可能不再阅读文档来确认 SDK 实际要求的环境变量名称。使用通用名称可以迫使它们:
- 阅读文档,找出产品实际使用的环境变量名称(例如
BROWSERBASE_API_KEY)。 - 将通用的
API_KEY值映射为 SDK 所需的形式——通过重新导出环境变量(export BROWSERBASE_API_KEY=$API_KEY),或在代码中直接传入(new Browserbase({ apiKey: process.env.API_KEY }))。
如果 Agent 无法找出映射方式,这就表明文档质量存在问题——文档没有清楚说明凭据名称。
步骤 2.5 — 凭据自动发现(仅当用户选择 Auto-discover 时)
运行分层查找。**在首次找到可用候选项的层级立即停止。**绝不要在聊天中打印凭据值——只显示名称和来源路径。用户按名称选择;技能会在内部将名称映射到值,再写入工作区 .env。
从目标 URL/仓库推导产品 slug,以优先匹配相关项。例如,https://docs.browserbase.com → slug browserbase。对候选项排序时,使用不区分大小写的小写子串匹配。
第 1 层——已导出的环境变量(免费,无副作用):
printenv | grep -iE '^[A-Z][A-Z0-9_]*_(API_KEY|TOKEN|SECRET|KEY)=' | cut -d= -f1
此操作只返回名称。如果任何名称包含产品 slug,它们就是首选候选项。
第 2 层——有限的点文件扫描(硬编码的短列表,不是递归 grep):
grep -hE '^[[:space:]]*export[[:space:]]+[A-Z][A-Z0-9_]*_(API_KEY|TOKEN|SECRET|KEY)=' \
~/.zshrc ~/.bashrc ~/.bash_profile ~/.zprofile ~/.env ./.env ./.envrc 2>/dev/null \
| sed -E 's/^[[:space:]]*export[[:space:]]+([A-Z0-9_]+)=.*/\1/' \
| sort -u
允许扫描的文件:~/.zshrc、~/.bashrc、~/.bash_profile、~/.zprofile、~/.env、./.env、./.envrc。**不要扩展此列表。不要递归扫描。不要扫描 ~/Library、~/.config/、~/Documents 等。**这就是完整的允许列表;其他任何内容都超出范围,可能泄露无关机密。
对于每个匹配项,记录 (NAME, source_path)。延迟读取值——只有在用户确认选择后,才对特定源文件重新执行 grep,查找该确切名称。
第 3 层——凭据管理器(仅当 op 或 security 在 PATH 中,且第 1 至 2 层没有找到合适匹配项时):
- 1Password CLI:除非
op account list以 0 退出(即用户已登录),否则跳过。不要在技能内触发交互式身份验证流程。 - macOS 钥匙串:
security find-generic-password -l "<expected-name>" -w——用最可能的名称尝试一次(例如BROWSERBASE_API_KEY);静默失败表示未存储。
如果凭据管理器找到匹配项,像第 1 至 2 层那样将其列为候选项。
**第 4 层——回退为粘贴:**如果以上所有层都没有找到候选项,则进入第 2 步中描述的手动粘贴流程。
**向用户展示候选项。**完成第 1 至 3 层后:
- 如果恰好有 1 个候选项,且其名称包含产品 slug → 静默使用。在聊天中记录一行确认:
Using BROWSERBASE_API_KEY from ~/.zshrc.(仅名称和来源——绝不包含值。) - 如果有多个候选项,使用 AskUserQuestion(单选,标题:
"Use which credential?"),最多提供 4 个选项:- 每个首选候选项对应一个选项,格式为
<NAME> (from <source>) - 另加一个
Paste manually instead选项,供用户选择其他方式 - 如果候选项超过 3 个,显示按 slug 相关性排序后的前 3 个,并添加一个
Show all选项,选择后重新询问其余候选项。
- 每个首选候选项对应一个选项,格式为
- 如果没有候选项 → 进入第 4 层(粘贴)。
**读取值。**用户确认选择后(或系统已自动选定后),读取该值:
- 第 1 层:
printenv <NAME>(捕获 stdout,不要回显)。 - 第 2 层:在特定源文件中重新 grep,查找确切的
export <NAME>=行并解析 RHS,去掉外围引号。 - 第 3 层:
op read "op://<vault>/<item>/<field>"或security find-generic-password -l <NAME> -w。
使用与粘贴流程相同的通用名称(API_KEY、PROJECT_ID、SECRET),将值写入每个 Agent 的工作区 .env 文件——参见第 2 步。发现层位于注入操作之前;下游行为(通用名称、Agent 必须阅读文档来完成映射)保持不变。
编排器保留的凭据。写入每个 Agent 的 .env 文件后,编排器会保留原始的产品专用名称 → 值(例如 BROWSERBASE_API_KEY),供自身在第 6/6.5/8 步中执行后续验证工作使用——例如调用产品 API 并通过 curl 确认 Agent 报告的会话 ID 确实可解析,或获取会话元数据以补充报告。编排器可以用 printenv 读取这些值(无需存储到任何位置——父 shell 已经有这些值,因为 auto-discover 会从那里加载它们)。
这样设计是不对称的,这是有意为之:子 Agent 只能看到通用的 API_KEY / PROJECT_ID / SECRET,这样文档质量测试才能保持客观(它们必须阅读文档才能发现实际的变量名)。协调器不在审计范围内,因此可以自由使用实际名称进行验证。
此技能必须遵守的隐私保障:
- 绝不将凭据值写入聊天输出、跟踪记录、报告或各 Agent 工作区
.env以外的任何文件。 - 绝不使用特定于产品的名称,将该值重新导出到子 Agent的工作区。子 Agent 只能看到通用名称。
- 将值视为不透明字符串——不要记录长度、前缀或指纹。
- HTML 报告会记录是否发生了自动发现(以及使用了哪个名称),但绝不记录该值。
第 3 步 — 安全检查
如果 exec_mode = "Allow Bash",在启动子 Agent 前向聊天中打印一条简短警告:"Agent 可能会在这台机器上运行真实的 shell 命令(npm install、curl、pip install、git clone)。请确保你当前所在的目录适合让 Agent 修改。5 秒后继续,或按 Ctrl-C 中止。" — 然后继续。
不要运行 sleep——打印后直接继续。用户会在 Agent 开始工作前看到警告。
第 4 步 — 生成简短提示词(不含清单)
对于 N 个变体中的每一个,生成一个 (persona, language, prompt) 元组。提示词为一到两句话,说明抽象目标和语言。不要包含子清单,也不要规定具体步骤。
模板:
{persona_prefix} {product}'s getting-started guide using {language}.{persona_tail} You've completed it when you've done whatever the guide treats as the primary successful outcome.
{persona_tail} 对大多数 persona 都为空。Skeptical persona 使用它来添加“指出任何问题”的指导,作为独立句子(前面带一个空格),这样前缀句子仍然符合语法。有关每种 persona 的完整前缀/尾部内容,请参阅 references/prompt-variants.md。
示例(以 Acme 为占位符——替换为用户提供的产品名称):
- Pragmatic × TypeScript → "浏览 Acme 的入门指南,然后使用 TypeScript (Node.js) 按指南操作。当你完成指南所设定的主要成功目标时,即表示任务完成。"
- Thorough × Python → "阅读 Acme 的入门指南,然后使用 Python 按指南操作。当你完成指南所设定的主要成功目标时,即表示任务完成。"
- Skeptical × Shell → "仅使用 bash/curl 按 Acme 的入门指南操作。过程中请指出文档中任何看起来有误或不清楚的内容。当你完成指南所设定的主要成功目标时,即表示任务完成。"
不会告知子 Agent 成功目标是什么——它们必须阅读文档才能弄清楚。重点就在这里:如果文档写得好,就会清楚地传达这一点。如果文档写得不好,Agent 就不知道何时算完成,这本身就是一项发现。
阅读 references/prompt-variants.md,了解 persona 前缀库。对 persona × 语言进行笛卡尔积组合,截取前 N 个。如果组合数量少于 N,就稍微变换前缀措辞后重复。
绝不要将文档内容粘贴到提示词中。
步骤 5 — 并行启动 N 个子 Agent
阅读 references/subagent-brief.md,了解每个子 Agent 收到的完整任务说明。其中告知他们:
- 你是一名正在处理真实任务的真实开发者
- 使用真实工具(
WebFetch、Bash(若允许)、Write) - 如果需要凭据,通过明确的暂停并询问消息向用户索取(该技能会将此记录为阻碍)
- 最后返回结构化跟踪记录,包含工具调用、错误、耗时估计和完成状态
对于每个变体,调用 Agent 工具(subagent_type: general-purpose)。按照用户的选择传入 model: "opus" | "sonnet" | "haiku"。对于 Mixed,按确定性顺序在 N 个槽位间轮换模型(Agent 1 → opus,Agent 2 → sonnet,Agent 3 → haiku,Agent 4 → opus,……),并在每个 Agent 的报告行中记录分配的模型。
在同一条消息中发起全部 N 次调用,使其并行运行。
子 Agent 的提示词 = 任务说明 + 简短任务。任务说明会通过 exec_mode 传递,让子 Agent 知道是否可以使用 Bash。
等待所有 N 个 Agent 返回后,再继续步骤 6。 当 Agent 在后台运行时,完成通知会逐个到达,很容易漏数。维护一个简单的内存计数,记录已返回和已启动的数量;最后一个 Agent 报告返回时,在聊天中明确打印一条里程碑消息:“全部 N 个 Agent 均已返回 — 正在开始解析跟踪记录。” 在打印该消息之前,不要开始步骤 6。如果用户在执行过程中询问“Agent 还在运行吗?”,请根据计数器直接回答当前的 <已返回数>/<已启动数>,不要重新统计之前的聊天记录。
使用协调者凭据验证 Agent 的声明。 评分前,如果步骤 2.5 保留了特定产品的凭据,协调者可以抽查子 Agent 的声明(例如,使用 curl -H "X-BB-API-Key: $BROWSERBASE_API_KEY" https://api.browserbase.com/v1/sessions/<id> 确认会话 ID)。无法确认的 ID 可作为 Agent 可能捏造信息的证据。报告中绝不要包含凭据标头,只需写明验证结果(已确认/未确认)。
步骤 6 — 解析结构化跟踪记录并保留完整文字内容
每个子 Agent 会在同一条回复中返回两项内容:
- 末尾的 fenced JSON 跟踪记录(结构化自述)。
- 此前的全部文字内容——推理、工具输出,以及 Agent 实际执行的操作。
两者都要保留。 提取 JSON 后不要丢弃文字内容。文字内容有助于发现 JSON 自述遗漏的问题。
使用以下正则表达式提取 JSON:/```json\s*(\{[\s\S]*?\})\s*```\s*$/。将格式错误或缺失的情况标记为 errored,并附上 raw_tail。如果超过 50% 的记录出错,请发出警告并提供重试选项。
根据 JSON 计算总体数据:
- 入门流程成功率 =
onboarding_status = "completed"的 Agent 占比。 - 文档承诺匹配率 =
docs_promise_met = true的 Agent 占比。
步骤 6.25 — 标注每次 WebFetch 的 URL 来源(内嵌在追踪记录中)
子 Agent 无法搜索——它们会根据训练数据中的先验信息猜测 URL。报告必须显示每次 WebFetch 调用的 URL 来源,并将其呈现为追踪记录中紧邻工具输入块下方的一行小号淡色文字。不要将其作为通用说明放在报告顶部——只有内嵌在对应调用旁边,读者才能将其与具体调用关联起来。
将每个 WebFetch URL 归为以下四种来源类别之一,并使用对应的标签和颜色呈现:
TRAINING PRIOR(紫色)——URL 是根据训练数据猜测的(产品名称加上常见文档站点惯例,例如/introduction、/quickstart、/sdk/{lang})。通常出现在前 1–2 次 WebFetch 调用中。FROM LLMS.TXT(蓝色)——URL 出现在同一追踪记录中之前获取的llms.txt的输出里。FROM PREV PAGE(绿色)——URL 列在同一追踪记录中之前的 WebFetch 或 Bash 工具调用输出里。GUESS · 404(琥珀色)——URL 是猜测出来的,但返回了 404——这是评估文档质量时最值得关注的类别(按照惯例,这个 URL 本应存在,但实际上不存在)。
分类启发式规则:
- 如果同一追踪记录中此前成功调用过
llms.txt的 WebFetch,且其输出提及了此 URL →FROM LLMS.TXT - 否则,如果同一追踪记录中此前任何 WebFetch/Bash 输出提及了此确切 URL →
FROM PREV PAGE - 否则,如果后续的 tool_result 中包含
error: true,且错误内容为 404 →GUESS · 404 - 否则 →
TRAINING PRIOR
评分解读:
- 大量
TRAINING PRIOR且调用成功 = 产品在训练数据中的呈现度较高(占得先机)。 - 大量
GUESS · 404= URL 分类与常见惯例不一致 → 这是关于文档可发现性的真实发现。 - 在
GUESS · 404之后频繁出现FROM LLMS.TXT=llms.txt正在承担文档的可发现性。请在调查结果中明确说明这一贡献。
步骤 6.5 — 跨 Agent 叙述审查(关键)
评分前,重新阅读每个 Agent 的完整叙述。JSON 追踪记录是 Agent 的自我报告——如果 Agent 臆造了错误的包名,它在自己的追踪记录中也会正确地描述这个错误。真相在工具输出和叙述中。
在 N 份记录中检查以下模式:
-
趋同错误。 是否有多个 Agent 尝试了相同的错误做法?错误的 npm 包名(例如,
exa而非exa-js)、错误的端点、错误的环境变量、错误的导入方式?如果 3/3 个 Agent 都用了错误的包名,即便每个 Agent 都“完成”了任务,这仍是文档质量灾难。Agent 不会凭空编造出相同的错误答案——相同的训练数据残留表明,文档没有纠正模型的错误先验。 -
幻觉产物。 将每个 Agent 声称的
primary_outcome_achieved与其工具输出实际显示的内容进行比较。如果它们声称“打印了标题”,但 Bash 输出中没有任何获取标题的工具调用,那就是在编造。文档很可能不够清晰,导致 Agent 只是按模式匹配,而没有认真阅读。 -
结果不一致。 如果 3 个 Agent 描述了 3 种不同的“成功”终态,说明文档没有明确界定成功的标准。
-
未说明的变通做法。 Agent 是否自行修补了问题(缺少
await、环境变量名错误、未记录的必填参数),而人工复制粘贴的人不会这么做?请标记这些问题——它们是只能从叙述中发现的隐性 DX 成本。 -
工具输出与叙述相矛盾。 有时 Agent 声称“成功了”,但 Bash 调用的 stderr 却表明结果并非如此,而 Agent 没有注意到。在叙述的工具输出中搜索
error、404、401、deprecated、warning。
撰写一段 3–5 句的叙述审查摘要,并在最终报告中醒目呈现。这往往能揭示整个审计中价值最高的发现。
第 7 步 — 为 Arena 的 5 个维度打分
阅读 references/evaluation-rubric.md,了解完整标准。根据汇总证据打出 0–100 分。
引导成功率是主要的合理性检查。 有关具体的分数上限档位,请参阅 references/evaluation-rubric.md § 0——完成率低于 50% 时,无论其他证据如何,每个维度的分数上限均为 55。
- 设置阻力(25%) — 凭据提示、身份验证重试、安装错误。“设置”阶段的失败会造成重大扣分。
- 速度(20%) — 总耗时、首次获得可运行代码所需时间。
- 效率(20%) —
completed_subtasks/tool_calls总数的比率、无效调用。 - 错误恢复(15%) — 错误是否阻碍引导完成,还是 Agent 绕过了问题?
- 文档质量(20%) — 文档是否提供了 Agent 所需的信息?
加权总分 → 字母等级(90+ 为 A,75+ 为 B,60+ 为 C,45+ 为 D,否则为 F)。
第 8 步 — 综合调查结果
生成以下内容:
- 执行摘要 — 2–3 句话。开头写出等级和最主要的阻碍。
- 进展顺利之处 — 3–5 个要点。
- 未达预期之处 — 3–5 个要点。
- 常见阻碍模式 — 至少 2 个 Agent 遇到的问题(高价值修复项)。
- 会话时间线 — 汇总各 Agent 的阶段(研究、设置、执行、验证)及大致耗时。
- 工具调用明细 — 按工具类型汇总所有 Agent 的调用总数。
- 建议修复项 — 按优先级排序;每项均指出文档章节或 SDK 方法,并给出具体改写方案。
第 9 步 — 渲染 HTML 报告
阅读 assets/report-template.html。填充占位符:
{{TITLE}}、{{TARGET_REF}}、{{META}}、{{GRADE_LETTER}}、{{GRADE_CLASS}}、{{OVERALL_SCORE}}、{{AGENT_COUNT}}、{{COMPLETED_COUNT}}、{{PARTIAL_COUNT}}、{{STUCK_COUNT}}、{{BLOCKED_COUNT}}、{{ERRORED_COUNT}}、{{NARRATIVE_REVIEW_SECTION}}(参见下方格式)、{{EXEC_SUMMARY}}、{{WENT_WELL_ITEMS}}、{{DIDNT_GO_WELL_ITEMS}}、{{TIMELINE_SECTION}}、{{TOOL_BREAKDOWN_SECTION}}、{{METRICS_GRID}}、{{PATTERNS_SECTION}}、{{FIXES_LIST}}、{{AGENT_RESULTS_TABLE}}(一览摘要表——参见下方格式)、{{AGENT_TRACES_SECTION}}(每个 Agent 的完整可折叠追踪卡片——参见下方格式)。
状态计数映射。 5 个状态计数必须恰好涵盖所有 Agent:每个 Agent 只能计入 {{COMPLETED_COUNT}}(onboarding_status=completed)、{{PARTIAL_COUNT}}(partial)、{{STUCK_COUNT}}(stuck)、{{BLOCKED_COUNT}}(blocked-on-credentials)或 {{ERRORED_COUNT}}(解析器失败的追踪)之一。5 个子计数之和必须等于 {{AGENT_COUNT}}。
渲染报告中的章节顺序(模板会强制执行此顺序——不要调整):
- 评分卡 + Agent 状态统计网格
- 叙述性评审(
{{NARRATIVE_REVIEW_SECTION}}) - 执行摘要
- 建议修复项
- Agent 的反馈(进展顺利之处 / 未达预期之处)
- 常见阻碍模式(
{{PATTERNS_SECTION}}) - 定量指标
- 工具调用明细
- 会话时间线
- 各 Agent 的运行记录(结果表 + 追踪)
理由:先呈现观点,再展示数据。读者需要先了解结论(叙述性评审 + 执行摘要)和可执行的修复清单,然后再查看指标或时间线。参考类章节(时间线、工具调用明细)放在靠后的位置,用于验证,而非铺陈背景。
{{NARRATIVE_REVIEW_SECTION}} 格式。 使用 <div class="narrative-review">,其中包含 <div class="label">Narrative Review</div> 和 <div class="body">…</div>;正文为第 6.5 步中的 3–5 句跨 Agent 总结。这是审查中最有价值的发现——文字要精炼,并以最重要的观察开头。如果第 6.5 步没有得出值得注意的跨 Agent 发现,则在正文中写一行:No cross-agent patterns of note — agents converged on the docs' intended path with minor individual variation. 不要省略此章节。
5 个维度的评分仍会计算(它们用于得出总体加权评分和字母等级),但不要渲染按维度拆分的部分——它只会增加视觉负担,而无法为读者提供叙事评审和推荐修复之外的可操作信息。将维度评分保留为内部使用。
{{AGENT_RESULTS_TABLE}} 格式。 一个 <table class="agent-results-table">,紧接在每个 Agent 卡片上方渲染。每个 Agent 一行,包含以下列(按顺序):
- # —— 槽位索引(从 1 开始),右对齐,等宽字体。
- Persona × Language —— 例如
Standard · TypeScript。使用该 Agent 的 JSON trace 中的值。 - Model —— 仅在
model = Mixed时渲染此列(否则完全省略该列;单一模型已在头部{{META}}行中注明)。 - Status —— 一个
<span class="status-pill {{status}}">,与 JSON 中的onboarding_status匹配(completed、partial、stuck、blocked-on-credentials)。将errored(解析失败的 trace)映射到其专属药丸标签。 - Tool calls —— 该 Agent 的
tool_calls[]数组中所有count的总和。右对齐,等宽字体。 - Time —— JSON 中的
wall_time_estimate_sec,格式为92s(若 ≥120s 则为2m 14s)。右对齐,等宽字体。
理由:下方的卡片虽然详细,但需要逐个展开。表格提供一屏之内的对比,让读者在深入查看之前就能发现异常值(耗时 3 倍的 Agent、工具调用次数 2 倍的 Agent)。
{{AGENT_TRACES_SECTION}} 格式。 每个 Agent 一个 <details class="trace-card">。每张卡片的摘要行必须包含所用的模型(例如 <span class="chip">opus</span>),以及 persona/language 标签。卡片展开后显示:
-
事件日志(来自
detailed_trace) —— 以紧凑的 Arena 风格渲染:等宽字体行,带颜色编码的方括号标签,极简装饰,无圆点或时间线。每行是一行文本;输入/输出块以缩进的<pre>块形式直接显示在其工具调用下方(始终可见,而非点击展开——用户希望快速浏览流程)。每个日志中的第一个事件是发送给该子 Agent 的提示词,以金色
[PROMPT]标签在时间戳[setup]处渲染。完整提示词藏在一个小型点击展开按钮之后(这是流中唯一可折叠的内容——提示词很长,用户并不总是需要它们)。视觉结构:
[setup] [PROMPT] Task prompt sent to subagent [▸ Show full prompt] [+0ms] [MILESTONE] agent_started [+100ms] [THOUGHT] I'll start by discovering the docs. [+1.2s] [TOOL_USE #1] WebFetch Input: { "url": "...", "prompt": "..." } [+3.4s] [TOOL_RESULT #1] Output: # Example Product ... [+4.5s] [TOOL_USE #2] Bash Input: { "command": "npm install ...", "description": "..." } [+9.2s] [TOOL_RESULT #2] Output: added 12 packages ... [+12s] [ERROR] install · PEP 668 blocked · recovered [+45s] [RESULT ✓] Session created, task done.CSS 约定(紧凑等宽字体,浅色背景):
- 容器:
.trace-timeline—— 浅灰色背景(#fafaf9),全程等宽字体,0.78rem 字号,可滚动(最大 640px) - 每行:无网格,仅内联文本。
[time](柔和色)+[LABEL](彩色,加粗)+ 正文内容 - 按类型区分的方括号标签颜色:
[PROMPT]:金色[MILESTONE]:蓝色[THOUGHT]:紫色(正文也使用斜体 + 柔和色)[TOOL USE]:橙色(#ff6b35或报告使用的任何品牌强调色)[TOOL RESULT]:绿色(若出错则为红色)[ERROR]:红色(正文也为红色)[RESULT ✓]:绿色(正文为绿色,加粗)
- 工具名:橙色 + 半粗体
- 输入/输出:以内联方式显示为
.trace-io块,带彩色左边框(输入为橙色,输出为绿色,错误为红色)。<pre>块显示完整的工具输入 JSON——绝不缩写。对于WebFetch而言,这意味着要同时显示url和prompt参数——prompt是 Agent 要求将页面内容提炼成的目标,是理解 Agent 意图的关键信号。如果输入很大,请在相关字符串内用…截断值(而非结构)。 - 提示词块是例外——默认折叠(提示词很长)。其摘要以一个小型“▸ Show full prompt”按钮的形式可见。
- 绝不恢复为深色背景——会与报告其余部分冲突。
- 无网格、无圆点、无垂直线——保持文本流。 主 Agent 会保留每个子 Agent 的提示词。 在第 5 步启动 Agent 时,按 Agent 索引缓存完整的提示词文本,以便在生成报告时检索。未来的你(负责渲染)需要查明发送给每个 Agent 的内容。
- 容器:
-
Agent 的最终文字摘要 — 作为次要的可滚动文本框保留在事件日志下方(这是自述;追踪记录才是事实依据)。
-
工具调用摘要表格(名称、次数、用途)— 便于快速查阅
-
证据(会话 ID、stdout 等)
-
遇到的问题
-
错误(如有)
-
积极表现
事件日志是核心内容——它让用户获得与 Arena 追踪视图相同的体验:“我能清楚看到 Agent 做了什么、想了什么”。文字摘要是叙述性回顾,但追踪记录才是主要依据。
每个 Agent 的结果表格必须在 model = Mixed 时包含 Model 列,方便一目了然地比较不同模型。若只使用了一个模型,则在标题的 {{META}} 行中提及一次即可。
对所有用户提供的字符串进行 HTML 转义。文档引用放在 <code> 或 <blockquote> 中。
所有 URL 都必须可点击。 报告中引用以下内容时:
- 相对文档路径(例如
/quickstart)→ 按如下格式包装为<a class="doc-link" href="{TARGET_BASE_URL}{path}" target="_blank" rel="noopener"><code>{path}</code></a>,其中{TARGET_BASE_URL}是审计目标的源地址(例如https://docs.example.com) - 会话/资源 ID(例如
f0ec58cc)→ 链接到完整资源 URL(例如https://app.example.com/sessions/{full-id}),并添加↗后缀表示外部链接 - 正文中出现的完整 URL → 已可链接,只需确保用
<a>包装,而不是仅放在<code>中
这些链接类的 CSS:
a.doc-link { text-decoration: none; color: inherit; }
a.doc-link:hover code { background: #fff4ef; border-color: var(--brand); color: var(--brand); }
a.session-link { color: #166534; text-decoration: none; }
a.session-link:hover { text-decoration: underline; }
理由:如果用户无法点击核实,404 发现就毫无用处。如果用户无法点击进入录制内容,会话 ID 也毫无用处。报告中的每个类似 URL 的字符串都应该只需点击一次即可核实。
第 10 步 — 保存并展示
保存到 ./agent-experience-<slug>-<timestamp>.html(当前工作目录)。Slug = 目标名称的小写形式,将非字母数字字符替换为 -。Timestamp = YYYYMMDD-HHMMSS。
在聊天中打印:
- 等级、总分,以及最重要的一项修复措施。
- 数量摘要:N 个 Agent、M 个已完成、K 个受阻。
- 完整文件路径。
如果允许使用 exec_mode,则在 macOS 上通过 Bash: open <path> 打开;否则仅打印路径。
第 11 步 — 清理工作区
如果 exec_mode = "Allow Bash" 且你在 ./dx-audit-tmp/(或类似目录)下创建了各 Agent 的子目录,则在渲染报告后删除该目录树:
rm -rf ./dx-audit-tmp/
理由:Agent 会安装 node_modules、venv、Go 模块等——每个 Agent 通常会占用数十 MB。保留这些内容会污染用户的代码库并浪费磁盘空间。
例外: 如果子 Agent 的 onboarding_status 为 stuck,或其追踪记录标记为 errored(JSON 解析失败),则保留该 Agent 的子目录,并在聊天中说明——用户可能需要检查失败状态。只删除已完成或受凭据限制的 Agent 的目录。
如果 exec_mode = "Draft-only",无需清理(除报告外没有文件写入)。
参考文件
references/evaluation-rubric.md— 5 个维度的评分标准(Arena 方法论)。references/prompt-variants.md— Persona 前缀库和核心任务启发式规则。references/subagent-brief.md— 原样任务说明和追踪 JSON 架构。
资源
assets/report-template.html— 带占位符的 HTML 模板,最终报告将以此为基础生成。
约束
- 切勿将目标文档粘贴到子 Agent 的提示词中——这正是这样做的全部意义。
exec_mode = Draft-only必须在子 Agent 说明中禁用 Bash 执行。- 切勿测试用户未明确指定的目标。
- 切勿在面向用户的问题中预先填入产品、URL 或公司。 忽略环境信号(电子邮件域名、git 远程地址、仓库名称、记忆)。从头开始——操作者可能正在审核任何对象。
- 如果子 Agent 索要凭据,这会计入评分中的阻碍——不要通过自动提供凭据来“帮助”它。让 Agent 碰壁并记录下来。
- 除 HTML 报告外,切勿写入 cwd 以外的文件。