把智能体嵌进一个既有应用。
螺在产品右边缘上的那个聊天面板,是你能交付的最便宜的东西,也是大多数应用内智能体被用两次就被弃用的原因——它对用户正盯着的那块屏幕一无所知,于是每一次提问都得先由用户把自己的应用重新描述一遍。真正决定一个嵌入式智能体能否在工作流里站住脚的,是对当前视图的读取权,以及沿着界面本来就在走的那条代码路径去写入的权限;而唯一无法事后补救的决定,是智能体的状态存在哪里。
按任务挑界面形态,别按侧边栏模板挑。
应用内智能体有三种形态,各自解决不同的问题。只交付第一种就宣告完工,是标准的失误。
- 面板。与应用并排的一段常驻对话。适合没有明显锚点的开放式工作——"为什么 EMEA 的收入掉了"——而对任何用户已经指着的东西都不合适。最省事,也最难做到不可或缺。
- 内联,锚定在一个对象上。在某一行、某份文档、某段选区、某个失败的测试上唤起智能体。锚点白送了大部分上下文,结果也落在用户本来就在看的地方。价值通常就在这里,而它压根不需要聊天记录。
- 环境式。无需唤起——智能体盯着状态,在某个条件成立时主动浮出一条建议。单次交互价值最高,惹人烦的风险也最高;请按异步与离场里讲的通知预算来配给它。
数一数你排名前十的用户任务里,有多少个带天然锚点——一行被选中的记录、一份打开的档案、一段被高亮的范围。如果多数都有,那面板就是错的第一形态,而你会在半年后从一张活跃度曲线上才学到这件事。
把视图交给智能体,以结构化上下文的形式。
一个看不见用户所见之物的智能体,会迫使每一段对话都以一大段"背景交代"开场,而用户很快就不愿再交这笔过路费了。解法是把当前视图作为请求的一部分传过去——但要传数据,不要传像素。
- 传标识符和状态,别传截图。路由、实体 ID、当前筛选条件、排序、选区,以及可见的时间范围。截图要花视觉 token、送达时不带智能体能用来行动的 ID,还把一次查表变成了一道 OCR 题。
- 在服务端解析。客户端发来
invoice_id;服务端以用户自己的权限去取这张发票,再放进上下文。绝不要让客户端把它恰好还留在内存里的记录直接递过来——智能体读到用户会话本已无权再次获取的数据,就是这么来的。 - 给它记预算。视图上下文每一轮都会被重发,并且会随页面一起变大。给它设上限、宁可传引用别传载荷,并把稳定的那部分放在最前面以便命中缓存——这笔账在智能体成本控制里。
- 把"过期"这件事说明白。用户在对话中途改了筛选条件。要么每一轮都重发视图、让智能体看着它变;要么只快照一次,并且说清楚。嘴上是后者、实际做前者,得到的就是关于一块已经不存在的屏幕的答案。
沿着界面已经在走的那条代码路径写入。
诱人的捷径是给智能体开一条快车道——一个绕过了人类路径上的校验、权限检查与审计写入的内部薄接口。它在演示里能跑通,然后给你贡献第一起事故。
- 只留一个执行点。如果界面不能归档一个已关闭的账户,智能体的工具也必须不能,而且理由必须是同一处检查,不是它的第二份副本。两份副本会分叉,而智能体那份是没人记得要更新的那份。
- 同一条审计记录,不同的执行者。每一次写入都记下人类委托人,以及"这是由一个智能体代为执行的"这个事实。一份分不清两者的动作日志,会让事后归因变得不可能——正是共享与多用户智能体里点名的那种、能终结试点的失败。
- 返回一个撤销句柄。每一个会改变状态的工具,都返回足以撤销自身的信息。这正是日后你敢于拿掉一个确认弹窗的底气;见撤销与可逆性。
- 按后果设关卡,别按新鲜度设。可逆的写入放行;不可逆或对外的写入设关。分级方法在审批与确认体验里。
决定智能体状态存在哪里——这就是那个无法事后补救的决定。
对话历史、待执行的工具调用、计划进度和中间结果,总得存在某个地方。诚实的答案只有两个,而这个选择会渗进你之后建的每一样东西。
- 存在客户端。状态待在应用自己的 store 里。快、与界面天然一致、不需要会话基础设施。它会在刷新时死掉,无法在另一台设备上续上,也撑不起一个活得比标签页更久的运行。
- 存在服务端。一个以会话为键的持久会话,客户端订阅它。能扛过刷新、能在手机上续上,也能让一个长任务在用户合上笔记本之后继续跑——这正是持久状态与可恢复性所讲的性质。
决定它的那条规则是:只要有任何任务可能活得比页面久,状态就必须存在服务端——而实践中总会有这样的任务,因为一个商业应用里第一个真正有用的智能体任务,耗时就已经超过用户愿意干坐着等的时长。日后从客户端迁到服务端,意味着重写流式输出、重连,以及每一个消费这段对话的界面,所以请在一开始就把这笔钱付了。
第二块界面就是那道检验。如果要为同一次运行做一条 Slack 通知、一个手机视图或一封邮件摘要,需要把智能体重新实现一遍而不是订阅它,那你的状态就放错地方了。
与一个自己也在变的界面做调和。
聊天窗口是一个只有一个写入者的页面。嵌入式智能体则是同一份文档的第二个写入者,而用户此刻正在编辑它——冲突是真会发生的。
- 把流式输出灌进一个容器,别灌进文档。把部分输出渲染到一块用户可以"接受"的复核界面里,而不是直接写进记录。否则一条被拒绝的建议早已把数据弄脏了——这正是流式与部分输出是一个呈现决策、而不只是一个传输决策的原因。
- 绝不覆盖人类的编辑。如果底层对象在智能体读过之后发生了变化,就停下来把冲突亮出来。一个悄悄回退了某人刚做完的修复的智能体,会永久失去信任,而这正是中断、引导与交接点名的那种失败。
- 让中断既便宜又不具破坏性。一个停止控件,按下后应用停在一个合法的中间态上,已完成的步骤保留,计划仍然可见。
- 定好一块生成出来的界面可以做什么。如果智能体渲染的是组件而不是散文,那它只能从一份你自己拥有的目录里挑选,并且绝不自行决定任何事——这份纪律在生成式界面与智能体渲染的界面里。
给你真正想推动的那件事装上仪表。
消息条数和会话时长量的是"聊了多少",那恰恰与目标相反。嵌入式智能体的成功方式,是从一条本来就存在的工作流里拿掉步骤,所以指标必须锚在那条工作流上。
- 应用内的任务完成率——发票对上了、工单解决了——归因到有智能体参与的那些运行,并与同一任务的人工完成做对照。
- 建议写入的接受率,按工具拆开。接受率低于五成的工具是在制造复核工作,不是在省下它;修好它,或者删掉它。
- 接受之后的编辑距离。一条用户先接受、随后又全部重写的建议,在你的漏斗里记成了成功,在他的下午里则是一次失败。
- 在同一对象上的再次唤起——用户就同一条记录又问了一遍,是最干净的信号:第一次的答案没接到你以为自己传过去的那份上下文。
在造面板之前,先在用户碰得最多的那一个对象上交付一个内联动作,接到既有的写入路径上,并且从第一天起状态就存在服务端。这是一周的工作量,能产出一个真实的接受率数字,并告诉你智能体究竟该不该出现在这个产品里——而这恰恰是聊天面板极擅长回避的那个问题。
相关:等待与延迟的交互设计讲它在干活时该显示什么,首次运行与用户引导讲如何在第一次使用时校准预期,智能体交互模式是概念层面的地图。