# Agent Note: 按意图命名公开的 agent 投递

Status: implemented

[English](2026-07-24-intent-named-agent-delivery.md) | 中文

## 问题

可配置的 `send(content, { target?, wakeup?, ... })` 会迫使每个调用方理解循环的路由矩阵、默认值，以及活跃轮次目标与模型激活之间的相互作用。可选路由字段还会让看似高级的调用悄然变成普通投递。大多数调用方只有一种语义意图，而有些适配器已经持有确切的路由信息，不应再被迫将这些信息反向映射为某个辅助方法名称。

通过抽象 `Agent` 类共享辅助方法的实现，实际上也会让公开 seam 具有名义类型约束。对象字面量适配器和测试必须继承原型方法，尽管该包承诺提供一个可替换的结构化句柄。共享基类只负责转发固定参数，而具体循环仍是唯一的生产适配器。

## 决策

`Agent` 是一个结构化接口，提供四种按意图命名的投递辅助方法：

- `followup()` 将一个普通轮次入队并唤醒驱动器。
- `queue()` 将一个普通轮次入队，但不唤醒空闲驱动器。
- `steer()` 以运行中的轮次为目标并请求另一个步骤；空闲时，它会变成一个唤醒式普通轮次。
- `inject()` 追加面向模型的上下文，但不运行模型。

`followup`、`queue` 和 `steer` 接收 `SendOptions`；`inject` 接收 `InjectOptions`，后者不包含附加上下文，因为注入没有 inbox 项来拥有它们。`followup` 为唤醒式下一轮操作命名，这项操作既用于初始提示词，也用于后续的独立提示词。

`Agent` 还公开 `send(ResolvedAgentInput)`，供已经持有完整路由的调用方使用。每个字段都必须提供：内容、来源、上下文、元数据（可以是 `undefined`）、目标和唤醒标志。对于目标为下一步且不触发唤醒的注入，可辨识联合类型要求上下文为空元组。`ReactLoopAgent` 统一实现这个方法；四个辅助方法都会先解析各自的默认值，再委托给它。调用方以一个解析后的输入向该方法提交各项投递事实；接受之后，工作仍可能在稍后出队、被丢弃或持久注入，而不是最终必然送达。

结构化 `Agent` 接口显式包含面向高级用法的 target/wakeup 矩阵；该矩阵不属于普通辅助方法的选项，也不是基类实现 seam。只有一个具体适配器时，protected 子类 seam 只是假想的；调用方和测试使用同一个公开接口。

## 考虑过的替代方案

**让解析后的原语保持私有。** 这会把公开方法数量降到最低，但会迫使已经持有精确 target/wakeup 路由信息的适配器将其反向映射为辅助方法调用，也会移除表示该解析后状态的可复用类型。

**使用可配置的 `send(content, options)` 作为原语。** 可选路由字段会让看似高级的调用悄然变成普通投递。一个各字段均为必填项的可辨识输入既能让解析后的路由保持显式，也会拒绝为注入附加上下文。

**把原语命名为 `acceptInput`、`sendInternal` 或 `addMessageAdvanced`。** `acceptInput` 描述了同步接受边界，却没有描述调用方的投递操作。公开方法不应在名称中把自己称为内部方法，`addMessageAdvanced` 也不准确，因为输入可能在之后被丢弃。

**使用 `send(content, options)` 作为唤醒轮次的辅助方法。** 这会让最简短的投递名称只表示一种预设操作，并迫使持有完整 target/wakeup 信息的调用方改用一个不够直接的原语名称。`followup` 明确区分下一轮/唤醒意图，并把 `send` 留给解析后的操作。

**先通过公开的发送方对象绑定来源。** 对于重复产生消息的来源，来源绑定适配器可以明确标注归属，但它会增加一个公开对象，也不会简化一次性的人类输入。现有的来源默认值予以保留，同时继续要求非人类生产方标注其内容。

## 验证

聚焦的 agent-loop 覆盖率测试通过公开方法覆盖直接接受完全解析的输入、唤醒式投递、静默排队、活跃与空闲状态下的 steering（中途引导）、注入、来源与上下文快照、取消，以及 inbox 生命周期关联。类型级覆盖使用结构化 `Agent` 测试替身，要求提供 `ResolvedAgentInput` 的每个字段，要求其注入变体的上下文为空，并确保 `SendOptions` 不包含路由字段。无密钥的 Cordis 检查快照固定了不采用抽象类实现的结构化接口。

## 后果

普通调用方选择一个动词即可，无需编码两条路由轴；高级调用方则可提交经过判别的精确路由。具体循环保留一条接受路径和一个归属边界，而结构化接口保留了对简单适配器和测试替身的支持。新增一种常见投递意图时，仍需要显式提供公开辅助方法及其映射，而不是再增加一种可选的矩阵组合。

这个高级方法会扩大接口范围，并要求结构化测试替身实现它。作为回报，解析后的路由只有一种类型化表示，而辅助方法的默认值和映射仍留在拥有它们的唯一实现旁边。

## 相关

- [统一投递并合并 user 消息](2026-07-22-unified-send-and-coalesced-user-messages.md)负责定义共享的接受机制、inbox 生命周期和持久事件趋同；本决策只收窄它们的公开 seam。
