在构建高效的智能体用户体验时,加载状态是最被低估(也最容易被遗忘)的设计环节之一。
根据我们的经验,当用户能看清智能体实际在做什么时,他们才会信任这些智能体。这种行为越来越多地以拟物化 UI 的形式出现——一种让数字对象模仿现实世界对应物的设计理念。那个富有远见的Domino's Pizza Tracker就是最突出的拟物化设计范例之一,可以应用到智能体上。如今,数字加载状态(即便是那些可能会骗你的)对于让任何用户体验变得易懂且高效都至关重要。全新的 Managed Deep Agents 智能体反应 SDK 是一个绝佳工具,可用于为与你的智能体交互的用户构建令人愉悦的界面和加载状态。
Managed Deep Agents 中新增的 reactions 属性
在 v0.9 中,Managed Deep Agents 包含一个新的 API,用于管理你的分布式智能体的反应,以及一个系统,可通过你选择的工具(如决策模型、前沿模型,或老派的if语句)动态分配 emoji 回应。

Thenew reactions属性用于Slack 频道接受一个表示 emoji 的字符串,或一个返回 emoji 的可调用对象:
frommanaged_deepagentsimportchannelsasyncdefchoose_emoji(context:dict) ->str:return"bug"if"broken"incontext["text"].lower()else"eyes"channel = channels.slack(name="Support Bot",reactions=choose_emoji)在这个示例中,我们默认使用 👀,但如果消息中包含“broken”一词,静态分析会分配 🐛。
我们希望 LangChain 开发者能够采用常见的、让用户在加载状态和等待模式中感到愉悦的模式,因为许多智能体任务可能会运行很长时间。与智能体交互的最终用户需要得到确认,知道任务已被接收。
例如,我们最近上线了一个内部营销智能体来制作视频内容。在等待智能体回复时,让用户了解智能体的进度会很有帮助。
以下是我们智能体可以制作的视频和动态图形内容类型的示例:
仅仅用一个 emoji 回复一条消息往往是不够的。我们还需要让智能体告诉用户它是如何理解任务的,而带有上下文的回复可能是智能体设计中的关键部分。
让我们把基本的 reaction 示例再推进一步。我们可以让一个决策模型,比如 Jev,根据输入上下文从一组固定的 emoji 词汇表中进行选择。Jev 最多支持 255 个选项,但你可以用多个问题构建一个决策矩阵(例如,把 emoji 分组为若干类别,先让 Jev 选择一个类别,再选择一个 emoji),从而在更多 emoji 上进行查询:
fromfunctoolsimportlru_cachefromlangchain_typesafeimportChoice, TypeSafeClassifierfrommanaged_deepagentsimportchannels# 描述是模型用来匹配的依据,所以要描述情境# 而不是图片。为任何不起眼的情况保留一个选项。VOCABULARY = Choice(instructions="哪个 emoji 最能回应这条消息?",criteria={"bug":"一个缺陷或错误行为。","rotating_light":"一个已声明的事件或故障。","mag":"一个需要查看的代码审查、拉取请求或 diff。","hourglass":"在等待某人或某事;被阻塞。","speech_balloon":"一个问题,或请求解释某事。","wave":"一句问候或打招呼。","eyes":"任何不能明确归入其他选项的情况。",},)@lru_cache(maxsize=1)defclassifier() -> TypeSafeClassifier:returnTypeSafeClassifier(model="typesafe/jev-latest")asyncdefchoose_emoji(context:dict) ->str:answer =awaitclassifier().ainvoke({"state":context["text"][:2000],"questions":{"emoji":VOCABULARY}})emoji = answer.choices["emoji"]# 低于这个值模型就没有真正的判断,所以优先使用通用的 reaction。returnemoji.choiceifemoji.confidence >=0.25else"eyes"channel = channels.slack(name="Support Bot",reactions=choose_emoji)在这个示例中,我们使用了新的TypeSafe Classifier,它是 LangChain 工具包的一部分。这是与TypeSafe 兼容的决策模型(比如 Jev)交互的好方法,但也可以使用具有相同端点的其他决策模型,比如托管在LangSmith LLM Gateway上的 SemIf。或者,在不同模型之间切换,以试验出最佳选项。
同一个 emoji 的含义可能截然相反,取决于智能体做了什么。例如,来自 on-call 智能体的 🔥 可能意味着生产环境着火了,你该起床了。来自 growth 智能体的 🔥 可能意味着营销活动奏效了,你可以继续睡了。这就是为什么criteria描述比 emoji 名称起的作用更大。模型是根据你对情境的描述进行匹配的,所以同一个符号承载的含义取决于你的工作区已经赋予它的意义。
上面的例子还说明你可以利用置信度阈值。如果决策模型对其首选结果的置信度低于 25%,我们会回退到 👀。如果词汇表中提供的 emoji 都不太合适,你也可以回退到不做任何反应。
你可能会说这种设计有失诚实:因为是由另一个模型来给做出反应的模型所给出的反应打分,所以在解读上可能存在细微差异。因此,重要的是要写好你期望每个反应如何被使用的有效描述。如果某个反应的描述过于笼统,打分模型就会过度偏向某些反应,即使换一个反应在未经训练的人看来并不会过拟合。
你可以通过 Slack shortcode 向词汇表中添加自定义 emoji。对于我们的内部内容智能体,应用 AI 团队创建了一组自定义 emoji,供智能体在回复中使用。我很喜欢lc-no-em-dash,当被指示撰写内容时,智能体会选择它:

尝试不同的方法。为 emoji 编写不同的描述(或者以完全不同的方式组织你的词汇表)会带来不同的结果。同样,也可以扩展或收缩智能体可用的 emoji 集合。
Managed Deep Agents 旨在通过简单、富有表现力的 API,充分利用我们认为对智能体落地至关重要的所有那些微妙的设计接口。使用以下方式为现有的 Managed Deep Agents 添加反应:我们的文档。或者,如果你之前没有构建过 managed deep agent,最好的入门之处是我们的快速入门。