每位 AI 工程师都必须构建的 30 个智能体——具身智能体与物理世界智能体

0 阅读57分钟

世界本身就是它最好的模型。
—— Rodney Brooks,iRobot 联合创始人、MIT CSAIL 前主任

1966 年,斯坦福的研究人员把一台名为 Shakey 的轮式机器人放进走廊,让它自己推理如何推动积木。教训立刻显现出来:在物理世界中行动的智能,每一个决策都必须经受重力、摩擦和后果的检验。三十年后,NASA 的 Sojourner 火星车穿越火星地形时,也受到同样约束。今天,自主无人机可以在风暴和施工现场中航行,无需人类操控。每一个系统都印证了 Shakey 所揭示的事实:被限制在屏幕里的智能,完全是另一类问题。

这种质的差异,创造了我们所说的 physicality constraint,也就是物理性约束。数字智能体运行在状态变化通常是虚拟且可逆的环境中。相比之下,物理智能体面对的是毫不妥协的物理定律;物体具有质量,执行器会引入延迟,传感器会产生有噪声、不完美的数据。最关键的是,物理行动通常不可逆。机械臂掉落一个脆弱部件时,无法执行 “undo” 命令。应急车辆被错误调度,会立刻产生有形危险。

为了让这个约束可操作化,我们可以将其拆解为三个具体属性。第一,不可逆性:物理行动一旦执行就无法回滚,因此规划必须在提交之前考虑最坏情况。第二,延迟:机械执行器、通信链路和传感器管线都会引入延迟,这些延迟会在实时控制循环中累积,使时序成为硬约束,而不是服务质量偏好。第三,能量限制:机载电力有限,任务中途无法补充,因此每个行动都有能量成本,并界定可行计划空间。

有了这一框架,我们可以将本章放进全书更大脉络中。前面章节探索的是运行在纯数字环境中的智能体:查询 API、围绕文本推理、协调多智能体管线。本章将这些基础扩展到物理世界,在那里,行动具有重量、质量和后果。

本章将覆盖以下主题:

  • 具身智能智能体
  • 跨领域转换集成智能体

技术要求

要运行本章中的示例,你需要准备以下内容:

  • Python 3.10 或更高版本
  • 以下 Python 包:langchain==0.2.16langchain-openai==0.1.23langgraph==0.1.4openai==1.40.0pydantic==2.8.2python-dotenv==1.0.1
  • 一个 OpenAI API key,并具备访问 gpt-4o 模型的权限

本章所有代码示例可在本书 GitHub 仓库中找到:

https://github.com/PacktPublishing/30-Agents-Every-AI-Engineer-Must-Build/chapter16

架构基础:深度—广度分界

物理世界智能体面对两个截然不同的问题,没有任何单一架构模式能够同时服务二者。第一个是深度:以毫秒级精度、硬安全保证和确定性反馈控制单个物理系统。第二个是广度:协调异构基础设施系统,这些系统的状态会跨不兼容时间尺度相互影响。由于深度和广度对任何试图同时解决它们的架构施加了相互矛盾的要求,因此需要两种不同设计。

在这一领域中,失败代价不是服务器错误或被捕获的异常,而是人类安全和物质损失。架构模式必须反映这一高风险现实。

这种高风险现实要求一种特定架构回应。传统机器人系统依赖刚性、预编程行为。现代 agentic 架构则将这一范式转向自适应、目标导向推理。这一转变引入了一个根本架构挑战:将高延迟推理与低延迟控制集成起来。

我们通过 asymmetric control loop,即不对称控制循环,解决这一问题。该模式将系统拆分为两个不同层:

推理层:一个异步智能体,通常基于 LLM,处理高层意图和环境上下文,以生成计划。

确定性控制器:一个同步、实时循环,负责执行计划,同时强制执行硬安全约束。

利用这种层级结构,操作员可以用自然语言描述任务目标。Agentic 系统将该意图翻译成一组安全、尊重约束的物理行动。智能体提供 “why” 和 “what”,而确定性控制器在物理安全边界内管理 “how”。

从推理层到确定性控制器的交接,由 bounded plan parameters,即有界计划参数治理。推理层生成带显式时间 horizon 的计划,通常是在任务规划速率下向前看 1 到 10 秒;计划中的每个行动都表示为预定义行动 envelope 内的参数化命令:目标位置、速度限制、力上限和工作空间边界。确定性控制器只接受落在这些边界内的命令;任何超出 envelope 的行动都会在执行前被拒绝,并通知推理层重新规划。

在详细考察每种架构之前,有必要理解为什么单一智能体设计无法同时承担两个角色。物理世界智能面对两个不同问题,它们对尝试解决它们的系统施加相互矛盾的要求:深度问题和广度问题。

深度问题关注的是以硬件要求的精度、速度和安全保证控制单个物理系统。一个仓库机器人从货架上拣选物品时,必须将有噪声的传感器数据融合成连贯世界模型,规划无碰撞轨迹,在毫秒级控制循环内执行这些轨迹,并在有人进入其工作空间时立即停下。这个栈的每一层都运行在严格延迟预算下。这里的推理很深,跨越从战略目标到电机电流的多个抽象层;但很窄,只局限于一个机器人和一个物理领域。

第二个是广度问题:协调多个基础设施系统,这些系统通过可测量但复杂的传递函数相互影响。城市交通网络、电网、供水系统和应急服务并非独立演化。停电会使交通信号失效,交通信号失效会增加拥堵,拥堵会延误救护车响应时间,进而提高死亡风险。任何单一领域控制器都无法推理这些级联互动。这里的推理很广,横跨具有不同物理机制、时间尺度和监管约束的异构系统;但相对较慢,决策发生在分钟、小时或政策周期层面,而不是毫秒级。

深度和广度问题如图 16.1 所示。

image.png

图 16.1——深度与广度问题

这两个问题需要根本不同的架构回应。深度需要紧密、快速、单领域控制,并具备硬实时保证。广度需要松散、审议式、跨领域协调,并能容忍不确定性和延迟。针对其中一个优化的架构,在另一个问题上会失败。以 1 kHz 运行的伺服循环不能暂停去查询天气 API。跨领域知识图谱遍历无法保证亚毫秒级执行。试图将二者压进同一个控制循环,会得到一个既太慢而无法安全物理控制、又太刚性而无法跨领域推理的系统。

考虑一个具体场景:一辆自动驾驶汽车在严重雷暴中穿行于智慧城市。这辆车本身就是一个具身智能体。它必须在受雨水降质的摄像头画面中跟踪车道线,在湿滑路面上保持安全跟车距离,因为制动距离可能增加 40% 或更多,并且在行人突然进入道路时执行避让动作。这些都是深度问题:紧密感知—行动循环,亚秒级规划 horizon,硬安全不变量。车辆的车载系统通过分层控制层级处理它们,将战略路径规划、实时轨迹跟踪和伺服级电机控制分离。

但风暴也会造成单个车辆无法独自解决的广度问题。城市交通管理系统必须将成千上万辆车绕开被淹路口。电网运营商必须在雷击摧毁变电站时管理负载,而这又会使下游路口交通信号失效。应急服务必须基于因能见度降低和拥堵增加所形成的预测事故热点重新部署救护车。这些跨领域互动,也就是天气影响电力、电力影响交通、交通影响应急响应,需要一个 Integration agent,它维护一套结构化跨领域依赖模型,并在网络中传播影响估计。

因此,这两种架构是互补的。具身智能智能体解决深度问题:它在单一领域中桥接高层推理和低层物理执行,并在多速率控制层级的每一层强制安全不变量。跨领域转换集成智能体解决广度问题:它通过编码跨领域依赖的类型化知识图谱协调异构基础设施系统,使影响传播和级联估计可以跨系统边界完成。真实世界部署需要二者同时存在。本章结尾的案例研究正展示这种综合:一架自主无人机必须执行精确物理飞行(深度),同时集成来自天气、空域、能源和危险领域的约束(广度)。

接下来的部分将分别详细考察每种架构:处理深度问题的具身智能智能体,以及处理广度问题的跨领域转换集成智能体。

具身智能智能体

具身智能智能体是一种分层控制架构,用于在单一领域内桥接抽象推理和物理执行。它将智能体职责拆解到四个层次:战略推理、模型维护、实时控制和安全执行,每一层运行在不同时间尺度上。本节解释该架构、其数学基础和 LangChain 实现,覆盖让物理世界运行可靠所需的控制层级、世界模型和安全约束。

连接推理和物理行动的挑战,已经定义了机器人领域六十多年。1961 年,通用汽车在新泽西 Ewing 的装配线安装了 Unimate,这是第一台工业机器人。Unimate 按固定序列运行:一组预先记录的关节位置循环回放。它没有感知、没有规划,也没有适应能力。如果一个零件到达位置偏差 2 厘米,机器人仍会继续执行已编程动作,导致缺陷或自损。这种脆弱性在严格受控工厂单元中尚可接受,但使机器人无法在非结构化环境中自主运行。

下一代追求了相反极端。1986 年,Rodney Brooks 发表 subsumption architecture,即包容式架构,主张智能行为可以从简单反应式规则的层叠中涌现出来,而无需中央规划器或世界模型。基于包容式架构的机器人直接响应传感器输入:如果检测到障碍,则转向;如果路径清晰,则前进。这种方法在杂乱环境中产生了惊人的稳健导航能力,但无法处理需要审议的任务。一个包容式机器人遇到锁着的门时,会反复尝试推门。它没有机制去推理另一间房里有钥匙、规划绕行,并返回。

现代 LLM 增强机器人系统试图通过结合高层语义推理和低层反应控制来解决这种张力。根本问题仍然是区分 Unimate 与 Brooks 机器人之间的同一个问题:如何将审议,也就是慢速、不确定、运行在抽象目标上的推理,连接到物理执行,也就是必须快速、确定,并受物理定律约束的行动?每一个具身系统,无论是仓库移动机器人、手术机械臂,还是自主飞行器,都面对同样的架构问题。答案决定系统能否在计划必须实时适应的环境中安全有效运行。

考虑一个具体实例:仓库机器人收到命令 “move package A to shelf B”。这条单一指令隐藏着一连串计算问题。机器人必须用车载摄像头和激光雷达定位包裹 A,而这些设备会在反光表面附近产生彼此不一致的有噪声深度估计。它必须规划从当前位置到包裹的路径,避开货架单元、其他机器人和人类工人,而这些都可能不可预测地移动。它必须计算抓取策略,考虑包裹重量、重心和表面摩擦。随后,它必须携带包裹导航到货架 B,而包裹会改变机器人动力学:更高重心、不同制动特征。在整个序列中,它还必须保证:如果任何传感器检测到有人进入安全周界,它会在 100 毫秒内停下。本节讨论的正是使这一切成为可能的架构。

具身智能体运行在连续、部分可观测的动力系统中,并受到严格实时约束。状态会根据物理定律演化。传感器提供有噪声且不完整的观察。行动会引入延迟、动量和不可逆效果。不同于纯数字智能体,具身系统不能依赖事务性回滚。控制决策必须随着系统随时间演化而保持安全不变量。

智能体维护一个 belief state b(s),即可能世界状态上的概率分布,并随着新观察到来而更新。规划发生在这个 belief space 上。然而,执行发生在近似当前状态估计的确定性控制循环中。这种分离至关重要。概率推理在高层影响行动选择。实时控制在低层强制稳定性。形式上,智能体与环境的交互可以建模为连续 Partially Observable Markov Decision Process(POMDP)。

POMDP 是一个数学框架,用于智能体无法观察完整世界状态时的决策。在标准 Markov decision process 中,智能体准确知道自己在哪里、周围是什么。物理机器人很少享有这种奢侈。仓库机器人知道自己的位置,来自轮编码器和惯性传感器;但它看不到货架后面,无法确定未扫描包裹的精确重量,也无法预测人类工人何时会走进通道。因此机器人维护一个 belief state b(s):所有可能世界配置上的概率分布,并在每次新传感器数据到达时更新。POMDP 中的规划,会选择在一系列可能状态上都表现良好的行动,而不只是当前最可能状态。这就是为什么设计良好的仓库机器人在盲角附近会减速:belief state 会给“视线外有人存在”分配非零概率。

实践中,belief state 更新使用 particle filters 或 Bayesian filtering 计算。粒子滤波器将 b(s) 表示为一组带权采样状态;每次新传感器观察都会重新加权并重采样,使概率质量向与观察一致的状态收缩。当状态空间连续且动力学近似线性时,Extended Kalman filters 扮演同样角色。两种方法都以传感器轮询频率运行,通常为 10 到 100 Hz,使 belief state 保持最新,而不会阻塞更高层规划。

操作员可能发出 “move package A to shelf B” 这样的目标。具身智能体必须将这条指令拆解为可接受的物理行动,确保每个行动遵守安全约束,并在毫秒级延迟预算内执行。因此,该设计分离四项职责:

  • 围绕目标和计划进行战略推理
  • 围绕物理状态和约束进行模型维护
  • 对轨迹和执行器进行实时控制
  • 将安全执行作为无条件覆盖层

这种拆解保持稳定性,并限制故障爆炸半径。

接下来的小节将依次展开该架构的每个组件:分离时间尺度的控制层级,将规划锚定到物理状态的世界模型,将它们集成起来的多速率感知—行动循环,以及将设计转化为可部署代码的 LangChain 实现模式。

控制层级作为时间尺度拆解

本小节考察结构化具身智能体运行的控制层级,展示如何在运行于不同时间尺度的层之间分配职责,以同时实现战略灵活性和实时安全。

机器人控制系统通过抽象层级实现这种分离,每一层以不同频率运行。高层以符号方式推理,并以秒为尺度规划。低层以千赫兹速率调节扭矩和电流。

LevelAbstractionFrequencyAlgorithm Class
Task Planning符号目标0.1–1 HzPDDL planners、LLM reasoning
Motion Planning无碰撞路径1–10 HzRRT、PRM、优化方法
Trajectory Control时间参数化路径50–200 HzPID、model predictive control
Servo Control电机电流1–10 kHz电流和扭矩环

表 16.1——控制层级:运行频率、算法类别与延迟预算

表中的 frequency 列描述每一层每秒执行多少次决策循环。1 Hz 表示每秒一个循环;1 kHz 表示每秒一千个循环。这些数字反映每一层职责的紧迫程度。

Task planning 以 0.1 到 1 Hz 运行,因为决定“接下来拣哪个包裹”是战略选择,可以承受一到十秒的审议。Motion planning 运行得更快,为 1 到 10 Hz,因为只要障碍物移动,就必须重新计算无碰撞路径。

Trajectory control 以 50 到 200 Hz 运行,确保机器人手臂平滑跟踪预期路径。在 100 Hz 下,控制器每 10 毫秒修正一次偏差,足以在连续运动中保持精度。

Servo layer 以 1 到 10 kHz 直接调节电机电流,在几分之一毫秒内抵消电气和机械扰动。如果伺服循环只以 1 Hz 运行,电机遇到意外阻力时,会在任何修正到达前剧烈振荡或失速。

多速率控制层级如图 16.2 所示,它将每一层运行频率映射到算法角色:任务规划在亚赫兹速率运行,运动规划在 1–10 Hz 运行,轨迹控制在 50–200 Hz 运行,伺服级电流调节在 1–10 kHz 运行。每个频带都反映该层的延迟预算,从数秒级战略审议到扰动抑制中的毫秒小数级响应。

image.png

图 16.2——具身智能智能体的多速率控制层级

每一层运行在不同频带,从任务规划(0.1–1 Hz)到伺服级电流调节(1–10 kHz)。高层围绕目标和计划推理;低层则实时执行物理稳定性,并抵消扰动。

这种层级不是风格问题,而是执行稳定性。伺服层必须在毫秒内抑制扰动,避免振荡或硬件损伤。轨迹控制保持平滑跟踪。运动规划器在几何约束下计算可行路径。任务规划器围绕离散目标推理。每一层都向上一层暴露受约束接口。

下面的代码块展示表 16.1 中没有 LLM 参与的低三层。每个函数接受与其层级频率和算法类别一致的输入,并返回上一层消费的输出。这些是简化骨架;生产实现依赖硬件专用驱动和实时操作系统原语。

# Pseudocode: Lower-layer control skeletons: motion planning, trajectory control, and servo regulation

# --- Motion Planning layer (1-10 Hz, RRT/PRM) ---
def plan_motion_trajectory(goal_pose, world_model, obstacles):
    """Compute a collision-free path from current pose to goal.
    Frequency: 1-10 Hz.  Algorithm class: RRT*, PRM."""
    current_pose = world_model.get_current_state()["pose"]
    path = rrt_star(current_pose, goal_pose, obstacles)
    return path  # list of waypoints for trajectory layer


# --- Trajectory Control layer (50-200 Hz, PID/MPC) ---
def compute_trajectory_setpoints(path, dt=0.005):
    """Time-parameterise the path into setpoints at the
    control frequency.  Frequency: 50-200 Hz.
    Algorithm class: PID, model predictive control."""
    for waypoint in interpolate(path, dt):
        error = waypoint - read_encoder_pose()
        torque = pid_controller.compute(error, dt)
        yield torque  # consumed by servo layer


# --- Servo Control layer (1-10 kHz, current loops) ---
def servo_control_loop(torque_setpoint, dt=0.0001):
    """Regulate motor current to achieve commanded torque.
    Frequency: 1-10 kHz.  Rejects electrical and
    mechanical disturbances within fractions of a ms."""
    current = read_motor_current()
    target_current = torque_to_current(torque_setpoint)
    pwm_signal = current_pid.compute(
        target_current - current, dt
    )
    write_pwm(pwm_signal)

具身智能体主要在任务规划层交互。结构化命令通过控制接口传递,该接口将符号意图翻译为可接受运动目标。在已部署系统中,该接口会与 ROS2 等中间件集成,ROS2 提供发布—订阅消息、用于长时任务的 action servers,以及分布式节点间时间同步。这里的中间件是实时分布式基础设施,而不只是便利 API。

image.png

图 16.3——从 LLM 推理到执行器的分层命令接口。安全执行会在执行前将每条命令与可接受行动集合 A_safe(s) 核对;ROS2 在层之间提供时间同步消息。

图 16.3 展示安全执行层位于控制接口和执行器之间,而不是与推理层并列。这种放置是有意的:安全不是正确规划的涌现属性。它是系统可执行行动集合上的显式限制。每条命令在到达执行器前都必须经过验证。验证会执行工作空间边界、力限制、速度约束和系统状态检查。违反这些约束的命令会在执行前被拒绝。

可接受行动集合 A_safe(s) 定义外边界;硬件急停机制是执行该边界的无条件覆盖。它位于命令管线外部,绕过所有软件层,立即停止执行。A_safe(s) 约束智能体选择,而急停则完全超越这些选择。这个边界定义了人类权威覆盖自主控制的位置;在安全关键系统中,这条覆盖路径必须简单、直接,并独立于高层推理。

概念上,安全层定义一个可接受行动集合 A_safe(s)。规划在这个集合内运行。控制永远不执行集合外行动。这种基于约束的框架,将安全对齐到控制理论,而不是事后验证。

世界模型作为物理引擎

Model 组件维护仓库环境的结构化表示。对于执行 “move package A to shelf B” 的机器人来说,这意味着不是原始摄像头画面或激光雷达点云,而是推断出的对象状态:包裹 A 的估计姿态、货架 B 周围的占用和空闲区域,以及机器人、包裹和通道中每个货架单元之间的空间关系。这些推断状态是规划层查询的对象;传感器数据永远不直接暴露。

仓库机器人的空间推理包括:从有噪声的深度返回中估计包裹 A 的姿态,在相邻金属货架反光表面附近进行特殊处理;计算碰撞检测所需的 bounding volumes,以避开货架单元和其他机器人;以及随着人类工人穿过通道,跟踪自由空间走廊。物理推理覆盖包裹 A 是否可放置在货架 B 上:只有当包裹重心投影保持在支撑多边形内,且满足平衡条件时,稳定性才成立。

这些约束会在操控或放置行动前被评估。

世界模型暴露可查询方法,规划层会直接调用这些方法。在机器人试图抓取包裹 A 之前,规划器会查询抓取难度;当包裹被卡在会降低深度精度的反光表面附近时,返回更高成本估计。在导航到货架 B 之前,规划器会查询预期路径上的碰撞状态。结果就是封装:所有物理和几何推理集中在世界模型中,规划器发出结构化查询,而不是自己解释原始传感器数据。

在生产系统中,该模型可能集成学习型感知模块、解析几何和物理仿真器。无论实现细节如何,不变量保持不变:没有任何行动可以在未根据连贯内部世界表示评估之前执行。

多速率感知—行动集成

具身智能体作为多速率感知—行动循环运行。快速循环处理感知和安全检查。中间循环跟踪轨迹。慢速循环执行重新规划和高层推理。昂贵计算永远不能阻塞安全关键反应。

每个控制周期中:

  • 传感器数据更新世界模型
  • 安全监控器评估不变量
  • 从当前计划中选择下一个可接受命令
  • 将命令派发给低层

如果发生安全违规,执行会立即停止。如果环境使当前计划失效,战略层会异步重新规划,而内层循环维持安全行为。

这种时间尺度分离,是具身智能的定义性架构模式。快速循环无条件执行物理约束。慢速循环解释目标、解决不确定性,并协调子系统。稳定性和安全性来自尊重这种层级。

因此,具身智能智能体不是单一算法。它是一个分层控制架构,在 belief-space 推理和不可逆物理行动之间架桥,并跨时间尺度保持不变量。

接下来的代码块会标为编号清单,方便交叉引用,因为多个实现会彼此构建。

实现:LangChain 具身智能体模式

四项职责拆解,即战略推理、模型维护、实时控制和安全执行,会直接转化为一个带专门工具的 LangChain 智能体。核心问题是:基于 LLM 的推理层如何向物理机器人发出命令,同时不绕过保护硬件的安全层和控制层?答案是 tool-mediated indirection,即工具中介间接调用。LLM 永远不直接控制执行器。它调用查询世界模型的工具,通过已验证控制接口提交命令的工具,以及在任何物理行动执行前检查安全约束的工具。

在考察具体清单之前,下面的共享设置定义了本章后续所有代码示例引用的接口 stub 和全局实例。这些是架构脚手架,指定每个组件的接口契约。生产系统会用硬件专用实现替换它们。

# Listing 16.1: Common setup: shared interface stubs for all chapter listings
"""Common setup for Chapter 16 listings.
These stubs define the interface contracts that all subsequent
listings reference.  They are architectural scaffolds, not
production implementations."""

from langchain_core.messages import HumanMessage


class WorldModel:
    """Maintains belief state b(s) over robot and environment."""
    def query(self, query: str) -> dict:
        raise NotImplementedError

    def get_current_state(self) -> dict:
        raise NotImplementedError

    def update(self, observations: dict) -> None:
        raise NotImplementedError


class ControlInterface:
    """Dispatches validated commands to the deterministic
    controller (50-200 Hz loop)."""
    def execute(self, *args, **kwargs) -> object:
        raise NotImplementedError


class SafetyMonitor:
    """Validates actions against A_safe(s) before execution."""
    def validate(self, action, target_or_state) -> object:
        raise NotImplementedError

    def halt(self, reason: str = "") -> None:
        raise NotImplementedError


def extract_actions(plan) -> list:
    """Parse proposed actions from agent plan output."""
    raise NotImplementedError


# --- Stubs for Domain-Transforming Integration Agent (Listings 16.3-16.4) ---
class _EnergyAPI:
    def get_substations(self, region: str) -> list:
        raise NotImplementedError


class _TrafficAPI:
    def get_network(self, region: str) -> list:
        raise NotImplementedError


class _KnowledgeGraph:
    def add_edge(self, src, tgt, rel, weight) -> dict:
        raise NotImplementedError


world_model = WorldModel()
control_interface = ControlInterface()
safety_monitor = SafetyMonitor()
energy_api = _EnergyAPI()
traffic_api = _TrafficAPI()
knowledge_graph = _KnowledgeGraph()

清单 16.2 展示四职责拆解如何映射到 LangChain 智能体,展示工具中介边界如何防止 LLM 推理层绕过安全与控制。

# Listing 16.2: Embodied agent with four-responsibility tool decomposition
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

# --- Model Maintenance: query the world model ---
@tool
def query_world_model(query: str) -> dict:
    """Query the robot's world model for object poses,
    collision status, or grasp difficulty estimates."""
    return world_model.query(query)

# --- Real-Time Control: dispatch validated commands ---
@tool
def dispatch_motion_command(target: str, action: str) -> dict:
    """Submit a motion command through the control interface.
    Safety validation occurs before dispatch."""
    return control_interface.execute(target, action)

# --- Safety Enforcement: validate before execution ---
@tool
def check_safety_constraints(action: str, target: str) -> dict:
    """Validate an action against the admissible action set.
    Checks workspace bounds, force limits, velocity caps."""
    return safety_monitor.validate(action, target)

# --- Strategic Reasoning: LLM agent with tool access ---
llm = ChatOpenAI(model="gpt-4o", temperature=0.0)
tools = [
    query_world_model,
    dispatch_motion_command,
    check_safety_constraints
]
embodied_agent = create_react_agent(llm, tools)

每个工具都恰好映射到架构拆解中的一项职责。LLM 充当战略推理层:它解释操作员目标,查询世界模型评估当前状态,在承诺行动前检查安全约束,并通过控制接口派发已验证命令。关键是,LLM 无法绕过安全层。工具架构执行了正文中描述的信任边界:推理层提出方案,而确定性控制器,也就是由控制接口和安全监控器中介的部分,决定能否执行。

第二个实现问题是行动执行循环本身。在物理系统中,智能体不能简单调用工具并等待结果。它必须根据可接受行动集合验证每条命令,优雅处理拒绝,并在规划与执行之间环境发生变化时维持安全行为。下面的代码展示这一模式。

# Listing 16.3: Safety-constrained action execution loop
def execute_with_safety(agent, task: str, world_model, safety_monitor):
    """Execute an embodied task with pre-execution safety
    validation and continuous monitoring."""
    # Step 1: Agent reasons about the task and proposes actions
    plan = agent.invoke({"messages": [HumanMessage(task)]})

    # Step 2: Extract proposed actions from agent output
    actions = extract_actions(plan)

    # Step 3: Validate each action against A_safe(s)
    for action in actions:
        state = world_model.get_current_state()
        validation = safety_monitor.validate(
            action, state
        )

        if not validation.is_safe:
            # Rejected: replan with constraint feedback
            plan = agent.invoke({"messages": [
                HumanMessage(
                    f"Action rejected: {validation.reason}. "
                    f"Replan within: {validation.constraints}"
                )
            ]})
            continue

        # Step 4: Execute validated action
        result = control_interface.execute(action)
        world_model.update(result.observations)

        # Step 4b: timeout and actuator feedback validation
        try:
            result = control_interface.execute(action, timeout=5.0)
            if not result.actuator_ok:
                # Actuator reported fault; halt and surface for replanning
                safety_monitor.halt(reason=result.fault_code)
                break
            world_model.update(result.observations)
        except TimeoutError:
            # Execution did not complete within timeout; production systems
            # require fuller error trees (retry, degrade, emergency stop).
            safety_monitor.halt(reason="execution_timeout")
            break

该执行循环实现了架构正文中的基于约束安全模式。任何行动到达控制接口之前,安全监控器都会基于当前世界状态评估它是否落在可接受行动集合 A_safe(s) 内。如果验证失败,智能体不会盲目前进。相反,拒绝原因和活动约束会反馈给 LLM,让它在更窄边界内重新规划。这个反馈循环是架构中“无条件安全覆盖”的实现层等价物:智能体可以自由推理,但只有可接受行动能穿过边界进入物理执行。每次成功行动后,世界模型会用新传感器观察更新,确保下一次规划循环基于当前状态而不是陈旧假设。

当机器人遇见真实世界:Kiva Systems 革命

2012 年,Amazon 以 7.75 亿美元收购 Kiva Systems,这是一家制造矮胖橙色机器人、用于在仓库地面穿梭搬运货架单元的初创公司。怀疑者质疑这一价格。机器人速度慢,仅限平整表面,只能在精心绘制地图的环境中运行。但 Kiva 创始人理解了机器人领域忽视的一件事:在物流中,规模化可靠性比边缘能力更重要。一台能在 800 台机群中成功完成 99.8% 简单取货任务的机器人,比十几个复杂但不可预测失败的机械臂移动更多商品。到 2024 年,Amazon 已在其履约网络中部署超过 750,000 个机器人单元,并改名为 Amazon Robotics。这一架构教训仍然有效。本章中的仓库协调系统体现同一原则:机群级编排、保守安全边界,以及单个机器人失败时的优雅降级。

具身智能智能体解决一个具体且严苛的问题:在单一领域内桥接抽象推理和物理执行。它的多速率控制层级、belief-state 规划和可接受行动执行,共同产生一个能将高层目标转化为安全、实时物理行为的系统。在一个机器人、一个仓库或一个手术室边界内,这种架构足够。

但是,当领域本身依赖外部系统时,单领域充分性就会变成局限。仓库机器人的性能会因建筑 HVAC 系统故障而退化,因为温度升高会超出传感器工作范围。手术机器人调度依赖医院电网可靠性、灭菌周期和患者运输物流。自动驾驶汽车的路径规划受交通信号时序、道路维护计划和天气预报约束,而这些都来自车载感知栈之外。在每一种情况下,具身智能体运行在单一控制循环内,但约束其行为的条件来自多个相互作用的基础设施领域。具身智能智能体没有机制来建模这些跨领域依赖、在系统边界间传播影响估计,或推理一个领域中的扰动如何级联到另一个领域。

这就是第二种架构的动机。跨领域转换集成智能体运行在完全不同尺度上:不是深入单个物理系统内部,而是横跨多个耦合基础设施系统。具身智能智能体优先考虑单一领域内的速度、确定性和紧密反馈;跨领域转换集成智能体则优先考虑广度、系统一致性,以及推理异构系统如何相互影响的能力。二者共同定义了自主系统的完整设计空间:这些系统必须在物理世界中安全行动,同时又能对该世界所依赖的基础设施进行连贯推理。

跨领域转换集成智能体

具身智能智能体在单一物理领域内协调感知、规划和执行。跨领域转换集成智能体则运行在另一个尺度。它协调多个部分耦合动力系统,每个系统都有自身状态变量、控制规律、时间尺度和监管约束。交通、能源、水、环境和公共安全并不是独立演化的。它们的状态通过可测量传递函数相互影响。

因此,集成问题不是数据聚合,而是异构交互系统之间的稳定性管理。

接下来的小节会从数学基础到实现,展开跨领域转换集成智能体:耦合动力系统模型及其校准,编码跨领域结构的类型化知识图谱,图上的影响传播,以及将架构落到代码中的 LangChain 智能体模式。

耦合异构动力系统

每个领域 i 都可以建模为一个带内部演化和跨领域扰动的动力系统:

下面变量定义上式中的耦合系统模型:

  • x_i 是领域 i 的状态向量
  • u_i 表示外生输入或控制动作
  • f_i 编码内部、通常非线性的动力学
  • g_ij 捕捉领域 j 到领域 i 的耦合

函数 f_ig_ij 通常是非线性且随时间变化的。电力负载遵循热力学和市场动力学。交通密度根据类似流体的流动方程演化。水压服从水力约束。跨领域耦合可能放大或削弱扰动。

校准不良的 g_ij 项,可能引入任何单个子系统中都不存在的振荡。集成系统的稳定性,并不由其各部分稳定性保证。

因此,校准耦合函数 g_ij 需要三个步骤:

领域专家播种:了解每个系统边界的工程师,基于历史事故数据或已知物理关系提出初始耦合权重,例如过去停电期间无信号路口观测到的交通吞吐下降。

敏感性分析:在每个 seed value 附近对 g_ij 进行扰动,并运行仿真,以识别哪些耦合主导系统行为,因此需要更严格边界。

迭代优化:将仿真输出与历史跨领域事件进行比较,也就是 hindcasting,并调整耦合权重,直到模型能在可接受误差范围内复现已观察到的级联模式。

因此,Integration agent 必须维护领域内部演化和领域间耦合的模型。

一个具体实例能澄清方程中的组件。考虑城市中两个耦合领域:交通和能源。令 x_transport 表示主干道上的平均车辆密度,即每公里车辆数。令 x_energy 表示电网负载,单位为兆瓦。内部动力学 f_transport 建模交通密度如何根据流动方程演化:车辆从入口进入,从出口离开,密度作为波通过网络传播。

耦合函数 g_transport,energy 捕捉 x_energy 的变化如何扰动交通:当变电站故障、电网负载下降时,下游 14 个路口的交通信号失去电力,被迫进入默认闪红模式。无信号路口会使吞吐量降低约 60%,导致该走廊中的 x_transport 激增。耦合也反向运行:g_energy,transport 建模交通密度上升如何增加电力需求,因为更多车辆在路口怠速,停滞车辆的 HVAC 系统从充电站取电,应急绕行会激活额外信号基础设施。任何一个领域的动力学都无法孤立理解。

结构拓扑:领域知识图谱

跨领域影响的离散结构被捕捉为一个类型化异构图。在城市 / 风暴场景中,这张图编码 Integration agent 必须推理的依赖网络。Substation-7(能源领域)通过 “powers” 边连接到 TrafficController-12(交通领域),TrafficController-12 再通过 “governs” 边连接到它控制的路口。每条边携带一个权重,反映名义耦合强度。

  • V:跨领域类型化实体
  • E:类型化、加权且可选方向性关系

这张图编码的是拓扑,而不是动力学。它指定哪些实体可以影响哪些其他实体,以及名义强度如何。节点携带领域特定指标。边表示 powersmonitorsaffectsdepends_on 等关系。

时间注释会将图从静态登记册转化为实时表示。每个实体状态都带有时间戳。关系可能有随时间变化的权重,这些权重来自历史数据或学习模型。

该结构服务两个目的:

  1. 定义跨领域传播的允许路径。
  2. 提供一个可检查、可审计的系统依赖表示。

可解释性直接来自图结构。当智能体报告变电站故障影响交通信号和应急响应时间时,它可以沿类型化边追踪确切影响路径。

影响传播与影响估计

精确评估耦合动力系统通常无法在实时环境中计算完成。因此,Integration agent 使用图拓扑上的近似影响传播。当闪电击毁城市场景中的 Substation-7 时,智能体无法实时模拟每一个下游后果。相反,它会沿图向外传播估计影响:从 Substation-7 到 TrafficController-12 的边权缩放初始扰动信号,而随后到下游路口的边会进一步衰减它。

带乘法衰减的加权 breadth-first traversal,也就是加权广度优先遍历,可以给出一阶影响强度估计。从源实体开始,影响沿出边传播。每一跳中,强度按边权缩放。当影响低于阈值时,传播停止。

这一过程近似当前运行点邻域内的线性化影响。它不能替代完整动力学仿真。它提供快速、可解释的估计,适合运营决策支持。

衰减不是装饰。它防止长依赖链上的虚假放大,并在缺乏完整非线性积分时充当稳定性启发式。

仿真作为受控近似

对于场景分析,Integration agent 使用校准后的领域模型,以离散时间推进领域状态。仿真步骤分两个阶段:在城市 / 风暴场景中,能源领域推进变电站负载和故障传播,交通领域推进车辆密度和信号状态,而连接二者的耦合项使模拟变电站故障会同时降低受影响走廊的交通吞吐。

  • 基于当前状态计算跨领域耦合项
  • 使用内部模型加耦合输入推进每个领域

每个领域模型可能运行在不同时间分辨率上。因此,仿真器充当粗粒度 integrator,而不是实时控制器。

校准至关重要。耦合参数必须从历史数据中估计,并通过 hindcasting 与已知跨领域事件对照验证。敏感性分析会识别哪些耦合主导系统行为,因此需要更严格边界。

仿真输出是探索性的。它们为政策和应急规划提供信息,但不保证预测确定性。

与具身智能智能体的对比

具身智能智能体在单一领域内部深入运行,并受到毫秒级控制约束。其挑战是在物理执行条件下实现实时稳定性。

跨领域转换集成智能体则横跨多个领域,面对从毫秒到年份的异构时间尺度。其挑战是在耦合和分布式不确定性下保持系统一致性。

一个架构优先考虑深度和紧密反馈。另一个优先考虑广度和协调适应。二者共同为自主系统奠定基础,使它们既能在物理世界中安全行动,又能对物理世界依赖的基础设施进行连贯推理。

LangChain 集成智能体模式

跨领域转换集成智能体面对的实现问题,不同于具身智能智能体。它不是通过分层控制层级控制单个物理系统,而是必须从异构数据源构建并维护跨领域知识图谱,然后在图上进行影响估计传播,以支持运营决策。在 LangChain 中,这会转化为两种智能体模式:一个 graph construction agent,使用工具调用查询领域专用 API 并组装类型化节点和边;一个 influence propagation agent,遍历已构建图来估计级联影响。

图形式 G=(V,E) 直接映射到两个角色工具集:领域查询工具将类型化实体填入 Vregister_cross_domain_edge 工具将加权、有方向的关系填入 E

下面的清单实现图构建阶段,展示 LLM 智能体如何使用领域专用查询工具填充节点集合 V,并用边注册工具组装类型化依赖图 G

# Listing 16.4: Cross-domain knowledge graph construction via tool-calling
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent

# --- Domain-specific data source tools ---
@tool
def query_energy_grid(region: str) -> list:
    """Query substations, capacity, and load for a region."""
    return energy_api.get_substations(region)

@tool
def query_traffic_network(region: str) -> list:
    """Query intersections, controllers, and throughput."""
    return traffic_api.get_network(region)

@tool
def register_cross_domain_edge(
    source_id: str, target_id: str,
    relation: str, weight: float
) -> dict:
    """Register a typed, weighted edge between two
    entities in different domains."""
    return knowledge_graph.add_edge(
        source_id, target_id, relation, weight
    )

# --- Graph construction agent ---
graph_builder = create_react_agent(
    ChatOpenAI(model="gpt-4o", temperature=0.0),
    [
        query_energy_grid,
        query_traffic_network,
        register_cross_domain_edge
    ]
)

工具架构映射前文中的图形式 G=(V,E)。领域查询工具(query_energy_gridquery_traffic_network)会用类型化实体填充节点集合 V:带容量和负载属性的变电站、带吞吐和信号状态的路口、带管辖范围的控制器。register_cross_domain_edge 工具则用类型化、加权关系填充边集合 E。LLM 的角色是语义性的:给定来自两个来源的领域数据,它识别存在哪些跨领域依赖,例如 “Substation-7 powers TrafficController-12”,并估计耦合权重。这就是 Integration agent 增加单一领域 API 无法提供价值的步骤:电网 API 知道变电站,交通 API 知道控制器,但二者都没有编码它们之间的依赖。

由于耦合权重由 LLM 估计,治理控制对于防止误校准数值破坏传播稳定性至关重要。适用四项控制:

Clamping:LLM 生成的每个 g_ij 值,在进入图之前都会被裁剪到领域专家定义的 [g_min, g_max] 范围内,防止任何单次 LLM 调用给出不合理影响强度。

领域专家覆盖:校准过程中验证过的耦合权重,优先于 LLM 估计值,只要存在校准条目,就使用验证值。

日志记录:所有 LLM 建议权重都写入审计日志,带上其来源 prompt 和时间戳,以支持事后审查,并在观测到的级联行为偏离模型预测时重新校准。

回滚触发器:如果传播产生的 impact score 超过稳定性阈值,表明集成系统接近振荡状态,系统会恢复到最后一组已验证耦合权重,并在进一步传播前提醒操作员。

图构建完成后,第二个实现问题是影响传播:给定源实体上的扰动,它的影响会在跨领域图中传播多远、多强?下面的清单实现架构中描述的加权广度优先遍历。

# Listing 16.5: Influence propagation via weighted breadth-first traversal
from collections import deque

def propagate_influence(
    graph, source_id: str,
    initial_strength: float = 1.0,
    threshold: float = 0.1
) -> dict:
    """Weighted BFS: propagate influence from a source
    entity through the cross-domain knowledge graph.
    Returns {entity_id: (strength, [path])}."""
    impacts = {source_id: (initial_strength, [source_id])}
    queue = deque([
        (source_id, initial_strength, [source_id])
    ])

    while queue:
        node_id, strength, path = queue.popleft()

        for edge in graph.outgoing_edges(node_id):
            propagated = strength * edge.weight

            if propagated < threshold:
                continue  # Attenuation cutoff

            new_path = path + [edge.target_id]

            # Keep strongest path to each entity
            if (
                edge.target_id not in impacts
                or propagated > impacts[edge.target_id][0]
            ):
                impacts[edge.target_id] = (
                    propagated, new_path
                )
                queue.append(
                    (edge.target_id, propagated, new_path)
                )

    return impacts

该函数返回一个 impacts 字典,将每个可达实体映射到其估计扰动强度,以及影响到达所经过的图路径。在城市 / 风暴场景中,使用 source_id = "Substation-7"initial_strength = 1.0 调用该函数,会返回 TrafficController-12 的 impact score(由 “powers” 边加权),它所治理的每个路口的 impact score(由 “governs” 边加权),以及依赖这些路口的应急响应路线的 impact score。衰减截止阈值(threshold = 0.1)并非随意设置:它防止长依赖链上的虚假放大,因为每多一跳都会降低保真度。这是架构部分中稳定性启发式在实现层面的体现;图捕获影响拓扑,但只有高于阈值的传播才具有运营意义。

下面的案例研究将两个架构应用到一个具体真实世界场景中,展示当单独任何一个架构都不够时,具身智能智能体和跨领域转换集成智能体如何协同运行。

案例研究:渥太华冬季条件下的自主无人机任务规划

本案例研究分四个小节展开。Mission scenario 定义操作环境和双架构要求。Constraint formalization 指定 Unified Constraint Envelope,也就是任何电机启动前必须满足的统一约束包络。Architecture instantiation 将前面各节中的每种架构映射到具体无人机级组件。最后,Implementation 提供将两个智能体实现为组合系统的 LangChain 代码。选择一月的渥太华作为环境,是因为其零下温度、阵风,以及分层监管空域(Transport Canada 受控区域和 Parks Canada Greenbelt 限制)会同时压力测试五个约束领域,使其成为联合架构的最高要求测试。

任务场景

一月的渥太华不是一个宽容的运行环境。位于北纬 45 度的首都,会带来零下温度、来自 Ottawa River 的西北阵风,以及一个早晨之内可能在 freezing rain 和 driven snow 之间切换的降水。这正是能暴露单一架构自主飞行局限的环境。渥太华冬季运行条件代表任何高纬度或高海拔任务,在这些任务中,环境、监管和能源约束会同时交叉,并且在电机启动前必须作为一个联合系统同时满足。

任务场景如下。一名操作员指示自主无人机沿着一条六公里走廊执行摄影测绘任务,路线从 Nepean 的 Centerpointe Technology Park 到 Ottawa River waterfront。该走廊跨越两个不同监管区域:由 Transport Canada 按 Canadian Aviation Regulations(CARs)Part IX 管理的受控城市空域,以及由 Parks Canada 管理的 National Capital Greenbelt,后者对 National Capital Region 内受保护绿地上空飞行施加额外限制。操作员用自然语言发出任务目标。智能体系统必须将该意图翻译成一个合法授权、物理可执行的飞行计划,或者拒绝解锁并解释哪个约束未满足。

该场景需要本章中的两种架构协同运行。精确飞行要求,包括在阵风中维持稳定 waypoint 轨迹,跨多公里路线管理电池 State of Charge,并在城市地形上执行安全高度保持,是一个深度问题,由具身智能智能体处理。监管授权要求,即协调 Transport Canada NOTAM feeds、Parks Canada restriction databases、实时天气数据和电池遥测,并形成单一 go/no-go 决策,是一个广度问题,由跨领域转换集成智能体处理。任何单一架构都不够。深度架构不维护跨领域依赖模型。广度架构不执行实时飞行控制。本案例研究展示二者的综合。

image.png

图 16.4——作者在极端环境中实验操作无人机。左:无人机在渥太华附近 -10°C 环境中起飞。右:无人机飞越冰冻荒野

图 16.4 中的照片拍摄于一月渥太华西部 Kanata 附近的一次测试飞行,当时环境温度为 -10°C,持续 20 km/h 西北风。起飞后 90 秒内,电池 state-of-charge 低于标称放电曲线,触发约束包络中 energy domain 的 AMBER 警告。阵风短暂将空速推高至走廊阈值以上,使安全层拒绝一个 waypoint 命令,并强制 hover-hold,直到条件稳定。无人机完成测绘 transect 并返航,剩余电量 28%:足以满足 reserve floor,但余量窄到足以确认 Unified Constraint Envelope 中内置的保守 SoC 阈值是运行上必要的,而不只是理论要求。

约束形式化

任务 supervisor 授权飞行之前,所有相关领域的每个 active constraint 都必须被同时评估并满足。所有领域级 go/no-go 条件的交集构成本章所称的 Unified Constraint Envelope,即状态空间中最小可接受区域,在该区域内飞行计划可以合法、安全且具有足够能量储备地执行并返航。只有当约束组装器报告下面定义的五个领域全部为 green 时,无人机才可以解锁。

天气约束界定环境运行窗口。只有当温度高于 -10°C,风速在任务高度低于 25 km/h,并且走廊内没有 active precipitation 报告时,才授权飞行。温度阈值是作者定义的运行限制,反映该阈值以下电池放电衰退,比 Transport Canada 公布的最低值更严格;风速阈值是任务特定运行限制,Transport Canada 并没有为 25 kg 以下遥控航空器规定通用风速上限。这三个条件映射到具身智能智能体一节中定义的可接受行动集合 A_safe(s) 中的天气约束组件:只有当天气子约束满足时,飞行动作才可接受。

电池约束界定能量包络。无人机出发时 State of Charge(SoC)必须不低于 30%,并且沿计划路线中任何 waypoint 的预测 SoC 都不得低于 20%,在 return-to-home 启动时必须保证至少 15% 储备。这些阈值确保没有单个飞行段会让飞行器越过可恢复能量预算。电池约束映射到跨领域转换集成智能体一节知识图谱 G=(V,E) 中的一条边:Battery 节点通过加权为剩余电量比例的 constrains 边,指向 FlightDuration 节点,后者表示总计划飞行时间及其能量预算。

空域约束执行监管合规。任务 supervisor 会查询 Transport Canada NOTAM(Notice to Air Missions)feed,查看 Centerpointe 到 Ottawa River 走廊内是否存在任何 active flight restrictions。走廊内的 NOTAM restriction 会立即使对应飞行段失效;约束组装器必须识别替代路径或中止。空域数据在 G 中建模为类型化节点 cluster:Airspace 节点通过 restricts 边指向 FlightCorridor 节点,后者表示两个 waypoint 之间命名的计划路线段,边权由限制严重程度决定。实时 NOTAM alert 会动态添加或移除 restriction edges。

Parks 约束执行 National Capital Commission 和 Parks Canada 上空飞行许可。任何穿越 National Capital Greenbelt 的路线段,都需要显式授权。图中的 Parks 节点携带指向 corridor segment 节点的 permitsdenies 边。

最后,任务几何约束界定飞行计划的结构可行性。在正式知识图谱中,Unified Constraint Envelope 因而是五个领域节点 cluster 状态的交集:Weather AND Battery AND Airspace AND Parks AND mission geometry 全部返回 satisfied status。保守约束融合适用:一个领域返回 unsatisfied state,就会否决整个 envelope,无论其他四个领域报告多么有利。

架构实例化

无人机任务在具体系统组件层面实例化了本章两种架构。下面两段先将每种架构映射到无人机级实现,再由代码清单实现这些映射。

具身智能智能体实例化:无人机的车载控制循环,直接映射到具身智能智能体一节中的四层控制层级。在任务规划层(0.1 到 1 Hz),mission supervisor 解释操作员路线指令,并在咨询 Unified Constraint Envelope 后授权飞行段。在运动规划层(1 到 10 Hz),Flight Planner 计算 corridor checkpoints 之间的 waypoint trajectories,并考虑风致漂移和地形净空。在轨迹和伺服层,自动驾驶固件执行平滑路径跟踪并调节电机电流,且独立于 LLM 推理层运行。安全执行是具身智能智能体一节中 A_safe(s) 的具体无人机实现:除非 Unified Constraint Envelope 报告全部满足,否则不得执行任何飞行动作。无人机维护一个围绕气象和空域状态的 belief state b(s),通过实时传感器读数和 API 查询持续更新,与具身智能智能体一节中的 POMDP 公式一致。

跨领域转换集成智能体实例化:约束组装器是跨领域转换集成智能体一节中知识图谱架构的无人机级实现。Constraint formalization 中的五个约束领域会成为 G=(V,E) 中的类型化节点 cluster:Weather 节点(温度、风、降水)、Airspace 节点(NOTAM、受控区域、走廊段)、Energy 节点(电池 SoC、放电率、距离预算)、Parks 节点(Greenbelt 区域、授权状态)和 Mission 节点(waypoint、路线几何)。类型化边连接各 cluster:WeatherStation 通过权重与约束 margin 成比例的 affects 边指向 MissionEnvelope;Airspace 通过任何 active NOTAM 都权重为 1.0 的 restricts 边指向 FlightCorridor;Battery 通过权重为 SoC - reserve thresholdconstrains 边指向 FlightDuration。清单 16.5 中的影响传播函数会在实时 NOTAM alert 到达时被调用,估计跨图级联影响,以判断 reroute 是否满足剩余约束领域。

实现

下面两个清单实现上文描述的架构。清单 16.6 扩展清单 16.1 和 16.2 中的具身智能体模式,将其应用到无人机任务上下文。清单 16.7 扩展清单 16.3 和 16.4 中的跨领域转换集成智能体模式,实现带 NOTAM 集成的跨领域约束组装器。二者共同展示 Architecture instantiation 一节所描述的综合。

# Listing 16.6: Embodied drone agent with safety-constrained mission execution
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from dataclasses import dataclass, field
from typing import Optional


@dataclass
class DroneFlightState:
    """Current belief state b(s) over the drone's physical and environmental state."""
    position_lat: float = 0.0       # Current GPS latitude
    position_lon: float = 0.0       # Current GPS longitude
    altitude_m: float = 0.0         # Current altitude (metres AGL)
    battery_soc: float = 1.0        # State of Charge, 0.0-1.0
    wind_speed_kmh: float = 0.0     # Wind speed at mission altitude
    temperature_c: float = 0.0      # Ambient temperature
    precipitation_active: bool = False  # Any active precip in corridor
    constraint_envelope_green: bool = False  # Unified Constraint Envelope status


# --- Tool layer: maps to control hierarchy layers (the Embodied Intelligence Agent section) ---

@tool
def check_flight_safety(state_json: str) -> dict:
    """Safety enforcement layer: validate current state against the Unified Constraint
    Envelope (the Constraint Formalization section). Maps to A_safe(s) from the Embodied Intelligence Agent section.
    Returns go/no-go with per-domain status."""
    import json
    s = json.loads(state_json)
    checks = {
        "temperature": s["temperature_c"] > -10.0,       # Author-defined operational limit
        "wind": s["wind_speed_kmh"] < 25.0,              # Mission-specific operational limit
        "precipitation": not s["precipitation_active"],
        "battery_departure": s["battery_soc"] >= 0.30,   # SoC floor: 30% at departure
    }
    envelope_green = all(checks.values())
    return {
        "envelope_green": envelope_green,
        "domain_status": checks,
        "safe_to_fly": envelope_green
    }


@tool
def query_flight_state(drone_id: str) -> dict:
    """World-model query layer: retrieve current telemetry belief state b(s)
    from drone sensors and environmental APIs. Maps to task-planning layer."""
    # Production: query live telemetry + weather API + battery management system
    return {
        "position_lat": 45.3490,
        "position_lon": -75.7544,
        "altitude_m": 0.0,
        "battery_soc": 0.82,
        "wind_speed_kmh": 18.5,
        "temperature_c": -6.2,
        "precipitation_active": False,
        "constraint_envelope_green": False   # Not yet evaluated
    }


@tool
def dispatch_waypoint_command(
    waypoint_lat: float,
    waypoint_lon: float,
    altitude_m: float,
    airspeed_kmh: float
) -> dict:
    """Motion-planning interface: submit a validated waypoint command to the
    deterministic flight controller. The controller executes at 50-200 Hz.
    This tool may only be called after check_flight_safety returns envelope_green=True."""
    # Production: serialize to MAVLink protocol and send to autopilot firmware
    return {
        "command_accepted": True,
        "waypoint": {
            "lat": waypoint_lat,
            "lon": waypoint_lon,
            "alt": altitude_m,
            "airspeed": airspeed_kmh
        },
        "estimated_duration_s": 120
    }

定义飞行状态模型和三个工具接口后,剩下的组件是 mission supervisor agent 本身,以及强制安全协议序列的入口函数。

# Listing 16.6 (continued): Mission Supervisor agent construction and execution loop
# --- Mission Supervisor agent (task-planning layer, 0.1-1 Hz) ---
mission_supervisor = create_react_agent(
    ChatOpenAI(model="gpt-4o", temperature=0.0),
    [
        check_flight_safety,
        query_flight_state,
        dispatch_waypoint_command
    ]
)


def execute_mission(operator_instruction: str) -> str:
    """Entry point: translate operator intent into authorized flight actions.
    The agent must call check_flight_safety and receive envelope_green=True
    before any call to dispatch_waypoint_command is permitted."""
    result = mission_supervisor.invoke({
        "messages": [
            {
                "role": "user",
                "content": (
                    f"{operator_instruction}\n\n"
                    "Protocol: (1) call query_flight_state to retrieve current b(s). "
                    "(2) call check_flight_safety with the state JSON. "
                    "(3) Only if envelope_green is True, call dispatch_waypoint_command. "
                    "(4) If envelope_green is False, report which domains failed and do not arm."
                )
            }
        ]
    })
    return result['messages'][-1].content

工具架构直接映射到具身智能智能体一节中的控制层级。check_flight_safety 工具是 A_safe(s) 的软件实现:它在任何飞行动作执行前,对所有天气和电池领域评估 Unified Constraint Envelope。query_flight_state 工具维护无人机物理和环境条件的 belief state b(s)dispatch_waypoint_command 工具是推理层和确定性飞控之间的接口,飞控独立于 LLM,以 50 到 200 Hz 运行自身实时循环。Mission supervisor 无法绕过安全检查:嵌入智能体任务描述中的协议指令,强制执行硬件控制层级中同样的架构不变量。空域和 Parks Canada 授权由清单 16.7 中的约束组装器提供,mission supervisor 在授权出发前会消费其输出。

# Listing 16.7: Cross-domain constraint assembler with NOTAM integration
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from typing import Optional
import json


# --- Domain query tools (extend Listing 16.4 tool pattern) ---

@tool
def query_weather_constraints(corridor_id: str) -> dict:
    """Query real-time weather data for the specified flight corridor.
    Returns constraint-relevant fields: temperature, wind, precipitation."""
    # Production: query Environment Canada API or equivalent
    return {
        "temperature_c": -6.2,
        "wind_speed_kmh": 18.5,
        "precipitation_active": False,
        "temperature_constraint_met": True,   # > -10C
        "wind_constraint_met": True,          # < 25 km/hr
        "precip_constraint_met": True
    }


@tool
def query_airspace_notams(corridor_id: str) -> dict:
    # NOTAM validity check (pseudocode):
    # 1. Temporal validity: discard NOTAMs where mission_time is outside
    #    [valid_from, valid_until]; only active windows constrain the plan.
    #    relevant_notams = [n for n in notams
    #                       if n.valid_from <= mission_time <= n.valid_until]
    #
    # 2. Geospatial overlap: check whether the restricted polygon
    #    intersects the planned corridor geometry (Shapely or equivalent).
    #    blocked = any(notam.polygon.intersects(corridor_geometry)
    #                  for notam in relevant_notams)
    #    airspace_constraint_met = not blocked
    """Query Transport Canada NOTAM feed for active flight restrictions.
    NOTAM: Notice to Air Missions, the standard Transport Canada format for
    real-time airspace restriction alerts issued under CARs Part IX."""
    # Production: query Transport Canada DroneZone API
    # Mock NOTAM response structure reflecting Transport Canada alert format
    return {
        "notams": [
            {
                "alert_id": "NOTAM-CYOW-2025-0042",
                "corridor": "CENTERPOINTE_OTTAWARIVER",
                "restriction_type": "NONE",    # NONE | TEMPORARY | PERMANENT | TFR
                "valid_from": "2025-01-15T08:00:00Z",
                "valid_until": "2025-01-15T20:00:00Z",
                "authority": "Transport Canada"
            }
        ],
        "airspace_constraint_met": True   # No active restrictions in corridor
    }


@tool
def query_battery_state(drone_id: str) -> dict:
    """Query battery management system for current State of Charge and
    projected SoC at each planned waypoint."""
    return {
        "current_soc": 0.82,
        "projected_min_soc": 0.34,     # Minimum projected during mission
        "return_reserve_soc": 0.21,    # Projected SoC at return-to-home
        "battery_constraint_met": True  # SoC floor 30% met at departure
    }


@tool
def query_parks_restrictions(route_geojson: str) -> dict:
    """Query Parks Canada and National Capital Commission databases for
    overflight restrictions along the planned route geometry."""
    # Production: intersect route geometry with NCC Greenbelt restriction polygons
    return {
        "greenbelt_intersection": True,     # Route crosses protected land
        "overflight_authorized": True,      # Authorization on file
        "authorization_reference": "NCC-UAV-2025-0017",
        "parks_constraint_met": True
    }


@tool
def register_constraint_node(
    domain: str,
    node_id: str,
    constraint_met: bool,
    weight: float
) -> dict:
    """Register a typed constraint node in the knowledge graph G=(V,E).
    Extends the register_cross_domain_edge pattern from Listing 16.4.
    domain: one of WEATHER, AIRSPACE, BATTERY, PARKS, MISSION."""
    return knowledge_graph.add_constraint_node(
        domain=domain,
        node_id=node_id,
        status='GREEN' if constraint_met else 'RED',
        weight=weight
    )


# --- Constraint assembler agent (Domain-Transforming Integration Agent) ---
constraint_assembler = create_react_agent(
    ChatOpenAI(model="gpt-4o", temperature=0.0),
    [
        query_weather_constraints,
        query_airspace_notams,
        query_battery_state,
        query_parks_restrictions,
        register_constraint_node
    ]
)


def assemble_unified_constraint_envelope(
    corridor_id: str,
    drone_id: str,
    route_geojson: str
) -> dict:
    """Assemble the Unified Constraint Envelope by querying all domain agents
    and applying conservative constraint fusion: all domains must report
    constraint_met=True for envelope_green to be returned as True."""
    result = constraint_assembler.invoke({
        "messages": [
            {
                "role": "user",
                "content": (
                    f"Corridor: {corridor_id}. Drone: {drone_id}.\n"
                    "Query all four constraint domains (weather, airspace, battery, parks). "
                    "Register each result as a typed constraint node in the knowledge graph. "
                    "Apply influence propagation if any NOTAM restriction is active: "
                    "call propagate_influence with the NOTAM node as source to estimate cascade. "
                    "Return unified_envelope_green=True only if ALL domains report constraint_met=True."
                )
            }
        ]
    })

    # Validate output structure before returning to Mission Supervisor
    raw = result['messages'][-1].content
    try:
        envelope = ConstraintEnvelope.model_validate_json(raw)
    except ValidationError as e:
        raise RuntimeError(f"Constraint assembler returned invalid schema: {e}")
    return envelope.model_dump()

约束组装器将跨领域转换集成智能体一节中的模式应用到无人机任务尺度。每个领域查询工具对应 G=(V,E) 中的一个类型化节点 cluster:weather 工具填充 Weather 节点,NOTAM 工具填充带实时 restriction edges 的 Airspace 节点,battery 工具填充 Energy 节点,parks 工具填充 Parks 节点。register_constraint_node 工具将组装好的状态写回知识图谱,附带二元 constraint_met 状态和 margin weight。前文引入并在这里显式应用的保守约束融合意味着:单个 RED 领域节点会否决整个 envelope;没有任何单个乐观来源可以覆盖安全关键限制。

领域数据源并不总是实时可用。当查询工具返回过期或失败响应时,约束组装器应用优雅降级模式。数据时间戳超过过期阈值的领域,会被标记为 STALE,而不是 GREEN 或 RED。过期阈值按领域配置:天气数据可以容忍 15 分钟,NOTAM 数据远少于此。保守融合规则会将 STALE 领域视为失败约束:只有当过期读数被刷新,或操作员显式确认该数据缺口并接受相关风险时,envelope 才会报告 fully green。如果领域 API 完全不可用,组装器会在短暂宽限期内回退到 last-known-good 读数;超过该期限后,它会升级为操作员告警,并暂停任务授权,直到连接恢复。

Unified Constraint Envelope 并不只在出发时评估。天气条件、电池状态和空域限制可能在无人机起飞后变化,因此飞行期间必须持续重新评估。约束组装器以可配置间隔运行刷新循环,例如天气和电池每 30 秒一次,空域则在每次收到 NOTAM push alert 时刷新。如果先前 GREEN 的领域在飞行中转为 RED,例如走廊内激活 NOTAM 限制,电池 SoC 低于 waypoint 最低值,或风速超过运行上限,mission supervisor 会立即收到通知。智能体随后会在下一个安全 holding point 停止前进,重新调用约束组装器评估 rerouting 能否恢复 fully green envelope,并执行修订计划;如果不存在合规路径,则启动 return-to-home。

清单 16.6 的 mission supervisor 与清单 16.7 的约束组装器作为组合系统运行。Mission supervisor 在调用 dispatch_waypoint_command 之前,会消费 assemble_unified_constraint_envelope 的输出。无人机直到约束组装器在全部五个领域,即天气、电池、空域、Parks 和任务几何上返回 envelope_green=True,才会解锁电机。这是本章反复出现原则的具体化:安全不是正确规划的涌现属性,而是对可接受行动集合的显式限制。约束 envelope 在推理开始前收窄行动空间;飞行计划只在预先批准的 envelope 内运行,而不是与之对抗。有了两个架构的组合和验证,本章完成。

小结

本章考察了当自主智能体运行在物理世界中时,必须如何重新设计;在那里,行动受不可逆性、延迟和有限能量约束。本章引入了深度与广度之间的根本架构分界:深度要求对单个物理系统进行精确、实时控制,而广度要求在具有复杂依赖关系的多个互联系统之间进行协调。

为了处理这些相互竞争的要求,本章提出了两种互补架构。具身智能智能体通过多速率控制层级、belief-state 规划和严格执行可接受行动集合来解决深度问题,确保每一层都保持安全。跨领域转换集成智能体通过将跨领域系统建模为类型化知识图谱,并传播影响来估计级联效应,从而解决广度问题。

这两个架构在无人机任务案例研究中结合在一起:实时飞行控制运行在由天气、能源、监管和任务约束共同派生出的 Unified Constraint Envelope 内。由此出现的核心原则是保守约束融合:自主系统必须同时满足所有约束,并将安全作为行动前提执行,而不是事后补充。

贯穿本书,我们从基础智能体模式走向越来越专门化和有能力的系统。早期章节建立了核心抽象:感知、推理、行动选择和记忆。后续章节将这些抽象应用于内容生成、多模态理解、协作多智能体工作流、知识检索,以及医疗、科学、受监管行业和软件工程等领域特定应用。最后一章将这些原则扩展到物理世界,在那里,实时约束、安全关键控制循环和跨领域知识集成施加了智能体所能面对的最严苛要求。这一进展不是偶然的:每一层能力都建立在前一层之上,而支配自主无人机的 constraint-first design philosophy,同样适用于文档处理管线或临床决策支持智能体。

随着这些系统成熟,前沿将从单个智能体能力转向跨数字与物理领域同时运行的编排式智能体生态。你通过这些章节建立的基础,将使你能够设计、实现并批判性评估下一代这类系统。