LLM 面试备考
首页/Agent 架构

异步事件驱动、语音与 Computer Use:交互的时机与模态扩展(Async, Event-Driven, Voice & Computer Use)

所属:01-fundamentals / 04-agent-architecture
面试权重:★★★(异步与事件驱动是主体,属必答;语音与 Computer Use 按「知识 + 边界」准备,权重低于异步 —— 考的是你能不能讲清架构、并诚实划界)
来源:《深入理解 AI Agent:设计原理与工程实践》第 6 章(李博杰,github.com/bojieli/ai-agent-book);非一手实测
相关知识点:human-in-the-loop.md、agent-react.md、context-engineering.md、memory.md、06-agent-infra/observability.md、01-llm-core/multimodal.md

一句话#

前五章的 Agent 都是**回合制(turn-based)**的:用户说完一句,Agent 想一段、调几个工具、回一句,而在它思考的这段时间里,世界被默认为静止的。这一章挑战的正是这个前提 —— 回合制是模型与接口的一种交互约定,不是环境的性质。真实世界不会等模型作出反应:邮件在它思考时到达,用户在它说到一半时插话,页面在两次截图之间已经变了样。于是观察空间与动作空间各多出两根轴:

  • 模态决定观察与动作的形式:只读文本,还是也能听见声音、看见屏幕;只能输出 token,还是也能发声、点击。
  • 时机决定观察与动作的节奏:观察是 Agent 主动去取,还是世界主动推来;动作是必须在一个回合内做完,还是可以跨回合、中途被打断、被更紧急的事抢占。

本章沿这两根轴展开四节:异步与事件驱动(时机,尺度秒—天)、语音(模态 + 时机,10 毫秒—1 秒)、Computer Use(模态,亚秒—秒),以及机器人操作(边界之外,毫秒)。

为什么重要(面试角度)#

  • 这是「demo agent」与「生产 agent」的分界线。demo 一定是回合制的:一问一答、干净可控。生产系统要面对「世界在你思考时发生了变化」——后台任务、定时任务、用户中途插话、外部回调。答得出异步,才像做过系统。
  • 它是编排能力的直接证据。事件队列、安全点、取消与抢占、任务句柄 —— 这些是并发编程里成熟的概念被搬到 agent 上。面试官能从这道题看出你有没有系统设计底子(同源概念见 06-agent-infra/batching-parallelism.md)。
  • 它把仓库里几块内容缝起来:事件流就是 06-agent-infra/observability.md 里的 trace;「只传路径不传内容」是 context-engineering.md 的上下文预算;虚拟身份用 VNC/RDP 做认证是 human-in-the-loop.md 的 HITL 的一个具体形态。
  • 语音与 Computer Use 是边界题。香港的 AI Engineer 岗位大多不要求做过 GUI Agent 或语音,但面试官可能拿它试深度。这时诚实划界 + 讲清架构得分最高;把书上读来的东西讲成做过的事,追问两层就崩(这条纪律见 01-llm-core/multimodal.md 顶部的硬规矩)。
  • 有一句可以直接背的话:不能仅凭代码用了 asyncio,就认定模型也具备原生异步能力 —— 应用层并发 ≠ 模型层的异步协议。这句话能立刻区分「读过高层的介绍」和「想过实现」。

核心内容#

一、异步与事件驱动#

1. 为什么需要异步:柜台 vs 秘书#

同步(Synchronous)意味着「做完一件事才能做下一件」;异步(Asynchronous)意味着「多件事可以同时进行」。

  • 同步 Agent = 只会排队的柜台:每次只处理一个顾客,处理完才叫下一个号。
  • 异步 Agent = 灵活的秘书:桌上摆着多个待办(邮件、电话、来访者),按紧急程度决定先处理哪个;处理到一半有更紧急的事,可以暂停切换。

同步架构下,Agent 要么等后台任务完成才能与用户对话,要么等对话结束才能处理新到达的事件。它无法支撑真实助理场景的三项核心能力:

  1. 异步执行是常态 —— 许多任务长时间运行,不应阻塞用户交互。
  2. 事件优先级的动态判断 —— 不是所有事件同等重要,Agent 要能选择策略:取消当前操作(紧急)、加入队列(常规)、还是并行处理(独立的轻量级查询)。
  3. 中断和恢复的流畅性 —— 被打断的对话或任务应能自然恢复。

⚠️ 关键判断:把异步范式套到 LLM 上,先要检查模型和 API 是否支持这种消息时序。有些接口要求先补齐工具结果才能继续;有些已经允许工具挂起、模型继续工作、生成过程中接受用户更新。前者需要事件队列、任务句柄和兼容层,后者可直接用原生异步协议。两者都仍需应用管理事件来源、工具生命周期与结果归属 —— 不能仅凭代码用了 asyncio,就认定模型也具备原生异步能力。

技术上,「事件驱动」意味着系统不再反复检查「有没有新消息」(轮询,效率低),而是在新消息到达时自动触发处理逻辑。所有输入、输出、思考过程和外部交互都被统一建模为事件流——一条时间线上依次排列的事件记录,由事件循环驱动。

2. 三种内置机制:Hooks / Cron / Heartbeat#

开源框架 OpenClaw 通过 Gateway 控制平面接收多渠道消息并路由到 Agent 运行时,提供三种内置的事件驱动机制:

机制 是什么 触发来源
Hooks(事件钩子) 响应 Agent 生命周期中的事件(会话创建、重置等),类似 GitHub Actions 中的事件触发器 框架内部,不是外部世界
Cron(定时调度器) 按 cron 表达式执行周期性任务,例如 0 9 * * 5 = 每周五上午 9 点 时间
Heartbeat(心跳守护进程) 每隔 N 分钟唤醒一次 Agent,检查是否有需要关注的事项 时间

这三种机制给了 Agent「自主」的外观 —— 即使用户不在线,也能定时生成报告、检查系统状态、处理例行事务。Gateway 对内置渠道(IM、Web 界面)的消息本身是推送式的,消息一到就路由给 Agent。

⚠️ 关键判断(面试里最容易被问住的一处):三种机制里,真正让 Agent 在没有用户消息时「自己动起来」的只有 Cron 和 Heartbeat,而它们都是时间驱动的 —— Heartbeat 每隔固定间隔查一次,Cron 按预设时间触发;Hooks 的事件来源是框架内部。结果:对内置渠道之外的第三方事件源(一封新邮件到达、一个外部 API 回调、一个需要立即处理的紧急通知),这套机制缺乏即时接入的通道,Agent 只能在事件发生后等下一个 Cron / Heartbeat 周期才可能察觉。

PineClaw 案例(说明「延迟不可接受」的代价):Pine AI 是一款代替用户拨打真实电话的 AI 助手(协商账单、取消订阅、处理保险理赔)。用户通过 OpenClaw Agent 发起 Pine 电话任务后,通话过程中可能随时需要用户介入:

  • 实时身份验证:客服要求验证账户持有人身份,需要用户立即提供安全码或 OTP(一次性密码)
  • 三方通话确认:客服要求与账户持有人直接对话,需要用户在几秒内接听电话
  • 进展同步与决策确认:协商到关键节点(如对方提出降价方案),需要用户确认是否接受

若依靠 Heartbeat 定时轮询,用户可能在客服等待验证码时迟迟收不到通知,导致客服挂断、通话失败。解法是引入 Channel 机制 —— 在 OpenClaw 的 Gateway 和 Pine API 之间建立实时事件通道,电话接通、需要用户输入、通话结束等关键事件发生时消息即时推送给 Agent。

这一案例的核心结论,值得原样记住:真正的「主动服务」不仅需要 Agent 能定时检查事件,更需要事件能主动通知 Agent。

3. 事件触发工具与用户沟通工具#

第一章的五类工具里,事件触发工具与用户沟通工具正是依托事件驱动架构发挥作用的。

事件触发工具 —— 让世界的变化转化为 Agent 可处理的事件,常见三类:

工具 处理什么 细节与例子
定时器 set_timer 依赖物理时间的事件 一次性:有明确时间点的任务,如周六时设定「下周一上午 10:00 致电银行」;循环:周期性任务,如每小时检查服务器健康;也用于外部服务不支持主动推送、只能主动查询的场合(定时反复查进度)。OpenClaw 的 Heartbeat 就是这种机制的系统化实现
后台任务监控 monitor_shell 异步执行的工具或命令行任务 Claude Code 的 monitor 工具:只监控命令行的新增输出或含特定关键词的输出。若让 Agent 不断「盯着命令行看」,浪费大量 token;若等任务完全结束才思考,则无法及时发现严重问题、甚至在命令行卡死时无法介入
外部事件通道 connect_channel 新邮件到达、API 回调、IM 消息 把外部事件实时推送给 Agent,PineClaw 的 Channel 就是典型实现

设计要点:事件触发工具应定义清晰的触发条件与过滤规则(避免无关事件唤醒 Agent 浪费算力);事件载荷(payload)应包含足够的上下文信息,减少 Agent 被唤醒后还要额外查询的次数。

用户沟通工具 —— 适应 Agent 与用户之间日益多元的沟通渠道。这里有一组必须能对比的两种范式:

原生 ReAct 循环(Claude Code、Manus) 专门工具发消息(OpenClaw)
用户看到什么 Agent「说」的所有话(assistant 消息)直接发给用户,用户需在应用里打开指定会话才能对话;往往能看到工具调用过程 用户无需感知会话存在,也不必关心工具调用细节
交互节奏 用户发一条、Agent 回一条 双方都可以随时给对方发消息,是异步沟通
效果 过程透明,但绑定了「一个会话」 很多人评价 OpenClaw 具备**「活人感」**,像一个通过文本消息异步沟通的秘书

这些专门的消息工具还可以附带图片和文件,并按紧急程度附加推送提醒。进一步的形态包括多模态沟通(结构化卡片消息、提醒邮件)与生成式 UI(Generative UI)——用 HTML 等方式生成交互式界面。设计要点:支持异步消息模式(用户不一定在线)、提供已读/未读状态追踪、在多渠道场景下保持消息一致性。

渠道选择本身就是召回机制。 Agent 的响应不应局限于单一渠道,通知机制同时也是用户召回机制。消息发送可扩展到即时通讯、短信、邮件、电话、推送等;Agent 根据紧急程度、用户状态、内容性质、用户偏好综合决定渠道,既不错过重要消息,又避免重复打扰。对长时间任务,完成时主动通知用户、召回其注意力;对定期任务(每日总结、周报),通知帮用户建立固定的交互习惯。

4. 虚拟身份与隔离执行环境#

Agent 以什么身份、在什么环境中代表用户行动,是一层独立的基础设施。

身份选择:直接管理用户的个人账号看似便捷,但一旦 Agent 出错或被攻破,用户的全部数字身份都会暴露。更稳妥的是赋予 Agent 一套独立的虚拟身份(如同秘书拥有自己的办公电话和邮箱)——专属通讯账号、存储空间、计算环境,使 Agent 能以透明身份代表用户工作。身份的明确性不仅没有削弱信任,反而增强了沟通的真实性。

隔离环境:虚拟电脑(VM / 容器)与虚拟手机(Android 模拟器)提供操作系统级的隔离和完整的桌面 / 移动操作能力。三个收益:① 虚拟电脑可全天候运行,不受用户设备联网状态影响,也不干扰用户正在操作的应用;② 即使 Agent 执行了错误操作,最多只导致虚拟环境崩溃;③ 隔离环境阻止 Agent 随意访问用户本地文件。

独立身份带来的两个现实挑战:

  • 反机器人机制:许多网站用 CAPTCHA 和 IP 信誉检测拦截自动化访问,使用数据中心 IP 的虚拟环境很容易被识别,实践中往往需要配置住宅代理(真实家庭 IP)才能正常访问。
  • 必须以用户本人身份登录的场景:应采用 Human-in-the-Loop 认证——通过 VNC / RDP 远程桌面让用户在可视化环境中亲自完成登录。用户能看到 Agent 正在操作的完整界面、理解为什么需要认证;认证后的会话令牌可在有效期内复用,避免频繁打断用户,在自主性与安全性之间取得平衡。

数据交换走共享文件系统:以卷挂载方式(如 /workspace/shared)连接 Agent、虚拟电脑与虚拟手机,数据以文件路径引用传递而非内容拷贝,避免占用上下文窗口。一个数据分析任务:用户上传 CSV 到共享目录 → 虚拟电脑中的 Agent 读取、分析、生成图表并保存回共享目录 → Agent 只需把图表的文件路径返回给用户。各方之间传递的始终只是轻量级的路径字符串(这正是 context-engineering.md 里「工具输出裁剪」的一个极致形态)。

5. 事件处理机制:事件循环、安全点、三种策略#

一个 Agent 实例可能同时面对多个事件:用户的新消息、工具返回的结果、定时器到期、另一个 Agent 的协作请求。

骨架是并发编程里的「事件循环」。可以把异步 Agent 看作一个长期运行的循环:每一轮从输入队列取出若干事件 → 追加到轨迹 → 调用一次 LLM → 执行它决定的工具 → 回到循环开头等下一批事件。这与 Go 的 goroutine 从 channel 读消息、在 for { select { ... } } 中逐轮处理是同一个结构。

在传统的同步接口实现中,事件在每轮循环的边界被消费:当 LLM 正在推理、工具正在执行时,新事件先在队列中等待,待本轮到达一个安全点(safe point)——一段推理结束、或一次工具返回——再处理。原生异步则允许在模型仍在思考或输出时接收新要求,由系统选择合适的时机继续处理。两者都有边界,只是边界由不同层管理。 工具取消仍需执行器响应取消信号(类似 Go 中对 ctx.Done() 的检查);接收一条「停止」消息本身不会撤销已经发生的动作。

三种处理策略(本质是「事件在哪等到安全点」):

策略 用于 做法(四步)
取消式(Cancellation-Based) 紧急事件 本质是为紧急事件提前制造一个安全点,主动中断当前步骤。(1) 停止当前操作——LLM 在推理就取消流式响应,同步工具在执行就发取消信号;(2) 清空待处理队列,取出所有事件;(3) 把队列事件与紧急事件一起追加到轨迹末尾;(4) 立即重新调用 LLM,以更新后的完整轨迹评估局势。例:用户在执行错误操作时输入「停!我说错了」
队列式(Queued) 常规事件 (1) 事件放入队列末尾,不打断当前操作;(2) 等当前操作完成(LLM 推理结束、同步工具返回);(3) 任一工具返回 tool.result 时检查队列,非空则一次性追加到轨迹;(4) LLM 综合处理。实现批量处理、提高效率:Agent 调搜索工具期间用户补充「只看最近一个月的结果」,搜索结果返回时两个事件一起呈现,避免不必要的往返
并行(Parallel) 独立的轻量级查询 如 Agent 正在分析大量数据时用户问「今天天气怎么样?」。这类查询有三个特征:与主任务无关、需要快速响应、执行成本低。既不该取消(打断重要主任务),也不该排队(让用户等太久)。系统先判断独立性与复杂度,再在一个并行的推理会话中独立执行,结果立即返回;查询与响应追加回主任务轨迹,并**明确标记为「与主任务并行执行」**以免 LLM 混淆

紧急度判定表(可背):

紧急(→ 取消式) 非紧急(→ 队列式)
user.interrupt(用户中断) user.input(常规用户输入)
supervisor.instruction(监督指令) agent.input(Agent 输入)
agent.interrupt(Agent 间中断) tool.result(工具结果)
标记为紧急的外部触发器(系统告警、支付失败) timer.trigger(定时器触发)、常规外部触发器

硬编码规则有局限 —— 事件的语义决定处理方式:「马上停下来」用取消式、「今天天气怎么样」用并行式、「报告需要用中文发给我」用队列式。建议使用轻量级的分类 LLM 作为事件路由器,在事件到达时快速判断应采用哪种策略。

两条硬规则:① 取消点必须是工具或推理能够安全收尾的位置;② 未完成的工具结果用显式占位符表示,不能伪造成功。

6. 事件的结构化建模:四维#

处理的前提是理解。通用 Agent 面对的输入不只来自用户一个人 —— 第三方发来的消息不是用户发给 Agent 的,但 Agent 需要理解它、评估其重要性、决定如何介入。这要求把每个输入建模为结构化事件,四个维度:

维度 回答 取值示例
来源(谁) source 谁发起的 用户本人、联系人、陌生人、系统通知
渠道(方式) channel 通过什么途径 电话语音、短信、即时消息、邮件、社交媒体、定时器触发、异步工具结果、命令行监控状态更新
内容(什么) content 说了什么 消息文本、情感色彩、紧急程度、是否需要回复
上下文(背景) context 什么背景 是对之前某个对话的回复还是新发起的沟通、与当前任务的关联

以一封客户退款请求邮件为例:

{
  "source": {"type": "email", "sender": "client@example.com"},
  "channel": "gmail_webhook",
  "content": {"subject": "退款请求", "body": "订单 #12345 希望退款..."},
  "context": {"priority": "high", "customer_tier": "vip", "related_orders": ["#12345"]}
}

四维建模的用途之一(面试里值得主动说):只有当这些维度被清晰建模,Agent 才能在多方通信中保持清晰认知 —— 避免把用户输入误当成工具结果,或把藏有指令的工具结果误认为用户指令而导致提示注入(prompt injection)。此外,多线程上下文的复杂性还要求 Agent 理解多个对话线程之间的关联:第三方消息如何影响用户情绪、用户在不同对话中扮演什么角色、何时需要把不同线程的信息综合起来给建议。

从 n8n 等工作流平台的触发器生态可以看到:Webhook、定时器、邮件、数据库变更、文件监听 —— 每一种触发器都是 Agent 感知世界的一个「感官」。异构事件被统一建模后,Agent 就能以一致方式处理不同来源的刺激,紧急度判定与处理策略都建立在这一统一建模之上。

7. 不支持原生异步时的兼容方案#

场景:Agent 正在帮用户起草邮件(工具调用:search_contacts),搜索还没返回,用户突然说「等一下,先帮我查一下明天的天气」。若接口要求未完成的工具调用先获得结果,Agent 就无法带着悬空调用处理新消息。这个限制来自所选协议与模型组合,并非所有 LLM 都必须遵循的规律。

核心思想是:在没发生打断的常态下,让 LLM 看到标准的同步轨迹,只在打断时才插入占位符来修复格式。 五条关键规则:

规则 内容
规则 1 及时记录 API 已完成的 assistant 消息与工具调用项;对服务端管理的 reasoning 状态,按提供商的续接协议保留,不自行拼接不可见的思考文本
规则 2 工具调用完成时才记录 tool result;执行中轨迹处于「部分完成」状态
规则 3 工具执行中的打断需要占位符:为未完成的工具生成占位符响应(如「工具正在后台执行,请优先处理新事件」),追加打断事件,重新调用 LLM。从 LLM 的视角看,assistant message 仍然有配对的 tool result
规则 4 在没有原生 steering 或受支持的中途续接接口时,取消未完成的生成,保留已经确认完成的消息与工具状态,追加新事件后重新请求。不能假定半截输出或隐藏推理可以作为合法前缀任意回灌
规则 5 非打断事件进入队列等待批处理,当前周期完成后才一次性追加

以「起草邮件 + 天气打断」为例,五条规则的运作过程:

  1. Agent 调用 search_contacts,assistant message 立即写入轨迹(规则 1)。
  2. 搜索未返回时用户发来「先帮我查一下明天的天气」。因为这是用户打断,系统为未完成的 search_contacts 生成占位符 tool result(「工具正在后台执行,请优先处理新事件」,规则 3),追加上天气查询,重新调用 LLM。此刻 LLM 看到的轨迹格式完全合法 —— assistant message 与 tool result 配对完好。
  3. 天气查询回复后,search_contacts 的真实结果到达,作为新事件追加(规则 2),Agent 读取联系人信息后继续起草邮件。

同时记住占位符的语义风险:模型可能把「任务已启动」误当成「任务已完成」,在真实结果返回前作出依赖该结果的判断。 应通过明确的任务状态与结果校验防止混淆,并在评估中检查是否编造了未到达的数据。不能仅凭一次失败,就把原因归结为某个未公开的训练过程。

8. 用任务句柄表达异步语义#

无论用不用原生异步协议,都可以从工具接口的设计层面明确异步语义 —— 对同步接口尤其有用:让「启动任务」成为一次有真实返回值的完整调用。

传统工具设计隐含「调用即完成」的语义。phone_call 这个名字暗示「调用将拨打电话并等待通话结束,返回通话记录」。异步范式下应把「启动」与「完成」解耦:

  • initiate_phone_call:启动电话呼叫,立即返回任务标识符与初始状态(如「呼叫已发起,正在拨号」)
  • 通话进展通过事件通知:phone_call_connected、phone_call_ended

关键在于工具的名称和描述本身就要传达异步语义。 模型看到 initiate_phone_call 会自然推断这是「发起」而非「完成」。工具描述应进一步强化:「此工具将启动由子 Agent 处理的电话任务。任务成功发起后立即返回任务 ID,你可以继续处理其他事项。通话结束后会收到单独的通知事件。」

9. 队列式处理中的注意力分散问题#

批量事件处理时,模型可能只回应最后一个事件而遗漏前面的要求。原生异步解决了「消息能否在运行中到达」,仍需检查「模型是否综合使用了所有更新」。两个层面的干预:

  • 提示词层面:告知模型「当收到多个连续事件时,请确保全面考虑所有信息」。
  • Agent 状态栏标记:在每个事件前加显式标记,并在末尾加汇总。
[未处理事件 1/4] Tool result from database_query:...
[未处理事件 2/4] User 补充说明:只看北京地区的数据
[未处理事件 3/4] 系统提醒:报告截止时间还有 30 分钟
[未处理事件 4/4] User 询问:进度如何?

末尾汇总:「上面有 4 个未处理事件,包括 1 个工具结果、2 条用户消息、1 个系统提醒。请确保回应涵盖所有信息。」

这与 context-engineering.md 的首尾效应是同一回事:关键约束不能埋在上下文中间,而未处理事件恰恰容易堆在中间被忽略。

10. 模型原生异步:异步工具调用 + 回合中途引导#

前面的兼容方案由运行时安排事件的接入顺序,让使用同步接口的模型参与异步任务。另一条路线是让模型原生理解这种交互节奏。截至 2026 年 9 月,GPT-6 Astra 已提供原生异步工具调用(Async tool calling)与回合中途引导(Mid-turn steering)。

能力 把什么分开 例子
异步工具调用 把「发起行动」和「获得结果」分开 查询会议场地时,可先整理议程和准备清单;等场地信息返回,再比较方案。关键是分清工作的依赖关系:能独立推进的继续做,必须依据结果的决策留到结果到达之后
回合中途引导 把「用户更新」与「整轮回答结束」分开 Agent 还在思考或组织回答时,用户就追加「预算减少了」「参会人数变了」;系统保留已完成的工作,把新约束带入后续处理,使 Agent 能在同一次任务中调整计划。接收到更新与作出调整之间仍可能有延迟,但用户不必等一整轮回答结束才表达变化

⚠️ 一句必须记住的边界:修改计划 ≠ 停止正在运行的工具,也不自动撤销已经发生的动作;实际执行、取消与状态管理仍由运行时负责。

并非所有模型都具备原生异步能力。 构建 Agent 时应根据模型的支持范围选择原生交互或兼容方案,再检查整个系统能否正确应对延迟返回、中途修改与任务恢复。

11. 从「能接收异步消息」到「可靠处理异步任务」#

原生异步只解决了「消息能否在运行中到达」,复杂任务中的可靠性还取决于模型如何使用这些消息。至少检查三件事:

检查项 要回答的问题
结果归属与未完成状态 能否把延迟到达的结果归入正确任务?在结果缺席时能否避免编造数据?
任务恢复与动作控制 能否在处理新要求后继续原任务?能否区分「修改计划」与「停止执行」?
多条更新的综合使用 能否同时遵守预算与人数等多个约束,而不是只记住最后一条消息?

评估必须覆盖两层:模型是否理解了变化、以及系统是否按变化正确执行。(这正好是 06-agent-infra/observability.md 里「trace 既是评测数据又是归因材料」在异步场景下的具体化 —— 异步事件流本身就是一条带时间戳的 trace。)

12. 四档时间尺度表(可背)#

尺度 场景 观察侧的变化 动作侧的变化
秒 — 天 异步与事件驱动 会被外部事件主动唤醒的 Agent 动作跨回合:先发起,后续靠事件收尾
10 毫秒 — 1 秒 语音 边说边听,不等一句说完 边想边说,可被打断
亚秒 — 秒 Computer Use 屏幕在两帧之间持续变化 动作后必须重新确认现实是否仍符合计划
毫秒 机器人 传感器连续回流 动作分块:一次规划一小段,可被抢占

四节共享同一条控制骨架:

持续感知 → 判断当前状态与时机 → 选择回复或动作 → 让输出进入环境
        → 观察反馈 → 继续、修正、重试、停止或重新规划

也共享同一组原语:唤醒、安全点、取消、抢占、快慢分离。

二、语音#

⚠️ 边界声明(§二–§四 通用,务必遵守):本节与后面两节是知识性与架构性的理解,不是一手实战经验。我的实际背景是 LLM / Agent 应用工程,没有做过 GUI Agent、语音 Agent 或具身(embodied)系统。面试里被问到,正确的做法是先划界、再讲原理:

「我没做过 GUI Agent / 语音 Agent,但我理解这套感知—思考—行动循环与动作空间设计:它的时序约束在哪、延迟从哪来、为什么动作之后要重新确认状态。」

把书里读来的内容讲成做过的事,追问两层就会当场崩塌,损失远大于承认不懂 —— 这条纪律与 01-llm-core/multimodal.md 顶部完全一致。

语音的价值不只是把文字换成声音。正常说话的速度约为打字的四倍,而且不占用双手与视线,因此它天然适合把 Agent 放进持续工作、随时可能被打断的输入输出回路。本节同时讨论两个方向:用户对 Agent 说话,以及 Agent 代替用户对外部世界说话。一句话分清两件事:语音模型决定「能回答什么」,交互架构决定「能否听清、及时回应、自然换手,并在通话中完成确认和工具调用」。

1. 三种交互范式#

范式 核心结构 主要优势 主要限制
级联(Cascading) VAD → ASR → LLM → TTS 模块清晰、易替换、易调试 延迟累积,副语言信息在接口处丢失
端到端 Omni 原生音频输入输出,按轮次交互 延迟较低,能保留语气、情绪和环境声 仍依赖轮次,训练和调试成本较高
全双工(Full-Duplex) 原生音频输入输出,持续听、说和决策 支持重叠说话、自然打断和连续流 模型训练、控制和评估都更复杂

三者不是简单的新旧替代,而是不同延迟、成本与可观测性约束下的取舍。贯穿三条路线的主线是:如何摆脱「轮流说话」和 VAD 对发言权的猜测。 级联和 Omni 仍要划分轮次,只有全双工把「该谁说话」变成模型的持续决策。

2. 范式一 · 级联流水线:四个瓶颈#

绝大多数商业语音助手基于串行流水线:VAD 判断用户何时说完 → ASR 把音频转文字 → LLM 理解并生成 → TTS 念出来。模块化让每个组件可独立优化,但每一级都增加等待。

模块 作用 典型瓶颈
VAD(语音活动检测) 判断是否说完 静音阈值带来等待和误切分
ASR(自动语音识别) 音频转文字 识别延迟与上下文丢失
LLM 理解、思考、生成 首 token 延迟,开启 reasoning 后等待更长
TTS(文本转语音) 文字转语音 首包合成和播放缓冲

完全串行的方案有三个问题:① 延迟累积(必须等到一段静音才能确认说完);② 信息丢失(有声/无声的二值信号无法表达犹豫、情绪、附和和环境声);③ 上下文被切断(邮箱、人名、专有名词可能被分片识别而出错)。

3. 从串行到流式感知#

在保留模块化分工的前提下,让各阶段尽早产出增量结果:

  1. ASR 边听边转:VAD 检测到用户开始说话就按一定时间间隔调用 ASR,流式生成临时转录;检测到说话结束后再确认最终文本。
  2. LLM 推测执行:临时转录一生成就送给 LLM;若最终文本与临时转录相同则不再调用,否则取消前序推测执行的思考,重新调用 LLM。
  3. LLM 分段输出:第一段适合播报的文本生成后立即交给 TTS,不等完整回复。
  4. TTS 增量合成:持续返回音频块,让后续生成、合成和播放重叠进行。

⚠️ 一个容易被考到的细节:Whisper 的解码虽然是自回归的,但编码器需要完整音频段,因此不能直接等同于流式模型。 真正的流式 ASR 需要模型本身支持。基于 LLM 的流式听觉模型可以从连续音频中输出文本和语义事件,把「识别」和部分「理解」放进同一个模型,保留从对话开始到当前时刻的上下文,也能利用世界知识处理品牌、人名和专有名词。

如果只想解决「用户是否说完」,也可以把轮次判断直接做进流式识别器:模型综合语义和静音判断一句话是否表达完整。端点判断的训练标签必须只使用决策时刻可见的信息,否则会因「上帝视角」产生线上无法复现的判断。

模型输出的不只是文字,还可以包含声学事件标记,与文字 token 形成统一事件流:

  • speak_start / speak_end / interrupt:说话起止与打断意图
  • emotion:情感、犹豫等状态
  • laugh / sigh / noise:副语言和环境声

Agent 因此可以识别犹豫、打断和环境变化,而不必把所有声音压成纯文本。

4. 范式二 · 端到端全模态(Omni)#

级联即使采用流式感知,听、想、说仍通过离散接口交接,情绪、语调和环境声可能在转成纯文本时丢失。Omni 用同一个模型直接听音频、生成回复并输出语音,因而有机会保留这些信息,但训练成本更高。优势主要体现在延迟和非文字信息的理解与生成上(例如理解声音中的停顿,或传递更丰富的副语言信息 —— 唱歌、用特殊语调讲一句话)。

⚠️ Omni 仍然假设轮流说话,通常仍要靠 VAD 划分发言权。因此,用户报数字时的中途停顿仍可能被误判为说完。 这是「轮次假设」没被去掉的直接后果。

5. 范式三 · 全双工#

Omni 仍把对话分成「用户说」和「模型说」两个时段,但同声传译等任务要求两者重叠进行。全双工模型不再预设轮次,而是持续听、持续说,并不断决定继续、停顿、打断还是调用工具。

  • Moshi(Kyutai,2024)是研究上的先声:并行建模用户和模型的音频流,因此重叠说话和打断可以成为模型的自然行为。
  • 交互模型(Interaction Model)(Thinking Machines Lab):交互性不再靠 VAD 等外部 harness 拼装,而是内建在模型中;其微轮次机制以短音频块持续推进,让静音、重叠和打断都作为连续上下文保留。交互模型还可以把完整对话委派给后台推理模型,自己继续维持话头,后台结果返回后在合适时机接入。
  • GPT-Live(OpenAI)把全双工路线带到生产规模:持续处理输入并生成输出,能等待用户、附和、被打断,也能处理实时翻译;同样把复杂任务委派给后台模型,前台继续维持对话。

6. 认知时序:实时交互与深度思考#

「交互表现」和「智能上限」是两个维度:前台模型要在用户仍在线时回应,后台模型可以花更多时间思考。三种方案是设计取舍,不是线性迭代;前两种可套在级联或 Omni 上,第三种把深度思考与实时表达统一在同一模型内部。

方案 做法 代价 / 风险
一、快思考回应,慢思考回答 快思考几百毫秒内先给即时回应,慢思考在后台完成更深推导 简单问题被重复处理;复杂问题可能前后不一致 —— 快模型先建议购买,慢模型随后发现套餐缺少关键功能,用户在几秒内便听到相互矛盾的答案。根本原因是两个实例各自完成了一次独立思考
二、快思考交互,慢思考提醒 后台模型通过状态栏或专门接口向前台提供建议,前台继续维持话头并决定如何表达 比方案一稳定,但通信仍然间接:前台可能误解建议,也看不到后台的中间思考;后台完成前用户追问时,前台仍只能靠自己应答。它能自然「等结果」,但不能真正做到边想边说
三、端到端思考与表达统一 把思考能力内化到端到端音频模型。Step-Audio R1 用两个互补机制:**模态锚定思考蒸馏(MGRD)**让模型基于声学特征思考(保证「想得对」),MPS 双脑架构让构思与表达并行(解决「说得及时」) 思考和实时表达需要一起重新训练

理想情况下,模型应从音高、节奏和语调判断情绪,而不只看转录文本:MGRD 筛选真正引用声学特征的思考过程,用这些数据训练模型,并通过强化学习防止模型跳过思考直接猜答案;MPS 让构思脑持续产出思考片段,表达脑收到片段后结合已有回复立即生成语音,两者以流水线方式并行,因此不必等完整思考结束才让用户听到第一句话。

7. 快慢分离 vs 端到端:取舍与两条独立轴#

统一模型最紧密地实现了「边想边说」,代价是思考和实时表达要一起重训;解耦路线更容易替换后台大脑。两者是取舍,不是替代关系。

在前沿思考模型快速演进的当下,快慢分离有一个重要的工程优势:它能直接承接慢模型的迭代红利。前台快模型只负责低延迟地倾听、应答、维持对话;后台慢模型负责推理、规划和工具调用;更强的思考模型发布后,只需替换后台模型,不必重新训练整套实时语音系统。统一路线则把推理与交互绑定在同一个训练周期里,每次升级都要重新兼顾智能水平、响应延迟和表达自然度。

这种分离不必然牺牲任务效果:截至 2026 年 8 月,采用快慢思考分离架构的 Pine AI 语音 Agent 在 τ³-Voice Leaderboard 上取得第一名,超过 Grok Voice、GPT-Realtime-2 等实时语音系统。

两条独立轴(务必写出来,这是本节最值钱的一句):

轴 问的是 例子
语音通路的端到端 模型是否直接接收音频、生成音频,不再由多个模型通过离散文本串接 Omni 与交互模型都属于,但 Omni 通常仍按轮次推进,交互模型可边听边说 —— 架构差别很大
认知架构的端到端 实时交互与深度思考是在同一模型内共享状态、共同训练,还是拆成前台快模型 + 后台慢模型 快慢分离 vs 统一模型

两条轴彼此独立。 一个系统完全可以在语音通路上端到端,同时在认知架构上保持快慢分离 —— Thinking Machines Lab 把复杂任务委派给后台推理模型,就是这种组合。把这两条轴混为一谈,是这一节最常见的答错方式。

8. 更像人的语音合成#

传统 TTS 过于流畅、零停顿,反而容易暴露机器身份 —— 停顿、填充词和偶尔的重复,是人类表达不确定性和思考状态的信号。做法是让主 LLM 在文本之外输出控制标记,例如 THINKING、EMO:happy、SPEED:0.8x,由 TTS 把它们映射为停顿、韵律、语速或笑声、叹气等非语言音频。实现上可以自研支持控制标记的 TTS,也可以用语音克隆准备不同情绪和风格的参考音频。

三、Computer Use#

语音把时机轴推到毫秒级,但它的观察仍是一维的声音流。Computer Use(GUI 自动化 Agent) 把同一个问题搬上二维屏幕:观察变成持续变化的像素,动作变成坐标上的点击与输入。语音强调「何时开口」,Computer Use 则强调「下一步点哪里」,以及一个语音中不存在的问题 —— 动作执行之后,现实是否还与计划一致。

核心是感知—思考—行动循环:(1) 截取当前屏幕画面 → (2) 多模态模型接收截图与任务指令,输出一段思考和一个具体动作 → (3) 执行层在真实环境执行该动作(移动鼠标、点击、输入文字)→ (4) 等界面响应后再截图,进入下一轮。

先分清两件事:「看懂界面」与「完成任务」。 前者更接近多模态理解能力,可以用一次截图问答来测量;后者要求模型把理解和生成动作放进闭环,处理页面加载、状态变化、误操作和不可逆后果。Computer Use 的难点因此不只是让模型在截图上答对,而是让它在每一步之后重新确认现实是否仍符合计划。

三个关键设计维度:动作空间(能做哪些操作)、视觉定位(如何在截图中找到目标元素)、模型架构(如何从截图生成正确动作)。

1. 动作空间设计#

Anthropic 的参考实现把完整交互能力分成三类工具(这是一种清晰的动作空间设计,不是模型供应商必须遵守的私有协议 —— 只要 harness 能把截图、动作约束和执行结果转换成目标模型支持的消息与结构化输出,Claude、开放权重视觉模型和自托管端点都可以驱动同一个循环)。

工具 内容
GUI 操作 computer 鼠标:移动(mouse_move)、左/右/中键点击、双击/三击、拖拽(left_click_drag)、更精细的按下/松开(left_mouse_down / left_mouse_up)。滚动(scroll):四个方向,可配合修饰键。键盘:逐字输入(type,每个字符间隔 12ms 模拟真实打字)、组合键(key,如 Ctrl+C)、长按(hold_key)。感知动作:截图(screenshot)、获取光标位置(cursor_position)、等待(wait)
命令执行 bash 持久的 bash 终端会话,120 秒超时,通过哨兵字符串检测命令是否执行完毕,多次调用之间保持环境状态(例如 cd 到某目录后下次调用还在那里)
文件编辑 str_replace_editor 通过字符串匹配实现安全编辑,支持查看、创建、替换、插入和撤销;比直接覆盖整个文件更精确,不容易误改其他内容

2. 视觉定位(Grounding)#

每一轮,模型都要在截图中准确定位目标元素(「搜索框在哪里?」「提交按钮的坐标是什么?」)。两大思路:

  • 选择题:先把界面元素标注好编号,模型只需从中选一个。
  • 纯坐标预测:让模型像人一样直接「看」着截图报出坐标。

选择题思路的共同优势,是把开放式的「在截图中找到按钮并预测坐标」转化为封闭式的「从已标注好的元素中选一个」——就像考试中选择题比填空题更容易答对,模型只需说「点击 [123]」而不是「点击屏幕 (350, 464) 处的按钮」。 输出坐标对模型挑战尤其大:需要大量训练才能做准,且在不同屏幕分辨率下很容易出错。选择题思路又有两种实现:

(a)Set-of-Mark(SoM):纯视觉标注法。 由微软研究院于 2023 年提出,最初为释放 GPT-4V 的视觉定位能力。用图像分割模型(SAM、SEEM 等)在截图上自动切出候选区域,为每个区域叠加编号标记;模型看到的是一张带编号的图,只需报出编号,由系统换算成对应区域的中心坐标。整个过程不需要 DOM、也不需要任何界面内部结构,因此原生桌面软件、游戏界面同样适用 —— 只要分割模型能把候选区域切出来。

(b)结构化元素索引:SoM 思想在 Web 上的结构化实现。 当界面本身能提供结构化信息时,标注可以做得更精确。现代网页在渲染前就已定义完整的元素结构(DOM 树)与语义角色(哪个是按钮、哪个是输入框),**无障碍树(Accessibility Tree)**为许多桌面应用提供类似信息。以 browser-use 为代表的 Web Agent 方案正是这样做的,流程四步:

  1. 通过**浏览器调试接口(CDP,Chrome DevTools Protocol)**获取网页的结构化表示(DOM 树)和无障碍信息
  2. 自动检测哪些元素可交互(按钮、输入框、链接等)
  3. 为每个可交互元素标注唯一 ID 并在截图上绘制边界框
  4. 同时生成文本列表描述每个 ID 对应的元素
Screenshot: [图片中关键元素标注了 [1]、[2]、[3]、[4] 等 ID]

Elements:
[1] <input type="text" placeholder="Search" aria-label="Search" />
[2] <button id="submit-btn" aria-label="Submit form" />
[3] <input type="text" placeholder="Enter your name" value="" />
[4] <a href="/docs" aria-label="Documentation" />

模型只需输出一个 ID,系统就自动用该元素的中心坐标执行点击。这类方案不省 token(要把所有标注信息都发给模型),但定位准确稳定,还免去了分割模型可能引入的漏检和误检。

(c)纯坐标预测。 不做任何标注,直接让模型输出坐标,以 SeeClick 和 Claude 的 computer use 为代表:在海量 GUI 截图与元素位置的配对数据上训练视觉模型,让它学会把自然语言描述(如「点击提交按钮」)直接映射到精确坐标 —— 就像人类用户一样,纯粹靠「看」找到要点击的位置。

分辨率匹配与双向坐标缩放(坐标预测路线的硬约束):模型对坐标的理解高度依赖训练时用的分辨率。Claude 训练使用 XGA 1024×768、WXGA 1280×800、FWXGA 1366×768。输入分辨率不匹配时,预测坐标会系统性偏移——像在小地图上量距离再直接用到大地图上。因此工具层要实现双向坐标缩放,并且要按宽高比选目标分辨率,避免非等比拉伸把画面压变形、连带把坐标判断带偏。

Worked example(值得背下来):真实屏幕 2560×1440 是 16:9,就该在 Claude 支持的三档里挑一个宽高比同样接近 16:9 的 —— FWXGA(1366×768)最匹配,而不是 4:3 的 1024×768。截图时把屏幕等比缩放到 1366×768 送入模型;模型输出点击坐标 (683, 384) 后,反向映射为真实坐标 (683×2560/1366, 384×1440/768) ≈ (1280, 720)。反过来,若硬把 16:9 拉伸进 4:3 的 1024×768,画面会被横向压扁,模型预测的坐标就会系统性偏移。

三条路线的选择逻辑:

  • 结构化信息可得时,优先用 DOM / Accessibility Tree 索引 —— 定位最精确稳定。
  • 不可得时(原生桌面软件如 Photoshop、Canvas/WebGL 渲染的界面、游戏):既可以用视觉标注(原始 SoM 路线),也可以用坐标预测。视觉标注把定位变成选择题,对未经专门训练的通用模型更友好;坐标预测省去标注步骤,对做过 GUI 定位训练的模型更直接。两者在小元素和密集界面上的精度都仍有差距。

3. 观察接口(AOI):该重设计的是「观察」而不是「动作」#

到目前为止,Computer Use 的感知都建立在一个隐含假设上:屏幕是静止的 —— 截一张图、想一步、点一下,再截下一张。可现实里的屏幕会放视频、会弹出转瞬即逝的通知、会播放会议里的人声。一个每 3–5 秒才睁一次眼、而且完全没有耳朵的 Agent,对这些「两帧之间发生的事」既看不见也听不到。

核心论点:这里真正该被重新设计的,不是「动作接口」,而是「观察接口」。构建 Agent–电脑观察接口(AOI),把连续的环境观察转换成模型便于处理的离散事件。三项关键技术:

  1. 屏幕关键帧截图:用一个小模型判断屏幕是否发生了有意义的变化,只在显著变化时截图;变化频繁时每秒截图 1 次就能有不错的效果。
  2. 音量门控的语音转写:有声音时才调用语音识别,把识别出的文字放入上下文,让 Agent 能「听到」声音。
  3. 用文字描述画面:让模型把捕获的截图描述成一句话 —— 这样即使原图之后被清理出上下文,这句文字仍留在上下文里,实现多模态交互历史的压缩。

4. 世界模型与效率#

观察接口解决的是「屏幕中间发生了什么」,但它不消除规划延迟:Agent 仍是串行的「截图—思考—点击」循环。OSWorld-Human 的效率研究显示,即使任务最终成功,Agent 的操作步骤仍明显多于人类,等待时间也更长 —— 准确率达到人类水平,并不等于已经足够实用。

人类操作电脑时不是「点击之后才开始想下一步」,而是先对动作后果作出预测:实际变化与预期一致,就沿原定计划继续执行;只有发现页面状态偏离预期,才停下来重新观察和规划。 世界模型让 Agent 能在行动前预测桌面接下来可能变成什么,从而实现这种类人的**推测执行(speculative execution)**机制。

桌面状态不只是一张像素图,还包括窗口、焦点、滚动位置、输入框内容、加载状态、权限和网络返回;动作则包括点击、键盘输入、滚动、拖拽和等待。一个可用于 Computer Use 的世界模型至少要能编码当前状态、预测候选动作造成的状态变化、并把预测交给规划器:

桌面状态 + click/type/scroll/wait ──> 下一状态的表示

这样 Agent 就能在真正点击前比较候选动作的后果,在页面加载期间准备下一步,并在弹窗一闪而过时根据状态差异恢复。例:任务是「在 VS Code 新建 Python 文件并写入 hello world」,模型可以先预测文件树和编辑器在成功后的关键状态,再选择点击、输入和保存动作;若任务是删除文件,则可以先在隔离的虚拟桌面中预测是否会出现不可逆确认框,必要时请求用户确认。重点不是让模型生成一张逼真的未来截图,而是预测完成任务所需的、可检查的状态差异。

Photon-1(Induction Labs,2026 年 7 月)是这条路线的实现之一:仅用 3 万小时的 H200 GPU 时间完成 computer use 世界模型的预训练;把每帧压缩为离散的潜在 token,自回归预测动作之后的下一状态表示,而不是在预训练阶段逐像素生成截图;另接入的图像生成器只用于把潜在表示可视化,并非推理必需组件。

5. 移动端:生态壁垒比技术更难#

移动端与桌面在技术上确有差异:动作空间通常不再是「鼠标坐标 + 键盘」,而是接入系统的无障碍服务 API(如 Android 的 AccessibilityService)读取界面元素、下发点击与文本输入;交互方式从鼠标指针变成触摸手势,坐标的语义随之改变 —— 同一个 (x, y) 到底是单击、长按,还是滑动手势的起点,需要额外的手势类型来界定。

⚠️ 但真正卡住移动端的往往不是技术差异,而是生态壁垒。 曾有手机厂商尝试在消费级手机中集成 AI 助手,让它自动操作微信、淘宝、支付宝等日常应用,但很快遭遇平台限制。封杀背后的根本原因是商业模式冲突:传统互联网应用的核心变现逻辑是流量与注意力 —— 用户刷信息流时看到广告、搜索商品时跟随推荐算法、浏览页面时产生冲动消费。而当 Agent 代替用户操作时,这条变现链路被彻底绕过:AI 不会关注广告,也不会冲动消费,直奔目标完成任务就走。 对靠广告和流量变现的平台来说,Agent 的每一次操作都在侵蚀其商业模式的根基。

这意味着 Computer Use 面对的不仅是 CAPTCHA 之类的技术对抗,更是一个结构性的利益冲突 —— 结构性利益冲突比 CAPTCHA 之类技术对抗更难调和。

四、边界之外:机器人操作#

机器人操作比「看图回答问题」难得多:模型不但要看懂画面,还要在真实世界里连续做出动作,而且每个动作都会改变下一刻的情况。机器人系统通常把不同时间尺度的工作分开:

层级 核心问题 输出 典型时间尺度
任务目标 人想完成什么 「把杯子和废纸归位」 分钟级
长程规划 先做什么、后做什么 先处理杯子,再处理废纸,最后检查 秒到分钟
基本技能 当前要完成哪个状态变化 pick(red_cup)、place(red_cup, tray) 约 1—3 秒
VLA / 技能策略 这个技能具体怎么动 夹爪的一小段动作或连续轨迹 约 1—10 Hz 推理
底层控制与安全层 如何稳定、及时地执行 关节或末端控制量、限速与急停 约 50—1000 Hz

这里只需要再知道一个概念:动作分块(action chunking) —— 大模型每秒通常只能推理 1—10 次,传统控制器每秒要更新几十到上千次;工程上让模型一次生成一小段未来动作,控制线程按较高频率回放这一小段,模型在后台准备下一段,从而把一部分推理等待藏在动作执行时间里。代价是动作段越长运动越平滑,模型在这段时间看到的新画面却越少 —— 物体若被碰动,它可能仍在执行根据旧画面生成的动作。

明确划界:这不是本次备考的赛道。 仓库的 JD 分析里,机器人岗是博士岗,与目标岗位不符。知道有这条路、能说出上面这张时间尺度表和「动作分块」这个词,就已经足够;其余(VLA、世界模型、sim2real、遥操作、跨环境泛化)不做展开。 面试里被问到就一句话:「机器人不是我准备的赛道,我只了解它把控制分成不同时间尺度、用动作分块把推理延迟藏在执行里这两个基本点,再往下的细节我不熟。」

常见面试问法#

Q:为什么 Agent 需要异步和事件驱动?同步架构缺什么? A:同步是「柜台排号」,异步是「秘书」—— 桌上多个待办,按紧急程度决定先处理哪个,处理到一半可以在更紧急的事上暂停切换。同步架构下 Agent 要么等后台任务完成才能对话,要么等对话结束才能处理新事件,因此缺三项核心能力:异步执行是常态(长任务不该阻塞交互)、事件优先级的动态判断(紧急就取消、常规就入队、独立轻量查询就并行)、中断与恢复的流畅性。技术上要把所有输入、输出、思考和外部交互统一建模为事件流,由事件循环驱动。要补一句边界:这需要先检查模型与 API 是否支持这种消息时序 —— 有些接口要求先补齐工具结果才能继续,那就得靠事件队列、任务句柄和兼容层;不能仅凭代码用了 asyncio 就认定模型具备原生异步能力。

Q:Agent 怎么知道「该自己动起来」了?定时机制有什么盲点? A:常见三类:定时器(set_timer,一次性或循环)、后台任务监控(monitor_shell,只看新增输出或关键词,避免 Agent 反复「盯着命令行看」浪费 token)、外部事件通道(connect_channel,实时推送新邮件、API 回调、IM 消息)。框架级的三种内置机制是 Hooks(生命周期事件,来源是框架内部)、Cron(按 cron 表达式,如 0 9 * * 5 = 每周五上午 9 点)、Heartbeat(每隔 N 分钟唤醒)。盲点在于:真正让 Agent 在没有用户消息时「自己动起来」的只有 Cron 和 Heartbeat,而它们是时间驱动的 —— 对第三方事件源(新邮件、API 回调、紧急通知)缺乏即时通道,只能等下一个周期。Pine AI 的电话代理案例里,靠 Heartbeat 轮询会让客服在等验证码时挂断;解法是建立实时 Channel。结论:真正的主动服务不仅需要 Agent 能定时检查事件,更需要事件能主动通知 Agent。

Q:多个事件同时到达,你怎么决定先处理哪个? A:先看紧急度:紧急事件(user.interrupt、supervisor.instruction、agent.interrupt、标记紧急的外部触发器如系统告警)用取消式,本质是提前制造一个安全点——中断当前步骤、清空队列、把队列事件和紧急事件一起追加到轨迹、立即重新调用 LLM;常规事件(user.input、agent.input、tool.result、timer.trigger)用队列式,等本轮到达安全点(一段推理结束或一次工具返回)再批量追加,顺带实现批处理;与主任务无关、需快速响应、成本低的独立轻量查询用并行式,另起一个推理会话执行,结果明确标注「与主任务并行」后并回主轨迹。硬编码规则有局限,因为事件的语义决定处理方式 —— 「马上停下来」用取消式、「今天天气怎么样」用并行式、「报告用中文发给我」用队列式 —— 所以建议用轻量级分类 LLM 当事件路由器。最后两条硬规则:取消点必须是能安全收尾的位置;未完成的工具结果用显式占位符表示,不能伪造成功。

Q:为什么要把事件建模成结构化对象? A:因为 Agent 的输入不只来自用户一个人。要理解第三方消息、评估其重要性、决定如何介入,就要把每个输入建模为四维结构化事件:来源(谁)source、渠道(方式)channel、内容(什么)content、上下文(背景)context。这不只是「整齐」,它有一个具体的安全用途 —— 区分「用户输入」与「工具结果」,避免把藏有指令的工具结果误当用户指令,从而防住提示注入。另外多线程上下文要求 Agent 理解对话线程之间的关联:谁的消息影响了用户的情绪、用户在不同对话里扮演什么角色、什么时候要把不同线程综合起来给建议。可以把 n8n 那类平台的触发器生态类比成感官:Webhook、定时器、邮件、数据库变更、文件监听,每一种都是 Agent 感知世界的一条通道。

Q:模型不支持原生异步,但工具还没返回时用户插话了,怎么办? A:核心思路是常态下让 LLM 看到标准同步轨迹,只在打断时插入占位符修复格式。五条规则:及时记录已完成的 assistant 消息与工具调用项(reasoning 状态按提供商协议续接,不自行拼接不可见思考);工具完成时才记 tool result;工具执行中被打断就为它生成占位符 tool result(如「工具正在后台执行,请优先处理新事件」),再追加打断事件重新调用 LLM,这样从 LLM 视角看 message 与 tool result 配对完好;无原生 steering 时取消未完成生成、保留已确认状态,不能假定半截输出可作为合法前缀回灌;非打断事件入队等批处理。同时要讲清代价:占位符有语义风险 —— 模型可能把「已启动」误当成「已完成」,在真实结果返回前作出依赖该结果的判断,所以要用明确的任务状态和结果校验防止混淆,评估时检查是否编造了未到达的数据。

Q:怎么让模型「知道」一个工具是异步的? A:从工具的接口设计层面表达异步语义,让「启动任务」成为一次有真实返回值的完整调用。传统设计隐含「调用即完成」——phone_call 这名字暗示它会拨号并等到通话结束、返回通话记录。异步范式下把「启动」和「完成」解耦:改成 initiate_phone_call,立即返回任务标识符与初始状态(「呼叫已发起,正在拨号」),通话进展用事件通知(phone_call_connected、phone_call_ended)。关键在于工具的名称与描述本身就要传达异步语义 —— 模型看到 initiate_phone_call 会自然推断这是「发起」而非「完成」;描述里进一步写清「任务成功发起后立即返回任务 ID,你可以继续处理其他事项,通话结束后会收到单独的通知事件」。

Q:语音 Agent 的三种架构是什么?各自的取舍? A:级联(VAD → ASR → LLM → TTS)模块清晰、易替换易调试,但延迟逐级累积,且情绪、语调这类副语言信息在转成纯文本的接口处丢失;端到端 Omni 用同一个模型直接听音频、生成回复、输出语音,延迟更低、能保留语气情绪和环境声,但仍按轮次交互(通常还要靠 VAD 分发言权),训练和调试成本高;全双工持续听、持续说、持续决策该谁说话,支持重叠说话与自然打断,但训练、控制和评估都最复杂。主线一句话:三条路线都在解决如何摆脱「轮流说话」和 VAD 对发言权的猜测,只有全双工把「该谁说话」变成模型的持续决策。级联的四个瓶颈要能点出来:VAD 静音阈值、ASR 识别延迟与上下文丢失、LLM 首 token 延迟(开 reasoning 更久)、TTS 首包合成与播放缓冲。

Q:Computer Use 是怎么在截图里找到要点的按钮的? A:两条思路、三种实现。选择题思路把开放式的「预测坐标」变成封闭式的「从已标注元素里选一个」——考试里选择题比填空题容易答对。其一是纯视觉标注 Set-of-Mark:用分割模型(SAM/SEEM)切出候选区域、叠加编号,模型只报编号,由系统换算成中心坐标;不需要 DOM,原生桌面软件和游戏也能用。其二是结构化元素索引(SoM 在 Web 上的实现,如 browser-use):CDP 取 DOM 与无障碍树 → 检测可交互元素 → 标唯一 ID 并画边界框 → 生成文本列表;不省 token,但定位准确稳定。纯坐标预测(SeeClick、Claude computer use)不做标注,靠训练直接把语言描述映射到坐标,但要按宽高比匹配训练分辨率并做双向坐标缩放,否则坐标系统性偏移。选择逻辑:结构化信息可得时优先 DOM/无障碍树,不可得时(Photoshop、Canvas/WebGL、游戏)用视觉标注或坐标预测。

Q:Computer Use 的瓶颈在哪?为什么说「准确率到人类水平」还不够? A:瓶颈已经从「能否完成任务」扩到三处。一是效率:OSWorld-Human 的研究显示,即使任务成功,Agent 的步骤也明显多于人类、等待更久 —— 它每一步都要「截图—思考—点击」,而人类会推测执行(预测动作后果,与预期一致就继续,偏离才重新规划),所以准确率达标 ≠ 足够实用。二是观察接口:截一张图想一步的假设下,屏幕其实是静止的,但现实屏幕会放视频、弹通知、播人声;该重新设计的不是动作接口而是观察接口 —— 关键帧截图(小模型判断是否有意义变化,变化频繁时每秒 1 次)、音量门控的语音转写、用文字描述画面以压缩多模态历史。三是生态壁垒:移动端真正卡住它的不是无障碍服务 API 和触摸手势这些技术差异,而是商业模式冲突 —— 传统应用靠流量与注意力变现(广告、推荐、冲动消费),Agent 直奔目标完成任务就绕过了整条链路,这种结构性利益冲突比 CAPTCHA 之类技术对抗更难调和。

易错点#

易错说法 问题 应该说
「代码用了 asyncio,所以模型具备异步能力」 混淆应用层并发与模型层协议 应用层并发 ≠ 原生异步。要先检查模型与 API 是否支持这种消息时序;不支持就靠事件队列、任务句柄与兼容层
「有 Cron 和 Heartbeat,Agent 就能响应一切外部事件了」 漏掉「时间驱动」这个致命限制 Cron / Heartbeat 是时间驱动;只有 Hooks 来源是框架内部。对第三方事件源缺乏即时通道,真正的主动服务需要事件能主动通知 Agent(Channel 机制)
「打断就是把当前这一步掐掉」 忽略了安全点与「取消不撤销已发生动作」 取消点必须是能安全收尾的位置(如工具执行前/一次推理结束);收到「停止」不会撤销已经发生的动作
「工具还在跑,先补一个假的 tool result 让格式合法」 不能伪造成功 未完成的工具结果用显式占位符表示;并防住占位符的语义风险 —— 模型可能把「已启动」误当「已完成」
「用户改了计划,Agent 就停下了原来的工具」 混淆「修改计划」与「停止执行」 修改计划 ≠ 停止正在运行的工具,也不自动撤销已发生的动作;执行、取消、状态管理是运行时的职责
「队列式处理会把所有事件都照顾到」 忽略注意力分散 批量事件时模型可能只回应最后一个;要用未处理事件标记 + 末尾汇总([未处理事件 1/4] ...)强迫它覆盖全部
把「语音通路端到端」与「认知架构端到端」混为一谈 两条轴彼此独立 可以在语音通路上端到端、同时认知架构上快慢分离。 分开说,才不会在「快慢分离是不是落后」上答错
「Whisper 是流式的」 记混了编码器与解码器的要求 Whisper 解码是自回归的,但编码器需要完整音频段,因此不能直接等同于流式模型
「端到端一定比快慢分离好」 忽略了工程取舍 统一模型最紧密地实现「边想边说」,但思考与表达要一起重训;快慢分离能直接承接慢模型的迭代红利 —— 换后台模型不必重训实时语音系统。Pine AI 用分离架构在 τ³-Voice 上拿过第一
「SoM 和 DOM 索引是一回事」 混了纯视觉与结构化两条实现 SoM 是纯视觉分割标注(不需要 DOM,桌面软件/游戏可用);DOM/无障碍树索引是 SoM 思想在 Web 上的结构化实现。前者通用、后者精确且稳定
「换个分辨率没关系,模型自己能适应」 忽略坐标的系统性偏移 坐标预测高度依赖训练分辨率;要按宽高比选目标档做双向缩放。2560×1440(16:9)应选 FWXGA 1366×768,硬塞进 4:3 的 1024×768 会把画面压扁、坐标系统性偏移
「Computer Use 的瓶颈是动作不够丰富」 指错了要改的接口 该重新设计的是「观察接口」而不是「动作接口」:关键帧截图、音量门控转写、用文字描述画面压缩多模态历史
「Agent 点得准就等于好用」 忽略效率差 即使成功,Agent 步骤也明显多于人类、等待更久;人类靠推测执行省步骤。准确率达到人类水平 ≠ 已经足够实用
「移动端只要解决无障碍 API 和手势问题」 漏掉更难的生态壁垒 真正卡住的是商业模式冲突(流量与注意力变现被绕过);结构性利益冲突比 CAPTCHA 之类技术对抗更难调和
「机器人这块我也很熟」/ 把书上内容讲成做过 违反边界纪律 机器人岗在 JD 分析里是博士岗,不是本仓库的目标赛道;知道五层时间尺度表 + 动作分块即可,明确说「不是我准备的赛道」

自测#

1. 为什么说「不能仅凭代码用了 asyncio,就认定模型具备原生异步能力」?两条实现路线分别靠什么维持正确性?

答案

因为应用层的并发和模型层的异步协议是两件事。asyncio 只让代码可以并发调度,但模型与 API 未必支持「工具挂起、模型继续工作、生成过程中接受用户更新」这种消息时序 —— 有些接口仍要求先补齐工具结果才能继续。路线一是兼容方案:运行时用事件队列、任务句柄和占位符,在同步格式里表达异步语义,让使用同步接口的模型参与异步任务;路线二是原生异步(如 GPT-6 Astra 的异步工具调用与回合中途引导),模型自己理解这种节奏。两条路线的共同点是仍然需要应用层管理事件来源、工具生命周期与结果归属 —— 这正是「不能仅凭 asyncio」的含义。无论哪条路线,系统都要能应对延迟返回、中途修改与任务恢复。

2. Cron 和 Heartbeat 让 Agent「自己动起来」,那为什么还需要 Channel?举一个具体场景。

答案

因为 Cron 和 Heartbeat 都是时间驱动的:一个按预设时间触发,一个每隔固定间隔检查一次,都只能等下一个周期才可能察觉事件;Hooks 的事件来源又是框架内部而非外部世界。所以对第三方事件源(新邮件、外部 API 回调、紧急通知),这套机制缺乏即时接入的通道。具体场景是 Pine AI 的电话代理:Pine 代替用户拨打真实电话,通话中可能随时需要用户介入 —— 实时身份验证(客服要安全码或 OTP)、三方通话确认(要求账户持有人几秒内接听)、关键节点决策确认。靠 Heartbeat 轮询,用户可能在客服等验证码时迟迟收不到通知,导致客服挂断、通话失败。 解法是 Channel:在 Gateway 与 Pine API 之间建立实时事件通道,关键事件发生时即时推送给 Agent。结论就是那句原话 —— 真正的「主动服务」不仅需要 Agent 能定时检查事件,更需要事件能主动通知 Agent。

3. 模型正在执行工具、工具还没返回时用户插话,但接口是同步的。你会怎么做?这套方案有什么风险?

答案

思路是常态下让 LLM 看到标准的同步轨迹,只在打断时插入占位符修复格式。五条规则:① 及时记录已完成的 assistant 消息与工具调用项,reasoning 状态按提供商协议续接(不自行拼接不可见的思考文本);② 工具调用完成时才记录 tool result,执行中轨迹处于「部分完成」状态;③ 工具执行中的打断,为未完成的工具生成占位符 tool result(如「工具正在后台执行,请优先处理新事件」),追加打断事件后重新调用 LLM —— 这样从 LLM 视角看 assistant message 与 tool result 仍然配对完好;④ 无原生 steering 时取消未完成的生成、保留已确认完成的消息与工具状态,不能假定半截输出或隐藏推理可以作为合法前缀任意回灌;⑤ 非打断事件入队等批处理,当前周期完成后一次性追加。风险是占位符的语义:模型可能把「任务已启动」误当成「任务已完成」,在真实结果返回前作出依赖该结果的判断。所以要用明确的任务状态与结果校验防止混淆,并在评估中检查是否编造了未到达的数据。(另外不要仅凭一次失败就归因到某个未公开的训练过程。)

4. 快思考 / 慢思考的三种方案各是什么?「端到端」这个词为什么容易答错?

答案

三种方案:方案一「快思考回应、慢思考回答」——快模型几百毫秒内先给即时回应,慢模型后台深度推导;风险是简单问题被重复处理,复杂问题可能前后矛盾(快模型先建议买、慢模型随后发现套餐缺关键功能,用户在几秒内听到互相矛盾的答案),根因是两个实例各自完成了一次独立思考。方案二「快思考交互、慢思考提醒」——后台通过状态栏或专门接口给前台建议,前台维持话头并决定怎么表达;比方案一稳,但通信间接(前台可能误解建议、看不到后台中间思考),能「等结果」但不能真正边想边说。方案三「端到端思考与表达统一」——把思考内化到端到端音频模型,典型是 Step-Audio R1 的模态锚定思考蒸馏(MGRD)(让模型基于声学特征思考,保证「想得对」)+ MPS 双脑架构(构思与表达并行,解决「说得及时」)。「端到端」容易答错,是因为它有两个彼此独立的含义:语音通路的端到端(模型直接音频进出,不用多个模型经离散文本串接 —— Omni 和交互模型都算,但 Omni 通常仍按轮次、交互模型可边听边说)与认知架构的端到端(实时交互与深度思考是同一模型内共享状态共同训练,还是拆成前台快 + 后台慢)。两条轴独立,一个系统完全可以在语音通路上端到端、同时认知架构上保持快慢分离。

5. 面试官问「你做过 Computer Use / GUI Agent 吗?」——诚实又不失分的答法是什么?为什么这件事在本仓库里是硬规矩?

答案

先划界,再讲原理,最后落回自己真正的经验。可以说:「我没做过 GUI Agent / 语音 Agent,但我理解这套感知—思考—行动循环和动作空间设计:动作空间上分三类工具(鼠标键盘、持久 bash 会话、字符串匹配的文件编辑);视觉定位两条思路分别是把定位变成选择题(Set-of-Mark 的视觉标注、或基于 DOM/无障碍树的结构化元素索引)和纯坐标预测,后者要按宽高比匹配训练分辨率并做双向坐标缩放;时序上真正的难点是动作之后要重新确认现实是否仍符合计划,所以该重新设计的是观察接口。」不要把从书里读来的东西讲成做过的事 —— 这是本仓库的硬规矩(同 01-llm-core/multimodal.md 顶部),因为面试官只要追问两层工程细节(真机上的失败率、某个网站的反爬、手势类型怎么界定),编造会当场崩塌,损失远大于承认不懂。要强调的是一手相关的部分:我的经验在 LLM / Agent 应用工程(编排、工具调用、评测),GUI Agent 与语音是我的知识面而不是实战面。