在事件驱动的智能体系统中,“谁调用谁”这个问题本身就需要被改写。传统函数调用关心调用者和被调用者,而智能体运行时(agent runtime)更关心事件从哪里产生、由谁消费、控制权何时让出,又在什么条件下恢复。
许多大语言模型智能体框架,默认采用一种“调用—返回”的思路:用户提出请求,模型生成工具调用,工具执行完毕后返回结果,模型再继续推理。这个模型看起来清晰,也容易实现,但它只适合那些短暂、边界明确、一次性完成的任务。
一旦工具会长时间运行,日志会持续出现,用户会中途操作,后台任务会自行触发,这种线性调用模型就很快不够用了。此时,与其追问模型是不是主程序,不如换一个问题:系统里有哪些过程在产生事件,哪些过程在消费事件,哪些状态由谁持有,下一步行动又由谁决定?
从这个角度看,通信顺序进程(Communicating Sequential Processes,CSP)1和协程(coroutine)2都能提供更自然的建模方式。前者强调独立过程之间通过通道传递消息,后者强调任务可以暂停、恢复,并把控制权交回运行时(runtime)。二者并不完全相同,但都能帮助我们摆脱同步函数调用的限制。
模型是不是主程序
在传统程序里,主程序负责控制执行顺序。它调用函数,等待返回值,然后继续下一步。如果把这种理解套到智能体上,就会得到一种直觉:大语言模型是主程序,工具只是被它调用的函数。
这个直觉只在一部分场景里成立。模型确实会提出工具请求,也会根据工具结果继续规划。但在事件驱动系统中,许多事情并不是由模型主动发起的。用户可以随时输入新指令,工具可以在完成时产生结果事件,观察器(observer)可以在发现异常时唤醒规划器(planner),调度器可以在时间条件满足时触发任务。模型不是唯一的起点,也不应被迫扮演唯一的控制中心。
因此,模型更适合被理解为规划器,而不是主程序。它负责解释事件对目标的意义,决定是否继续等待、请求用户确认、提交工具任务、调整计划或终止流程。它不是整套系统的调用栈顶端,而是事件系统中的一个高层过程。
通信过程视角
通信顺序进程的核心不是函数调用,而是独立过程之间的消息通信。每个组件都是一个长期存在的过程,它们不共享同一个调用栈,也不要求一个组件直接等待另一个组件返回。它们通过通道传递事件,并根据收到的事件继续行动。
如果用这种方式建模一个大语言模型智能体系统,可以把系统拆成几个主要过程:用户界面过程、规划器过程、工具执行过程、外部环境或服务过程、日志观察器过程、调度过程和执行过程。
规划器这个过程通常由大语言模型承担,负责解释事件、更新判断并规划下一步。工具执行过程负责运行工具。外部服务过程持续产生状态变化和日志。日志观察器过程负责读取日志,筛选与当前任务相关的信息。调度过程负责定时触发任务。执行过程负责把规划转化成具体操作,例如调用接口、发送消息、启动自动化流程或控制设备。
这些过程之间通过通道交换事件。用户操作进入用户事件通道,规划器发出的工具请求进入工具请求通道,工具结果进入工具结果通道,服务日志进入日志流通道,观察器的判断进入观察通道,最终行动进入行动通道。
在这种模型中,一个典型流程不再是“用户调用模型,模型调用工具,工具返回结果”。更准确的描述是:用户界面产生一个操作事件,规划器收到事件后生成工具请求,工具执行过程接收请求并开始工作,工具在执行过程中或完成后发出结果事件,规划器再根据新的事件决定下一步。
这里没有传统意义上的函数返回。系统中的一切都是事件通信。工具完成是一种事件,日志更新是一种事件,用户追加输入是一种事件,定时任务触发也是一种事件。规划器不是压在所有组件之上的主函数,而是众多过程中的一个,只是它承担了更高层的解释和规划职责。
这种建模方式更接近真实的智能体系统。很多工具会运行很久,很多服务会持续输出日志,用户也可能随时输入新的操作,机器人行为更是天然需要持续反馈。这些场景都不适合用单一调用栈来描述,却很适合用多个过程和通道来描述。
日志流为什么适合通信模型
日志流尤其能说明这种模型的价值。
在传统思路里,规划器似乎需要主动调用日志系统,然后等待日志系统返回一段内容。但真实服务的日志不会因为模型调用才存在。服务自己在运行,日志自己在产生。日志观察器应持续读取日志流,并在发现与当前动作相关的内容时,向规划器发送观察事件。
这样一来,规划器不需要主动盯住日志系统。它只需要等待重要观察结果。日志观察器负责判断哪些日志与当前任务有关,哪些只是背景噪声;哪些只是普通进展,哪些意味着错误、超时或需要重新规划。
这正是通信模型的优势。每个过程自己运行,自己处理局部输入,只有在必要时才把信息发给其他过程。规划器不必读取所有原始信号,也不必频繁轮询每个组件。它只处理对决策有意义的事件。
在这种结构中,观察器本质上可以看作一个独立过程。它不是规划器的缩小版,而是负责监测、筛选和上报的过程。它持续消费日志流或工具输出,再把压缩后的状态变化发送给规划器。
协程视角下的控制权转移
协程提供了另一种实现视角。与 CSP 相比,协程更接近工程中的执行方式:一个任务可以在等待某个结果时暂停,把控制权交还给运行时;等结果到来后,再从暂停处继续执行。
在协程模型中,规划器可以是一个长期运行的任务。它不断等待下一个事件,收到事件后进行推理,生成行动计划,然后把计划分发给对应执行器。如果它需要等待工具结果,它不会阻塞整个系统,而只是暂停自己。运行时可以继续调度日志观察器、工具执行器、用户界面处理器或调度器。
工具执行器也可以是一个长期运行的协程。它等待工具请求,收到请求后启动执行,过程中可以不断发出进度事件,完成后发出结果事件。日志观察器则可以持续读取日志流,发现相关内容后发送观察结果。调度器等待时间条件满足,然后发出定时事件。
从代码写法上看,协程有时像同步流程,因为可以写成“等待某个事件后继续”。但从系统逻辑上看,它仍然是事件驱动的。等待并不意味着整个系统停住,而只是当前协程暂停。其他协程仍然可以继续处理用户输入、工具进度、日志异常或定时触发。
没有固定的发起方
传统结构可以概括为:主程序调用大语言模型,大语言模型调用工具,工具返回,大语言模型继续。这个结构把模型放在中心,也把所有交互压成一条线。
在事件驱动系统中,发起方会不断变化。用户输入时,用户界面是发起方;工具完成时,工具执行器是发起方;日志异常时,观察器是发起方;定时任务触发时,调度器是发起方;外部服务状态变化时,外部服务本身也是发起方。大语言模型并不总是站在最前面。
这不是削弱模型,而是把模型放回合适的位置。模型最有价值的地方,是在多个事件之间建立语义关系:这个错误是否影响目标,这个用户输入是否改变约束,这个工具结果是否足够进入下一步,这个异常是否需要请求人工确认。它负责判断和规划,但不必伪装成所有事件的源头。
更合理的结构是:运行时维护一个事件循环,多个过程或协程同时存在。规划器处理高层决策,工具执行器处理外部工具,观察器处理日志和状态变化,调度器处理时间触发,用户界面处理用户输入,执行器处理实际操作。系统真正的中心不是某一次模型调用,而是事件流和状态更新机制。
规划器也不需要持续轮询所有信息。它只需要等待几类关键事件:用户事件、观察事件、工具结果事件和调度事件。每当其中一类事件到来,规划器再判断它是否影响当前目标和行动计划。
这可以类比 Go 语言中的 select:系统同时监听多个通道,哪个通道先出现事件,就处理哪个事件。对智能体运行时来说,这种模式比单线程调用链更自然,因为它天然支持并发、等待、中途取消、错误恢复和流式输出。
工具调用应变成任务提交
如果用通信过程实现智能体运行时,那么大语言模型的工具调用也需要重新理解。它不再是一次函数调用,而是提交一个任务,并等待后续事件返回。
模型不是说“调用这个工具并立即得到结果”,而是说“启动这个任务”。工具执行器接收任务后,可以返回一个任务编号或任务引用。随后,任务可能持续产生进度、日志、中间结果、错误或完成事件。规划器可以选择继续等待,也可以在中途取消、重试、切换方案,或者根据观察器上报的信息重新规划。
这样,许多原本棘手的问题会变得自然。长时间任务不再需要规划器盲等。流式输出可以作为事件逐步处理。中途取消可以通过取消事件完成。错误恢复可以由观察器识别后触发。多个工具也可以并发执行,而不是挤在一条同步调用链里。
从控制流角度看,这个变化很关键。工具调用不再把控制权长期占在模型和工具之间,而是把控制权交还给运行时。运行时可以继续处理其他事件,也可以在任务完成、失败、超时或被取消时重新唤醒规划器。
在状态不完全可见的环境中控制
再进一步,可以把整个智能体运行时看成一个在状态不完全可见的环境中做控制的系统。环境并不会把完整状态直接告诉模型。模型只能通过用户输入、工具结果、日志观察、指标变化和传感器反馈来间接理解当前状态。在控制理论和机器人系统中,这类问题常被称为部分可观测环境。
规划器的任务不是简单地把输入变成输出,而是不断接收观察,更新对环境的判断,再选择下一步行动。行动执行后,环境发生变化,又产生新的观察。这个循环不断重复。
这与机器人系统和自动驾驶系统有相似之处。机器人并不知道世界的完整状态,只能通过传感器和内部状态估计来行动。大语言模型智能体也一样。它面对的是一个不断变化、信息不完整、反馈可能延迟的环境。日志、工具结果和用户动作都只是观察信号,而不是完整真相。
因此,智能体不是把输入变成输出的函数,而是在不完整反馈中持续控制的系统。它观察、更新判断、行动,再观察。模型负责规划,但规划必须建立在可靠的事件组织之上。
结论
对于包含大语言模型、工具、日志流、用户行为和自动化动作的智能体系统,用同步调用模型来理解会越来越困难。它把系统压成一条线,却无法自然表达长任务、流式输出、持续日志、并发操作和环境反馈。
更合适的方式,是把智能体运行时建模为一个由多个过程共同推进的事件系统。用户、工具、观察器、调度器、执行器和规划器都是独立过程,通过通道交换事件。大语言模型是规划器,不是唯一主程序。它接收观察,更新判断,再选择行动。
从通信顺序进程的角度看,系统由多个独立过程组成,通过通道传递消息。从协程的角度看,系统由多个可暂停、可恢复的任务组成,共同挂在事件循环上。两种视角都指向同一个结论:智能体的本质不是一连串函数调用,而是在变化环境中持续观察、判断和行动。
当工具调用被改造成任务提交,当日志被改造成观察事件,当用户输入、调度触发和外部反馈都被统一纳入事件流,“谁调用谁”就不再是一个固定层级问题。真正重要的是事件如何通信,状态如何更新,控制权如何让出,又如何在正确的时刻恢复。