# M00 系统边界与第一条可验收任务

> 本章产出：一页任务契约、一份系统边界图、一条能被独立判断成败的售后任务。不要先安装Agent框架。

## 1. 从一个失败的演示开始

我们要为虚构的“青禾商店”开发售后助手。用户说：“订单A100还没收到，物流如果已经确认丢件，就申请退款。”一个演示系统查询了物流，然后回答“已经为你退款”。录屏看起来成功，数据库却没有退款记录。另一个系统真的退款了，但没有核验订单属于当前用户。第三个系统成功退款，网络断开后重试，又退了一次。

三者分别暴露**任务结果错误、权限错误和执行语义错误**。它们不是靠同一句“请认真检查”就能解决的问题。本课程要教的不是让模型显得更聪明，而是把模型的选择放进可验证的系统里。

为避免混淆，全文的商店政策都是教学设定，不代表真实商家规则。金额以人民币分表示；时间由测试时钟提供，不读取真实“今天”。业务数据与模型输出同样可能包含不可信内容。

## 2. Agent到底是什么，为什么不默认需要它

在本课程中，Agent是这样一个闭环：观察任务和环境，提出下一步行动，由执行器校验并执行，接收结果，再决定继续、询问、转人工或结束。模型负责提出候选行动，不自动获得执行权限。

固定工作流把主要控制路径写在代码里；Agent允许模型在运行时选择部分路径。两者不是非黑即白：退款资格校验可以是确定性代码，查哪些资料可以交给模型，提交退款必须通过确定性审批。Anthropic区分工作流与动态Agent的方式可以作为术语参照，但这里的混合架构是本课程的具体设计。[S01](../../references/SOURCES.md#s01)

判定是否需要Agent时，先问三个问题。输入是否足够结构化？下一步是否已经能用规则决定？错误操作是否可逆？如果表单已经提供订单号、损坏原因和照片，固定流程可能足够；如果用户只说“上个月那件蓝色的没到”，任务需要搜索、澄清和根据结果改变路径，模型才可能减少人工协调成本。

<!-- interaction:I00 -->

## 3. 把成功写成契约，而不是一句主观评价

对A100，我们定义：当前租户为`shop-a`，用户为`u-alice`；订单属于该用户；物流状态为`lost`；可退余额为10000分；退款金额必须由业务服务计算；操作必须经过绑定具体金额的审批；同一退款意图无论尝试多少次，账本只能新增一笔。

成功条件是下面这个合取，而不是只检查回答文本：

`业务目标达成 ∧ 权限未越界 ∧ 审批有效 ∧ 账本不重复 ∧ 回答与事实一致`

“找不到订单，需要澄清”在订单信息不足的任务里可以是正确结果；在信息充分的普通查询里反复澄清则是失败。不能给所有任务强套一个“必须调用退款工具”的标准。

任务契约至少包含：输入与已知身份、可见资源、允许动作、禁止动作、终态判据、预算、超时、人工接管条件。验收器读取最终数据库或外部服务事实，而不是相信Agent给自己打的分。

## 4. 五个层次，三个不同的状态

本课程采用以下逻辑分层。它是为了清楚地分配责任，不要求部署成五个微服务。

```text
用户界面/API
   ↓ 认证身份、创建任务
协调层：任务状态、审批、预算、恢复
   ↓ 构造下一次模型输入
Agent Core：模型适配、上下文选择、行动解析
   ↓ 候选工具调用
工具网关：参数校验、授权、幂等、审计
   ↓ 已授权的领域操作
业务服务 / 隔离执行环境
```

第一种状态是**上下文状态**：下一次模型调用看到的消息、证据和工具定义。它可被压缩，不是完整事实源。

第二种状态是**执行状态**：任务走到哪一步、正在等谁、哪个工具尚未确认结果、预算还剩多少。它必须能支持恢复。

第三种状态是**业务状态**：订单、退款、工单和库存。它由业务服务维护，不由模型消息列表决定。

再加一个经常遗漏的对象：**事件记录**。事件是对已经发生的系统动作的记录，用于诊断、UI更新或恢复。观测日志可以采样，审计记录和恢复所依赖的业务事件通常不能任意采样。不要把三者混成一个无限增长的`messages`数组。

Anthropic的Managed Agents文章把协调、执行环境和持久会话拆开，是有价值的真实系统参照；课程不复制其产品实现，也不承诺其性能收益能迁移。[S11](../../references/SOURCES.md#s11)

<!-- interaction:I01 -->

## 5. 一条任务的完整走读

第一步，API从认证会话得到`tenant_id`和`user_id`，而不是让模型生成。第二步，创建`run_id`并保存用户请求，返回任务已接收。第三步，模型建议查询A100；工具网关验证参数并以当前主体访问订单。第四步，查询物流，只把必要字段和证据ID返回给模型。第五步，模型建议退款，但业务服务重新计算资格与金额，生成`proposal_id`。第六步，任务进入等待审批，不占用工作线程空转。第七步，用户在经过认证的界面批准这个提案。第八步，业务服务以稳定的`operation_id`提交退款。第九步，协调器记录结果，再让模型生成与账本一致的解释。

这里存在两个不同的“完成”：模型生成了最终文本，以及业务操作被确认。界面必须能表达“申请已提交，结果待核对”，不能把网络超时翻译成“退款失败”或者“退款成功”。

## 6. 用一个小模型描述工程目标

设任务集合为D，每个任务有质量Q、成本C、延迟T，以及安全约束V。我们不把它们草率合成一个漂亮分数。第一步先满足硬约束，例如跨租户泄露数为0、未授权退款数为0；第二步比较完成率；第三步在质量相近时比较成本与延迟。

可以记录`每个成功任务成本 = 所有试次总成本 / 成功任务数`。失败试次也要计费；成功数为0时返回“未定义/不可计算”，不要显示0元。训练、调参、评测的成本另列，避免把一次昂贵搜索包装成便宜推理。

工程优化的一个正确叙述是：“在相同任务集、模型配置和预算下，删去重复工具输出后，输入token降低，完成率是否变化仍需检验。”错误叙述是：“上下文越短越好。”

## 7. 项目驱动不等于不学原理

每章采用同一学习循环：先预测一个失败例会发生什么，再运行或手动推演，提出机制，补上反例，最后与真实系统比较。模型可以帮助解释代码、生成边界测试，但你必须能独立说明状态转移和失败边界。

建议为每个实验保存四件东西：失败轨迹、最小修复、回归测试、设计决策记录。面试中有价值的不是“用了某框架”，而是“我发现哪条假设不成立，用什么证据修正了它”。

Stanford CS329Z从组件构建、评测到项目的教学结构是参考之一；本课程正文、业务场景和验收数据是独立设计。[S13](../../references/SOURCES.md#s13)

<!-- knowledge:K01 -->
<!-- knowledge:K10 -->

## 8. 本章实施任务与过关标准

打开`specs/PROJECT_CONTRACT.md`，先读商店政策，再自己写A100的任务契约。画出哪部分拥有身份、哪部分拥有退款事实、哪部分可以被模型建议改变。把“同一个订单又退款一次”与“同一退款请求重试一次”分开描述。

过关不是写出更多组件，而是能用五分钟解释：为什么需要模型，哪些事情不能交给模型保证，什么是可验收的结果，以及为什么聊天历史不是可靠数据库。完成本章六道习题后进入M01；现在还不需要Redis、向量数据库或多Agent。
