我曾经做过一个很“完整”的 AI 助手。
它能读取书签、笔记、文件、待办和标签,也能调用工具完成修改;支持连续对话、引用材料、生成笔记、创建待办,还尝试理解用户下一句话是在承接上一轮,还是开始一个新任务。
单看功能列表,它很像大家想象中的 AI Agent:
一个入口,几乎什么都能问、什么都能做。
但真正长期使用之后,问题也越来越集中。
用户只是想总结当前文件,AI 却先要猜他处在哪个模块;用户已经选中一篇笔记,系统仍可能把上一轮资料带进来;一句“再详细一点”,既可能是改上一份草稿,也可能是新问题。
每修一个例子,Prompt、关键词、特殊分支和上下文规则都会再长一点。
最后我做了一个看起来很激进的决定:
删掉全局 AI 助手,把它拆成 20 个嵌入业务页面的 Skills。
功能入口看起来变少了,AI 不再悬浮在所有页面上,也不再承诺“什么都能聊”。
结果反而更好用。
一、全局助手最难的不是模型能力,而是“它现在到底该做什么”
一个全局助手接到用户消息时,往往要同时判断:
- 这是普通聊天,还是业务任务;
- 目标是书签、笔记、文件还是待办;
- 应该读取当前页面,还是去整个工作区检索;
- 是否要沿用上一轮材料;
- 只回答,还是调用工具;
- 写操作是否需要确认;
- 缺少信息时要不要追问。
这些判断并不是语言表达的小细节。
每判断错一项,后面整条链路都会歪。
例如用户在文件预览页点击 AI,只说:
总结一下。
页面其实已经给出了最强信号:当前就是这个文件。
但全局助手如果仍把它当成开放式对话,就可能:
- 重新猜测“总结什么”;
- 在历史里寻找上一轮对象;
- 向工作区搜索类似资料;
- 暴露一批不相关工具让模型选择。
用户已经通过页面完成了一次明确选择,系统却让模型再猜一遍。
这种“重复理解”既增加延迟,也增加错误概率。
二、拆成 Skills 后,页面先替模型回答三个问题
Skill 不是把同一个聊天框复制到二十个地方。
它更像一份由页面和服务端共同确定的任务契约。
用户点击某个 Skill 时,三个问题已经有答案。
当前要处理什么对象
例如:
- 当前笔记;
- 当前选区;
- 当前书签;
- 当前文件;
- 当前待办表单;
- 用户在资源中心明确选择的一组资料。
当前允许做什么
例如:
- 总结;
- 比较;
- 改写;
- 生成大纲;
- 拆解清单;
- 解析为待办草稿;
- 根据所选材料生成新笔记。
结果应该长什么样
例如:
- 一段只读回答;
- 带来源的总结;
- 可应用到编辑器的文本预览;
- 待办清单草稿;
- 新笔记预览或已保存结果;
- 明确的失败和覆盖提示。
模型不再决定“进入哪个业务模块”。
它只处理 Skill 内仍然开放的语言理解和生成。
三、20 个 Skills 不是 20 套 Agent
这是重构时最重要的一点。
如果笔记、书签、文件和待办各自复制一套调用模型、算额度、处理错误和记录日志的代码,系统只会从一个巨型 Agent 变成二十个小型混乱。
最终结构更接近:
业务页面
↓
选择一个 Skill
↓
服务端 Registry 确认任务、版本、权限和范围
↓
重新读取当前资源
↓
统一 AI Execution
↓
一次或多次模型调用
↓
输出校验、来源与覆盖检查
↓
回答 / 草稿 / 可确认结果
所有 Skill 共用同一套内核:
- 权限和 owner 校验;
- 资源版本读取;
- Provider 策略;
- Token 用量;
- 错误映射;
- 来源和 Coverage;
- 写入预览;
- 幂等和终态。
变化的只是任务契约。
四、为什么页面上下文比更长的 Prompt 更可靠
以前为了让全局助手知道用户“正在看什么”,我们会尝试向 Prompt 塞入更多上下文:
- 当前路由;
- 最近访问;
- 上一轮引用;
- 页面标题;
- 用户选择;
- 对话历史;
- 可能相关的资源。
材料越多,模型看起来知道得越多。
但其中很多只是“候选”,并不是权威事实。
现在页面只提交资源引用,服务端再按当前账号重新读取:
- 资源是否存在;
- 是否仍属于当前用户;
- revision 是否变化;
- 类型是否满足当前 Skill;
- 数量和大小是否超过范围。
客户端告诉服务端:
用户选择了这个对象。
服务端负责确认:
当前用户此刻确实可以用这个对象完成这个 Skill。
这比把页面内容直接拼进 Prompt 更稳,也避免前端旧状态成为事实源。
五、对话历史不再跨模块流动
全局助手还有一个很难处理的问题:历史到底应该保留多久。
用户先分析一个书签,再打开文件问一句:
这里的风险是什么?
如果共用同一会话,模型可能把书签内容也带进来;如果每次都清空历史,“再详细一点”又无法承接。
Skills 让历史生命周期变得清楚:
- 单次改写、解析、待办草稿:不需要历史;
- 当前书签总结:只保留少量同资源追问;
- 文件问答:在同一个文件范围内保留有限轮次;
- 资源搜索:历史只用于理解省略,每轮重新检索;
- 帮助中心:只能继续检索公开帮助;
- 不同 Skill、不同资源、不同账号主体永不共享历史。
历史终于只服务当前任务,而不是整个产品。
六、写操作不再让模型直接决定“现在就执行”
页面 Skill 里仍然有写能力,但模型不直接改数据库。
例如待办拆解:
- 读取当前标题、说明和已有清单;
- 模型生成结构化步骤;
- 页面展示可检查预览;
- 用户点击应用;
- 最终仍走原来的待办保存逻辑。
笔记改写同样如此:
- 先生成草稿;
- 用户检查;
- 再替换当前正文或创建新笔记。
这条边界让 Skill 更像“业务功能中的智能辅助”,而不是拥有额外权限的另一个系统。
模型负责提出结果,现有业务 Service 负责提交事实。
七、用户看到的入口少了,但每个入口更容易理解
全局助手的入口通常只有一句:
问问 AI。
用户点进去以后,才需要思考“我该怎么描述”。
页面 Skill 则直接把任务写出来:
在笔记里:
- 摘要;
- 润色;
- 纠错;
- 续写;
- 翻译;
- 生成大纲。
在文件里:
- 总结当前文件;
- 基于当前文件问答;
- 比较所选文件。
在待办里:
- 拆解待办;
- 解析自然语言草稿。
这种变化看起来限制了自由度,却降低了用户的提示词成本。
用户不再需要先学会“怎么对 AI 说”,而是直接选择自己想完成的动作。
八、为什么移动端最显眼的位置也不再留给 AI
移动底栏的位置很稀缺。
过去最中间的位置放全局 AI,看起来很有产品辨识度,但它并不一定是最高频动作。
用户在手机上更常做的是:
- 存一个链接;
- 记一句话;
- 上传一个文件;
- 新建一条待办。
所以中间入口最终换成了确定性的“快速添加”。
AI 没有消失,而是回到真正需要它的页面:
- 看笔记时处理正文;
- 看书签时分析网页;
- 看文件时总结和问答;
- 编辑待办时拆解任务。
这比用户先离开当前页面、打开全局助手、再重新告诉它上下文更自然。
九、旧会话怎么处理
删除全局助手,不代表把用户历史一起删掉。
旧会话保留:
- 查看;
- 导出;
- 删除。
但不允许继续发送新消息。
原因很简单:旧会话建立在旧的全局材料、工具和历史语义上。如果继续允许发送,就等于长期维护两套互相冲突的产品边界。
把它变成只读档案,既保留用户内容,也阻止新逻辑继续依赖旧架构。
十、功能真的变少了吗
从“一个入口能不能做所有事”来看,确实少了。
不再把下面这些当作产品目标:
- 普通知识闲聊;
- 跨模块自由规划;
- 自动猜测用户正在处理哪类资源;
- 在一个无限会话里承接所有历史。
但用户真正高频的能力仍然存在,而且更靠近任务:
- 笔记处理;
- 书签分析;
- 文件问答;
- 待办拆解;
- 跨资源只读检索;
- 产品帮助问答。
少掉的是模糊承诺,留下的是可以解释、可以测试、可以稳定交付的能力。
十一、这种形态也有代价
模块化 Skills 并不适合所有产品。
它会牺牲一部分开放感:
- 用户不能随意把多个模块和写操作拼成超长任务;
- 新能力需要先定义 Skill 契约;
- 页面要承担更多入口设计;
- 跨模块任务需要显式选择资料,而不是让模型自动漫游。
但对于一个长期保存私人数据、还能执行写操作的知识工具,我更愿意接受这种约束。
AI 越接近真实数据和真实动作,边界越应该先于自由度。
结语
我们最初想做的是一个“懂整个知识库”的助手。
最后发现,真正好用的 AI 不一定需要一直站在产品中央。
它可以安静地待在每个具体任务旁边:
- 当用户写笔记时帮他改写;
- 当用户看文件时帮他理解;
- 当用户建待办时帮他拆解;
- 当用户明确选择资料时帮他整理。
删掉全局助手以后,功能看起来少了,产品却更容易理解,也更容易信任。
这次重构来自我维护的一个开源知识工作区,完整项目可以在这里查看: