Home Projects Blog Resume Contact 中文
Back to list
2026年7月5日 2,113 words 5 min read

00:我为什么做 RunLens:把 Agent 放进可验证的运行链路

从一份用户反馈 CSV 分析任务出发,说明 RunLens 为什么把模型调用扩展成一条可执行、可限制、可恢复、可验证的 Agent 运行链路。

#RunLens#AI Agent#项目复盘#Agent Runtime

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 工程模块继续拆解:

  1. 整体架构:业务插件和 Agent Runtime 怎样分工。
  2. 完整链路:一次 Run 从 API 走到最终产物。
  3. Agent 工作方式:Skill、Prompt、Plan 和 Tool 怎样配合。
  4. 工具与安全:模型动作怎样经过 Schema、权限和 Hook。
  5. 可靠收束:状态机、终止条件和失败恢复。
  6. 结果可信:Artifact Contract 和 Evidence Validation。
  7. 过程解释:Events、Trace、Metrics 和 Manifest。
  8. 业务扩展:不同插件怎样共享 Runtime。
  9. 工程复盘:测试、部署、边界和后续方向。

小结

RunLens 从一个反馈分析任务开始,逐渐形成了一套围绕 Agent Run 的工程底座。

模型负责理解目标和选择动作;Runtime 负责组织状态、执行工具、控制权限、处理失败、验证结果和记录过程。

下一篇先看最重要的架构选择:我怎样把具体业务插件和通用 Agent Runtime 分开,让 Feedback Analysis 和 File Summary 能够共享同一套执行底座。