OpenHands启动原理,你能吗?
摘要:AI Agent 框架探秘:拆解 OpenHands(3) 启动 目录AI Agent 框架探秘:拆解 OpenHands(3) 启动0x00 概要0x01 背景1.1 总体架构1.2 切入点0x02 初始化 @ run_controlle
AI Agent 框架探秘:拆解 OpenHands(3)--- 启动
目录AI Agent 框架探秘:拆解 OpenHands(3)--- 启动0x00 概要0x01 背景1.1 总体架构1.2 切入点0x02 初始化 @ run_controller2.1 总体流程2.2 创建注册中心2.3 创建Agent2.4 构建Runtime2.5 构建Memory & Microagent2.5.1 创建 Memory2.5.2 创建Microagent2.6 创建MCP2.7 创建Controller2.8 发送启动事件2.9 订阅事件流:注册用户输入回调函数2.10 运行代理2.11 run_controller全部代码0xFF 参考
0x00 概要
当分析一个系统时,启动部分和用户典型使用场景是比较理想的切入点,因为这两个部分可以覆盖系统大部分功能模块,可以借此深入架构。
因为本系列借鉴的文章过多,可能在参考文献中有遗漏的文章,如果有,还请大家指出。
0x01 背景
1.1 总体架构
以下是 OpenHands 的架构图,这是一个复杂的系统。
抛开复杂的技术细节,OpenHands Agent 的交互逻辑可提炼为 “初始化 - 事件注入 - 协同处理 - 等待” 的极简流程,核心围绕 EventStream 实现模块联动:
初始化就绪:用户创建会话时,系统自动完成 Agent、AgentController、Runtime、Memory 有核心模块的初始化,且每个模块都会自动订阅 EventStream,确保能捕获相关事件;
任务发起:用户发送消息本质是向 EventStream 中注入一条事件,这条事件会触发所有订阅相关回调函数的模块,启动协同处理;
多模块协同响应:
Session 模块持续上报事件流中的各类状态事件,保障全局可观测;
若用户开启 Security Analyzer,该模块会通过安全分析,自动确认低风险任务,减少用户手动干预;
AgentController 向事件流注入 RecallAction,Memory 模块判断是否为首次接收的用户信息,据此补充相关记忆并返回 RecallObservation 事件;
状态同步:AgentController 更新任务当前状态,并将相关信息传递给 Agent。即AgentController 调用 Agent.step 方法处理当前事件,生成 Action 并注入事件流。
行动决策:Agent 基于接收的状态信息,向 LLM 发起请求,生成下一步具体行动方案;
行动输出:Agent 明确输出行动指令,可能是运行系统命令、读取文件、调用工具等具体操作;
行动分发:该行动指令通过 EventStream 传递至 Runtime 组件,等待执行;
执行与反馈:Runtime 执行行动指令,生成包含执行结果、错误信息等内容的观察结果;
结果回传:观察结果通过 EventStream 回传给 AgentController,完成一次执行闭环;
循环或终止:AgentController 根据观察结果判断任务是否完成,若未完成则重复上述流程;若需协同,则委派给其他 Agent,直至任务结束。
1.2 切入点
以下是一个例子。我们由此进入,看看OpenHands如何启动,也可以从此处看看OpenHands的基本逻辑。
config = load_openhands_config()
action = MessageAction(content="Write a hello world program")
state = await run_controller(config=config, initial_user_action=action)
上述代码是直接命令行调用 run_controller,因此我们从run_controller入手。
0x02 初始化 @ run_controller
run_controller 作为 OpenHands 后端单个会话的核心入口协程,核心职责是依据预设配置启动运行时环境、智能体及对应控制器,搭建起从接收用户指令到多步骤执行任务,再到最终将会话状态持久化存储的完整处理链路。
