查看一次 Agent 运行
pnpm tutorial:dev v3-04 --locale zh源码examples/tutorials/v3-04-declared-action/第一条 Todo Agent 路径已经可以工作。界面上能看到它新增了任务、勾选了记录,但“动作成功了”只是结果,不足以解释过程:模型当时看到了哪些任务,拿到了哪些工具,为什么选择其中一个,又为什么没有选择另一个。
本章打开 Pling 的只读运行检查器。它展示一次会话中每次模型调用真正收到的系统提示词、工具清单和 messages,以及请求发生时的页面快照。
本章不增加页面能力,也不改变 Todo 业务。目标只有一项:让读者在后续学习和排障时,能直接观察 Agent 的运行,而不是根据最终答复猜测。
为什么需要检查请求
同一种失败可能来自完全不同的原因。模型没有找到动作,可能是控件没有声明;模型选错了动作,可能是说明或区域不够清楚;动作执行后没有效果,可能是目标解析、业务前置条件或后置检查没有满足。只改系统提示词无法区分这些情况。
浏览器开发者工具能看到网络请求,却不一定能方便地把一次请求与当时的页面状态对应起来。Pling 的检查器保存的是运行内部已经使用的那一份数据,因此可以直接回答三个问题:
- 这次调用时,页面向模型暴露了什么?
- 请求里实际发送了哪些规则、工具和对话消息?
- 模型回复了什么,下一步又基于什么继续?
检查器是开发工具,不是调试器替代品。它不执行动作,不修改页面,也不能证明业务一定成功。
打开检查器
在助手入口上显式开启 debug:
<AgentDock
title="待办助手"
:debug="{ maxCalls: 8 }"
/>maxCalls 限制内存中保留的模型调用数。省略时默认保留最近 20 次;maxCalls: 8 适合教程和普通调试。
使用默认上限时,直接写不带冒号的属性:
<AgentDock debug />它等价于 :debug="true"。只写 :debug、不给表达式不是合法的 Vue 模板语法。
这个选项默认关闭。它会把页面投影、对话内容和模型请求放进当前聊天界面,任何能打开该界面的人都能看到。检查器不是隐私边界,生产环境不要默认开启;需要展示诊断入口时,应由构建开关、角色或环境决定。
进入运行记录
启动本章示例,打开助手,先发送一条真实任务。然后:
- 打开助手顶部的“运行”(英文界面为 Activity)。
- 在“执行记录”标题旁选择“诊断信息”。
- 展开最近一次模型调用。
页面投影可以立即查看。模型调用、messages、tools 和响应只有在至少完成一次请求后才会出现。
界面同时保留两个时间视角:
- 当前页面投影:打开检查器这一刻,注册表里有哪些区域、动作、不可用动作、记录和状态;
- 每次调用的页面快照:模型当时看到的那一份页面。
页面在动作后会继续变化,因此排障时通常应看“请求时快照”,而不是只看当前投影。
一次请求由哪几层组成
检查器把一次模型调用拆成几个部分。它们来自不同位置,生命周期也不同。
system:稳定规则与当前页面
每条 system 消息都由两部分组成:稳定的 Agent 规则,以及根据当前快照重新生成的页面上下文。页面上下文可能包含页面身份、区域树、可用动作、记录、页面反馈、被隐藏的内容和显式暴露的状态。
应用提示词与回答语言
稳定的操作规则由 Pling 提供。应用可以再补充一段简短的身份说明。本章的 Todo 示例把它和 createPling 放在一起:
const pling = createPling({
agent: {
config: {
systemPrompt: "You are the assistant for a small Todo app. Keep answers short.",
},
},
});Pling 会把这段说明追加到操作规则之后,放在 ## This application 标题下,而不是替换操作规则。没有配置应用提示词时,这一段不会出现。
回答语言不由应用提示词决定。Pling 已经要求模型使用用户最近一条消息的语言。界面为中文时,运行时会再为本次请求附加中文回答约束;除非用户最近一条消息使用其他语言。把语言策略放在框架里,可以避免应用自己的提示词与界面或用户的要求相互矛盾。
换到其他应用时,应把这段文字换成该应用的身份和业务约束。所有权、审批策略和领域规则适合放在这里;动作 id 和逐个控件的操作步骤不适合。
下面是经过截取的示例,不是完整提示词:
## This application
You are the assistant for a small Todo app. Keep answers short.
## Page structure (regions)
- main "待办" (todo): 待办列表,以及新增待办的表单。; in viewport; actions 6/6
## Available actions on this page
- composer_text [type] (write, region: todo): 在这个输入框中填写一条新待办的内容。
- composer_submit [click] (write, region: todo): 把新待办输入框中的文字加入待办列表。
- toggle [record] (write, region: todo): 将“{record}”标记为已完成或未完成。
## Records on this page
- 1. t1: text 检查发布清单; status open
- 2. t2: text 预约设计评审; status open
- 3. t3: text 跟进客户; status completed这解释了前几项声明的去向:v-scope 进入区域树,v-tool 进入动作清单,v-record 进入记录部分。它们不是写进每一条用户消息,而是根据当前页面状态组装进本轮 system。
system 每轮重建。模型执行一个动作后,下一次请求会看到更新后的记录、可用动作和页面反馈。稳定规则不必重复拼接,变化部分也不会停留在旧快照。
tools:模型可以调用的函数
tools 是与 messages 并列的请求字段。每个工具包含名称、说明和参数 schema。检查器中的工具清单来自当前动作投影,而不是开发者手写的另一份定义。
同一类行内动作会被折叠。例如三个 toggle@t1、toggle@t2、toggle@t3 会投影成一个 toggle 工具,并增加必填的 record 参数。模型不需要在三个几乎相同的函数名之间猜。
工具清单与 system 中的动作文字描述的是同一组能力。两者用途不同:文字帮助模型理解页面,function schema 约束实际调用。
messages:真实组装的对话
messages 只保存会话历史,通常包括:
- 用户原话;
- 助手发起工具调用时的回复;
- 与每次调用 id 对应的工具回执;
- 助手此前的回答。
用户原话是一条 user 消息,不会把整份页面快照重复写进去。页面状态来自本轮 system,因此同一段对话可以随着页面变化继续使用,而不需要不断在用户消息里追加 DOM 文本。
一个常见的中间调用大致如下:
[
{ "role": "user", "content": "把“预约设计评审”标记为完成。" },
{
"role": "assistant",
"content": "",
"toolCalls": [{ "id": "call_1", "name": "toggle", "arguments": { "record": "t2" } }]
},
{
"role": "tool",
"toolCallId": "call_1",
"name": "toggle",
"content": "工具执行结果与可观察的页面变化"
}
]实际字段与回执内容会比这个例子多。检查器展示的是发送给模型的版本,不是界面层的摘要。
response:这一轮的模型输出
响应部分显示模型返回的文本和工具调用。没有工具调用时,文本通常就是最终答复;有工具调用时,文本可能只是动手前的说明,真正的动作在 tool_calls 中。
读取顺序应当是:先看 response 决定了什么,再看下一次请求新增了什么工具回执,最后看页面和最终回答是否一致。
跟随一次多轮调用
新增一条待办通常不是一次模型请求。检查器里会看到类似下面的过程:
| 调用 | 请求中新增的内容 | 模型选择 |
|---|---|---|
| 1 | 用户要求新增任务 | composer_text |
| 2 | 上一步的工具回执 | composer_submit |
| 3 | 提交后的工具回执与更新快照 | 最终文字回答 |
每一步都有自己的请求时快照。第一次调用看不到提交按钮,因为输入框为空时按钮处于禁用状态;第二次调用发生时,输入已经写入,composer_submit 才出现在动作清单里。
完成已有待办通常更短:模型从记录中找到 t2,调用折叠后的 toggle,然后确认结果。随着动作声明和流程设计变得更复杂,调用数会变化。不要预设固定次数,应以实际 trace 为准。
对照阅读,而不是只看最后一条
检查器最适合回答三类问题:
动作没有出现
先看请求时的页面投影:动作是否已声明,是否因为禁用、不可见、被遮挡或业务前置条件而没有进入可用清单。当前页面有动作,不代表前一次请求时也有。
模型选了错误的动作
对照 system 中的区域路径、动作说明和记录字段,再看 tools 中名称与参数。两个语言相近的按钮如果没有清楚的区域或结果说明,模型只能依赖更弱的线索。
动作执行了,但页面没有变化
先看工具回执中的执行结果,再看 changed 或其他可观察证据,最后检查下一次请求的页面快照。原因可能在于目标元素、业务逻辑、异步更新,也可能在于改动根本没有暴露给模型。不要只根据助手的最终措辞判断。
边界
检查器当前有三条重要边界:
- 只读:不提供执行按钮,也不创建第二个 runtime;
- 有界:只在内存中保留最近若干次模型调用,清空会话时一并清除;
- 开发期:不替代服务端审计、计费、限额或长期观测。
模型调用记录会占用内存。页面处理敏感信息时,检查器也会显示实际出站内容;已经 token 化的值仍以代号显示,但页面投影和对话本身仍可能包含敏感上下文。是否允许打开它,应按环境决定。
运行并验证
从仓库根目录启动本章示例:
pnpm tutorial:dev v3-04 --locale zh打开:
http://127.0.0.1:5197/?lang=zh按下面顺序检查:
- 发送“把‘回复客户’加入待办”。
- 打开“运行”,再点“诊断信息”。
- 展开第一次调用。确认 system 中有“待办”区域和任务记录,tools 中有
composer_text。 - 展开第二次调用。确认 messages 里已有第一次工具调用的回执,tools 中出现了
composer_submit。 - 展开最后一次调用。确认模型基于更新后的页面给出最终答复。
- 再发送“把‘预约设计评审’标记为完成”,确认其中使用折叠后的
toggle工具与record参数。 - 清空会话,确认调用记录一起消失。
使用英文界面时,启动命令不加 --locale zh,打开 http://127.0.0.1:5197/。
常见问题
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 运行页没有“诊断信息” | debug 没有开启 | 在 <AgentDock> 上显式传入 :debug="..." |
| 只有页面投影,没有模型调用 | 还没有发送请求,或会话已清空 | 先完成一次任务再展开调用 |
| 看不到提交动作 | 请求时输入框为空,按钮处于禁用状态 | 对照下一次调用的页面快照 |
| tools 与动作清单数量不一致 | 行内动作被折叠 | 查看折叠工具的 record 参数与记录列表 |
| 敏感值没有还原 | 检查器展示的是出站内容 | 这是预期行为;调试不是隐私边界 |
| 旧调用消失 | 超过了 maxCalls 上限 | 调大上限,或在更小的复现中定位 |
下一步
现在可以看见模型实际收到的页面、工具和消息。接下来的问题不再是“它有没有工作”,而是怎样让业务操作更接近人的意图。
下一章会把“填写输入框”和“点击提交”合并成一个 add_task 动作,并为它声明参数、可用条件和成功判据。

