1. 项目概述:OpenHarness,一个为AI智能体打造的“缰绳”
如果你最近在关注AI智能体(Agent)的开发,可能会发现一个现象:大语言模型(LLM)本身很聪明,但让它真正“动手”去完成一个复杂的任务——比如分析代码库、修复Bug、或者管理一个项目——却异常困难。这就像你有一个天才的头脑,却没有手脚、没有记忆、也看不到周围的世界。OpenHarness(简称oh)就是为了解决这个问题而生的。它不是一个全新的AI模型,而是一个智能体基础设施,或者说,是一个给AI智能体套上的“缰绳”和“鞍具”。
简单来说,OpenHarness 提供了一套完整的、轻量级的框架,将大语言模型的“思考”能力,与真实世界的“行动”能力连接起来。它内置了工具调用、技能系统、记忆管理、权限控制以及多智能体协作等核心模块。你可以把它理解为一个高度可定制、开箱即用的“智能体操作系统”。无论你是想构建一个本地的代码助手,一个自动化脚本工具,还是一个复杂的多智能体协作系统,OpenHarness 都为你准备好了底层引擎和标准接口。
这个项目来自香港大学数据科学实验室(HKUDS),其设计哲学非常务实:模型负责提供智能,而代码(即Harness)负责提供手、眼、记忆和安全边界。它完全开源,采用Python实现,目标用户是研究者、开发者和广大社区。通过它,你不仅可以快速构建可用的智能体,更能深入理解一个生产级AI智能体是如何在“幕后”工作的。
2. 核心架构与设计哲学拆解
2.1 什么是“智能体缰绳”(Agent Harness)?
在深入代码之前,我们必须先理解核心概念。一个“智能体缰绳”远不止是调用API那么简单。它是一个完整的、环绕在LLM周围的基础设施层。我们可以用一个公式来概括:
Harness = Tools(工具) + Knowledge(知识) + Observation(观察) + Action(行动) + Permissions(权限)
- Tools(工具):这是智能体的“手”。OpenHarness内置了43+个开箱即用的工具,涵盖文件读写、Shell命令执行、网络搜索、MCP(模型上下文协议)集成等。没有工具,模型就只是一个会聊天的“哲学家”。
- Knowledge(知识):这是智能体的“经验库”。通过技能(Skills)系统,你可以以Markdown文件的形式,为智能体注入特定领域的专家工作流和知识。例如,“如何进行一次规范的Git提交”、“如何系统性地调试代码”。这些知识可以被按需加载,极大地扩展了智能体的能力边界。
- Observation & Action(观察与行动):这是智能体的“感知-行动”循环。OpenHarness的引擎核心是一个持续的循环:接收用户输入 -> 模型思考并决定调用工具 -> 执行工具 -> 将结果返回给模型 -> 模型根据结果决定下一步行动。这个循环使得智能体可以完成多步骤的复杂任务。
- Permissions(权限):这是智能体的“安全边界”。在真实环境中,让一个AI程序拥有无限制的文件系统访问或Shell执行权限是极其危险的。OpenHarness提供了多级权限模式(默认、自动、计划模式)和细粒度的路径/命令规则,确保智能体的所有操作都在可控范围内。
OpenHarness的设计目标就是将这五个要素无缝地整合在一起,提供一个稳定、安全、可扩展的基座,让开发者可以专注于智能体本身的逻辑和业务,而不是重复造轮子。
2.2 十大子系统深度解析
OpenHarness的代码结构清晰地反映了其架构思想。整个项目被组织成10个核心子系统,每个子系统职责单一,通过清晰的接口进行交互:
engine/- 智能体循环引擎:这是整个系统的心脏。它管理着从用户查询到最终响应的完整生命周期,包括流式响应处理、工具调用调度、API重试策略(含指数退避)、并行工具执行以及Token计数和成本跟踪。这个循环是智能体具备“自主性”的关键。tools/- 工具注册表:所有可用工具的集合。每个工具都是一个独立的Python类,使用Pydantic进行严格的输入验证,并自动生成供模型理解的JSON Schema。工具的执行会经过权限检查和工作流钩子(Hooks)。skills/- 技能系统:一个基于Markdown的按需知识加载系统。技能文件描述了在特定场景下(如代码审查、制定计划)应该如何思考和行动。它与Anthropic官方的skills仓库完全兼容,意味着你可以直接使用社区积累的大量现成技能。plugins/- 插件生态系统:这是扩展OpenHarness能力的主要方式。插件可以包含新的命令(Commands)、生命周期钩子(Hooks)甚至是全新的智能体类型(Agents)。它同样兼容Claude Code的插件格式,生态互通性很好。permissions/- 权限与安全:实现多层次的安全控制。除了全局的权限模式,还支持基于正则表达式的路径规则(例如,禁止访问/etc/*)和命令黑名单。所有工具调用在执行前都必须通过权限检查。hooks/- 生命周期钩子:在工具执行的关键节点(如PreToolUse、PostToolUse)插入自定义逻辑。这可以用来实现日志记录、审计、修改工具参数或结果,甚至中断执行。它为高级定制提供了入口。commands/- 交互式命令:提供了54个内置命令,通过输入/触发。例如,/help查看帮助,/commit启动Git提交工作流,/plan进入计划模式,/resume恢复历史会话。这些命令极大地丰富了终端交互体验。mcp/- 模型上下文协议集成:MCP是一种新兴的协议,旨在为AI模型提供动态的、结构化的上下文信息(如数据库schema、实时数据)。OpenHarness内置了MCP客户端,可以连接MCP服务器,从而让智能体“看到”更丰富的动态数据源。memory/- 持久化记忆:智能体可以跨会话记住重要信息。通过MEMORY.md文件和工作区发现(如CLAUDE.md),智能体能够建立持久的上下文,实现更连贯的长期对话和任务执行。coordinator/- 多智能体协调器:支持创建子智能体(Subagent)、进行任务委派和团队协作。这为构建复杂的、由多个专门智能体组成的“团队”提供了基础框架,是迈向智能体集群(Swarm)的关键。
这种模块化设计使得OpenHarness既是一个完整的解决方案,又是一个可任意拆卸组合的工具包。你可以只使用它的工具调用引擎,也可以深度定制其技能和插件系统。
3. 从零开始:完整安装与配置实战
3.1 环境准备与一键安装
OpenHarness对运行环境的要求比较明确。你需要准备:
- Python 3.10+:这是最低版本要求,确保你能使用现代的Python特性。
- 包管理工具 uv:项目推荐使用
uv,这是一个用Rust编写的、速度极快的Python包管理器和安装器。如果你没有安装,可以通过curl -fsSL https://astral.sh/uv/install.sh | bash快速安装。 - Node.js 18+(可选):如果你希望使用那个炫酷的React终端用户界面(TUI),则需要安装Node.js。如果只使用纯命令行接口(CLI),则不需要。
最快速的入门方式是使用官方提供的一键安装脚本。这个脚本会自动检测你的操作系统(Linux/macOS/WSL),检查环境依赖,并完成安装。
# 基础安装 curl -fsSL https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.sh | bash这个命令会完成以下几件事:
- 检测你的操作系统类型。
- 验证Python版本是否≥3.10。
- 如果检测到Node.js,会安装React TUI的前端依赖。
- 通过
pip安装OpenHarness核心包。 - 在用户主目录下创建配置文件夹
~/.openharness/。 - 最后,运行
oh --version来验证安装是否成功。
安装脚本还提供了一些有用的选项:
# 从源码安装(适合开发者或想体验最新代码的用户) curl -fsSL https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.sh | bash -s -- --from-source # 安装并包含即时通讯(IM)频道依赖(为后续的ohmo个人助理功能做准备) curl -fsSL https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.sh | bash -s -- --with-channels实操心得:对于大多数用户,我强烈推荐使用
--with-channels选项。即使你现在不用ohmo,提前安装好slack-sdk、python-telegram-bot这些依赖,可以避免未来想尝试时再折腾环境。另外,如果从源码安装,你之后可以通过git pull轻松更新到最新版本。
3.2 核心配置:理解“工作流”与“供应方”
安装完成后,最关键的一步是配置LLM后端。OpenHarness在这方面设计得非常人性化,它引入了“工作流”的概念,将复杂的“认证->选择供应方->选择模型”流程封装成了清晰的步骤。你不再需要手动拼接环境变量。
运行配置向导:
uv run oh setup这个交互式命令会引导你完成以下步骤:
- 选择工作流:你会看到几个选项,如“Anthropic-Compatible API”、“Claude Subscription”、“OpenAI-Compatible API”等。这代表了一类API的通用访问方式。
- 选择具体后端:以“Anthropic-Compatible API”为例,接下来会让你在几个预设的后端中选择,比如官方的Claude、月之暗面(Kimi)、智谱AI(GLM)、MiniMax等。这些预设已经填好了对应的Base URL和API格式。
- 进行认证:系统会提示你输入对应服务所需的API Key。OpenHarness会安全地将其保存在本地配置中。
- 选择或确认模型:列出该后端支持的可选模型,比如Kimi的
kimi-k2.5,Claude的claude-3-5-sonnet等。 - 保存并激活配置:最后,为这个配置组合起一个名字(即“Profile”),并可以立即将其设为当前活跃的配置。
这个设计的好处是,它将“兼容同一套API协议的多个服务商”归类管理。例如,所有遵循Anthropic API格式的服务(Kimi, GLM等)都被归入“Anthropic-Compatible API”工作流下,你切换起来非常方便。
高级供应方管理: 配置完成后,你可以通过以下命令管理你的供应方配置:
# 列出所有已保存的配置 oh provider list # 切换到名为“kimi”的配置 oh provider use kimi # 手动添加一个自定义的兼容端点(适用于私有化部署或小众服务) oh provider add my-private-endpoint \ --label "公司内部Claude网关" \ --provider anthropic \ --api-format anthropic \ --auth-source anthropic_api_key \ --model custom-model-1 \ --base-url https://internal-gateway.example.com/anthropic重要注意事项:OpenHarness支持按配置档案(Profile)保存密钥。这是一个非常实用的安全特性。这意味着,你的Kimi API Key和OpenAI API Key可以分别保存在不同的Profile里,互不干扰。而不是像一些工具那样,所有Anthropic兼容的服务都共享一个
ANTHROPIC_API_KEY环境变量。
3.3 初体验:你的第一个智能体任务
配置好供应方后,就可以开始使用了。最直接的方式是通过命令行传递一个任务:
# 设置环境变量(如果你没有通过`oh setup`保存配置) export ANTHROPIC_API_KEY=你的密钥 # 如果是Kimi,还需要设置BASE_URL export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic export ANTHROPIC_MODEL=kimi-k2.5 # 让智能体分析当前目录的代码库 uv run oh -p "请检查当前代码仓库的结构,并列出三个最值得重构的代码片段"OpenHarness会启动智能体循环。模型会分析你的指令,决定需要调用哪些工具(比如read_file、bash执行find命令等),并在获得你的许可(默认权限模式下)后执行它们,最终将分析结果呈现给你。
你也可以使用非交互模式,这对于自动化脚本非常有用:
# 输出纯文本结果到标准输出 uv run oh -p "列出当前目录下所有.py文件的行数" --output-format text # 输出结构化的JSON,方便其他程序解析 uv run oh -p "获取系统信息" --output-format json # 流式输出JSON事件,可以实时看到智能体的思考过程和工具调用 uv run oh -p "修复这个脚本中的语法错误" --output-format stream-json4. 核心功能实战与深度使用指南
4.1 工具系统:赋予智能体“超能力”
OpenHarness内置的43+个工具是其能力的基石。这些工具被精心设计,覆盖了智能体与计算机交互的绝大多数场景。我们可以将其分为几个大类:
文件与系统操作工具:
read_file,write_file,edit_file: 基础的读写编辑,是代码助手的核心。bash: 执行Shell命令,功能强大但需谨慎控制权限。glob: 文件模式匹配,用于查找文件。grep: 在文件中搜索文本。
搜索与信息获取工具:
web_search: 联网搜索(需要配置搜索引擎API)。web_fetch: 获取网页内容。tool_search: 在工具库中搜索可用的工具。
高级工作流工具:
agent: 创建并管理子智能体。task_create,task_get,task_stop: 后台任务管理,允许智能体发起一个长期运行的任务并稍后检查结果。mcp_tool: 调用通过MCP协议连接的外部工具,这是扩展能力边界的关键。enter_plan_mode,exit_plan_mode: 切换工作模式。在“计划模式”下,智能体只制定计划而不执行任何写操作,非常适合用于方案评审。
每个工具都遵循统一的范式:
- 输入验证:使用Pydantic模型定义,确保传入的参数类型和结构正确。
- 自描述:自动生成符合OpenAI Function Calling或Anthropic Tool Use规范的JSON Schema,模型能自动理解工具的用途和用法。
- 权限集成:每次调用前都会经过权限系统的检查。
- 生命周期钩子:支持
PreToolUse和PostToolUse钩子,方便注入自定义逻辑。
避坑技巧:在使用
bash工具时,务必结合权限系统的path_rules。我个人的配置中,会明确禁止对/home/*(用户目录)以外的关键系统路径进行写操作,并且将rm -rf、dd等危险命令加入denied_commands列表。永远不要在生产环境或重要开发机上使用auto权限模式。
4.2 技能与插件:生态扩展之道
如果说工具是智能体的“手”,那么技能就是它的“大脑皮层”,插件则是它的“行为模式”。
技能系统:技能是以Markdown文件形式存在的领域知识。例如,一个commit.md技能文件会详细描述:“当用户要求提交代码时,你应该先运行git status查看更改,然后git diff审查改动,接着撰写清晰的分行提交信息...”。智能体在遇到相关任务时,会主动加载这些技能文件,从而遵循最佳实践。
技能文件的存放位置是~/.openharness/skills/。其最大优势是与Anthropic官方skills仓库兼容。你可以直接克隆该仓库,将里面的.md文件复制到上述目录,瞬间获得数十个高质量的领域技能。
# 示例:快速获取社区技能 git clone https://github.com/anthropics/skills.git /tmp/skills cp /tmp/skills/*.md ~/.openharness/skills/ # 重启oh,你的智能体就“学会”了代码审查、调试、写测试等技能插件系统:插件则是一个更重量级的扩展单元,它可以包含命令、钩子、甚至全新的智能体类型。OpenHarness的插件系统兼容Claude Code的插件格式。这意味着整个Claude Code的插件生态理论上都可以迁移过来。
插件通常以文件夹形式存在,结构如下:
.my-plugin/ └── .claude-plugin/ ├── plugin.json # 插件元数据 ├── commands/ # 自定义命令 │ └── my-command.md ├── hooks/ # 生命周期钩子定义 │ └── hooks.json └── agents/ # 自定义智能体定义 └── reviewer.md你可以通过命令管理插件:
oh plugin list # 列出所有可用插件 oh plugin install ./path/to/plugin # 从本地路径安装 oh plugin install https://github.com/xxx/yyy.git # 从Git仓库安装 oh plugin enable my-plugin # 启用插件实操心得:不要试图一开始就编写复杂的插件。最好的入门方式是先研究现有的插件,比如官方的
commit-commands。理解其commands/下的Markdown文件如何定义一个新的/commit命令,以及这个命令如何触发一系列工具调用。从修改一个现有插件开始,是学习插件系统最快的方式。
4.3 权限与安全:为智能体划定“行动边界”
这是OpenHarness设计中非常出色且必要的一环。在默认模式下,每当智能体试图执行一个具有“写”风险或执行外部命令的操作时,终端都会弹出一个交互式对话框,询问你是否批准。
权限模式详解:
default(默认):交互式询问。最安全,适合日常使用。每次潜在的写操作或命令执行都需要你确认。auto(自动):自动允许所有操作。极度危险,仅应在完全受控的沙箱环境或执行绝对信任的脚本时使用。plan(计划):禁止所有写操作。智能体只能“纸上谈兵”,输出计划而不会执行。非常适合用于复杂任务的前期规划和评审。
细粒度规则配置: 你可以在~/.openharness/settings.json中配置更精细的规则:
{ "permission": { "mode": "default", "path_rules": [ { "pattern": "/home/myuser/projects/**/*", "allow": true, "ask": false }, { "pattern": "/etc/**/*", "allow": false }, { "pattern": "/tmp/**/*", "allow": true } ], "denied_commands": [ "rm -rf /", "rm -rf /*", ":(){ :|:& };:", "mkfs.*", "dd if=* of=*" ] } }上述配置意味着:
- 对
/home/myuser/projects/下的所有文件操作自动允许,无需询问。 - 绝对禁止访问
/etc/目录。 - 允许操作
/tmp/目录。 - 禁止执行一系列极端危险的Shell命令。
安全警告:永远不要在生产服务器或存有重要数据的个人电脑上使用
auto模式。即使是在default模式下,也要仔细阅读权限对话框中的工具调用详情,确认其操作是你所预期的。权限系统是你的最后一道防线。
4.4 多智能体与后台任务:走向复杂自动化
OpenHarness的coordinator和tasks子系统为构建更复杂的自动化流程打开了大门。
创建子智能体:主智能体可以像项目经理一样,将任务分解并委派给具有特定技能的子智能体。
# 假设我们有一个“代码审查专家”智能体定义 # 主智能体可以调用 `agent` 工具来创建它,并分配任务 uv run oh -p “我需要审查src/utils.py文件。请创建一个专注于代码审查的子智能体来完成此事,并向我报告结果。”在这个过程中,主智能体会调用agent工具,指定子智能体的角色、目标和可用工具,然后通过send_message工具与它通信,最后整合结果。
后台任务管理:对于需要长时间运行的任务(如监控日志、定期拉取数据、训练模型),智能体可以创建后台任务。
uv run oh -p “启动一个后台任务,每5分钟检查一次网站的可用性,并将结果记录到log.txt中。”智能体会调用task_create工具,提供一个包含循环和检查逻辑的脚本或指令。该任务会在后台独立运行,之后你可以用task_list查看运行中的任务,用task_get获取其最新输出或状态。
实际应用场景:你可以构建一个“开发运维主管”智能体。当收到一个“部署新功能”的指令时,它可以:
- 创建一个“代码合并审查”子智能体去检查PR。
- 创建一个“测试运行”子智能体去执行测试套件。
- 在上述两者都通过后,再创建一个“部署执行”后台任务,在深夜进行自动化部署。
- 在整个过程中,主管智能体负责协调和向你汇报进度。
5. 高级主题:ohmo个人助理与深度定制
5.1 ohmo:你的专属个人助理应用
ohmo是构建在OpenHarness之上的一个“开箱即用”的个人助理应用。它与oh共享核心,但提供了更贴近最终用户的产品体验,特别是集成了即时通讯(IM)通道。
核心概念与初始化:ohmo拥有自己独立的工作空间~/.ohmo/,其中包含定义助理个性、记忆和配置的关键文件。
# 初始化ohmo工作空间(只需一次) ohmo init初始化会创建以下结构:
soul.md: 定义助理的长期性格、说话风格和行为准则。identity.md: 定义“它是谁”(例如,“一个高效的编程助手”)。user.md: 定义用户(你)的偏好和历史。BOOTSTRAP.md: 首次运行时的启动仪式和初始化对话。memory/: 存储跨会话的持久化记忆。gateway.json: 存储配置(使用哪个LLM供应方、连接哪些IM通道)。
配置网关: 初始化后,需要配置助理如何运行以及在哪里与你交互。
# 启动交互式配置流程 ohmo config这个流程会引导你:
- 选择LLM供应方:和
oh setup一样,从“Anthropic-Compatible API”、“GitHub Copilot”等工作流中选择。 - 配置IM通道:目前支持Telegram、Slack、Discord、飞书。你需要提供相应的Bot Token或Webhook URL。
- 保存并启动:配置完成后,
ohmo会尝试启动一个后台网关进程。这个网关负责监听IM消息,将其转发给OpenHarness核心处理,并将回复发送回IM。
运行与管理:
# 运行个人助理(启动网关并连接) ohmo # 单独运行网关(通常由`ohmo`命令自动管理) ohmo gateway run # 检查网关状态 ohmo gateway status # 重启网关(例如在修改配置后) ohmo gateway restart部署建议:
ohmo的网关适合运行在个人电脑或一个长期在线的服务器(如树莓派、家庭NAS或云服务器)上。对于Telegram/Slack等通道,你需要按照对应平台指南创建一个Bot并获取Token。这是一个将AI助理无缝融入日常沟通流(比如在团队Slack频道中@它获取帮助)的绝佳方式。
5.2 扩展OpenHarness:开发你的工具和插件
当你需要OpenHarness做一件它目前做不到的事情时,就是扩展它的时刻了。
添加一个自定义工具: 假设我们需要一个工具来查询当前的天气。首先,在OpenHarness的源码目录(或通过插件机制)创建一个新的工具文件,例如weather_tool.py。
from pydantic import BaseModel, Field from openharness.tools.base import BaseTool, ToolExecutionContext, ToolResult import aiohttp # 假设我们使用异步HTTP客户端 class WeatherInput(BaseModel): city: str = Field(description="The city name to query weather for") unit: str = Field(default="celsius", description="Temperature unit: 'celsius' or 'fahrenheit'") class WeatherTool(BaseTool): name = "get_weather" description = "Get the current weather for a given city." input_model = WeatherInput async def execute(self, arguments: WeatherInput, context: ToolExecutionContext) -> ToolResult: # 这里是工具的核心逻辑 # 1. 构建API请求(示例,需要替换为真实的天气API) api_url = f"https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q={arguments.city}" # 2. 发起异步请求 async with aiohttp.ClientSession() as session: async with session.get(api_url) as resp: if resp.status == 200: data = await resp.json() temp = data['current']['temp_c'] if arguments.unit == 'celsius' else data['current']['temp_f'] condition = data['current']['condition']['text'] output = f"The current weather in {arguments.city} is {condition}, temperature is {temp}°{arguments.unit[0].upper()}." else: output = f"Failed to fetch weather for {arguments.city}. API returned status {resp.status}." # 3. 返回工具执行结果 return ToolResult(output=output)接下来,你需要将这个工具注册到系统中。这通常通过修改工具注册表或在一个插件中声明来实现。工具一旦注册,智能体在思考过程中就能自动发现并调用它,模型会根据你提供的description和input_model生成的Schema来理解如何使用这个工具。
创建一个自定义技能: 技能更简单,就是一个Markdown文件。创建~/.openharness/skills/weather-forecast.md:
--- name: weather-forecast description: Provides guidance on how to properly ask for and interpret weather information. --- # Weather Forecast Skill ## When to use Use this skill when the user asks about weather, temperature, or planning activities based on weather conditions. ## Workflow 1. **Clarify Location**: Always ask for the specific city if not provided. Example: "Which city are you interested in?" 2. **Determine Unit**: Ask for temperature preference (Celsius or Fahrenheit). Default to Celsius if unspecified. 3. **Use the Tool**: Call the `get_weather` tool with the confirmed city and unit. 4. **Provide Context**: Don't just state numbers. Add helpful context like: - "That's quite warm, you might not need a jacket." - "It's below freezing, be sure to dress warmly if going outside." 5. **Offer Follow-up**: Suggest related actions. Example: "Would you like me to check the forecast for the rest of the week?"现在,当用户问“今天天气怎么样?”时,智能体会加载这个技能,按照里面描述的步骤与你交互,并最终调用你刚创建的get_weather工具。
开发流程总结:
- 明确需求:你的工具要解决什么问题?
- 定义接口:用Pydantic模型清晰定义输入参数。
- 实现逻辑:在
execute方法中编写核心功能。注意使用异步(async/await)以保持系统响应性。 - 编写文档:为工具和技能编写清晰的描述,这直接决定了模型能否正确使用它们。
- 测试集成:将工具注册后,通过简单的提示词测试其是否被正确调用和执行。
6. 常见问题、故障排查与性能优化
在实际使用OpenHarness的过程中,你可能会遇到一些典型问题。以下是我在深度使用后总结的排查清单和优化建议。
6.1 安装与配置问题
问题1:安装脚本在 macOS 或特定 Linux 发行版上失败。
- 排查:首先检查Python版本:
python3 --version。确保≥3.10。如果使用uv安装,确保uv已正确安装。脚本可能依赖curl、bash和git。 - 解决:手动安装通常更可靠。
git clone https://github.com/HKUDS/OpenHarness.git cd OpenHarness # 使用uv(推荐) uv sync --extra dev # 或者使用传统pip pip install -e .[dev]
问题2:运行oh命令提示“命令未找到”。
- 排查:安装可能未将
oh添加到PATH,或者虚拟环境未激活。 - 解决:
- 如果使用uv,确保使用
uv run oh来运行。 - 如果使用pip全局安装,确认安装路径在PATH中。
- 在项目目录下,可以尝试
python -m openharness.cli直接运行模块。
- 如果使用uv,确保使用
问题3:API 密钥配置后,调用模型超时或报错。
- 排查:
- 密钥错误:确认密钥无误,且对应服务商账户有余额或额度。
- 网络问题:特别是使用国内服务商(如Kimi、GLM)时,检查网络连接和代理设置。OpenHarness默认会读取系统的
HTTP_PROXY/HTTPS_PROXY环境变量。 - Base URL错误:对于非官方服务商,
ANTHROPIC_BASE_URL或OPENAI_BASE_URL必须完全正确。例如Kimi是https://api.moonshot.cn/anthropic,末尾的/anthropic不能省略。 - 模型名称错误:确认你请求的模型在该端点可用。例如,在Kimi端点请求
claude-3-opus会失败。
- 解决:使用
oh setup重新配置一遍是最快的方法。它引导的流程能避免手动配置的常见错误。也可以直接检查配置文件~/.openharness/profiles.json。
6.2 运行时与功能问题
问题4:工具调用被无限期挂起,没有响应。
- 排查:这通常是权限系统在等待用户交互。在
default模式下,如果工具需要写文件或执行命令,会弹出权限对话框。如果你在非交互式环境(如脚本、CI/CD)中运行,或者终端不支持交互式提示,就会卡住。 - 解决:
- 对于脚本:使用
--permission-mode auto(极度危险,仅用于完全信任的脚本)或--permission-mode plan(只计划不执行)。 - 对于已知安全操作:在
settings.json中配置path_rules,对特定路径设置"ask": false。 - 检查终端:确保你是在一个支持交互式的终端中运行。
- 对于脚本:使用
问题5:智能体陷入循环,不断重复调用同一个工具或说“我还在思考”。
- 排查:这可能是“幻觉”或上下文管理问题。
- 上下文过长:如果对话历史或注入的技能内容太多,可能超出模型上下文窗口,导致模型行为异常。
- 工具结果不明确:工具返回的结果可能过于模糊或格式混乱,导致模型无法理解,从而反复询问或调用。
- 技能冲突:加载了多个描述相似但流程矛盾的技能,导致模型困惑。
- 解决:
- 使用
--max-turns参数限制最大对话轮数。 - 检查工具返回的结果,确保是清晰、结构化的文本。
- 简化当前会话的系统提示词或暂时禁用部分技能,进行隔离测试。
- 查看调试输出
-d/--debug,观察模型接收到的完整消息和工具调用历史。
- 使用
问题6:React TUI 界面无法启动或显示异常。
- 排查:
- Node.js未安装或版本过低(需要≥18)。
- 前端依赖未安装。一键安装脚本在检测到Node.js时会自动安装,如果跳过或失败,需要手动安装。
- 解决:
如果问题依旧,可以尝试纯CLI模式,TUI是可选的增强功能,并非核心。# 进入OpenHarness项目目录 cd OpenHarness # 安装前端依赖 npm install # 或者使用yarn/pnpm # 然后再次运行oh uv run oh
6.3 性能优化与最佳实践
优化1:控制上下文长度,节省Token成本。
- 技巧:OpenHarness有上下文压缩功能,但你可以主动管理。
- 对于长会话,适时使用
/new开始一个新会话,清空历史。 - 在技能文件中,保持描述精炼,只包含最关键的工作步骤。
- 考虑使用
--effort参数(如果后端支持)来平衡速度与成本。
- 对于长会话,适时使用
优化2:编写高质量的工具和技能描述。
- 原理:模型完全依赖你提供的
description和技能文本来理解如何工作。模糊的描述会导致低效或错误的工具调用。 - 最佳实践:
- 工具描述:以动词开头,清晰说明功能、输入和输出。例如:“
read_file: Reads the contents of a file at the given path. Returns the text content or an error if the file cannot be read.” - 技能结构:遵循
## When to use和## Workflow的模板。在Workflow中,使用编号步骤,并明确说明在每一步应该调用什么工具或进行什么判断。
- 工具描述:以动词开头,清晰说明功能、输入和输出。例如:“
优化3:利用会话记忆和持久化。
- 场景:如果你经常在同一个项目上工作,可以利用
MEMORY.md和CLAUDE.md。- 在项目根目录创建
CLAUDE.md,描述项目结构、约定、常用命令。智能体启动时会自动读取。 - 让智能体将重要的项目决策或学习到的信息写入
MEMORY.md,下次启动时会加载,实现跨会话记忆。
- 在项目根目录创建
- 命令:使用
/resume命令可以快速恢复之前的会话历史。
优化4:为复杂任务使用“计划模式”。
- 流程:对于重构、大型代码修改等任务,不要直接让智能体执行。
- 先进入计划模式:
/permissions plan或启动时加--permission-mode plan。 - 给出任务:“请为重构
src/目录下的模块依赖关系制定一个详细计划。” - 智能体会输出一个步骤列表,而不会执行任何写操作。
- 你审查这个计划,确认无误后,再退出计划模式,让它逐步执行。
- 先进入计划模式:
OpenHarness是一个强大且不断演进的项目。它的价值在于提供了一个经过深思熟虑的、可扩展的智能体基础架构。与其从零开始搭建轮子,不如基于它来快速实现你的AI智能体想法,并将精力集中在业务逻辑和领域知识上。从简单的命令行助手开始,逐步探索其技能、插件和多智能体功能,你会逐渐发现,将大语言模型的能力安全、可控地接入真实世界的工作流,并没有想象中那么遥远。