# 单 Agent 与受控工具

本参考适用于产品确实需要一个可调用业务能力的对话 Agent。它复用 Study Buddy 的核心取舍：一个服务端模型工具循环，由平台守住机制与权限，由模型理解自然语言和决定何时使用已授权工具。没有 Agent 需求的项目不应引入本参考中的运行时、目录或 Tool 结构。

## 先确定边界

默认只建立一个 Agent，而不是为每个领域、页面或功能建独立 Agent。它是每个用户／会话／运行相互隔离的一次服务端执行，不是所有用户共享的可变实例。不要在没有明确需求时引入多 Agent 编排、角色路由、Agent 交接、任意代码执行、用户 Shell、虚拟机、通用沙箱、长期记忆或后台自主规划。

模型负责理解意图、处理指代、自然追问、选择工具、处理可恢复错误和自然结束；平台负责可信身份、能力目录、资源授权、顺序、持久化、预算、取消和审计。平台不能用关键词路由、页面位置、按钮来源或隐藏 `activeTask` 状态来替代模型对用户意图的判断。

```text
用户请求或经确认的任务完成事件
  -> Host 取得可信身份、上下文和本轮可用能力
  -> 唯一模型循环
  -> 自然回复，或调用受控 Tool
  -> Tool 结果／可恢复错误返回同一模型循环
```

## 职责划分

| 层 | 拥有的事实 | 不应承担的职责 |
| --- | --- | --- |
| Host／聊天入口 | 身份、运行记录、历史窗口、附件／引用解析、能力快照、用量、取消与事件 | 领域业务事务和语义路由 |
| Agent 执行层 | 模型循环、按步能力工作集、技术预算、取消传播 | Cookie、SQL、领域权限或业务写入规则 |
| 能力目录 | Skill／Domain 定义、依赖、版本与本轮加载记录 | 用户数据读取或永久意图状态 |
| Tool 适配器 | 参数 schema、结果转换、调用业务服务 | 复制业务授权、事务和幂等规则 |
| 业务服务 | 资源权限、校验、事务、版本、幂等与外部副作用 | 依赖模型 SDK 或猜测对话意图 |
| Worker | 确定任务的执行、重试、状态和结果 | 自主规划、加载能力或理解下一步目标 |
| 浏览器 | 文本、草稿、引用选择、活动与已确认结果展示 | 生成权威 Tool 结果或授权声明 |

每层提供不同抽象。若一个“运行时层”只将全部参数转发给下层，应删除或将职责收拢；不能用 Coordinator／Manager 链条制造架构。

## 能力、数据与工具

对可扩展能力使用四个不同概念，只有当前产品确有多个业务能力时才建这套目录：

- 扩展包：安装、配置、启停和版本的单位；只接受仓库内受审查定义，不下载或执行第三方代码。
- Skill：处理某类问题的方法说明，可声明依赖的 Domain。
- Domain：一组相关数据或业务操作及其契约。
- Tool：一个业务动作，包含 schema、授权和执行；一个 Tool 归属一个 Domain。

加载 Skill 自动加载其必要 Domain；只需业务数据时可以直接加载 Domain。已安装、已加载、可执行是三件不同的事：只有本轮实际加载的 Skill 指令和 Tool schema 才提供给模型；每次 Tool 调用仍需重新检查运行有效性、资源访问权和业务状态。安装、模型文字、引用正文、前端状态和历史记录都不能成为授权。

工具要表达完整业务操作，例如“更新计划”或“保存资料版本”，而不是“查 owner”“拿锁”“写表”“扣费”等要求模型固定排序的内部步骤。API 和 Tool 共用同一业务服务。Tool 的错误应是有限、可理解、可由模型处理的结构化结果；身份失效、取消、运行过期和不可恢复基础设施错误终止运行。

对公共资源、私人资料和本轮引用范围分别做授权。先过滤访问权，再检索或读取；引用以服务端确认的对象 ID、版本和选区表示，不能由用户或模型提交权威正文。资料内容和网页内容均是不可信数据，不能覆盖 Host 规则或授予写入权限。

## 对外 Agent API 与可分发 Skill

只有产品确实要让站外 Agent 访问用户业务数据时，才额外提供 Agent API。它是受鉴权的数据／受限写入接口，不是将本站完整 Agent、网页动作或云端教学判断远程化。正式练习、支付、复杂编辑等依赖网页交互生命周期的操作应保留在网页；对外 API 返回事实、稳定引用和可选 deep link，由调用方 Agent 做其自身的推理与呈现。

Capability 的 ID、标题、描述、输入 schema、认证、scope、side effect 和 destructive 标记应只有一个编译期定义来源，并可由网页 Host、本站 Tool、对外 API 和公开 discovery manifest 复用。页面注册表只绑定可信的输入、状态与操作，不能维护第二份能力定义。删除、归档等破坏性调用要求用户明确确认；用户 Agent 与后台／Operator Agent 使用不同的 Token、scope、最小权限和审计边界。

可公开安装的 Skill 源码与主产品仓库应保持独立，二者只通过版本化 API／manifest 协作。公开 Skill 只描述如何调用公开能力，不能携带用户数据、内部工作流实现、私有部署细节或随运行时动态拼出的 `SKILL.md`。没有外部使用者时，不需要创建这套分发与 Token 体系。

## 连续上下文、事件和副作用

服务端持久化的会话和运行记录是连续语义的来源。浏览器只传本轮输入和受控引用；不回传完整历史、owner 或 Tool 结果。将记录分成三个投影：

- 模型上下文：最近完整轮次、必要的紧凑 Tool 事实、稳定对象引用和本轮资料；受明确的文本／图片预算约束。
- 用户界面：正文增量、进行中的 Tool 活动、已确认成果和失败状态。
- 审计记录：完整的 Tool 调用／结果／错误、版本、耗时、用量和最终状态；不全量塞入模型上下文。

工具调用和结果必须关联。失败或取消的轮次也可能已有成功写入：持久化并在后续上下文保留这些已确认事实，不能因为整轮失败而宣称“没有保存”。取消不撤销已提交事实；重试不能重复副作用。

流式响应可采用受共享契约验证的 NDJSON：`text`、`activity`、`error`、`done` 分开表达。先持久化终态和已确认活动，再发送完成事件。断线、进程崩溃和页面刷新可读取已保存运行记录，但不要承诺未经实现的逐 token 续传。

## 资源限制与后台任务

每次运行设置明确的超时、并发和成本／轮次边界；这些限制来自实际业务与费用，不假装是全站安全边界。模型不需要固定“思考步骤”或人为调用次数上限；让它在自然完成、取消、超时或致命错误时结束，并关闭本轮 Tool。

长任务只有在确实出现跨请求执行需求时才引入。业务 Tool 提交确定输入，Worker 保存 queued／running／completed／failed／cancelled 和结果引用；重试依赖持久幂等键。需要自动续接时，将去重后的完成事件重新交给原会话的同一个 Agent，由 Host 再检查身份、能力安装、用户撤销和顺序。任务成功不自动等于用户目标达成。

## 客户端与验收

聊天 UI 可以使用成熟组件，但客户端 Tool 执行、服务端历史替换和本地权限升级不属于展示框架。由应用保持真实发送锁、取消控制器、草稿恢复、私有上传和结果投影。

至少以行为验证：加载前模型不可见业务 Tool，加载后下一步可见；停用能力不能从旧历史恢复执行权；权限、版本冲突、引用范围、重复提交、取消和已经发生的副作用均保持正确；刷新仍能显示服务端记录的活动与结果。用模型／网络替身验证协议和边界；真实模型质量、外部服务费用和用户体验另行、显式验收。

需要跨端 Capability 契约、BFF 或公开 API 时，补充阅读[IELTS Buddy 的扩展工程经验](ieltsbuddy-development-experience.md)。
