Tier 1 · 应用层
产品入口与组织资产:Agent 管理、协作工作台、能力中心、运营控制台、开放平台
Tier 2 · 协同运行时
多 Agent 调度与会话状态:任务编排、协作策略、AgentSession、共享记忆
Tier 3 · 执行内核
单 Run 的安全执行:Run 管理、上下文装配、计划执行、工具控制、HITL、审计
详细设计说明
用三层架构把产品入口、运行时协同和内核治理分开
这份文档明确 Tier 1 应用层、Tier 2 协同运行时、Tier 3 执行内核三层的边界与协作契约。评审重点是每层"承担什么 / 不承担什么"是否能在版本演进中保持稳定,让上层产品可替换、运行时可演进、内核保持治理底线。
设计主张
三层不是简单的代码分层,而是三种变化频率不同的关注点:应用层跟着业务走、运行时跟着协作模式走、内核跟着治理与合规走。让它们各自演进,是平台能持续生长的前提。
评审关注点
- 每层承担与不承担是否清晰
- 跨层调用是否只走契约、不漏抽象
- 治理 / 可观测 / 隔离三条横切是否真贯穿三层
- 新模块加入时该落在哪一层、是否需要破坏边界
1. 定位与概念
用一张总体架构图和一张跨层时序图,回答"三层各装什么、一次任务怎么穿过三层"两个问题。这是阅读其余章节的入口。
1.1 总体架构图
下图按 Tier 1 / Tier 2 / Tier 3 三条横向带组织,每条带列出该层的主要模块;顶部是终端用户与外部系统入口,底部是基础设施依赖;右侧贯穿三层的纵列是横切关注点(治理、可观测、隔离),它们不属于任何单层,但渗透每一层。点击任一层标签跳到对应章节。
1.2 跨层调用时序图
下图把一次完整任务拆开来看:从用户在 Tier 1 发出请求,经 Tier 2 协同运行时派单,到 Tier 3 内核执行单次 Run,再原路返回 Tier 1。点击顶部任一 lifeline 色块跳到对应章节。这张图也是后续每个模块设计文档的"坐标系"。
1.3 为什么三层
"产品入口、运行时、内核"听起来像 MVC,但三层架构要解决的是变化频率不一致带来的工程问题。下表是不分层时的具体缺口:
| 缺口 | 具体表现 | 影响 |
|---|---|---|
| 业务逻辑与执行机制纠缠 | Agent 配置改动要触碰底层 Run 调用栈;新增协作模式要改单次执行代码 | 每个产品迭代都在动核心治理代码,回归面巨大 |
| 多 Agent 协作没有承载层 | 派单 / 汇总 / 会话状态散落在产品代码或单 Run 内部 | 新增协作模式要复制一份调度逻辑;DelegationTrace 串不起来 |
| 治理能力散点 | HITL 阈值在前端、成本预算在中间件、审计在数据库 | 无法统一审计;同一种风险在不同模块用不同标准 |
| 基础设施假设硬编码 | 沙箱 / 模型 / 向量库 直接引用具体实现 | 换一家 LLM 或换一个沙箱就改大量调用方代码 |
| 跨层数据结构互通 | 产品代码直接读 RunState 的内部字段做展示 | 内核每次调整字段都要等业务跟着改,演进锁死 |
三层架构解决的具体问题:
- 把变化频率不同的关注点拆开——T1 跟业务变、T2 跟协作模式变、T3 跟治理与合规变,互不干扰
- 给"多 Agent 协作"一个独立运行时——T2 是 Coordinator 的家,机制(fan-out / sequential / lead-driven)和承载实体(Team / Session)都在这层
- 让治理沉到内核——状态机、Policy、HITL、Trace 不再每个产品自己实现一遍,T3 提供统一基线
- 让基础设施可替换——LLM、沙箱、向量库走 Provider 抽象,业务代码不感知具体后端
- 让跨层只通过契约通信——T1 不读 RunState 内部字段、T2 不读 RunContext 私有结构,避免内核演进锁死
1.4 三层契约定位
| 层 | 承担 | 不承担 |
|---|---|---|
| Tier 1 · 应用层(Agent Platform) | 组织与权限、Agent / Persona / Team / Skill 的 CRUD、协作工作台 UI、运营治理面、渠道接入、开放平台 API | 不负责协作调度;不持有运行时状态机;不直接调用 LLM 或沙箱 |
| Tier 2 · 协同运行时 | 多 Agent 协作策略选择、@mention 展开、AgentSession 长会话状态、Job 调度与 child Run 派发、共享记忆 scope 路由 | 不存储产品实体;不暴露管理 API;不感知具体业务语义;不替内核做单 Run 的执行 |
| Tier 3 · 执行内核(Harness Kernel) | 单 Run 的 8 步管道:上下文装配、计划执行、工具调用、Policy 校验、HITL 审批、Trace 收口;RunState 状态机;Provider 抽象(LLM / Sandbox) | 不感知 Team / Session / Job 等多 Run 概念;不做协作调度;不做产品 UI;不直接服务终端用户 |
2. Tier 1 · 应用层
列出应用层承载的产品入口与组织资产模块,明确每个模块的边界以及与下层的接口定位。这一层贴近用户与组织运营,迭代最快。
2.1 模块清单
| 模块 | 承担 | 主要交付物 |
|---|---|---|
| 组织与权限 | 租户 / 组织 / 用户 / 角色的实体与 RBAC;Workspace 隔离 | 组织管理 UI · 权限矩阵 · 邀请与转让 |
| Agent 管理 | Persona 的定义、配置、版本、能力绑定、上下架 | Agent 商店 · 配置编辑器 · 版本历史 |
| 协作工作台 | 群聊 / 长会话 / @mention / @团队;多端同步;Team 管理 UI | 主交互界面 · Team 管理面板 |
| 能力中心 | Skill 仓库、MCP 接入、第三方工具凭据托管、工具白名单 | Skill 列表 · 凭据管理 · 工具白名单配置 |
| 运营控制台 | 审计中心、成本面板、HITL 审批入口、合规报表 | 审计 dashboard · 审批工作台 · 成本报表 |
| 渠道接入与集成 | 入站:群聊 / 邮件 / IM / Webhook;出站:通知 / 凭据;外部系统对接 | 渠道适配器 · 凭据托管 · Webhook 网关 |
| 开放平台 | 对外 REST / SDK、应用市场、计费、第三方 Agent / Skill 上架 | 开发者门户 · API 网关 · 应用市场 |
2.2 与下层的接口定位
应用层不直接执行任务,所有需要"跑一次 Agent"的能力都通过提交 Job下沉到 Tier 2。具体接口位置:
- 提交任务——把用户消息、上下文、Persona / Team 引用、必要的 caller_extra(团队 ID、风险标签等)打包成 Job,投递到 T2 队列
- 查询状态——通过 RunTrace / DelegationTrace 的只读视图展示进度,不直接读 T2/T3 内部数据结构
- 响应 HITL——审批工作台收到 T3 的审批请求,把决策结果回传给 T2,由 T2 通知 T3 继续
- 治理配置下发——HITL 阈值、成本预算、Skill 白名单等在 T1 编辑后,通过配置广播让 T2/T3 在下一次 Run 生效,不修改正在跑的 Run
2.3 设计原则
- UI 状态归 T1——草稿、表单、编辑器状态属于产品层;运行时不持有这些
- 实体的真值在 T1——Persona / Team / Skill 的配置定义归 T1,T2/T3 只读这些定义的快照
- 不要在 T1 拼协作逻辑——只要涉及"派给多个 Agent / 串接多步",立刻下沉 T2,避免 T1 长成第二个运行时
3. Tier 2 · 协同运行时
说明运行时层的四大组件——多 Agent 协作、任务调度、AgentSession、共享记忆——的职责与彼此关系。这一层是"机制层":把单 Run 的内核能力组合成多 Agent 协作。
3.1 模块清单
| 模块 | 承担 | 关键产出 |
|---|---|---|
| 多 Agent 协作 | @mention 解析、@team 展开成员列表、协作策略选择(fan-out-broadcast / sequential-relay / lead-driven)、consolidation 汇总轮 | 派单上下文 · 多 Agent 输出汇总 |
| 任务调度 | Job 队列与优先级、child Run 派发、跨 Run 重试、DelegationTrace 串接 | RunGraph · 跨 Run 状态可观测 |
| AgentSession 会话 | 长会话状态机:成员名册、轮次水位、上下文检查点、休眠 / 唤醒 / 归档 | 持久化群会话 · 上下文快照 |
| 共享记忆 | 个人 / 团队 / 会话三档 scope 的写入与召回;隔离规则;写入回流到 T1 治理面 | 多 Agent 共享上下文 · 团队级经验沉淀 |
| 协作策略引擎 | 读取 Team config / Persona config,注入 RunConfig(max_round / hitl_threshold / cost_budget) | 策略下发 · 默认值回退 |
3.2 与上下层的接口定位
- 对 T1 暴露——投递 Job 接口、查询 RunTrace / DelegationTrace 的只读视图、HITL 决策回调入口
- 对 T3 调用——为每个 Agent 创建一次 Run,传入 RunConfig 与 caller_extra;接收 RunResult 后再做汇总;把 T3 的 HITL 请求转回 T1 审批工作台
- 不感知——产品 UI 状态、组织实体定义;不直接读 T3 内部的 RunState 内部字段
3.3 设计原则
- 机制 ≠ 产品——T2 不知道用户在做什么业务,只知道协作模式。新业务通过组合现有协作模式落地,不要在 T2 加业务分支
- 多 Agent 协作的承载实体在 T2——Team 在 T1 定义但 T2 用它驱动协作;AgentSession 完全在 T2,T1 只是消费它的快照
- 共享记忆 scope 由 T2 管——T3 的单 Run 不知道"团队级"概念,所有 scope 路由都在 T2 完成
- 策略缺失回退默认——任何 team / persona 级配置缺失时回退到全局默认,不让 T3 看到空值
4. Tier 3 · 执行内核
说明执行内核的六个组件与它们组成的 8 步管道。内核只做一件事——把一次单 Run 安全地从输入跑到终态,并保证治理底线在每一步都强制执行。
4.1 模块清单
| 组件 | 承担 | 对应 8 步 |
|---|---|---|
| Run 管理器 | 创建 run_id、维护 RunState 状态机、所有终态前必经 Trace 的不变量 | ① Run 创建 · 主控全局 |
| 上下文装配器 | 从记忆 / 历史 / system prompt 装配本次 Run 的输入上下文;无副作用、可重试 | ② 上下文装配 |
| 计划执行器 | 调用 LLM 生成步骤序列;管理重规划、步骤推进、工具结果回写 | ③ Skill 加载 · ④ Plan 规划 |
| 工具调用控制器 | Skill schema 注入与参数校验;走沙箱 Provider 执行;重试与结果回包 | ⑥ Tool 调用 |
| HITL 控制器 | Policy 路由(结构 / 权限 / 成本 / 安全);高风险动作分流到人工审批;通过 / 拒绝决议 | ⑤ Policy 校验 · ⑦ HITL 审批 |
| 审计追踪器 | 写 RunTrace / StepTrace / ToolTrace;成本结算;状态收口;所有终态前必经 | ⑧ Trace 留痕 |
详见 Harness Kernel 设计文档。本章只标定它在三层架构里的位置与边界。
4.2 与上下层的接口定位
- 对 T2 暴露——create_run(接收 RunConfig + caller_extra)、ResultSink(输出 RunResult + 终态)、HITL 请求/回调通道
- 对外部依赖——LLM Provider、Sandbox Provider 通过抽象层调用,可在不修改内核代码的前提下替换具体后端
- 不感知——多 Agent 协作、Team、Session、Job;T3 只看到自己被指派的一次 Run
4.3 设计原则
- 单 Run 纯粹——内核只跑一次 Run,不知道这个 Run 是 child 还是 root、属不属于某个 team
- 所有终态必经 Trace——SUCCEEDED / REJECTED / FAILED / TIMEOUT 在写入终态前必须先写 Trace,这是治理底线
- Policy 与 HITL 双守门员——结构 / 权限 / 成本 / 安全四类规则在 ⑤ 自动判断;不可逆动作必须经 ⑦ 人工审批
- Provider 抽象——LLM 与 Sandbox 走 Provider,OpenClaw 非必须、可替换为 Hermes Agent / K8s 等
- 内核稳定优先于功能堆叠——内核演进遵循"打基础"节奏,不为短期产品需求破坏边界
5. 横切关注点
列出贯穿三层的三条纵线——治理 / 可观测 / 隔离——以及它们在每一层的具体落点。横切不归属任何单层,但每一层都必须为它们留出钩子。
5.1 治理
治理是"谁可以做什么、在什么预算 / 风险 / 合规边界内、出了问题如何追责"。三层各自的落点:
| 层 | 治理落点 | 典型能力 |
|---|---|---|
| Tier 1 | 治理定义面——配置与审批入口 | RBAC 编辑、HITL 阈值配置、成本预算编辑、Skill 白名单、合规报表、审批工作台 |
| Tier 2 | 治理注入面——把 T1 的配置注入到每次 Run | 读取 Team / Persona 配置生成 RunConfig;策略缺失时回退默认;HITL 决策回传 |
| Tier 3 | 治理执行面——强制执行规则、写入审计 | Policy 校验、HITL 审批拦截、风险等级判定、所有终态写 Trace |
5.2 可观测
可观测是"任何一次 Run 都要可回溯、可解释、可重放"。三层各自的落点:
| 层 | 可观测落点 | 典型能力 |
|---|---|---|
| Tier 1 | 查询面——审计中心 / 成本报表 / Replay 入口 | 按时间 / 团队 / 用户 / 风险等级筛选;导出报表;触发 Replay |
| Tier 2 | 串接面——把多个 RunTrace 串成 DelegationTrace | 跨 Run 链路视图;多 Agent 协作可观测;Session 状态历史 |
| Tier 3 | 采集面——RunTrace / StepTrace / ToolTrace 写入 | 每一步的输入输出、成本、耗时、错误堆栈;终态前必写 |
5.3 隔离
隔离是"租户 / 组织 / 团队 / 个人 / 凭据 / 沙箱执行边界"在三层都要保持一致,任何一层泄漏都意味着治理失败。三层各自的落点:
| 层 | 隔离落点 | 典型能力 |
|---|---|---|
| Tier 1 | 定义 scope——组织 / Workspace / Team 边界 | 实体的可见性矩阵;凭据托管;Skill 白名单 |
| Tier 2 | 路由 scope——记忆召回与派单都按 scope | 个人 / 团队 / 会话三档共享记忆 scope;@team 展开不跨边界 |
| Tier 3 | 执行 scope——沙箱内执行不可越界 | Sandbox Provider 强制隔离;凭据按 Run 注入;Skill 白名单在 ⑥ 强制 |
6. 跨层契约
简要列出 T1↔T2、T2↔T3 两条边界上的关键调用契约。契约稳定是三层架构能持续演进的前提;这里只列轮廓,详细字段在各模块设计文档中。
6.1 T1 ↔ T2 契约
| 方向 | 契约 | 关键载荷 |
|---|---|---|
| T1 → T2 | 提交 Job | 消息文本、Persona / Team 引用、用户与组织身份、caller_extra(团队 ID、风险标签)、回调通道 |
| T1 → T2 | HITL 决策回传 | 审批 token、决议(通过 / 拒绝 / 备注)、操作人身份 |
| T2 → T1 | Job 完成回调 | JobResult、多 Agent 输出、终态、引用的 RunTrace / DelegationTrace ID |
| T2 → T1 | HITL 审批请求 | 风险描述、待审批动作摘要、超时时间、审批 token |
| T2 → T1 | RunTrace 只读视图 | 状态、步骤摘要、成本、耗时;不暴露 RunState 内部字段 |
6.2 T2 ↔ T3 契约
| 方向 | 契约 | 关键载荷 |
|---|---|---|
| T2 → T3 | create_run | RunConfig(max_round / hitl_threshold / cost_budget / tools_whitelist)、调用人身份、caller_extra(team_id 等仅透传字段)、上下文输入 |
| T2 → T3 | HITL 决策回传 | 审批 token、通过 / 拒绝;T3 据此从 AWAITING_HITL 推进到下一态 |
| T3 → T2 | ResultSink | RunResult(终态 + 输出)、引用的 Trace ID、成本结算 |
| T3 → T2 | HITL 审批请求 | 风险描述、待执行动作摘要、超时时间、审批 token;由 T2 转给 T1 |
| T3 → T2 | Trace 写入事件 | RunTrace / StepTrace / ToolTrace;T2 据此串接 DelegationTrace |
6.3 契约稳定性原则
- caller_extra 是透传通道——T2 想给 T3 任何上下文都通过 caller_extra;T3 不解析这些字段,只在 Trace 留痕
- 禁止跨层私有结构——T1 不读 RunState 内部字段、T2 不读 RunContext 私有结构;只通过上述契约通信
- 新增字段向后兼容——契约新增字段必须可选(带默认值),下层旧版本能忽略不识别的字段
- HITL 审批跨两条契约——T3 发审批请求 → T2 转 T1 → T1 用户决策 → T2 回传 T3,途中不能丢、超时要降级到拒绝
- Trace 是单向写——只有 T3 写、T2 串接、T1 读,没有反向调用
caller_extra 与可选字段扩展;只有当新能力本质上属于另一层时,才考虑挪动模块归属,而不是破坏契约让上下层互通私有数据。