Files
blog/content/posts/feishu-doc-as-ssot.md
T
Fam Zheng 945c7ac45d
publish / build-and-publish (push) Successful in 5s
post: 飞书文档作为 AI Agent 的 SSOT
2026-05-08 08:52:56 +01:00

112 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "将飞书文档定义为 AI Agent 的 Single Source of Truth"
date: 2026-05-08T08:40:16+01:00
draft: false
tags: ["AI", "Agent", "协作", "Ida"]
summary: "文档承载内容,对话承载信号。把飞书文档当成 AI Agent 的 SSOT,把单聊降级为触发与通知通道——这不是工具选型,是协作模型的重构。"
---
跟 AI Agent 协作久了,我越来越确信一件事:**对话流不是协作的本体,文档才是**。
聊天窗口是人和 agent 都很容易掉进去的舒适区——一来一回、随手发问、即时反馈。但凡用过几次就会发现问题:上下文滚走了找不回来,agent 改过的东西散落在十几条消息里,想审阅一下"现在到底是什么状态"得自己往上翻。聊天流天然是**线性**且**易腐**的,它适合传递信号,不适合沉淀状态。
所以我最近在琢磨一种协作模型:**把飞书文档定义为 AI Agent 的 Single Source of Truth,把单聊降级为触发与通知通道**。
## 双通道分工
| | 飞书文档 | 单聊对话 |
| --- | --- | --- |
| 角色 | Single Source of Truth | Trigger & Notification |
| 承载 | 需求、上下文、过程记录、最终产出 | 启动信号、完成提醒 |
| 寿命 | 长期、可追溯 | 短期、易腐 |
| 操作 | 读写、审阅、协作编辑 | 发送、接收 |
一句话概括就是:**内容沉淀在文档,信号流转在对话**。
这个分工不是为了让对话变得没用——恰恰相反,它让对话回到了它最擅长的事:**告诉对方"该看了"**。把内容塞进对话,是在让一个本来负责传信号的通道兼职做归档,结果两头都做不好。
## 一次完整的协作回合
具体跑起来是这样的四个阶段。
### 一、混沌投递
用户在飞书文档里**自由地抛**:需求一句话、背景三段话、参考链接五个、随手贴的截图两张、还没想清楚的问题若干。文档允许处于"混沌状态",无需预先结构化。
这一阶段用户的负担是**抛出**,不是**整理**。这点很重要——传统流程里,人最大的内耗在"我得先把这事儿想清楚才能让 AI 干",结果光是整理需求就消耗了一半精力。让文档容忍混沌,是把结构化的成本转嫁给了 agent。
### 二、信号触发
用户在**单聊**里把文档链接发给 agent。这一动作是**显式的启动指令**——明确告诉 agent:哪个文档、什么时候开始。
显式触发很关键。你不希望 agent 在你还在打草稿的时候就跳出来开干,也不希望它在群里看到 @ 一下就以为是叫它。**让用户主动按下这个按钮**,边界就清晰了。
### 三、文档内施工
主 agent 拉取文档全文作为上下文,解析意图,调度子 agent 矩阵分工执行。重点是这一步——**所有的工作产出都直接写回文档**:
- 当前阶段、进度
- 子 agent 任务分配与完成情况
- 结论性文字
- 执行日志(Update Log
- 附件、内联图片、中间产物
而且产出策略是 **Append-only**——只增不减。用户的原始混沌输入不会被覆盖,agent 只在它之上追加新的层。任何回滚、对比、复盘都有据可查。
这一步等于把传统聊天流里那些"agent 内心戏"**全部外化**到文档里。你随时点开文档就能看到它正在做什么、做到哪一步、为什么这么做。不需要追问,不需要等总结。
### 四、回流审阅
阶段性工作完成后,agent 在**单聊**发一条 "请审阅" 信号。信号本身极简——链接 + 一两句摘要要点,**绝不复述文档内容**。用户回到文档进行审阅、修改、追加新需求。
这就形成了一个闭环:**文档 → 单聊触发 → 文档施工 → 单聊通知 → 文档再审阅**。
注意整个闭环里,对话从未承载过任何"状态"。它只在两个时刻出现:开始和"该你了"。
## 为什么这样设计
### 文档是意图的编译产物
我之前写过 [Ida](/posts/ida-intent-driven-agent/) 的工程观——人提供意图,agent 把意图编译成各种产物。这个 SSOT 模型其实是 Ida 的一个直接落地:
- 用户输入的混沌片段是**意图与上下文**(源代码)
- agent 的工作是把意图"编译"成结构化、可执行、可审阅的产物
- 文档是这次"编译"的**输出工件**,而不是草稿本
这个视角的好处是:你不会再纠结"文档里这部分是用户写的还是 agent 写的"。所有内容都是同一份意图的不同投影,区别只在于**层级**——原始输入是底层,agent 产出是上层。
### 用结构化记录消除黑盒感
agent 最让人不放心的地方是黑盒——它去了,干了,回来了,但中间发生了什么你不知道。各种"思考过程可视化"的方案都在试图打开这个黑盒,但聊天流里那些 thinking、reasoning、tool call 看着热闹,过后回头找东西基本找不到。
把过程**直接写进文档**是一种粗暴但有效的解法。Update Log 不是给 agent 看的,是给人看的——结构化、时间序、可检索。你随时打开文档就能回答"这个 agent 现在在做什么 / 为什么这样做",不依赖事后解释。
**过程透明本身就是文档的一部分**。这一点是我在 [白盒施工,黑盒交付](/posts/whitebox-blackbox/) 里讲的"白盒"在 agent 协作里的具体形态——施工期把所有零件摆在台面上。
### Append-only 是不可逆承诺
agent 不删除用户内容,只在其上追加。这条规则看起来朴素,实际上是**一种契约**:
- 用户的原始混沌输入是**历史档案**
- agent 的新产出是**演进层**
- 任何时刻都能回到任何一个版本
它解决的核心焦虑是"agent 会不会把我写的东西改坏了"。在 append-only 之下,这个焦虑不成立——它没有"改"的权限,只有"加"的权限。审阅成本因此急剧降低:你不需要 diff,只需要扫一眼新增的部分。
## 几个实践要点
把这套模型落到飞书上,有几个细节值得拎出来:
- **文档结构化模板**。给每篇协作文档预设固定区块——"原始输入"、"执行计划"、"Update Log"、"产出"、"待确认"。agent 只在指定区块写东西,不污染用户区。
- **单聊信号语言极简**。"请审阅"、"已完成阶段 X"、"卡在 Y 需要你决策"——三种以内。复杂内容一律链接+回文档。
- **每阶段一个明确的"该你了"节点**。不要让 agent 不停推进 50 步以后才回头。审阅频率应该是**人决定**的,不是 agent 自己掌握。
- **权力归用户**。agent 提建议、写产出、记录过程;但删什么、保留什么、下一步走哪儿,永远是用户拍板。
## 收口
这个模型最让我喜欢的一点是它**不需要新工具**。飞书文档有了、单聊有了、文档 API 有了——拼起来就能跑。它本质上不是技术问题,而是一个**协作约定**:内容归文档,信号归对话,过程透明,只增不减。
聊天界面还会存在,它是必要的——人和 agent 之间总得有个直接说话的地方。但聊天不应该是协作的主舞台。把舞台让给文档,让对话回到它该在的位置——一个**短促、克制、用来传信号的通道**——整个协作流程会立刻变得可控、可审、可复盘。
agent 不再是个聊天框里的黑盒,而是一个**在文档上施工的施工队**。这个画面,比"对话式 AI 助手"清楚太多了。