🚀

OpenHands 开源 AI Agent 部署实战

OpenHands 是一个开源的 AI Agent 框架,支持自定义工具调用和复杂任务自动化。本教程涵盖 Docker 部署、本地开发、工具注册全流程。

OpenHands AI Agent Docker 部署

OpenHands(原 OpenIntern)是由 微软开源的 AI Agent 框架,能够自主执行复杂的多步骤任务。它可以像人类一样操作浏览器、读写文件、执行代码,是目前最强大的开源 Agent 之一。

OpenHands 是什么

OpenHands 的核心能力:

对比项 OpenHands LangChain Agents
浏览器自动化 ✅ 内置 Playwright ❌ 需自行集成
代码执行 ✅ Jupyter 内核 ❌ 需自行集成
Web UI ✅ 开箱即用 ❌ 需自行开发
部署难度 ⭐ 简单(Docker) ⭐⭐⭐ 复杂

Docker 快速部署

最简单的部署方式,一行命令启动:

$
docker run -it \ --name openhands \ -p 3000:3000 \ -e OPENHANDS_MODEL=anthropic/claude-sonnet-4-5 \ -e OPENHANDS_API_KEY=sk-ant-xxxxx \ -v openhands_data:/app/data \ openhands/openhands:latest

启动后访问 http://localhost:3000 打开 Web UI。

使用 Docker Compose(推荐)

version: '3.8'
services:
  openhands:
    image: openhands/openhands:latest
    container_name: openhands
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - OPENHANDS_MODEL=anthropic/claude-sonnet-4-5
      - OPENHANDS_API_KEY=${OPENHANDS_API_KEY}
      - OPENHANDS_SANDBOX_TYPE=local
    volumes:
      - openhands_data:/app/data
    # GPU 支持(可选)
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]

volumes:
  openhands_data:
$
export OPENHANDS_API_KEY=sk-ant-xxxxx docker compose up -d

本地开发环境配置

安装依赖

$
git clone https://github.com/All-Hands-AI/OpenHands.git cd OpenHands uv venv && source .venv/bin/activate uv pip install -e . # 安装 Playwright 浏览器 playwright install chromium

配置环境变量

$
# 创建 .env 文件 cat > .env << 'EOF' OPENHANDS_MODEL=anthropic/claude-sonnet-4-5 OPENHANDS_API_KEY=sk-ant-xxxxx OPENHANDS_SANDBOX_TYPE=local EOF

启动开发服务器

$
python openhands/app/app.py
💡
开发模式优势
本地开发可以直接修改源码、调试 agent 行为、使用 IDE 的断点调试功能。适合需要深度定制 OpenHands 的用户。

自定义工具注册

OpenHands 支持通过 Python 装饰器注册自定义工具,让 Agent 可以调用任意 API。

创建自定义工具

# tools/custom_tools.py

from openhands.tools import tool

@tool
def search_hackernews(query: str) -> str:
    """Search Hacker News for articles matching the query.
    
    Args:
        query: Search keywords (e.g., 'AI agents', 'Rust web frameworks')
    
    Returns:
        Top 5 matching articles with titles, scores, and URLs
    """
    import requests
    from datetime import datetime
    
    # 使用 Hacker News API
    base_url = "https://hn.algolia.com/api/v1"
    
    # 先搜索
    resp = requests.get(f"{base_url}/search", params={"query": query, "tags": "story", "hitsPerPage": 5})
    data = resp.json()
    
    results = []
    for hit in data.get("hits", []):
        title = hit.get("title", "Untitled")
        score = hit.get("points", 0)
        url = hit.get("url", f"https://news.ycombinator.com/item?id={hit['objectID']}")
        date = datetime.fromtimestamp(hit.get("created_at_i", 0)).strftime("%Y-%m-%d")
        results.append(f"- [{title}]({url}) ⬆️{score} ({date})")
    
    if not results:
        return f"No results found for '{query}'"
    
    return f"Top results for '{query}':\n" + "\n".join(results)


@tool
def get_github_trending(language: str = "python", since: str = "daily") -> str:
    """Get trending GitHub repositories.
    
    Args:
        language: Programming language filter (default: python)
        since: Time period: daily, weekly, monthly (default: daily)
    
    Returns:
        Top 10 trending repositories with stars and description
    """
    import requests
    
    url = f"https://api.github.com/search/repositories"
    params = {
        "q": f"language:{language} created:>{get_date(since)}",
        "sort": "stars",
        "order": "desc",
        "per_page": 10
    }
    headers = {"Accept": "application/vnd.github.v3+json"}
    
    resp = requests.get(url, params=params, headers=headers)
    data = resp.json()
    
    results = []
    for repo in data.get("items", []):
        name = repo["full_name"]
        stars = repo["stargazers_count"]
        desc = repo.get("description", "No description")
        results.append(f"- **{name}** ⭐{stars}: {desc}")
    
    return "\n".join(results) if results else "No trending repos found"


def get_date(since: str) -> str:
    from datetime import datetime, timedelta
    days = {"daily": 1, "weekly": 7, "monthly": 30}.get(since, 1)
    return (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")

注册工具

config.toml 中添加:

[tools]
enabled = ["search_hackernews", "get_github_trending"]

[[tool_dirs]]
path = "./tools"

Web UI 使用指南

OpenHands 的 Web UI 包含三个主要区域:

任务示例

在任务框中输入:

$
Search Hacker News for the best articles about AI coding assistants from the past week. Create a markdown file called ai_coding_assistants.md with a summary of the top 5 articles, including the title, URL, score, and a one-sentence description of each.

Agent 会自动:

  1. 调用 search_hackernews 工具
  2. 分析结果并决定内容
  3. 创建 markdown 文件
  4. 将结果写入文件

实战任务示例

1. 自动化代码审查

$
Clone the repository https://github.com/torvalds/linux and run a code review on the most recent 10 commits. Create a file called code_review.md with a summary of any potential issues found, categorized by severity.

2. 数据分析与可视化

$
Download the CSV file from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv. Create a Python script that generates 4 visualizations (histogram, scatter plot, pair plot, box plot) and saves them as PNG files in the current directory.

3. 自动化测试生成

$
Read the file /path/to/my_module.py. Generate comprehensive unit tests using pytest. Save the tests to test_my_module.py. Make sure to cover all public functions with at least 3 test cases each (normal, edge, and error cases).

常见问题

Q: Agent 执行任务时卡住不动

增加 timeout 或使用更长的 max_steps:

# 在 config.toml 中
[agent]
max_steps = 100  # 默认 30
llm_timeout = 300  # 秒

Q: Playwright 浏览器报错

$
playwright install chromium --with-deps

Q: 如何使用本地模型

配置 Ollama 作为后端:

OPENHANDS_MODEL=ollama/llama3.2:3b
OPENHANDS_BASE_URL=http://localhost:11434/v1
OPENHANDS_API_KEY=ollama  # Ollama 不需要真实 key
Advertisement