00:我为什么做 RunLens:把 Agent 放进可验证的运行链路
从一份用户反馈 CSV 分析任务出发,说明 RunLens 为什么把模型调用扩展成一条可执行、可限制、可恢复、可验证的 Agent 运行链路。
00:我为什么做 RunLens:把 Agent 放进可验证的运行链路
RunLens 最早来自一个很具体的需求:读取一份用户反馈 CSV,整理主要问题,再输出产品待办和洞察报告。
单看需求,它很像一次大模型分析。把数据放进 Prompt,让模型生成几段内容,演示很快就能跑起来。
进入实现阶段后,我发现重点逐渐转移到了模型外面。
模型需要先读到真实 CSV,后续结论要引用原始反馈。三个产物要真实写进工作区,文件结构还要满足约定。工具参数可能出错,Provider 可能临时失败,模型也可能提前宣布完成。一次 Run 结束以后,我还希望知道它调用过哪些工具、在哪一步失败、最终结果为什么被接受。
这些问题叠在一起,项目自然长出了一套运行时。
RunLens 关注的是怎样让一次 Agent 任务安全推进、可靠结束,并留下可以检查的结果与过程证据。

从一份反馈 CSV 开始
Feedback Analysis 是 RunLens 的第一条业务链路。
输入是一份结构化反馈数据,输出包括:
feedback_analysis.json:逐条反馈分析和分类结果。product_backlog.json:带证据 ID 的产品优先级待办。insight_report.md:面向产品负责人的洞察报告。
这三个文件之间存在明确关系。分析结果要来自 CSV,Backlog 要引用分析证据,最终报告要能够回到真实反馈。
如果只让模型返回一段文本,很多事情很难确认:
- 它是否真的读取了指定文件。
- 引用的 feedback_id 是否存在。
- Backlog 的优先级是否符合约定。
- Markdown 报告是否包含完整章节。
- 三个产物是否都已经落盘。
我希望交付结果具有清晰结构,也希望系统能够自己检查这些结构。
这让项目从“调用一次模型”走向了“运行一次任务”。
工具调用只是起点
给模型接入工具以后,它已经可以读取文件和写入产物。
接下来还会遇到一组运行时问题。
1. 工具参数需要明确契约
模型生成的参数来自自然语言推理。字段可能缺失,类型可能出错,文件名也可能偏离约定。
RunLens 为每个工具声明输入和输出 Schema。Handler 执行前先校验参数,执行后再校验返回值。错误会形成结构化 ToolResult,并作为下一轮 observation 交回模型。
2. 文件操作需要边界
模型能提出路径,实际文件访问由 Runtime 执行。
RunLens 把读取范围限制在 data/ 和当前 Run,把写入范围进一步收窄到当前工作区。.env、其他 Run 和工作区外路径会在 Handler 执行前被拦截。
3. 多步骤任务需要状态
反馈分析包含读取数据、生成分析、整理 Backlog、写报告四个阶段。
RunLens 为插件声明 Plan,并把 Plan 投影成 Todo。当前步骤决定这一轮可以使用哪些工具,也决定系统怎样判断进度。
4. 失败需要进入下一轮判断
一次参数错误通常还有修正空间。Provider 的 429 或连接失败也可能适合重试。
RunLens 会区分错误类型,记录恢复次数,并把可修正的信息交回 Agent Loop。连续重复调用、重复失败、超时和恢复耗尽则进入明确的终止路径。
5. 最终结果需要验证
模型返回 final answer 以后,Runtime 会进入 validating 状态。
Stop Hook 会继续检查文件、JSON、Markdown 和证据引用。所有成功条件满足后,Run 才会进入 completed。
工程问题集中在模型外面
把一次 Run 拆开,大致包含这些部分:
| 部分 | 负责的问题 |
|---|---|
| Plugin | 当前业务任务需要什么输入、工具和产物 |
| Skill | 这类任务应该怎样完成,能力边界在哪里 |
| Prompt | 本轮模型需要看到什么信息 |
| Plan | 当前任务按什么步骤推进 |
| Tool Executor | 模型提出的动作怎样执行 |
| Permission | 动作是否位于允许边界 |
| Recovery | 失败以后怎样继续 |
| Stop Validation | 结果是否达到交付条件 |
| Observability | 整个过程怎样被记录和解释 |
模型负责理解目标和选择下一步。Runtime 负责把这些决策放进确定的工程流程。
这套分工给了我一个很直接的项目主线:
模型提供动态判断,运行时提供稳定边界。
Prompt 可以提醒模型先读数据,Plan 可以限制当前步骤,Permission 可以限制文件范围,Stop Hook 可以检查最终产物。多层机制共同作用时,任务的可预期性会高很多。
我希望一次 Run 具备什么
RunLens 目前围绕一次 Run 组织能力。
每次运行都有独立 run_id 和工作区,输入、计划、Prompt、事件、指标和业务产物都保存在对应目录中。
一次完整 Run 需要具备五类特征。
1. 可执行
模型能够通过工具读取真实数据、生成结构化文件并查看当前工作区。
2. 可限制
工具白名单、路径权限、读写大小和 Plan Step 共同控制动作范围。
3. 可恢复
Provider 临时错误和工具参数错误进入不同恢复流程,恢复过程也会被记录。
4. 可验证
Artifact Contract 定义交付产物,Stop Hook 根据确定规则检查完整性、结构和证据。
5. 可解释
统一事件时间线记录 Run、LLM、Tool、Permission、Hook、Recovery 和 Artifact。Metrics 从事件聚合,Manifest 决定前端可以查看哪些文档。
这五类能力也构成后续系列的主要内容。
从业务插件走向通用 Runtime
Feedback Analysis 跑通以后,我增加了第二个 file_summary 插件。
它读取本地文本文件,分析文档结构,再生成 JSON 和 Markdown 摘要。业务输入、工具和产物都发生了变化,底层 Agent Loop、Permission、Plan、Hook、Events 和 Workspace 继续复用。
第二个插件验证了一件事:这套运行机制可以独立于反馈分析业务存在。
项目名称也随之从 FeedbackLens AI 调整为 RunLens。
新的命名关系更清楚:
RunLens
├─ 通用 Agent Runtime
├─ feedbacklens 插件
└─ file_summary 插件
Run 对应一次完整任务,Lens 对应运行过程的检查和观察。项目后续增加新的插件时,名称仍然能够覆盖整体能力。
RunLens 当前的设计主线
RunLens 可以用一条链路概括:
用户目标
→ 选择业务插件
→ 加载 Skill
→ 解析工具、权限和产物
→ 组装 Prompt 和 Plan
→ 模型选择下一步动作
→ Runtime 执行工具
→ 工具结果进入下一轮判断
→ 失败恢复或继续推进
→ Stop Hook 验证产物
→ 写入 Events、Metrics 和 Manifest
→ 返回可检查的结果
这条链路里既有模型参与的动态判断,也有 Runtime 执行的确定规则。
模型决策和工程约束分开
模型可以选择工具和生成参数,Schema、Permission、Plan 和 Hook 负责确定性检查。
业务声明和通用执行分开
插件描述具体任务,Runtime 提供稳定运行能力。增加新业务时,大部分执行机制可以继续复用。
结果和过程一起保存
业务产物用于交付,运行文件用于解释。一次 Run 既留下结果,也留下它怎样走到结果的证据。
这个系列准备怎样展开
后续文章会沿着一次 Run 和 Agent 工程模块继续拆解:
- 整体架构:业务插件和 Agent Runtime 怎样分工。
- 完整链路:一次 Run 从 API 走到最终产物。
- Agent 工作方式:Skill、Prompt、Plan 和 Tool 怎样配合。
- 工具与安全:模型动作怎样经过 Schema、权限和 Hook。
- 可靠收束:状态机、终止条件和失败恢复。
- 结果可信:Artifact Contract 和 Evidence Validation。
- 过程解释:Events、Trace、Metrics 和 Manifest。
- 业务扩展:不同插件怎样共享 Runtime。
- 工程复盘:测试、部署、边界和后续方向。
小结
RunLens 从一个反馈分析任务开始,逐渐形成了一套围绕 Agent Run 的工程底座。
模型负责理解目标和选择动作;Runtime 负责组织状态、执行工具、控制权限、处理失败、验证结果和记录过程。
下一篇先看最重要的架构选择:我怎样把具体业务插件和通用 Agent Runtime 分开,让 Feedback Analysis 和 File Summary 能够共享同一套执行底座。