OpenHands 运行流程分析:杭州三天旅游案例

一、整体架构概述

OpenHands 是一个基于 Agent Hub 的智能端到端编码平台,通过多个组件的协同工作来完成用户任务。从日志可以看出,系统主要包括以下核心部分:

  1. 会话管理器 (Conversation Manager):负责创建、管理和跟踪对话
  2. 代理控制器 (Agent Controller):协调各组件的工作流程
  3. 大模型组件 (LLM):使用 Claude 3.7 Sonnet 进行核心推理
  4. 运行时环境 (Runtime):在 Docker 容器中提供安全的执行环境
  5. Agent工具集 (Agent Tools):包括文件操作、命令执行等各种工具
  6. 事件流系统 (Event Stream):所有组件通过事件流进行通信
OpenHands执行流程日志 (点击展开)

12:08:38 - openhands:DEBUG: state.py:122 - Could not restore state from session: [Errno 2] No such file or directory: '/tmp/openhands_file_store/sessions/740715d40a3c4be385b644a20b0fdfaf/agent_state.pkl' 12:08:38 - openhands:DEBUG: agent_session.py:381 - No events found, no state to restore 12:08:38 - openhands:DEBUG: agent_controller.py:881 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] AgentController 740715d40a3c4be385b644a20b0fdfaf - created new state. start_id: 0 12:08:38 - openhands:DEBUG: microagent.py:152 - Loading agents from /home/ubuntu/GitHub_Workspace/pro-agent/microagents 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/README.md... 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/update_test_for_new_implementation.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent update_test_for_new_implementation from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/update_test_for_new_implementation.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/get_test_to_pass.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent get_test_to_pass from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/get_test_to_pass.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/add_openhands_repo_instruction.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent add_openhands_repo_instruction from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/add_openhands_repo_instruction.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/update_pr_description.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent update_pr_description from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/update_pr_description.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/address_pr_comments.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent address_pr_comments from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/tasks/address_pr_comments.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/docker.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent docker from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/docker.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/swift-linux.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent swift-linux from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/swift-linux.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/github.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent github from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/github.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/npm.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent npm from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/npm.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/kubernetes.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent kubernetes from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/kubernetes.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/add_agent.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent add_agent from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/add_agent.md 12:08:38 - openhands:DEBUG: microagent.py:155 - Checking file /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/flarglebargle.md... 12:08:38 - openhands:DEBUG: microagent.py:167 - Loaded agent flarglebargle from /home/ubuntu/GitHub_Workspace/pro-agent/microagents/knowledge/flarglebargle.md 12:08:38 - openhands:INFO: base.py:346 - [runtime 740715d40a3c4be385b644a20b0fdfaf] Selected repo: None, loading microagents from /workspace/.openhands/microagents (inside runtime) 12:08:38 - openhands:INFO: memory.py:233 - Loading user workspace microagents: [] 12:08:38 - openhands:DEBUG: stream.py:273 - Adding MessageAction id=1 from USER 12:08:38 - openhands:DEBUG: stream.py:273 - Adding ChangeAgentStateAction id=2 from ENVIRONMENT 12:08:38 - openhands:INFO: agent_session.py:161 - Agent session start 12:08:38 - openhands:DEBUG: agent_controller.py:441 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] MessageAction (source=EventSource.USER) CONTENT: 给我做一个杭州三天春游的规划,给我一个可访问的web让我看规划内容 12:08:38 - openhands:DEBUG: agent_controller.py:456 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Extended max iterations to 500 after user message 12:08:38 - openhands:DEBUG: stream.py:273 - Adding RecallAction id=3 from USER 12:08:38 - openhands:INFO: agent_controller.py:520 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Setting agent(CodeActAgent) state from AgentState.LOADING to AgentState.RUNNING 12:08:38 - openhands:DEBUG: stream.py:273 - Adding AgentStateChangedObservation id=4 from ENVIRONMENT 12:08:38 - openhands:DEBUG: memory.py:86 - Workspace context recall 12:08:38 - openhands:DEBUG: stream.py:273 - Adding RecallObservation id=5 from ENVIRONMENT 12:08:38 - openhands:INFO: agent_controller.py:520 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Setting agent(CodeActAgent) state from AgentState.RUNNING to AgentState.RUNNING 12:08:38 - openhands:DEBUG: agent_controller.py:409 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] AgentStateChangedObservation(content='', agent_state='running', observation='agent_state_changed') 12:08:38 - openhands:DEBUG: agent_controller.py:409 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] RecallObservation recall_type=RecallType.WORKSPACE_CONTEXT, repo_name=, repo_instructions=..., runtime_hosts={'http://localhost:53941': 53941, 'http://localhost:56576': 56576}, additional_agent_instructions=... 12:08:38 - openhands:INFO: agent_controller.py:696 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] LEVEL 0 LOCAL STEP 0 GLOBAL STEP 0 12:08:38 - openhands:DEBUG: codeact_agent.py:171 - Processing 3 events from a total of 3 events 12:08:38 - openhands:DEBUG: conversation_memory.py:71 - Visual browsing: False 12:08:38 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/prompt_001.log 12:09:37 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/response_001.log 12:09:37 - openhands:DEBUG: llm.py:561 - Cost: 0.10 USD | Accumulated Cost: 0.10 USD Response Latency: 58.893 seconds Input tokens: 5411 | Output tokens: 4202 Input tokens (cache write): 5407

12:09:37 - openhands:DEBUG: agent_controller.py:1171 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Action metrics - accumulated_cost: 0.09953925, tokens (prompt/completion/cache_read/cache_write): 5411/4202/0/5407 12:09:37 - openhands:DEBUG: stream.py:273 - Adding FileEditAction id=6 from AGENT 12:09:37 - openhands:DEBUG: agent_controller.py:795 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] FileEditAction Path: [/tmp/hangzhou_trip_planner.py] Thought: 我将为您创建一个杭州三天春游的规划,并通过一个网页展示给您。我会使用Python的Flask框架来创建一个简单的网页应用。

首先,让我创建一个包含杭州三天春游规划的网页应用: Command: create Created File with Text:

from flask import Flask, render_template_string
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # 启用CORS以允许跨域请求

# HTML模板
HTML_TEMPLATE = """
...//省略
"""

@app.route('/')
def index():
    return render_template_string(HTML_TEMPLATE)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=53941, debug=True)

12:09:37 - openhands:DEBUG: stream.py:273 - Adding FileEditObservation id=7 from AGENT 12:09:37 - openhands:DEBUG: agent_controller.py:409 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] File created successfully at: /tmp/hangzhou_trip_planner.py 12:09:37 - openhands:INFO: agent_controller.py:696 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] LEVEL 0 LOCAL STEP 1 GLOBAL STEP 1 12:09:37 - openhands:DEBUG: codeact_agent.py:171 - Processing 5 events from a total of 5 events 12:09:37 - openhands:DEBUG: conversation_memory.py:71 - Visual browsing: False 12:09:37 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall(index=1, function=Function(arguments='{"command": "create", "path": "/tmp/hangzhou_trip_planner.py", "file_text": "...', name='str_replace_editor'), id='toolu_01SjNBn1Mkke6C1DJjkPcjsN', type='function')] 12:09:37 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/prompt_002.log 12:09:40 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/response_002.log 12:09:40 - openhands:DEBUG: llm.py:561 - Cost: 0.03 USD | Accumulated Cost: 0.13 USD Response Latency: 3.062 seconds Input tokens: 9639 | Output tokens: 102 Input tokens (cache hit): 5407 Input tokens (cache write): 4226

12:09:40 - openhands:DEBUG: agent_controller.py:1171 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Action metrics - accumulated_cost: 0.13123485000000001, tokens (prompt/completion/cache_read/cache_write): 9639/102/5407/4226 12:09:40 - openhands:DEBUG: stream.py:273 - Adding CmdRunAction id=8 from AGENT 12:09:40 - openhands:DEBUG: agent_controller.py:795 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] CmdRunAction (source=EventSource.AGENT, is_input=False) THOUGHT: 现在,让我安装必要的依赖并运行这个网页应用: COMMAND: pip install flask flask-cors 12:09:42 - openhands:DEBUG: stream.py:273 - Adding CmdOutputObservation id=9 from AGENT 12:09:42 - openhands:DEBUG: agent_controller.py:409 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] CmdOutputObservation (source=EventSource.AGENT, exit code=0, metadata={ "exit_code": 0, "pid": -1, "username": "openhands", "hostname": "2d4de2f65b26", "working_dir": "/workspace", "py_interpreter_path": "/openhands/poetry/openhands-ai-5O4_aCHf-py3.12/bin/python", "prefix": "", "suffix": "\n[The command completed with exit code 0.]" }) --BEGIN AGENT OBSERVATION-- Collecting flask Downloading flask-3.1.0-py3-none-any.whl.metadata (2.7 kB) Collecting flask-cors Downloading flask_cors-5.0.1-py3-none-any.whl.metadata (961 bytes) Collecting Werkzeug>=3.1 (from flask) Downloading werkzeug-3.1.3-py3-none-any.whl.metadata (3.7 kB) Requirement already satisfied: Jinja2>=3.1.2 in /openhands/poetry/openhands-ai-5O4_aCHf-py3.12/lib/python3.12/site-packages (from flask) (3.1.6) Collecting itsdangerous>=2.2 (from flask) Downloading itsdangerous-2.2.0-py3-none-any.whl.metadata (1.9 kB) Requirement already satisfied: click>=8.1.3 in /openhands/poetry/openhands-ai-5O4_aCHf-py3.12/lib/python3.12/site-packages (from flask) (8.1.8) Collecting blinker>=1.9 (from flask) Downloading blinker-1.9.0-py3-none-any.whl.metadata (1.6 kB) Requirement already satisfied: MarkupSafe>=2.0 in /openhands/poetry/openhands-ai-5O4_aCHf-py3.12/lib/python3.12/site-packages (from Jinja2>=3.1.2->flask) (3.0.2) Downloading flask-3.1.0-py3-none-any.whl (102 kB) Downloading flask_cors-5.0.1-py3-none-any.whl (11 kB) Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB) Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB) Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB) Installing collected packages: Werkzeug, itsdangerous, blinker, flask, flask-cors Successfully installed Werkzeug-3.1.3 blinker-1.9.0 flask-3.1.0 flask-cors-5.0.1 itsdangerous-2.2.0 [The command completed with exit code 0.] [Current working directory: /workspace] [Python interpreter: /openhands/poetry/openhands-ai-5O4_aCHf-py3.12/bin/python] [Command finished with exit code 0] --END AGENT OBSERVATION-- 12:09:42 - openhands:INFO: agent_controller.py:696 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] LEVEL 0 LOCAL STEP 2 GLOBAL STEP 2 12:09:42 - openhands:DEBUG: codeact_agent.py:171 - Processing 7 events from a total of 7 events 12:09:42 - openhands:DEBUG: conversation_memory.py:71 - Visual browsing: False 12:09:42 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall(index=1, function=Function(arguments='{"command": "create", "path": "/tmp/hangzhou_trip_planner.py", "file_text": "...', name='str_replace_editor'), id='toolu_01SjNBn1Mkke6C1DJjkPcjsN', type='function')] 12:09:42 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall(index=1, function=Function(arguments='{"command": "pip install flask flask-cors", "is_input": "false"}', name='execute_bash'), id='toolu_01CDVDLZbXn5Ge8adnBXCSzC', type='function')] 12:09:42 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/prompt_003.log 12:09:45 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/response_003.log 12:09:45 - openhands:DEBUG: llm.py:561 - Cost: 0.01 USD | Accumulated Cost: 0.14 USD Response Latency: 2.354 seconds Input tokens: 10457 | Output tokens: 99 Input tokens (cache hit): 9633 Input tokens (cache write): 818

12:09:45 - openhands:DEBUG: agent_controller.py:1171 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Action metrics - accumulated_cost: 0.14114925, tokens (prompt/completion/cache_read/cache_write): 10457/99/9633/818 12:09:45 - openhands:DEBUG: stream.py:273 - Adding CmdRunAction id=10 from AGENT 12:09:45 - openhands:DEBUG: agent_controller.py:795 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] CmdRunAction (source=EventSource.AGENT, is_input=False) THOUGHT: 现在让我运行这个网页应用: COMMAND: python /tmp/hangzhou_trip_planner.py 12:10:16 - openhands:DEBUG: stream.py:273 - Adding CmdOutputObservation id=11 from AGENT 12:10:16 - openhands:DEBUG: agent_controller.py:409 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] CmdOutputObservation (source=EventSource.AGENT, exit code=-1, metadata={ "exit_code": -1, "pid": -1, "username": null, "hostname": null, "working_dir": null, "py_interpreter_path": null, "prefix": "", "suffix": "\n[The command has no new output after 30 seconds. You may wait longer to see additional output by sending empty command '', send other commands to interact with the current process, or send keys to interrupt/kill the command.]" }) --BEGIN AGENT OBSERVATION--

  • Serving Flask app 'hangzhou_trip_planner'
  • Debug mode: on WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
  • Running on all addresses (0.0.0.0)
  • Running on http://127.0.0.1:53941
  • Running on http://172.17.0.2:53941 Press CTRL+C to quit
  • Restarting with stat
  • Debugger is active!
  • Debugger PIN: 996-648-230 [The command has no new output after 30 seconds. You may wait longer to see additional output by sending empty command '', send other commands to interact with the current process, or send keys to interrupt/kill the command.] --END AGENT OBSERVATION-- 12:10:16 - openhands:INFO: agent_controller.py:696 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] LEVEL 0 LOCAL STEP 3 GLOBAL STEP 3 12:10:16 - openhands:DEBUG: codeact_agent.py:171 - Processing 9 events from a total of 9 events 12:10:16 - openhands:DEBUG: conversation_memory.py:71 - Visual browsing: False 12:10:16 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall(index=1, function=Function(arguments='{"command": "create", "path": "/tmp/hangzhou_trip_planner.py", "file_text": "...', name='str_replace_editor'), id='toolu_01SjNBn1Mkke6C1DJjkPcjsN', type='function')] 12:10:16 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall(index=1, function=Function(arguments='{"command": "pip install flask flask-cors", "is_input": "false"}', name='execute_bash'), id='toolu_01CDVDLZbXn5Ge8adnBXCSzC', type='function')] 12:10:16 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall(index=1, function=Function(arguments='{"command": "python /tmp/hangzhou_trip_planner.py", "is_input": "false"}', name='execute_bash'), id='toolu_01HwMwZtdS8dsFCDREbPKopu', type='function')] 12:10:16 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/prompt_004.log 12:10:24 - openhands:DEBUG: logger.py:445 - Logging to /home/ubuntu/GitHub_Workspace/pro-agent/logs/llm/25-04-11_12-07/response_004.log 12:10:24 - openhands:DEBUG: llm.py:561 - Cost: 0.01 USD | Accumulated Cost: 0.15 USD Response Latency: 8.065 seconds Input tokens: 10753 | Output tokens: 419 Input tokens (cache hit): 10451 Input tokens (cache write): 296

12:10:24 - openhands:DEBUG: agent_controller.py:1171 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Action metrics - accumulated_cost: 0.15258555000000001, tokens (prompt/completion/cache_read/cache_write): 10753/419/10451/296 12:10:24 - openhands:DEBUG: stream.py:273 - Adding MessageAction id=12 from AGENT 12:10:24 - openhands:DEBUG: agent_controller.py:795 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] MessageAction (source=EventSource.AGENT) CONTENT: 太好了!网页应用已经成功运行起来了。您现在可以通过以下链接访问杭州三天春游规划:

http://localhost:53941

这个网页包含了详细的杭州三天春游规划,内容包括:

  1. 第一天:西湖精华游

    • 上午:断桥-白堤-孤山
    • 中午:湖畔午餐
    • 下午:苏堤-雷峰塔
    • 晚上:河坊街-清河坊
  2. 第二天:西湖西线与灵隐寺

    • 上午:灵隐寺-飞来峰
    • 中午:素斋午餐
    • 下午:龙井村-九溪烟树
    • 晚上:西湖音乐喷泉
  3. 第三天:城市文化与休闲

    • 上午:西溪湿地
    • 中午:农家午餐
    • 下午:杭州博物馆-运河
    • 晚上:宋城千古情

此外,网页还包含了春季杭州旅游小贴士、美食推荐和购物建议,帮助您更好地规划行程。

请点击上面的链接查看完整的旅游规划。如果您需要对规划内容进行任何修改或有其他问题,请随时告诉我! 12:10:24 - openhands:INFO: agent_controller.py:520 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Setting agent(CodeActAgent) state from AgentState.RUNNING to AgentState.AWAITING_USER_INPUT 12:10:24 - openhands:DEBUG: stream.py:273 - Adding AgentStateChangedObservation id=13 from ENVIRONMENT 12:10:24 - openhands:DEBUG: agent_controller.py:409 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] AgentStateChangedObservation(content='', agent_state='awaiting_user_input', observation='agent_state_changed') 12:11:05 - openhands:DEBUG: shutdown_listener.py:26 - shutdown_signal:2 12:11:06 - openhands:INFO: listen_socket.py:81 - sio:disconnect:SRJs3cbDFCDEbGmoAAAD 12:11:06 - openhands:INFO: standalone_conversation_manager.py:334 - disconnect_from_session:SRJs3cbDFCDEbGmoAAAD:740715d40a3c4be385b644a20b0fdfaf 12:11:06 - openhands:INFO: standalone_conversation_manager.py:351 - _close_session:740715d40a3c4be385b644a20b0fdfaf 12:11:06 - openhands:INFO: standalone_conversation_manager.py:359 - removing connections: [] 12:11:06 - openhands:INFO: standalone_conversation_manager.py:371 - closing_session:740715d40a3c4be385b644a20b0fdfaf 12:11:06 - openhands:DEBUG: state.py:107 - Saving state to session 740715d40a3c4be385b644a20b0fdfaf:AgentState.AWAITING_USER_INPUT 12:11:06 - openhands:INFO: agent_controller.py:520 - [Agent Controller 740715d40a3c4be385b644a20b0fdfaf] Setting agent(CodeActAgent) state from AgentState.AWAITING_USER_INPUT to AgentState.STOPPED 12:11:06 - openhands:DEBUG: stream.py:273 - Adding AgentStateChangedObservation id=14 from ENVIRONMENT 12:11:06 - openhands:WARNING: stream.py:260 - Callback not found during unsubscribe: 740715d40a3c4be385b644a20b0fdfaf 12:11:06 - openhands:INFO: standalone_conversation_manager.py:373 - closed_session:740715d40a3c4be385b644a20b0fdfaf

二、工作流程分解

1. 会话初始化阶段

12:08:07 - openhands:INFO: manage_conversations.py:148 - Initializing new conversation
12:08:07 - openhands:INFO: manage_conversations.py:54 - Creating conversation

当用户发起请求时,系统首先初始化一个新的会话,分配一个唯一的会话 ID (740715d40a3c4be385b644a20b0fdfaf),用于后续所有组件的协调和跟踪。

2. 配置加载阶段

12:08:07 - openhands:INFO: manage_conversations.py:58 - Loading settings
12:08:07 - openhands:DEBUG: llm.py:385 - Model info: { "key": "claude-3-7-sonnet-20250219", ... }

系统加载配置信息,包括语言模型的设置、最大token限制、支持的功能等。此案例使用的是 Anthropic 的 Claude 3.7 Sonnet 模型。

3. 运行时环境准备

12:08:07 - openhands:DEBUG: agent_session.py:232 - Initializing runtime `docker` now...
12:08:08 - openhands:INFO: runtime_build.py:182 - Building image: ghcr.io/all-hands-ai/runtime:oh_v0.29.1...

系统启动一个隔离的 Docker 容器作为运行时环境,这样可以安全地执行代码而不影响主系统。容器有特定端口映射(53941、56576)用于网络应用访问。

4. 工具加载阶段

12:08:38 - openhands:DEBUG: codeact_agent.py:75 - TOOLS loaded for CodeActAgent: execute_bash, think, finish, web_read, browser, execute_ipython_cell, str_replace_editor

系统启动 Agent (CodeActAgent) 并为其加载相关工具,让 Agent 能够执行命令、编辑文件等操作。这些工具是 CodeActAgent 与 Runtime 运行时环境交互的接口。

5. 用户输入处理

12:08:38 - openhands:DEBUG: agent_controller.py:441 - **MessageAction** (source=EventSource.USER)
CONTENT: 给我做一个杭州三天春游的规划,给我一个可访问的web让我看规划内容

系统捕获并处理用户输入,识别出这是一个需要创建网页内容的请求。

6. Agent 思考与规划阶段

12:08:38 - openhands:DEBUG: logger.py:445 - Logging to .../prompt_001.log
12:09:37 - openhands:DEBUG: logger.py:445 - Logging to .../response_001.log

Agent 使用大型语言模型 (Claude 3.7) 分析用户请求,并制定执行计划。这个过程大约持续了59秒,系统记录了完整的思考过程。

7. 文件创建操作

12:09:37 - openhands:DEBUG: stream.py:273 - Adding FileEditAction id=6 from AGENT
12:09:37 - openhands:DEBUG: agent_controller.py:795 - **FileEditAction**
Path: [/tmp/hangzhou_trip_planner.py]

Agent Controller 决定创建一个 Flask 网页应用,包含完整的杭州三天春游规划。它使用 str_replace_editor 工具创建文件,并嵌入了 HTML、CSS 和后端逻辑。

8. 依赖安装阶段

12:09:40 - openhands:DEBUG: stream.py:273 - Adding CmdRunAction id=8 from AGENT
COMMAND: pip install flask flask-cors

Agent 识别到需要安装依赖库(Flask 和 Flask-CORS),并自动执行安装命令。这显示了 Agent 能够理解和处理依赖关系。

9. 应用启动阶段

12:09:45 - openhands:DEBUG: stream.py:273 - Adding CmdRunAction id=10 from AGENT
COMMAND: python /tmp/hangzhou_trip_planner.py

安装完依赖后,在运行时环境中启动创建的网页应用。应用在端口 53941 上运行,允许用户通过浏览器访问。

10. 结果呈现阶段

12:10:24 - openhands:DEBUG: stream.py:273 - Adding MessageAction id=12 from AGENT
CONTENT: 太好了!网页应用已经成功运行起来了。您现在可以通过以下链接访问杭州三天春游规划:http://localhost:53941

Agent 返回成功消息,告知用户可以通过指定链接访问旅游规划,并提供内容概览。

三、核心组件详解

1. 事件流系统

整个系统基于事件流工作:

12:08:38 - openhands:DEBUG: stream.py:273 - Adding MessageAction id=1 from USER
12:08:38 - openhands:DEBUG: stream.py:273 - Adding RecallAction id=3 from USER

所有操作都被封装为事件,由事件流系统处理,确保组件间通信有序可追踪。

2. 代理状态管理

12:08:38 - openhands:INFO: agent_controller.py:520 - Setting agent(CodeActAgent) state from AgentState.LOADING to AgentState.RUNNING

系统维护了代理的状态机,从加载(LOADING)到运行(RUNNING)再到等待用户输入(AWAITING_USER_INPUT),确保行为的连贯性。

3. 语言模型使用

12:09:37 - openhands:DEBUG: llm.py:561 - Cost: 0.10 USD | Accumulated Cost: 0.10 USD
Response Latency: 58.893 seconds
Input tokens: 5411 | Output tokens: 4202

系统对语言模型的使用非常精确,记录每次调用的成本、延迟和token使用情况,并使用缓存优化性能:

Input tokens (cache hit): 9633
Input tokens (cache write): 818

4. Docker运行时环境

12:08:08 - openhands:DEBUG: docker_runtime.py:256 - Mount dir: /home/ubuntu/GitHub_Workspace/pro-agent/workspace
12:08:08 - openhands:DEBUG: docker_runtime.py:262 - Sandbox workspace: /workspace

系统创建隔离的Docker容器作为沙盒环境,并挂载必要的目录以保持文件持久性,同时确保安全执行。

5. 工具调用系统

12:09:37 - openhands:DEBUG: conversation_memory.py:207 - Tool calls type: <class 'list'>, value: [ChatCompletionMessageToolCall...]

Agent通过结构化格式调用工具,每个工具调用都包含明确的参数和目标。这种方式让AI能以一致的方式使用各种系统功能。

四、关键技术亮点

  1. 事件驱动架构:系统通过事件流协调各组件,使复杂流程更容易管理和追踪

  2. 沙盒安全执行:使用Docker容器创建安全的执行环境,防止恶意代码影响宿主系统

  3. 智能工具使用:AI能够识别任务所需的工具链(如依赖安装、代码执行),并按正确顺序使用

  4. 清晰的工作流状态:系统维护代理状态机,确保处理流程的连贯性

  5. 资源优化:通过缓存和累计成本跟踪优化语言模型使用

  6. 多模态输出:不仅生成文字描述,还能创建完整的网页应用,提供更丰富的用户体验

五、执行流程图

OpenHands执行流程详细图示 (点击展开)

OpenHands执行流程图

六、Agent Hub架构的优势

在OpenHands的Agent Hub架构下,各个组件通过事件流系统紧密协作,形成了一个高效的智能编码生态系统:

  1. 组件解耦:每个组件负责特定功能,可以独立升级和维护
  2. 流程透明:完整的日志记录和事件跟踪使得系统行为可预测和可调试
  3. 扩展性强:新工具可以轻松集成到现有架构中,无需修改核心逻辑
  4. 安全可控:Docker运行时提供了隔离执行环境,同时支持丰富的权限控制
  5. 快速响应:事件驱动模式确保系统能够实时响应用户输入和环境变化

这种架构设计使得OpenHands能够处理从简单的代码生成到复杂的应用开发等多样化任务,同时保持系统的稳定性和安全性。

七、实际应用场景分析

我们的杭州春游案例展示了OpenHands处理实际问题的能力。值得注意的是,Agent在整个过程中表现出了以下关键能力:

  1. 需求理解:正确解析了用户想要一个可访问的网页展示旅游规划的需求
  2. 技术选型:自主选择了Flask作为网页框架,适合快速构建轻量级应用
  3. 依赖管理:识别并安装了所需的Python包(flask、flask-cors)
  4. 内容创建:组织了有价值的旅游信息,包括景点、美食和交通建议
  5. 用户体验设计:创建了一个包含CSS样式的美观网页,而不是简单的文本输出
  6. 端口配置:正确配置了Web服务器端口,确保用户可访问

这个案例完美展示了OpenHands如何从用户简单的自然语言请求出发,通过一系列复杂但协调一致的步骤,最终交付一个完整可用的解决方案。

留言与讨论