Open Agent Harness · Model-Runtime Protocol

Agent Protocol DSL

这是 Open Agent Harness 治理协议中的模型-Runtime 交互协议章节,定义模型如何声明意图、Runtime 如何治理执行、以及执行结果如何以可控 observation 返回模型。

Model-Runtime Protocol Declarative Action Graph Runtime Governance ToolCall Carrier Compatible Trace / Observability

协议定位

Agent Protocol DSL 不是多 Agent 治理协议总纲,而是其中的模型交互协议。总纲定义 Harness 的治理愿景、对象关系、状态模型和分层边界;本协议只处理模型与 Runtime 之间如何表达、校验、执行和返回结果。

它的目标是让模型声明“想做什么”,而不是让模型直接拥有工具执行权。Runtime 接收声明后负责解析、校验、调度、执行、记录、投影和恢复。

设计思路

模型保留判断、规划和解释能力;Runtime 接管权限、状态、执行、观测和恢复。协议的核心形态是声明式 action graph:模型描述语义动作、依赖关系、上下文引用、结果策略和持久化意图。

为了适配当前模型能力,协议可以通过 Runtime 拥有的 toolCall carrier 承载,例如 AgentProtocolOutput。ToolCall 只是承载方式,协议边界仍然是 Runtime 接受并归一化后的 Action。

对现有 Agent 交互方式的改变

1. 从工具调用变成意图声明 模型声明语义 Action,Runtime 决定是否允许、由谁执行、如何记录。
2. 从逐步循环变成 Action Graph 模型可以声明多个 Action 及其依赖,Runtime 可以并行、排序、阻塞、恢复和压缩结果。
3. 从原样返回变成 Observation Policy Runtime 按策略返回摘要、结构化结果、引用或失败信息,完整输出进入 Artifact 和 Trace。
4. 从会话历史变成上下文构造 Session log 是持久记录;模型上下文是 Runtime 根据场景动态构造的输入。
5. 从隐式委派变成受控 Assignment Agent delegation 先归一化为 Action,再由 Runtime 创建 Assignment;当工作需要跨会话接续时,再生成结构化 Handoff。
6. 从聊天痕迹变成治理证据 Event、Projection、Trace 和 Artifact 共同构成可审计、可恢复、可评测的运行记录。

以下是模型-Runtime 交互协议全文。本协议是 Open Agent Harness 治理协议的一部分,负责定义模型输出、Runtime 归一化、执行结果回放、上下文噪声控制和 Workflow Adapter 的连接边界。

Agent Protocol DSL

目标

Agent Protocol DSL 是 Open Agent Harness 中的模型-Runtime 交互协议。

它的目标形态是一套通用 DSL:模型声明语义 Action、依赖关系、上下文引用、结果策略、持久化策略和恢复意图;Runtime 在 Harness 治理边界内校验并执行这些声明。

该协议可以表达短生命周期的工具编排、Agent 任务委派、上下文请求、引用展开、UI 可见的结构化结果、恢复决策和最终报告。Workflow 这类 durable orchestration 可以建立在本协议之上,但 Workflow 不是本协议的边界。

本协议不是让模型编写一门替代 Runtime 的程序语言。它让模型以结构化方式声明意图,同时让 Runtime 拥有解析、校验、执行、权限、调度、存储、恢复和上下文构造的控制权。

协议载体与恢复

协议目标是通用 DSL。模型侧载体可以随 Runtime 版本和模型能力变化。

当前可通过 Runtime 拥有的 toolCall entrypoint 承载协议声明,例如 AgentProtocolOutput。这个 toolCall 是协议载体,不是协议边界本身。

Runtime 应把所有被接受的执行请求归一化为同一种内部 Action 表示:

  • Harness DSL 声明
  • AgentProtocolOutput toolCall carrier
  • 可安全恢复的直接工具请求
  • 可安全恢复的任务或委派请求

只有当意图明确且 policy 允许时,Runtime 才可以执行恢复。如果 Runtime 无法确定 executor、参数、side effect、依赖或权限,就不执行;它应返回协议错误,或要求模型按协议格式重试。

核心主张

Agent Protocol DSL 是声明式协议。

模型声明一个 action graph:
- 检查这些来源
- 并行执行这些 Action
- 将一个结果作为后续 Action 的输入
- 除非需要细节,否则只返回摘要
- 当任务需要 durable recovery 时持久化运行记录

Runtime 解释并执行这个声明。模型专注于目标、计划、判断和最终解释,不再管理每一个底层工具步骤。

为什么使用 Action Graph

Agent Protocol DSL 可以表达更高层的 Action Graph:

  • 语义 Action,而不是原始工具调用
  • Action 之间的依赖
  • 条件执行
  • 有边界的循环
  • 结果返回策略
  • 持久化策略
  • 失败策略
  • 权限要求
  • 模型可见摘要策略
  • Runtime 可见完整 Artifact 存储

DSL 的价值不是消除所有信息量,而是让 Runtime 能把大量低层工具操作压缩成更少的语义 Action,并只把有用的结果层返回给模型。

示例:

{
  "id": "review_toolbar",
  "title": "Review Toolbar",
  "description": "Review toolbar button implementation and interaction boundaries.",
  "reason": "The user asked for per-button review across behavior, display, focus, undo/redo, and edge cases.",
  "operation": "review_code",
  "executor": {
    "type": "agent",
    "target": "auto",
    "capabilities": ["code_review", "frontend"]
  }
}

模型随后收到的是:

{
  "id": "review_toolbar",
  "title": "Review Toolbar",
  "description": "Review toolbar button implementation and interaction boundaries.",
  "status": "completed",
  "summary": "Found two issues: undo/redo state is not wired through, and the table dropdown can be hidden by a higher layer."
}

这里仍然保留 id,但避免把每次搜索、读取、编辑、测试、重试和原始 stdout 都暴露给模型,除非模型确实需要这些细节。

上下文噪声策略

Provider 侧缓存可以降低重复 prompt 前缀的成本和延迟,但它不会消除语义噪声。

如果过期 trace、失败尝试、冗长原始输出和已废弃计划都出现在模型上下文中,模型仍然可能关注它们。缓存 token 可能更便宜,但它们仍是 prompt 的一部分。噪声关乎注意力、显著性、歧义和过期信息,不只是 token 计算成本。

因此,Agent Protocol DSL 把上下文构造作为 Runtime 的一等职责。

适用范围

本协议面向明确配置为可使用该协议的 Agent,例如 protocol runner、planner、controller 或其他编排类 Agent。

Workflow 使用 durable orchestration adapter,并通过显式 adapter 边界连接到本协议。

普通聊天 Agent 不需要输出本 DSL。

Agent prompt 应明确说明该 Agent 是否允许输出 Agent Protocol DSL。如果某个 Agent 未配置为使用本协议,Runtime 应忽略看起来像协议的文本,或把它当作普通 assistant 内容处理。

兼容载体语法

协议完整形态较丰富,可以表达 action graph、typed executor、上下文引用、持久化策略、结果策略、恢复策略和 UI projection metadata。兼容载体语法保持模型侧表面尽量小,同时保留 Runtime 拥有协议边界这一原则。

载体语法包含三种顶层输出:

type ProtocolOutput =
  | Act
  | Answer
  | Done

act 请求 Runtime 执行一个或多个 call:

{
  "kind": "act",
  "message": "I will inspect the package files first.",
  "calls": [
    {
      "id": "read_package",
      "type": "tool",
      "name": "read",
      "args": {
        "filePath": "package.json"
      },
      "result": "summary"
    }
  ]
}

answer 在不需要更多 Runtime 工作时返回用户可见 Markdown:

{
  "kind": "answer",
  "message": "This project is a VS Code extension for visual HTML editing."
}

done 结束当前 turn,不再请求额外工作;它仍可以包含用户可见结束语:

{
  "kind": "done",
  "message": "The requested check is complete."
}

顶层字段

  • kind:必填。取值为 actanswerdone
  • messageactdone 可选,answer 实际上应提供。内容是用户可见 Markdown 或短进度说明。
  • callsact 必填;answerdone 不使用。

Call 字段

  • id:必填。稳定 call id,用于日志、图节点、结果引用和依赖。
  • type:必填。toolagent
  • name:必填。对 tool 来说是 Runtime 工具目录中的具体工具 id;对 agent 来说是具体 agent id 或 auto
  • args:可选对象。对 tool 必须匹配所选工具的输入 schema;对 agent 是委派输入。
  • depends:可选字符串或字符串数组。表示当前 call 启动前必须完成的 call id。
  • result:可选结果返回策略。允许值包括 summaryfullstructuredon_failureon_demandadaptive。默认是 summary
  • title:可选短标签,用于 UI 展示。

批量 Call

Runtime 执行统一使用 calls,即使只有一个 call。这样可以避免同一个概念出现两种等价语法。

简单依赖示例:

{
  "kind": "act",
  "message": "I will find project manifests, then read the package manifest.",
  "calls": [
    {
      "id": "find_manifests",
      "type": "tool",
      "name": "glob",
      "args": {
        "pattern": "*.json"
      }
    },
    {
      "id": "read_package",
      "type": "tool",
      "name": "read",
      "args": {
        "filePath": "package.json"
      },
      "depends": "find_manifests",
      "result": "summary"
    }
  ]
}

Agent 委派示例:

{
  "kind": "act",
  "message": "I will delegate a focused code review.",
  "calls": [
    {
      "id": "review_changes",
      "type": "agent",
      "name": "auto",
      "args": {
        "description": "Review the protocol schema and prompt behavior."
      },
      "result": "summary"
    }
  ]
}

Runtime 归一化

Runtime 应把兼容载体语法归一化为内部 Action 表示,用于执行、日志和 UI projection:

  • kind: "act" 映射为 intent: "execute"
  • 每个 calls[] item 映射为一个内部 Action。
  • calls[].type 映射为内部 executor type。
  • calls[].name 映射为内部 executor target。
  • calls[].args 映射为内部 Action input。
  • calls[].depends 映射为内部依赖。
  • calls[].result 映射为内部 result policy。
  • kind: "answer" 映射为响应消息。
  • kind: "done" 映射为停止当前 turn,可选包含可见消息。

兼容载体语法是模型侧 carrier。Runtime 将它映射到更丰富的内部协议表示,用于执行、日志、UI projection 和完整 DSL 演进。

Runtime 到模型:Request Transcript

模型侧输出可以是结构化的:模型通过原生 tool-call 通道提交 AgentProtocolOutput

模型侧输入应不同:Runtime 不应把 provider API 对象、原始 tools 声明、toolChoice 或原始 AgentProtocolOutput 参数作为模型可见历史。这些是实现细节。下一轮请求应以模型可读 transcript 说明发生了什么。

协议 Agent 使用一种与 provider request JSON 不同的模型可见 transcript 格式。Runtime 内部可以使用 provider tool schema,但回放给模型的内容应保持协议形态且易读。

这个 transcript 是兼容载体下唯一的 Runtime 到模型 request 格式。它包含用户请求、先前 assistant 协议声明、Runtime observation、协议能力说明,以及当前模型调用的输出要求。

当前建议使用 Markdown turn:

<turn index="1">
## User request

当前插件各个按钮点了都没效果,你进行一次 code review,定位问题,然后修复
</turn>

<turn index="2">
## Assistant protocol request and runtime observations

run_id: `apr_abc123`
Purpose: Inspect extension wiring
Status: completed

### Call read_extension

Tool: `read`

```shell
tool read <<'JSON'
{
  "filePath": "src/extension/extension.ts"
}
JSON
```

### Result for read_extension

Status: completed
Artifacts: artifact://call_read_extension

```md
extension.ts registers the custom editor provider and command handlers.
```
</turn>

Based on all turns above, decide the next step.
Strictly follow the Agent Protocol output requirements for this request.

规则:

  • 每个历史 turn 应像简短 transcript 一样易读,而不是 provider request JSON。
  • 不在 turn tag 中编码 provider message identity。使用 ## User request## Assistant protocol request and runtime observations## Assistant answer 等 Markdown 标题描述发生了什么。
  • 一个 protocol runtime turn 应把每个 call 和对应 result 放在一起,避免先列所有 call 再列所有 result,减少模型配对歧义。
  • call section 包含所选 tool 或 agent 及其参数。result section 不重复参数,只包含 status、artifact reference 和结果内容。
  • run_id 是 Runtime 执行 id,用于关联日志、UI projection、隐藏上下文和 artifact。
  • Purpose 是模型提供的短理由或标题,用于说明这组 call 为什么被请求。显示标签保持中性可读,不必定义成严格字段。
  • Status 是 Runtime 计算的聚合结果:completedblockedfailed
  • turn 之后的最终指令不是历史 turn 的一部分,而是本次请求提醒模型判断下一步并遵守输出格式。
  • 不把模型私有推理回放为模型可见历史。只回放用户可见 assistant 文本、显式协议请求和 Runtime 生成的 observation。

直接请求恢复

Runtime 可以在安全时恢复直接工具请求或委派请求:

  • 模型对已知 Runtime 工具的直接请求,可以转换为 kind: "act",并生成一个 calls[] item。
  • 文本调用块只有在目标工具名和参数都明确时,才能被标记为协议违例并恢复。
  • 被恢复的 call 必须在日志中可见,这样可以衡量协议遵循率和恢复率。
  • 不安全或含糊的恢复必须 fail closed。Runtime 应要求模型用简化协议形态重试,或返回清晰的协议错误。

恢复请求不定义协议。它们只是 Runtime normalization 的输入;归一化后的 Action 继续走同一套校验、权限、日志和 projection 路径。

词汇与抽象边界

协议核心词汇应足够抽象,以描述多个执行领域;同时又要足够具体,以便校验和 UI 展示。

推荐核心概念:

  • Protocol:模型-Runtime contract 和版本化 grammar。示例:agent.protocol version 1agent.protocol.result version 1agent-protocol fenced JSON block。
  • Declaration:模型生成的一个协议块。示例:包含 action graph 的 execute declaration、请求更多细节的 expand_ref declaration、失败后的 revise declaration。
  • Envelope:declaration 的顶层路由 metadata。示例:typeversionintentpersisttitleexecutionpayload
  • Payload:declaration 的结构化主体。示例:action_graph payload、expand_ref payload、decision payload。
  • Action:语义工作单元。示例:检查相关文件、审查一个模块、运行测试命令、请求用户批准风险变更、总结结果。
  • Operation:Action 想做什么。示例:searchreadreview_coderun_testseditsummarizeask_userexpand_reference
  • Executor:Runtime 能执行 Action 的能力类别。示例:读取文件的 tool、审查代码的 agent、合并摘要的 runtime operation、用户批准请求、执行 lint/test 的 pipeline
  • Assignment:Runtime 将一个 Action 绑定给 Agent Session 后形成的执行边界。它描述谁来执行、带着什么 authority、接收什么 Context Bundle、产出什么 result、写入哪些 Artifact 和 Trace。
  • Handoff:Runtime 在两个 Assignment 或执行者之间建立的结构化交接边界。Handoff 不是执行结果本身,而是把上一个 Assignment 的 result summary、evidence、Artifact refs、risks、unresolved issues 与下一步 goal、constraints、dependencies 组织起来,交给下一个 Agent Session、human 或其他 executor 继续处理。
  • Target:具体 executor 名称或 auto。示例:read_filecode-reviewerask_usertest_pipelineauto
  • Capability:用于匹配的可复用能力标签。示例:filesystem.readcode_reviewfrontendtestingapprovalsummarizationexternal.search
  • Resource:Action 可能读取或写入的数据、文件、服务、artifact 或上下文。示例:repo://currentfile:src/toolbar.tsartifact:source_indexruntime://runs/run_123/actions/review/outputinput:user.goal
  • Policy:执行、失败处理、结果返回、持久化、权限和预算约束。示例:persist: truereturn_to_model: "summary"max_tokens: 6000requires_approval: trueon_failure: "ask_model"store_full: true
  • Result:Runtime 产生的 declaration 或 Action 结果。示例:status: "completed"、受影响文件列表、测试报告摘要、review findings、artifact references、failure reason。
  • Reference:指向 Markdown section、先前 Action 输出、Runtime record 或 artifact 的引用。示例:md:review.promptaction:inspect.summaryartifact:test_reportruntime://runs/run_123input:user.goal
  • User Visible Note:可选的人类可见说明,用于展示进度和建立信任。示例:“我会检查 toolbar 代码,然后返回逐按钮审查结果。”

这些概念有意保持抽象。协议不应把 workflowcode_reviewtoolbartestagent_task 等领域对象变成核心协议类别。它们可以作为示例、operation、capability 或 executor target 出现,但不是固定协议边界。

使用 type 表示对象分类,使用 operation 表示 Action 的语义意图。

示例:

{
  "type": "action",
  "id": "review_toolbar",
  "operation": "review_code",
  "executor": {
    "type": "agent",
    "target": "auto",
    "capabilities": ["code_review", "frontend"]
  }
}

在这个例子中,type: "action" 表示对象类型,operation: "review_code" 表示要做什么,executor.type: "agent" 表示由哪类 executor 处理。

消息类型

协议应为不同方向定义不同格式。它们相关,但不完全相同。

Runtime 到模型:Request

Runtime request 告诉模型当前任务是什么、可用协议能力是什么、先前 Action 产生了什么 observation,以及本轮期望输出什么形态。

在兼容载体下,Runtime 到模型的 request 使用上文定义的 Markdown transcript。这里不再定义另一套 XML 示例,避免同一方向存在两种互相竞争的格式。

Runtime 内部仍可以使用 provider tool schema,但模型可见 request 应把 prior user request、assistant protocol request、具体 call、Runtime observation、协议能力和 output rule 组织成同一份可读 transcript。

模型到 Runtime:Declaration

模型 declaration 优化目标是程序解析和校验。推荐用 JSON fenced block 承载结构化 metadata 和 action graph,用 Markdown section 承载长文本。

兼容载体可以通过 AgentProtocolOutput 提交扁平的 { kind, message, calls } 形态。下面是它映射到的完整 DSL 形态。

推荐完整 DSL:

```json agent-protocol
{
  "type": "agent.protocol",
  "version": "1",
  "intent": "execute",
  "persist": false,
  "title": "Toolbar Button Review",
  "payload": {
    "type": "action_graph",
    "actions": [
      {
        "type": "action",
        "id": "inspect_code",
        "title": "Inspect Code",
        "description": "Find toolbar components, editor integration, styles, and tests.",
        "reason": "Review needs source locations before judging behavior.",
        "operation": "inspect_sources",
        "executor": {
          "type": "tool",
          "target": "auto",
          "capabilities": ["filesystem", "search"]
        },
        "prompt_ref": "md:inspect_code.prompt",
        "result_policy": {
          "return_to_model": "summary",
          "store_full": true
        }
      },
      {
        "type": "action",
        "id": "review_toolbar",
        "title": "Review Toolbar",
        "description": "Review toolbar button behavior, display layering, focus, undo/redo, and selection edge cases.",
        "reason": "This is the main user-requested review.",
        "operation": "review_code",
        "executor": {
          "type": "agent",
          "target": "auto",
          "capabilities": ["code_review", "frontend"]
        },
        "depends_on": ["inspect_code"],
        "context_refs": ["action:inspect_code.summary"],
        "prompt_ref": "md:review_toolbar.prompt",
        "result_policy": {
          "return_to_model": "structured",
          "store_full": true
        }
      }
    ]
  }
}
```

## inspect_code.prompt

Locate toolbar-related components, composables, styles, editor integration, and tests.

## review_toolbar.prompt

Review each toolbar button. Check click handlers, selection behavior, focus behavior, undo/redo state, dropdown z-index, and test coverage. Return findings with severity and evidence.

Runtime Observation:执行结果回放

Runtime observation 是执行结果的模型可见表示。它不是另一个独立通信方向,而是 Runtime 到模型 request transcript 中的一类内容块。

Observation 通常包含语义 Action id、标题或描述、状态、摘要和 artifact refs。默认不包含每个原始工具调用或完整输出。

兼容载体下,Runtime 使用 Markdown transcript 返回 observation,每个 call 紧跟对应 result。结构化记录保存在 Runtime storage 和 metadata 中,用于日志、UI 和恢复;模型可见文本则以理解为目标。

模型可见 observation 示例:

<turn index="2">
## Assistant protocol request and runtime observations

run_id: `run_123`
Purpose: Toolbar Button Review
Status: completed

### Call inspect_code

Executor: `tool:auto`
Operation: `inspect_sources`

### Result for inspect_code

Status: completed
Artifacts: artifact://run_123/inspect_code

```md
Found Toolbar.vue, ToolbarButton.vue, toolbarConfig.ts, useToolbar.ts, useEditor.ts, and related tests.
```

### Call review_toolbar

Executor: `agent:auto`
Operation: `review_code`
Depends: `inspect_code`

### Result for review_toolbar

Status: completed
Artifacts: artifact://run_123/review_toolbar

```md
Found two issues: undo/redo state is not wired through, and the table dropdown can be hidden by a higher layer.
```
</turn>

Runtime 也可以为日志、UI、trace export、恢复或程序化处理保存机器可读 JSON 记录。这个 JSON 记录不是默认的模型可见 transcript:

{
  "type": "agent.protocol.result",
  "version": "1",
  "run_id": "run_123",
  "status": "completed",
  "actions": [
    {
      "id": "inspect_code",
      "title": "Inspect Code",
      "description": "Find toolbar components, editor integration, styles, and tests.",
      "status": "completed",
      "summary": "Found Toolbar.vue, ToolbarButton.vue, toolbarConfig.ts, useToolbar.ts, useEditor.ts, and related tests."
    },
    {
      "id": "review_toolbar",
      "title": "Review Toolbar",
      "description": "Review toolbar button behavior, display layering, focus, undo/redo, and edge cases.",
      "status": "completed",
      "summary": "Found two issues: undo/redo state is not wired through, and the table dropdown can be hidden by a higher layer."
    }
  ],
  "next": "final_answer"
}

模型到用户:Final Answer

最终用户响应是普通 assistant text。它应把 Runtime observation 综合成用户需要的答案。

除非用户要求,否则最终回答不暴露原始协议细节。

模型到用户:Visible Note

当模型输出可执行协议时,也可以输出一段短的用户可见说明,用来解释它准备做什么。

这段说明不参与执行。它用于用户信任、进度可见性和 UI 展示。

推荐规则:

  • 对简单或快速的协议声明,可以省略 visible note。
  • 对长任务、多 Agent、durable、风险较高或用户需要观察进度的执行,应包含 visible note。
  • 保持简短,不重复完整 DSL。
  • 不包含只对 Runtime 有用的实现细节。

示例:

```json agent-protocol
{
  "type": "agent.protocol",
  "version": "1",
  "intent": "execute",
  "persist": true,
  "title": "Toolbar Button Review",
  "payload": {
    "type": "action_graph",
    "actions": []
  }
}
```

## user.visible

I will inspect the toolbar implementation, review each button's behavior, and then return a concise issue report with evidence.

Runtime 可以在协议执行期间立即展示 user.visible。如果 UI 已经能清楚展示解析后的 action graph,这一段可以省略。

Envelope

Envelope 标识一个协议声明,并告诉 Runtime 如何路由它。

Envelope 字段位于 JSON block 顶层:

{
  "type": "agent.protocol",
  "version": "1",
  "intent": "execute",
  "persist": false,
  "title": "Toolbar Button Review",
  "payload": {}
}

推荐字段:

  • type:必填,必须是 agent.protocol
  • version:必填,协议版本字符串。
  • intent:必填。示例:executeplanexpand_refcancelrevisedecide
  • persist:可选布尔值。表示 Runtime 是否应在执行前持久化状态。
  • title:可选,人类可读标题。
  • response_policy:可选,模型可见响应偏好。
  • payload:必填,带类型的声明主体。

Envelope 在逻辑上独立于 plan/action 层,但物理上可以是同一个 JSON object。放在同一 JSON block 中能简化解析和校验。

Payload 类型

第一批支持的 payload type 应保持有限:

  • action_graph:短生命周期或 durable 的语义 Action 图。
  • expand_ref:请求展开已存储 Runtime reference。
  • decision:模型对 blocked 或 failed run 的决策。
  • final_report_spec:最终报告的结构化说明。

避免把协议做成通用编程语言。第一版不支持任意表达式或无边界循环。

Durable workflow 行为应表示为 action_graph 上的 execution policy,而不是另一种顶层 DSL 类型:

{
  "type": "agent.protocol",
  "version": "1",
  "intent": "execute",
  "persist": true,
  "execution": {
    "mode": "durable",
    "strategy": "dag"
  },
  "payload": {
    "type": "action_graph",
    "actions": []
  }
}

这让协议保持通用,同时允许 Runtime 对长任务图进行调度、持久化、恢复和展示。

Action 字段

推荐 Action 字段:

{
  "type": "action",
  "id": "review_toolbar",
  "title": "Review Toolbar",
  "description": "Review toolbar button behavior and edge cases.",
  "reason": "The user asked for per-button review.",
  "operation": "review_code",
  "executor": {
    "type": "agent",
    "target": "auto",
    "capabilities": ["code_review", "frontend"]
  },
  "depends_on": ["inspect_code"],
  "context_refs": ["action:inspect_code.summary"],
  "prompt_ref": "md:review_toolbar.prompt",
  "result_policy": {
    "return_to_model": "structured",
    "store_full": true
  }
}

字段说明:

  • id:必填。稳定语义 id。它类似 tool_call_id,但粒度是语义 Action,而不是单次工具调用。
  • type:必填,必须是 action
  • title:推荐,短展示名称。
  • description:推荐,说明 Action 做什么。Runtime 应在模型可见结果中包含它。
  • reason:推荐,说明这个 Action 为什么存在。结果稍后返回时有助于模型理解。
  • operation:推荐,领域级动词,例如 searchreview_coderun_testssummarizeask_useredit
  • executor:可选,请求 executor class、target 和 capability hint。省略时由 Runtime 选择。
  • depends_on:可选,必须先完成的 Action id。
  • context_refs:可选,指向上下文材料。
  • prompt_ref:可选,指向长任务说明的 Markdown payload。
  • result_policy:可选,模型可见结果返回策略。
  • persist:可选,Action 级 durable 覆盖。
  • failure_policy:可选,retry、abort、continue 或 ask-model 策略。

Markdown 引用

长文本不应作为转义 JSON 字符串嵌入,除非文本很短。

使用 md: reference 从 JSON 指向同一模型输出中的 Markdown section。

示例:

{
  "prompt_ref": "md:review_toolbar.prompt",
  "context_refs": ["md:shared.context"]
}

对应 Markdown:

## shared.context

Project context and constraints.

## review_toolbar.prompt

Detailed task instructions.

引用规则:

  • md:<section_id> 解析为 normalized heading text 等于 <section_id> 的 Markdown heading。
  • 使用稳定语义 section id,不使用数字 id。
  • Runtime 在执行前解析 md: reference。
  • 执行 Agent 应接收展开后的文本,而不是 unresolved md: reference。
  • Runtime 应存储原始 DSL、解析后的 Markdown section、prompt hash 和内部 parsed representation。

Context 与 Prompt

contextprompt 作用不同。

  • prompt:当前 Action 必须做什么。
  • context:背景、约束、先前发现或支撑信息。
  • input:结构化值。
  • result:执行输出。

示例:

{
  "id": "review_toolbar",
  "context_refs": ["md:shared.context", "action:inspect_code.summary"],
  "prompt_ref": "md:review_toolbar.prompt"
}

Runtime 应将其展开为类似下面的 node request:

<node-request run_id="run_123" action_id="review_toolbar">
  <context>
    Expanded shared context.
    Expanded inspect_code summary.
  </context>
  <task>
    Expanded review_toolbar prompt.
  </task>
</node-request>

Reference 类型

推荐 reference 类型:

  • md:<section_id>:当前 Markdown payload 中的 section。
  • action:<action_id>.summary:当前 run 中先前 Action 的摘要。
  • action:<action_id>.output:当前 run 中先前 Action 的输出。
  • input:user.goal:原始用户目标。
  • runtime://...:持久化 Runtime artifact 或 record。
  • artifact:<name>:当前 run 产生的命名 artifact。

模型不需要传统工具来读取 md: reference。Runtime 直接解析它们。对于 runtime:// reference,Runtime 可以自动展开,或允许模型声明 expand_ref intent。

Result Policy

Result policy 控制执行后返回给模型什么。

return_to_model 推荐取值:

  • none:不返回内容,只返回状态。
  • summary:返回简洁摘要。
  • structured:返回结构化字段。
  • excerpt:返回选定摘录。
  • full:请求完整返回;Runtime 仍可截断或拒绝。
  • on_failure:仅失败时返回细节。
  • on_demand:返回 ref 和摘要;模型请求时再展开。
  • adaptive:模型声明优先级,Runtime 在预算内选择。

示例:

{
  "result_policy": {
    "return_to_model": "adaptive",
    "priority": ["errors", "matching_lines", "file_paths", "diff"],
    "max_tokens": 6000,
    "store_full": true,
    "if_truncated": "provide_ref_and_summary"
  }
}

模型可以声明偏好,但 Runtime 拥有最终控制权。Runtime 必须强制执行上下文预算、安全、权限和隐私约束。

完整 DSL 与上下文回放

模型没有当前请求之外的记忆。除非 Runtime 把之前的 assistant output 放入下一次请求,否则模型无法记住之前输出过什么。

因此,observation 回放有三种有效模式。

Replay 不是一个单独的 XML 协议对象,而是 Runtime 到模型 request transcript 内部的分组规则。Runtime 应把模型 declaration、declaration summary 或 reference、Action id、Runtime observation、Artifact refs 和下一步指令放在同一组里,让模型知道哪个 observation 属于哪个 declaration。

Full Replay

Runtime 包含先前模型声明,包括 JSON 和 Markdown payload,然后追加 Runtime observation。

在这种模式下,observation 不需要重复完整 prompt,但仍应包含 Action id 和摘要。

Compressed Replay

Runtime 不包含完整先前声明,而是包含 declaration summary 和 observation。

这种模式下,observation 必须包含足够的任务描述,让模型理解每个 Action 的含义。

Hybrid Replay

Runtime 在声明短且新时包含精确声明。对于长声明或陈旧声明,Runtime 用摘要加 runtime:// reference 替代。

这是长期默认策略。

Observation Grouping

使用 observation group 将模型 declaration 和 Runtime observation 逻辑分组。

这种分组帮助模型理解某个 observation 属于哪个 declaration。当周围会话包含多个 run 时尤其有用。

推荐分组字段:

  • run_id
  • declaration summary 或 declaration ref
  • Action id 和 Action title
  • Action status
  • result summary
  • artifact refs
  • failure 或 block reason
  • next instruction

在模型可见 transcript 中,这些字段以 Markdown heading 和短结构化行的形式出现在 Runtime observation turn 内。

Streaming

模型输出可能逐 token streaming。Runtime 不应执行不完整 JSON block。

第一版规则:

  • 收集完整 assistant message。
  • 对兼容载体,优先使用一个完整的原生 AgentProtocolOutput call。
  • message 完成后再解析并校验原生 tool arguments。
  • 只把完整 agent-protocol fenced block 作为替代 carrier 恢复。
  • 只执行已通过校验的 declaration。

未来可以在完整 fenced block 出现后、assistant message 结束前提前解析和执行,但这是可选优化,风险更高。

Runtime 执行也可以 streaming progress。默认不要把每个进度片段回填给模型。进度属于 UI 和日志。只在决策点返回模型可见 observation:

  • completed
  • failed
  • blocked
  • permission needed
  • user input needed
  • model decision needed

不把模型私有推理作为 Runtime observation 回放。Reasoning trace 在允许时可用于调试和 UI,但它不是未来模型 turn 的可靠 source of truth。未来 turn 应接收用户可见 assistant message、显式协议 declaration 和 Runtime 生成的 observation。

XML、JSON 与 Markdown

根据方向和目的选择格式。

XML-like Section

适合模型可读输入和分组上下文:

  • 边界清晰
  • 长文本不需要 JSON string escaping
  • 适合嵌套上下文 section
  • 对 LLM attention 友好

XML-like 文本可以解析,但 schema 和数据类型不如 JSON 明确。XML 也存在多种等价形态:attribute、child element、text node、CDATA、namespace 和 whitespace rule。

JSON

适合模型输出且程序必须解析的内容:

  • 直接 schema validation
  • 明确 array 和 object
  • 原始类型清楚
  • JSON Schema 和 Zod 等工具成熟
  • 符合常见 tool/function calling 训练模式

JSON 不适合承载很长的自然语言 payload,因为长字符串需要 escaping。

Markdown

适合长的人类/模型可读 payload:

  • 任务说明
  • 上下文段落
  • 报告模板
  • 示例

推荐约定:

  • Runtime 到模型 request:使用 Markdown transcript。
  • 模型到 Runtime declaration:兼容载体使用原生 AgentProtocolOutput tool call;未来完整 DSL 使用 JSON fenced block 加 Markdown payload。
  • Runtime observation:模型可见回放使用 Markdown transcript;日志、UI、trace export、恢复或程序化处理使用 JSON record。
  • 模型到用户 final answer:普通 Markdown。

Persistence

并非每个协议声明都应该 durable。

对能在当前 turn 内完成的短生命周期 Action 编排,使用 persist: false

以下情况使用 persist: true

  • 执行必须跨重启存活
  • run 跨 turn 或 session 持续
  • 涉及多个 Agent
  • UI 需要展示进度
  • 审计或恢复重要
  • 用户明确请求 workflow、plan 或 long-running execution

Durable workflow-like 行为应被表示为 persist: true 加 execution policy,而不是另一个协议族。短工具编排可以是 persist: false

Executor Registry

协议把可执行对象视为 Runtime 注册的 executor。

Tool 和 Agent 是重要 executor type,但不是唯一类型。从模型视角看,下列能力都可以通过同一种声明式 Action grammar 表达:

  • 调用普通工具
  • 把任务分配给 Agent
  • 请求 Runtime 执行内部控制 Action
  • 请求 human decision 或 approval
  • 调用预定义 pipeline 或 external service

这不意味着每类 executor 内部完全相同,而是表示模型可以使用统一 Action grammar,由 Runtime 选择具体执行路径。

推荐 executor type:

  • tool:确定性或有边界的系统函数。
  • agent:由 LLM 驱动、具备推理和局部自主性的执行者。
  • runtime:Runtime 拥有的控制操作,例如 wait、merge、checkpoint、summarize、expand references。
  • human:用户或人类 operator 的 decision。
  • pipeline:预定义多步骤确定性流程。
  • service:外部服务或集成。

暴露给启用协议的 Agent 的 registry 信息示例:

{
  "executors": [
    {
      "name": "read_file",
      "type": "tool",
      "description": "Read a file from the current workspace.",
      "capabilities": ["filesystem", "read"]
    },
    {
      "name": "code-reviewer",
      "type": "agent",
      "description": "Reviews code changes and reports correctness, regression, and test risks.",
      "capabilities": ["code_review", "testing", "risk_analysis"],
      "can_execute": true
    },
    {
      "name": "ask_user",
      "type": "human",
      "description": "Request clarification, approval, or a decision from the user.",
      "capabilities": ["clarification", "approval"]
    }
  ]
}

Action selection rule:

  • 如果 executor.target 指定具体 executor,Runtime 校验后可以使用它。
  • 如果 executor.targetauto 或省略,Runtime 根据 executor.type、capability、任务描述、可用性、policy 和成本选择。
  • executor.type 表示 executor 类别,不应是 auto
  • Runtime 有最终权力拒绝或覆盖不安全、不可用的选择。
  • 模型应描述所需 capability,而不是硬编码实现假设。

示例:

{
  "type": "action",
  "id": "review_toolbar",
  "title": "Review Toolbar Buttons",
  "operation": "review_code",
  "executor": {
    "type": "agent",
    "target": "auto",
    "capabilities": ["code_review", "frontend", "ui_action"]
  },
  "description": "Review every toolbar button implementation and report issues.",
  "reason": "The task requires source inspection and judgment across multiple UI behaviors.",
  "prompt_ref": "md:review_toolbar.prompt"
}

Summary

Summary 可以来自多个层级:

  1. Tool 原生结构化摘要,例如匹配数量、文件列表、退出码或受影响文件路径。
  2. Runtime 机械摘要,例如状态计数、artifact reference、截断标记和 error。
  3. Executor final output,当 Action 由 agent、tool、human、pipeline、runtime operation 或 service 处理时。
  4. 专用 summarizer model 或 summary agent,用于压缩长原始输出。

Runtime 应单独存储完整输出,并默认返回 summary 加 reference,除非 policy 要求更多。

Expansion

当模型需要更多细节时,可以输出 expansion declaration:

{
  "type": "agent.protocol",
  "version": "1",
  "intent": "expand_ref",
  "payload": {
    "refs": [
      {
        "ref": "runtime://run_123/actions/review_toolbar/output",
        "reason": "Need exact evidence for the undo/redo finding.",
        "range": {
          "around_matches": true,
          "context_lines": 20
        }
      }
    ]
  }
}

Runtime 决定展开多少,并返回另一个 protocol result。

安全与校验

Runtime 必须强制执行:

  • 只有启用协议的 Agent 可以输出可执行协议声明。
  • 第一版只解析完整 assistant message。
  • 只识别带 type: "agent.protocol" 的显式 fenced block。
  • 执行前进行 schema validation。
  • 工具或文件操作前进行 permission check。
  • 强制上下文预算限制。
  • Durable execution 前进行持久化。
  • Result policy 不能覆盖安全或隐私约束。
  • DSL 不包含任意脚本语言。

用户体验契约

协议不只是模型-Runtime contract。它也影响用户能否理解、信任、中断和检查系统行为。

Runtime 应为可执行 declaration 提供用户可见 projection:

  • title:短 run label。
  • user.visible:执行前或执行中展示的可选说明。
  • actions[].title:每个 Action 的展示标签。
  • actions[].description:每个 Action 的简要说明。
  • status:pending、running、completed、failed、canceled、blocked 或 waiting。
  • progress:可选计数或阶段说明。
  • result_summary:完成后的用户可见结果。
  • details_ref:可选 reference,指向原始协议、日志、artifact 或执行细节。

用户不应该为了理解系统行为而阅读 JSON。UI 可以为检查、调试和高级使用暴露 raw DSL,但普通展示应来自 title、description、status 和 summary。

后续版本需要明确的设计空间

第一版应保持小,但协议需要为这些主题预留明确设计空间:

  • permission_policy:哪些 Action 执行前需要用户 approval。
  • budget_policy:token、时间、成本、retry 和并行度限制。
  • cancellation_policy:用户取消或 Runtime abort 如何影响正在运行的 Action。
  • idempotency:Action 是否可以安全 retry 或 resume。
  • side_effects:Action 是 read、write、send、delete、purchase、publish,还是改变外部状态。
  • data_visibility:结果对模型、用户、日志、未来 run 可见,还是仅 Runtime 可见。
  • privacy:哪些 artifact 或输出不得回放进模型上下文。
  • conflict_resolution:两个 Action 请求不兼容写入时如何处理。
  • schema_evolution:版本化 declaration 如何在 schema 演进后继续解析。
  • partial_results:图执行到一半失败时 Runtime 返回什么。
  • approval_gates:模型如何在高风险或不可逆 Action 前请求用户。
  • result_granularity:如何选择 summary、structured field、excerpt 和 full artifact。
  • ui_projection:哪些协议字段足够稳定,可以支撑前端展示。

这些应是 policy 或 projection,而不是领域特定 Action type。

最小协议边界

第一版协议边界可以包含:

  • 每个 assistant response 只允许一个 agent-protocol JSON block。
  • 支持由 md: 引用的 Markdown payload section。
  • 支持 action_graph payload。
  • 支持 Action 字段:typeidtitledescriptionreasonoperationexecutordepends_oncontext_refsprompt_refresult_policy
  • 支持 result policy:summarystructuredfullon_failureon_demandadaptive
  • 支持 protocol exchange result wrapper。
  • 对短且新的 declaration 使用 full replay。
  • 对长或陈旧 declaration 使用 compressed replay。
  • 支持 persist: false 的 ephemeral run。
  • 支持 persist: true 的 durable action graph run。
  • 暴露 executor registry。
  • 使用 executor.typeexecutor.targetexecutor.capabilities 进行 Action 选择。
  • 支持可选 user.visible Markdown section,用于用户可见进度说明。

暂不纳入核心边界:

  • assistant message 完成前的 streaming partial execution。
  • 任意嵌套表达式。
  • 无边界循环。
  • 用户自定义脚本。
  • 同一 response 中多个 protocol block。
  • 未启用协议的 Agent 自动执行协议文本。

与 Workflow Adapter 的关系

Workflow 是 Harness durable orchestration adapter,不是本协议边界。

模型-Runtime 协议与 Workflow Adapter 共享治理对象,但保持独立执行契约。Workflow state、recovery 和 UI projection 行为可以反哺协议设计,但不让 workflow execution 变成隐式协议行为。

二者关系如下:

Workflow adapter:
  - 专用 durable orchestration 实现
  - 拥有 workflow DAG、node state、artifact 和 recovery decision
  - 通过显式 adapter boundary 暴露 durable run 行为

Agent Protocol DSL:
  - 通用模型-Runtime 协议目标
  - 支持 tool action 和 agent action
  - 使用 action_graph 加 execution policy
  - 可以通过 durable action_graph policy 表达 workflow adapter run

如果 Workflow Adapter 通过 Agent Protocol DSL 表示,它应映射为带 persist: trueexecution.strategy: "dag"action_graph。这个映射是显式 adapter contract。