Commit bfd92b98 by luoqi

docs(站点): 装配那节按 agent-architecture §六 的深度重写 —— 补上判据,不只描述现象

产品指出我写的不如 `docs/design/agent-architecture.md` §六。对比之后确实:
我只写了「按权限装出角色/现场/工具」这个**现象**,而那份写的是**判据** ——
为什么必须这么装、不这么装会怎样。照它的骨架重写。

补进来的四块:
  · **哪几维必须按身份分**:会话、工具清单(看不见比看见被拒更安全)、数据范围
    (下推到查询条件, 不是查全量再过滤)必须分;系统提示词分**但这是最不重要的一条**;
    模型和代码实现不用分
  · **为什么同一会话不能切换身份**:上下文是**单向**的,高权限会话里已载入的数据
    不会因为一句「你现在是低权限角色」而消失 ——
    **提示词不是删除操作,也从来不是安全边界**
  · **「两个 agent」要拆开**:同一套实现按身份参数化; 这不是「多 agent 编排」——
    编排指 agent 互相调用,而不同身份之间不需要通信,真要协作走业务对象
  · **四条硬规则**(身份随调用传递 / 授权在工具内部 / 数据范围下推 / 工具清单按身份下发),
    连同那条判据:**如果模型不传某个参数,越权就不可能发生 —— 那这个参数就不该是参数**

️ 保留我原来那个推论(它没有"记性" ⇒ 动过手之后必须重新看那张单),
  那条在原文里没有,而它正好解释了「看当前确认单」为什么存在。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
parent b2de3308
...@@ -223,25 +223,51 @@ flowchart TD ...@@ -223,25 +223,51 @@ flowchart TD
助手的行为由一段系统提示词决定。它不是一篇散文,是**五层拼起来的**,装配顺序就是模型的阅读顺序:**通用 → 特殊**。 助手的行为由一段系统提示词决定。它不是一篇散文,是**五层拼起来的**,装配顺序就是模型的阅读顺序:**通用 → 特殊**。
### 助手不是一个"对象",是登录之后现装出来的 ### 它是登录那一刻装出来的,⛔ 不是一个常驻的"对象"
系统里**没有**一个叫「助手」的东西常驻在那儿等人来问。每次请求都按**当前登录人的权限**现拼一份: 系统里没有一个叫「助手」的东西守在那儿等人来问。**每次请求都按当前登录人现装一份**,装配的输入只有一个:他的权限。
``` ```
登录人的权限 ──┬──→ ④ 角色 主管的助手 / 客服的助手 登录人的权限 ──┬──→ 会话 主管的会话 / 客服的会话,各归各的
├──→ ⑤ 现场 分配这条线 / 打单这条线 ├──→ 工具清单 21 个 / 9 个
└──→ 工具清单 21 个 / 9 个 ├──→ 数据范围 能查哪几家诊所的人
└──→ ④角色 ⑤现场 他是谁的助手、此刻在做哪条线
①②③ 与谁登录无关永远是同一份。 ①②③ 与谁登录无关,永远是同一份。
``` ```
由此得到三件事: ### 为什么必须按身份装,而不是"一个助手换个说法"
- **换个账号登录,它就是另一个助手** —— ⛔ 不是"同一个助手换了套权限"。三样东西同源同一个开关,不会出现「给了主管的话术,却没给主管的工具」。 | 这一维 | 要不要按身份分 |
- **不登录就是一块白板** —— 没有角色、没有现场、没有工具。现在没有这种场景,但结构上就是如此。 |---|---|
- **加一条新业务线 = 多一个 ⑤**,前面四层一个字不动。 | **会话** | **必须分** |
| **工具清单** | **必须分** —— 由登录态下发,**看不见比看见被拒更安全** |
| **数据范围** | **必须分** —— 下推到查询条件里,⛔ 不是查全量再过滤 |
| 系统提示词(④⑤) | 分,**但这是其中最不重要的一条** |
| 模型 | 不用分 |
| 代码实现 | 不用分 |
<Callout type="warn">
**为什么同一个会话里不能"切换身份"。** 上下文是**单向**的:高权限会话里已经载入的数据,不会因为一句「你现在是低权限角色」而消失。
**提示词不是删除操作,也从来不是安全边界。**
</Callout>
所以「主管一个 agent、客服一个 agent」这个说法要拆开看:**同一套实现,按身份参数化**。⛔ 这不是「多 agent 编排」—— 编排指 agent 之间互相调用,而不同身份之间**不需要通信**;真要协作,走业务对象,⛔ 不走 agent 消息。
四条硬规则,都在结构上而非嘴上:
1. **身份随每次调用传递**,⛔ 不随连接建立 —— 一个连接可能服务多个用户
2. **授权在工具内部执行**,⛔ 不在助手这一层
3. **数据范围下推到查询语句** —— 「查全量再过滤」漏一处就泄露;「条件里就带范围」漏一处只是查不到,**失败方向不同**
4. **工具清单本身按身份下发**
> **判据:如果模型不传某个参数,越权就不可能发生 —— 那这个参数就不该是参数。**
> 顺带的好处:模型不用猜,少一个必错的空格。
<Callout type="info">**它也因此没有"记性"。** 助手不是一个存着状态的对象 —— 上一轮的东西要么在对话历史里,要么就得重新查一遍。所以他在确认单上动过手之后,助手**必须重新去看那张单**,⛔ 不能拿出方案那一版的数接着算。</Callout> 由此还得到一个平时容易忘的推论:**它没有"记性"** —— 不是存着状态的对象,上一轮的东西要么在对话历史里,要么就得重新查。所以主管在确认单上动过手之后,助手**必须重新去看那张单**,⛔ 不能拿出方案那一版的数接着算(「看当前确认单」那个工具就是为此存在的)。
### 分层的判据是「什么会让它变」 ### 分层的判据是「什么会让它变」
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment