首页 项目 博客 简历 联系 English
返回列表
2026年7月5日 约 1,872 字 预计 5 分钟读完

01:整体架构:为什么把业务插件和 Agent Runtime 分开

拆解 RunLens 的接口层、业务插件层与通用 Runtime,解释为什么业务能力应通过契约声明,而执行、权限、恢复和观测由统一底座承接。

#RunLens#插件架构#软件架构#Agent Runtime

01:整体架构:为什么把业务插件和 Agent Runtime 分开

上一篇从一份反馈 CSV 出发,介绍了 RunLens 想解决的问题:让一次 Agent 任务能够执行、限制、恢复、验证和解释。

沿着这条主线继续往下看,第一个架构选择是业务插件和 Agent Runtime 的分离。

Feedback Analysis 需要读取 CSV、提取证据、生成产品待办。File Summary 需要读取文本、分析标题结构、生成摘要。两类任务的输入和产物差异很大,运行过程却共享很多机制:模型循环、工具执行、权限、计划、恢复、验证和事件记录。

我把这两部分拆成业务声明层和通用执行层。

Plugin 描述这次任务需要什么,Runtime 负责让这次任务稳定地跑完。

从单一业务代码到通用执行底座

反馈分析的第一版很容易写成一条固定流程:

读取 CSV
→ 调用模型分析
→ 写 JSON
→ 写 Markdown

这种写法适合快速验证需求。随着工具、权限、重试、Plan 和产物检查逐渐加入,固定流程会承担越来越多通用职责。

如果后续再加入文档摘要、日志诊断、研究报告或代码审查,每条业务链路都需要重新实现一遍:

  • 模型客户端选择。
  • Tool Schema 转换。
  • 工具参数校验。
  • 文件权限判断。
  • 运行次数限制。
  • Provider 重试。
  • 任务状态记录。
  • 最终产物验证。
  • Events 和 Metrics。

这些能力和具体业务关系较弱,更适合沉到统一 Runtime。

业务代码保留直接相关的内容:输入、工具、任务步骤、产物和质量规则。

RunLens 的三层结构

当前后端可以分成三层。

层次主要职责典型代码
接口层接收请求、返回 Run 状态和文档app/api/
业务声明层声明任务输入、工具、Skill、Plan 和产物app/plugins/feedbacklens/app/plugins/file_summary/
通用执行层执行模型循环、权限、Hook、恢复和观测app/agent_engine/

这三层沿着一次请求依次交接。

FastAPI Request
→ PluginRegistry
→ BusinessPlugin
→ AgentRunRequest
→ Agent Runtime
→ Run Status / Artifacts

接口层知道用户选择了哪个插件,业务声明层知道这类任务如何完成,Runtime 知道一次 Agent Run 如何推进。

API 只负责接住请求

Run 创建入口位于 app/api/routes.py

请求中包含:

  • plugin:本次运行的业务插件。
  • goal:用户目标。
  • input:插件输入。
  • skill:可选 Skill。
  • model:Provider 和模型配置。
  • limits:迭代、工具调用、重试和超时限制。

API 层完成 Pydantic 请求校验,再把参数交给 run_registered_plugin()

这一层专注 HTTP 传输和错误映射,CSV 读取与文件写入继续交给 Runtime 工具链。

Run 检查接口也遵循同样思路:

  • /api/runs/{run_id} 读取状态。
  • /plan/todos 读取任务进度。
  • /events/metrics 读取可观察数据。
  • /documents 根据 Manifest 暴露运行文件。

API 面向调用者提供统一形态,插件差异留在业务声明中。

Plugin 负责声明业务能力

RunLens 使用 BusinessPlugin 聚合一类业务任务需要的能力。

一个 Plugin 会声明:

内容作用
plugin_nameversion标识插件和版本
input_schema校验业务输入
tool_definitions提供模型可调用的动作
prompt_fragments描述业务规则和输出要求
required_outputs定义最终交付产物
plan_template定义任务步骤和成功条件
skill_roots提供任务方法和权限声明
hook_config增加业务质量校验

以 Feedback Analysis 为例,它声明了:

  • 输入文件是反馈 CSV。
  • 模型可以读取反馈、提取证据、统计分类和写入产物。
  • 任务按读取、分析、Backlog、报告四步推进。
  • 最终需要两个 JSON 和一个 Markdown。
  • 证据 ID 和原文片段要回溯到源 CSV。

Plugin 负责把这些业务要求交给 Runtime。

Runtime 负责执行和收束

app/agent_engine/ 处理所有插件共享的运行问题。

Runtime 初始化

runtime/runner.py 会创建工作区、加载 Skill、解析能力、生成 Plan、组装 Prompt,并准备 ToolExecutor。

模型与工具循环

runtime/loop.py 负责模型调用、tool_calls、observation 回流、恢复和终止。

工具执行

tools/executor.py 依次完成 Schema、权限、Hook、Handler 和结果记录。

任务状态

planning/runtime/state.py 分别记录业务步骤和 Runtime 生命周期。

结果验证

hooks/validation.py 在模型结束后检查必需文件、JSON、Markdown 和 Evidence。

可观察性

observability/ 记录统一事件并聚合 Metrics。

Runtime 只依赖 Plugin 提供的契约,执行时关注工具、状态和产物规则,具体业务含义留在插件中。

中心注册表怎样形成可信边界

RunLens 当前通过 app/plugins/builtins.py 显式注册内置插件:

feedbacklens
file_summary

PluginRegistry 在注册时检查:

  • 插件名称唯一。
  • 版本符合语义化格式。
  • 工具名称无重复。
  • 产物路径无重复。
  • 插件拥有输入 Schema。

显式注册让可执行代码来源保持清楚。Runtime 只运行项目代码中明确启用的插件。

这也是当前版本的信任模型:RunLens 面向可信内置插件,第三方插件系统需要额外的代码签名、依赖隔离和执行沙箱,适合放到后续阶段。

第二个插件 file_summary

file_summary 是一个很小的插件,却承担了重要验证作用。

它的业务流程是:

读取文本文件
→ 分析标题和行数
→ 写 document_analysis.json
→ 写 summary.md

与 Feedback Analysis 对比:

对比项Feedback AnalysisFile Summary
输入CSV 反馈Markdown 或文本
核心工具CSV、Evidence、统计文本读取、结构分析
Plan四步三步
最终产物三个两个
特殊验证证据回溯Markdown 标题

两者共享:

  • Skill Loader。
  • Prompt Assembler。
  • AgentLoop。
  • ToolExecutor。
  • PermissionGuard。
  • PlanProgress。
  • Stop Hook。
  • EventBus 和 Metrics。
  • RunWorkspace 和 Manifest。

当第二个插件能够沿同一 Runtime 跑通时,业务和执行层的边界也得到了实际验证。

架构约束也进入测试

只靠目录命名维持分层很容易发生漂移。

RunLens 增加了架构约束测试,例如:

  • Runtime 源码不导入具体业务插件。
  • Tool Layer 不导入 LLM Provider。
  • API 不直接调用 Tool Handler。
  • Skill 模块不执行 Handler,也不写工作区。
  • 测试用 ScriptedLLM 不进入生产 Provider Factory。

这些测试把架构边界变成可以自动验证的规则。

业务迭代时,如果某次修改把 FeedbackLens 逻辑重新塞进 Runtime,测试会直接暴露依赖方向变化。

这种拆分带来的收益和代价

收益

  1. 业务扩展更集中。 新插件主要声明自己的输入、工具、Plan 和产物。
  2. 运行机制保持一致。 不同业务共享权限、恢复、观测和验证语义。
  3. 测试更容易分层。 Runtime、插件和业务工具可以分别测试。
  4. 前端接口更稳定。 Run、Events、Metrics 和 Documents 对所有插件保持统一。
  5. 运行证据可比较。 不同插件使用同一 Event Schema 和 Metrics。

代价

  1. Plugin Contract 会增加前期设计工作。
  2. 简单任务也需要经过统一 Run 初始化。
  3. Runtime 和业务之间要维护清晰的数据契约。
  4. 插件能力较多时,Skill、Plan 和 ArtifactContract 需要同步演进。

这些代价换来的是长期边界。当前项目规模已经足以让这套拆分产生价值。

小结

RunLens 把系统分成接口层、业务声明层和通用执行层。

API 接住请求,Plugin 声明任务,Runtime 负责执行和收束。Feedback Analysis 和 File Summary 拥有各自的输入、工具和产物,同时共享同一套 Agent 工程底座。

下一篇沿着一条真实请求继续看:用户创建 Run 以后,插件、Skill、Prompt、Plan、模型、工具、验证和 Manifest 怎样依次接力。