在软件开发的宏伟殿堂中,开发者们如同现代的西西弗斯,日复一日地将一块名为“功能开发”的巨石推向山顶。然而,每当他们接近顶峰,另一块名为“Bug”的巨石便会悄然滚落,随之而来的是无尽的技术债和堆积如山的问题清单(Issue List)。这永无休止的循环,耗尽了无数工程师的才情与心血,将本应挥洒于创新的精力,禁锢在了修复与维护的囹圄之中。然而,就在这片看似无解的困境中,一缕破晓之光正悄然升起。这束光并非来自一种新的编程语言或是一个革命性的框架,而是源自一个全新的物种——人工智能代理(AI Agent)。
我们今天将要深入剖析的主角,OpenHands,正是这一新兴物种中的杰出代表。它并非一个冰冷无情的自动化脚本,也不是一个只会根据指令执行任务的机器人。相反,我们可以将其想象成一位充满潜力的“算法学徒”。这位学徒孜孜不倦,能够阅读人类用自然语言描述的“问题”,理解其中的上下文和细微差别,然后像一位经验丰富的开发者一样,深入代码库,诊断病因,编写修复方案,并最终以一个“拉取请求”(Pull Request)的形式,恭敬地呈上自己的“作业”,等待人类导师的检阅。
本文旨在对 OpenHands 这一 AI 驱动的代码修复框架进行一次全面的解剖。我们将从其设计的哲学思想入手,深入探讨其两种核心工作模式——便捷的“一键召唤”与精细的“工匠手作”。我们将逐一拆解其配置的每一个环节,阐明每一行命令背后蕴含的逻辑,并展望这种人机协作新范式将如何重塑软件工程的未来版图。这不仅是一份技术文档的深度解读,更是一场关于人、代码与人工智能三者关系的哲学思辨之旅。现在,让我们一起揭开这位“算法学徒”的神秘面纱,探寻它是如何学会自我修养,并最终成为我们修复代码的得力助手的。
🌍 第一章:现代软件开发的困境与 AI 协作者的黎明
🏔️ 西西弗斯之石:现代软件项目中的“问题”黑洞
在古希腊神话中,西西弗斯因触怒众神而被罚,必须将一块巨石推上山顶,而每当巨石即将到达顶峰,便会滚落回原点,如此循环,永无止境。这个悲剧性的隐喻,在今天惊人地映射了软件开发者的日常。每一个项目,无论大小,都伴随着一个不断膨胀的“问题”列表(Issue Tracker)。这个列表就像一个黑洞,无情地吞噬着开发团队的时间和精力。
这些“问题”形态各异:有的是用户报告的功能缺陷(Bug),有的是系统在特定条件下崩溃的致命错误,有的是代码库中潜藏的技术债务,还有的是为了适应新需求而必须进行的重构。每一个问题,无论大小,都需要开发者投入时间去理解、复现、定位、修复和验证。这个过程繁琐、重复,且极易出错。当一个团队将 80% 的时间用于“救火”和维护,那么用于创新和构建核心价值的时间,便只剩下可怜的 20%。这便是现代软件开发中普遍存在的“西西弗斯困境”。开发者们渴望创造,却被困在了维护的巨轮之上。
注解:技术债务(Technical Debt)
这是一个非常形象的比喻。想象一下,为了快速上线一个功能,你选择了一条“捷径”,写了一些不够优雅、不够健壮的代码。这就像是借了一笔“技术上的债务”。短期来看,你节省了时间。但长期来看,这些“债务”会累积“利息”——未来的维护会更困难,添加新功能更容易引发问题,新员工理解代码的成本也更高。修复这些问题,就如同“偿还债务”。
长期以来,我们试图通过更完善的流程(如敏捷开发、CI/CD)、更先进的工具(如静态代码分析、自动化测试)来缓解这一困境。这些方法无疑取得了显著成效,但它们并未从根本上改变开发者作为“问题最终解决者”的核心角色。问题的洪流依然汹涌,而开发者的精力终究是有限的。我们需要一种新的力量,一个能够分担这份重担的伙伴。
🤖 算法学徒的诞生:软件维护的新范式
就在这样的背景下,AI 协作者应运而生。这里的 AI,不再是那个在棋盘上战胜人类冠军的博弈大师,也不是那个能与你闲聊几句的聊天机器人。它正在演变成一个能够深度参与复杂智力劳动,尤其是软件工程的“数字同事”。OpenHands 正是这一演化趋势下的产物,它为自己设定的角色,并非取代人类的“大师”,而是辅助人类的“学徒”。
这位学徒的核心能力,是理解上下文并采取行动。传统的自动化脚本只能执行预设的命令,而 OpenHands 能够:
- 阅读与理解:它能够通读整个 GitHub、GitLab 或 Bitbucket 的 Issue 讨论串,从标题、描述到每一条评论中,提取出问题的关键信息、用户的期望以及可能的解决方案线索。
- 规划与推理:基于对问题的理解,它会像人类开发者一样,在心中(或者说,在其算法模型中)构建一个解决问题的计划。例如:“首先,我需要定位到用户提到的那个函数。然后,根据错误日志,问题可能出在边界条件的处理上。我需要增加一个空值检查。最后,我需要修改相关的单元测试以覆盖这个新的场景。”
- 行动与执行:它会检出(checkout)代码,打开文件,进行修改,添加或删除代码行,甚至创建新文件。它的操作,与一位开发者通过键盘和鼠标完成的工作别无二致。
- 提议与沟通:完成修改后,它不会直接将代码合并到主干。相反,它会创建一个拉取请求(Pull Request),清晰地展示自己的所有改动,并自动在原始 Issue 下发表评论,告知大家:“我已经尝试修复了这个问题,这是我的解决方案(PR链接),请查阅。”
这种“理解-规划-行动-提议”的闭环工作流,使其超越了“工具”的范畴,更像一个真正的“协作者”。它的出现,预示着一种新的人机协作范式:开发者从繁琐的修复工作中解放出来,转而扮演“导师”、“架构师”和“审查者”的角色,将精力集中在更具创造性和战略性的任务上。
🌍 第二章:召唤学徒的双行道——从一键部署到精细操控
要让这位能干的算法学徒为您效力,OpenHands 提供了两条截然不同的路径。一条是为追求效率和便捷而生的“高速公路”——GitHub Actions 自动化工作流;另一条则是为希望深入细节、完全掌控的“工匠作坊”——本地手动安装与执行。这两条路径殊途同归,最终都能让 AI 动起手来,但其过程和适用场景却大相径庭。接下来,我们将分别探索这两条道路的风景。
🚀 高速公路:通过 GitHub Actions 实现的一键式召唤
对于绝大多数希望快速将 OpenHands 集成到现有项目中的团队而言,GitHub Actions 无疑是最佳选择。它就像一个预先配置好的“召唤法阵”,你只需提供一些必要的“祭品”(配置和密钥),就能在需要时自动唤醒 AI 学徒。整个过程被设计得尽可能简单,但其背后每一步都值得我们细细品味。
第一步:获取王国的钥匙——个人访问令牌(PAT)
想象一下,你的代码仓库是一个戒备森严的王国。任何外来者想要进入并进行操作,都必须持有合法的“通行证”。个人访问令牌(Personal Access Token, PAT)就是 GitHub 授予 AI 学徒的这枚特殊通行证。
-
为何需要它? 当 OpenHands 以 GitHub Action 的形式运行时,它实际上是在 GitHub 的服务器上代表你进行操作。它需要你的授权才能读取 Issue 内容、克隆代码、推送新的分支以及创建拉取请求。PAT 就是这份授权的凭证。
-
权限的艺术: 创建 PAT 时,最关键的一步是配置其“作用域”(Scope)。这体现了软件安全中的“最小权限原则”。OpenHands 明确要求了四个核心权限:
contents
(read/write): 这是最核心的权限。读权限让 AI 能看到你的代码,写权限则让它能修改代码并创建新的分支来存放修复方案。issues
(read/write): 读权限让 AI 能阅读问题的详细描述和所有讨论,这是它理解任务的起点。写权限则让它能够在修复完成后,回到 Issue 下留言,完成工作流的闭环。pull requests
(read/write): 写权限是关键,它允许 AI 将自己的修复方案打包成一个拉取请求(PR),供团队审查。workflows
(read/write): 这个权限允许 AI 与 GitHub Actions 工作流本身进行交互,例如在工作流中更新状态或触发其他流程。
注解:最小权限原则(Principle of Least Privilege)
这是网络安全的一个基本原则。它的核心思想是,任何一个用户、程序或进程,都只应拥有完成其任务所必需的最小权限。就像给一位修理工一把进入锅炉房的钥匙,而不是整栋大楼所有房间的万能钥匙。这样做可以最大限度地减少因凭证泄露或被滥用而造成的潜在损害。
值得注意的是,如果你是在一个组织(Organization)的仓库中工作,可能需要先由组织管理员调整相关的安全策略,才能成功创建和使用具有这些权限的 PAT。这体现了企业级应用的严谨性。
第二步:聆听神谕的声音——配置大语言模型(LLM)API 密钥
如果说 PAT 是 AI 学徒进入王国的钥匙,那么大语言模型(LLM)就是它背后的大脑和智慧源泉。OpenHands 本身是一个执行框架,它负责与代码仓库交互、执行文件操作,但真正进行“思考”——即理解问题、构思解决方案的部分,则是由一个强大的 LLM 完成的。
-
大脑的选择: OpenHands 推荐使用 Anthropic 公司的 Claude 系列模型,或 OpenAI 公司的 GPT-4。这并非偶然。代码修复是一项极其复杂的认知任务,它需要模型具备强大的逻辑推理能力、对代码结构的深刻理解以及生成精确、符合语法规范的代码的能力。就像在招聘一位程序员时,你会倾向于选择经验丰富、能力更强的候选人一样,为 AI 学徒选择一个更强大的“大脑”至关重要。虽然 OpenHands 也支持其他模型,但使用较弱的模型可能会导致修复效果不佳,好比让一位初学者去处理一个棘手的架构问题。
-
通信的凭证: LLM API 密钥(
LLM_API_KEY
)就是你的 AI 学徒用来与这个“大脑”进行交流的“密语”。每一次当 AI 需要“思考”时,它都会通过 API 调用,将问题上下文、相关代码片段等信息发送给 LLM 服务,并取回解决方案。这个密钥是付费服务的使用凭证,必须妥善保管。
第三步:绘制魔法阵图——openhands-resolver.yml
工作流文件
有了钥匙和大脑,我们还需要一张“魔法阵图”来定义召唤仪式(即自动化流程)的具体步骤。在 GitHub Actions 的世界里,这张图就是位于 .github/workflows/
目录下的一个 YAML 文件,例如 openhands-resolver.yml
。
这个文件本质上是一个结构化的指令集,它告诉 GitHub:
- 何时触发(Triggers):定义什么事件会启动这个工作流。对于 OpenHands,这通常是当一个 Issue 被打上特定标签(如
fix-me
)或者在评论中被特别提及(如@openhands-agent
)时。 - 在什么环境下运行(Runner Environment):指定一个虚拟服务器环境(如
ubuntu-latest
)。 - 执行哪些步骤(Steps):这是文件的核心部分,它会像脚本一样按顺序执行一系列操作。
下面是一个简化的 openhands-resolver.yml
文件结构示意图,以帮助理解其内部构造:
# .github/workflows/openhands-resolver.yml
name: OpenHands Issue Resolver
# 触发器:当 issue 被标记或评论时运行
on:
issues:
types: [labeled]
issue_comment:
types: [created]
jobs:
resolve-issue:
# 条件判断:仅当标签为 'fix-me' 或评论包含 '@openhands-agent' 时才继续
if: |
(github.event.action == 'labeled' && github.event.label.name == 'fix-me') ||
(contains(github.event.comment.body, '@openhands-agent'))
runs-on: ubuntu-latest
steps:
# 第一步:检出代码库
- name: Checkout Repository
uses: actions/checkout@v4
# 第二步:运行 OpenHands 核心 Action
- name: Run OpenHands Resolver
uses: all-hands-ai/openhands-action@v1 # (假设的 Action 名称)
with:
# 将机密信息作为参数传入 Action
github-token: ${{ secrets.PAT_TOKEN }}
llm-api-key: ${{ secrets.LLM_API_KEY }}
issue-number: ${{ github.event.issue.number }}
# ... 其他参数
# 第三步:处理结果(例如,在 issue 下留言)
# ...
这份“魔法阵图”将整个复杂的流程自动化,开发者无需关心背后的细节,只需完成触发动作即可。
第四步:授予官方许可——配置仓库权限
为了让这个自动化工作流顺利运行,你还需要在仓库的设置中明确授予它足够的权限。这就像是国王为你的 AI 学徒颁发一道皇家法令,允许它在领地内自由行动。
你需要进入仓库的 Settings -> Actions -> General -> Workflow permissions
,并进行两项关键设置:
- 选择 “Read and write permissions”:这为所有从该仓库运行的 GitHub Actions 提供了一个基础的读写权限集。
- 启用 “Allow GitHub Actions to create and approve pull requests”:这是一个至关重要的开关。打开它,才算正式授权 AI 学徒拥有创建 PR 的能力。
如果这些选项是灰色的,无法点击,这通常意味着权限受到了更高级别的(组织或企业)策略限制,需要联系管理员进行调整。这一设计确保了在大型组织中,安全策略能够得到统一的贯彻。
第五步:藏匿神圣符文——使用 GitHub Secrets
在前面的步骤中,我们提到了两个极其敏感的信息:个人访问令牌(PAT)和 LLM API 密钥。将这些信息直接写在 .yml
文件中是极其危险的行为,因为 .yml
文件是代码库的一部分,任何能看到代码的人都能看到这些密钥。这就好比将你家的钥匙和银行卡密码刻在家门口的墙上。
GitHub Secrets 提供了一个完美的解决方案。它是一个加密的“保险箱”,你可以将敏感信息存储在其中,并为其命名(如 PAT_TOKEN
, LLM_API_KEY
)。在工作流文件中,你只能通过名字引用这些秘密(如 secrets.LLM_API_KEY
),而无法看到其真实内容。只有在工作流运行时,GitHub 才会将这些值安全地注入到执行环境中。
需要配置的 Secrets 包括:
- 必需:
LLM_API_KEY
: 你的 LLM 服务 API 密钥。
- 可选(但强烈推荐):
PAT_USERNAME
: 你的 GitHub 用户名。PAT_TOKEN
: 你创建的个人访问令牌。LLM_BASE_URL
: 如果你通过代理服务器访问 LLM 服务,需要设置此项。
将密钥存储在 Secrets 中,既保证了工作流的正常运行,又最大限度地保护了你的凭证安全。
第六步:念出召唤咒语——两种触发方式
当一切准备就绪,召唤仪式便可开始。OpenHands 提供了两种简单直观的“咒语”来唤醒沉睡的 AI 学徒。
-
咒语一:贴上
'fix-me'
标签- 场景:你发现了一个 bug,或者团队决定处理一个积压已久的技术债。
- 操作:只需找到对应的 Issue,在标签区域添加
'fix-me'
标签即可。 - 效果:这个动作会立即触发 GitHub Action。AI 学徒被唤醒后,会将整个 Issue 的所有讨论内容(包括原始描述和所有后续评论)作为它理解问题的全部上下文。这适用于那些需要全面信息才能解决的复杂问题。
- 后续:工作流执行完毕后,会自动移除
'fix-me'
标签,以避免重复触发。
-
咒语二:念出
@openhands-agent
- 场景:在一个正在进行的 Issue 讨论中,你突然有了一个具体的修复想法,或者需要 AI 针对某条特定指令进行操作。
- 操作:在该 Issue 下发表一条新的评论,内容中包含
@openhands-agent
。 - 效果:AI 学徒同样会被唤醒,但这一次,它只会将包含
@openhands-agent
的那条评论作为其主要的任务指令。这提供了一种更精确、更即时的交互方式,适用于目标明确的微小修改或迭代修复。
无论使用哪种咒语,其结果都是一致的:如果 AI 成功地构思出解决方案,它会创建一个草稿拉取请求 (Draft PR);如果失败,它也会将自己尝试过的代码改动推送到一个新的分支。无论成败,它都会在原始 Issue 下留言,报告自己的工作成果,形成一个完美的自动化闭环。
🌍 第三章:工匠的作坊——手动安装与精细化操控
如果说 GitHub Actions 是为日常生产设计的自动化流水线,那么手动安装和命令行执行,则是为那些希望深入探究 AI 学徒工作原理、进行实验性研究或需要对修复过程进行极致微操的“工匠”们准备的精密作坊。这条路径赋予了用户最大的自由度和控制权,但也要求用户对环境配置和命令行操作有更深入的了解。
🛠️ 第一步:锻造你的工具集——安装与环境配置
进入作坊的第一步,是准备好所有必需的工具。
核心组件的安装
这第一步出奇地简单,只需一条命令即可将 OpenHands 的核心程序库请入你的本地环境:
pip install openhands-ai
这条命令会通过 Python 的包管理器 pip
下载并安装 openhands-ai
及其所有依赖项。这就像是为你的作坊添置了一台核心的精密机床。
三平台通行证:为 GitHub, GitLab, Bitbucket 铸造令牌
与 GitHub Actions 类似,在本地运行 OpenHands 也需要授权它访问你的代码托管平台。但由于是在你自己的机器上运行,你需要为可能用到的每一个平台单独创建访问令牌。
-
GitHub 访问令牌:
- 创建地点:GitHub 令牌设置页面
- 权限范围 (Scopes):同样遵循最小权限原则,你需要一个“细粒度令牌”(fine-grained token),并授予以下权限:
Content
(内容读写)、Pull requests
(PR读写)、Issues
(问题读写)和Workflows
(工作流读写)。这些权限的含义与 GitHub Actions 中完全相同。
-
GitLab 访问令牌:
- 创建地点:GitLab 令牌设置页面
- 权限范围 (Scopes):GitLab 使用不同的权限模型。你需要授予
api
,read_api
,read_user
,read_repository
,write_repository
等权限,以确保 AI 能够完整地执行克隆、修改、推送和与 API 交互等操作。
-
Bitbucket 应用密码:
- 创建地点:Bitbucket 应用密码设置页面
- 权限范围 (Scopes):Bitbucket 使用“应用密码”作为程序访问的凭证。你需要授予以下权限:
Repositories: Read/Write
,Pull requests: Read/Write
,以及Issues: Read/Write
。
这个过程,就如同为你的 AI 学徒办理了进入不同国家(代码平台)的“签证”,让它可以畅行无阻。
指挥中心的仪表盘:配置环境变量
在本地环境中,环境变量是向程序传递配置信息的标准方式。它将敏感信息(如令牌)与代码逻辑解耦,提高了安全性与灵活性。你需要像设置仪表盘一样,配置好以下环境变量:
为了更清晰地展示,我们使用一个 Markdown 表格来梳理这些环境变量:
环境变量 | 描述 | 是否必需/推荐 | 示例值 |
---|---|---|---|
GITHUB_TOKEN | 用于访问 GitHub 仓库的个人访问令牌(PAT)。 | 条件必需 | ghp_xxxxxxxxxxxxxxxxxxxx |
GITLAB_TOKEN | 用于访问 GitLab 仓库的个人访问令牌。 | 条件必需 | glpat-xxxxxxxxxxxxxxxxxx |
BITBUCKET_TOKEN | 用于访问 Bitbucket 仓库的应用密码。 | 条件必需 | xxxxxxxxxxxxxxxxxxxx |
GIT_USERNAME | 你的 Git 用户名。AI 会用这个身份进行提交。 | 可选 | your-github-username |
LLM_MODEL | 指定使用的 LLM 模型。 | 必需 | anthropic/claude-3-sonnet-20240229 |
LLM_API_KEY | 你的 LLM 服务 API 密钥。 | 必需 | sk-xxxxxxxxxxxxxxxxxxxxxxxx |
LLM_BASE_URL | LLM API 的代理地址(如果使用代理)。 | 可选 | https://api.proxy.com/v1 |
注解:环境变量(Environment Variables)
环境变量是操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如,当你在命令行输入
python
时,系统会通过一个名为PATH
的环境变量来查找python
程序的可执行文件在哪里。在 OpenHands 中,程序启动时会读取这些预设的环境变量,从而知道该用哪个令牌、哪个模型、连接到哪个地址,而无需将这些信息硬编码在代码或命令中。
配置好这些变量后,你的“作坊”就万事俱备,可以开始进行精密的“锻造”工作了。
🪄 第二步:念动核心咒语——执行修复与交互命令
在工匠的作坊里,每一次操作都由一句精准的命令驱动。这些命令就是你与 AI 学徒沟通的语言。
核心指令:resolve_issue
这是启动一次完整问题修复任务的核心命令。它的结构清晰,意图明确:
python -m openhands.resolver.resolve_issue --selected-repo [OWNER]/[REPO] --issue-number [NUMBER]
让我们来分解这个命令的每一个部分:
python -m openhands.resolver.resolve_issue
: 这部分告诉 Python 解释器,不要执行一个.py
文件,而是去运行openhands.resolver
包中名为resolve_issue
的模块。这是一种标准的 Python 模块执行方式。--selected-repo [OWNER]/[REPO]
: 这个参数指定了你的目标。[OWNER]
是仓库所有者(个人或组织)的名称,[REPO]
是仓库的名称。例如all-hands-ai/openhands
。--issue-number [NUMBER]
: 这个参数精确地告诉 AI 学徒,它需要解决的是哪一个 Issue。例如100
。
当你在终端敲下并执行这条命令后,一场无声的“头脑风暴”便在你的电脑上展开了。OpenHands 会连接到指定的代码平台,拉取问题信息和代码,与 LLM 反复沟通,尝试各种修改,并将整个过程的详细日志、中间产物和最终结果输出到你当前目录下的 output/
文件夹中。这个文件夹,就是 AI 学徒的“工作台”,记录了它每一次的思考和尝试。
参与对话:在拉取请求中回应
软件开发不仅是写代码,更是持续的沟通。一个 PR 被创建后,往往会伴随着团队成员的审查评论。OpenHands 同样具备参与这种对话的能力:
python -m openhands.resolver.send_pull_request --issue-number PR_NUMBER --issue-type pr
这个命令允许 AI 对一个已有的 PR 发表评论。例如,如果审查者要求 AI 对其解决方案进行某项修改,你可以通过构造合适的指令,让 AI 理解这个新要求,然后再次运行修复流程,并使用此命令将更新信息或新的解决方案评论到该 PR 中。这使得 AI 能够参与到迭代式的开发和审查循环中,而不仅仅是一个“一次性”的修复工具。
事后复盘:可视化与验证
AI 的工作过程有时像一个“黑箱”,为了增强透明度和可信度,OpenHands 提供了复盘工具。
-
筛选成功案例:AI 学徒的尝试并非总能成功。你可以使用一条
grep
命令,像侦探一样从output/output.jsonl
日志文件中筛选出所有成功的修复记录:grep '"success":true' output/output.jsonl | sed 's/.*\("number":[0-9]*\).*/\1/g'
这条命令会找出所有标记为
"success":true
的行,并提取出对应的 Issue 编号,让你一目了然地知道哪些问题已被成功解决。 -
重现解决路径:对于一个成功的案例,你可能想知道 AI 究竟是如何一步步解决问题的。
visualize_resolver_output
命令就是为此而生:python -m openhands.resolver.visualize_resolver_output --issue-number ISSUE_NUMBER --vis-method json
这个命令会以一种结构化的格式(如 JSON)为你展示整个解决过程的轨迹,包括 AI 的推理链、它执行的每一个命令、以及最终生成的文件差异。这对于理解 AI 的“思维模式”、调试其行为以及建立信任至关重要。
最终交付:将成果公之于众
当你在本地验证了一个成功的修复方案,并对其感到满意时,最后一步就是将其正式提交。send_pull_request
命令再次登场,但这次它扮演的是“信使”的角色。
python -m openhands.resolver.send_pull_request --issue-number ISSUE_NUMBER --username YOUR_GIT_USERNAME --pr-type draft
此命令可以将本地 output/
文件夹中针对某个 Issue 的修复结果,正式推送到远程仓库并创建 PR。你可以通过 --pr-type
参数来控制创建的 PR 类型:
branch
: 只推送一个包含了修复内容的新分支,而不创建 PR。这适用于你还想在推送后进行一些手动修改的场景。draft
: 创建一个草稿 PR。这是一个明确的信号,告诉团队“这个方案已经初步完成,但还需要进一步的审查或测试,请勿合并”。ready
: 创建一个准备就绪的 PR,直接进入正式的审查流程。
此外,OpenHands 还贴心地考虑到了开源贡献的场景。如果你没有目标仓库的直接推送权限,可以通过添加 --fork-owner
参数,将修复分支推送到你自己的分叉(Fork)仓库中,然后再从分叉仓库向上游发起 PR。
# 将修复方案推送到你自己的 fork,再创建 PR
python -m openhands.resolver.send_pull_request --issue-number ISSUE_NUMBER --username YOUR_GIT_USERNAME --pr-type draft --fork-owner YOUR_GIT_USERNAME
这种精细化的控制,使得手动模式下的 OpenHands 成为一个强大而灵活的开发与研究工具,让用户能够完全掌控 AI 工作的每一个环节。
🌍 第四章:驯服智慧野兽——高级定制与社区支持
掌握了召唤与操控 AI 学徒的基本法门后,真正的“大师”之旅才刚刚开始。要让这位学徒的行为完全符合你的团队规范、项目特色,甚至是你个人的编码偏好,你需要学会如何“训练”它。OpenHands 通过“仓库微代理”提供了一条独特的定制化路径。同时,作为一个活跃的开源项目,它也建立了完善的求助渠道。
🧠 教授你的学徒:仓库微代理(Repository Microagents)的艺术
想象一下,你新招了一位初级程序员。上岗第一天,你一定会交给他一份《团队开发规范手册》,里面写着诸如“代码缩进请使用4个空格”、“所有公开函数必须有JSDoc注释”、“日志记录请调用公司自研的Logger库”之类的规则。
仓库微代理文件,即位于你项目根目录下 .openhands/microagents/repo.md
的这个 Markdown 文件,扮演的正是这份“开发规范手册”的角色。
- 它的原理:每当 OpenHands 开始处理你仓库中的一个 Issue 时,它会首先寻找并读取这个
repo.md
文件。该文件的内容,会被自动、高优先级地插入到发送给大语言模型(LLM)的系统提示(System Prompt)的最前端。
注解:系统提示(System Prompt)
在与 LLM 交互时,我们发送的指令通常包含两部分。一部分是用户的具体问题(User Prompt),例如“修复这个空指针异常”。另一部分是系统提示,它是一种更高层次的、定义 AI 角色、行为准则和约束条件的元指令。例如,“你是一个资深的 Java 程序员,你的代码风格必须遵循 Google Java Style Guide…”。系统提示为整个对话定下了基调。
repo.md
的内容就是动态地、针对性地强化了这个系统提示。
-
你能教它什么? 这个文件的潜力几乎是无限的。你可以用自然语言在里面写入任何你希望 AI 遵守的规则、惯例和背景知识。下面是一些例子:
-
编码风格:
# 编码风格指南 - 所有 Python 代码必须使用 aoutformatter 工具进行格式化。 - 缩进使用 4 个空格,而不是制表符。 - 变量命名采用蛇形命名法(snake_case)。
-
架构与库的使用:
# 架构约束 - 本项目采用分层架构,表现层逻辑禁止直接调用数据访问层。 - 对于状态管理,请优先使用我们内置的 `useGlobalState` hook,而不是引入新的状态管理库。 - 日志记录必须使用 `Logger.info()` 或 `Logger.error()`,严禁使用 `console.log()`。
-
特定领域的知识:
# 领域知识 - 在处理用户订单时,'status' 字段有 'pending', 'processing', 'shipped', 'delivered' 四种状态,请确保状态转换的逻辑是正确的。 - 避免使用已废弃的函数 `old_calculate_price()`,请改用 `new_calculate_price_with_vat()`。
-
通过精心编写这份 repo.md
,你不再只是给 AI 分派任务,而是在真正地“训练”它,让它的产出越来越符合你的期望,越来越像一位真正融入了你团队的成员。这种机制,极大地提升了 AI 解决方案的“可用性”和“接受度”,是从“能用”到“好用”的关键一步。
🆘 当魔法失灵时:寻求帮助与社区的力量
即便是最强大的魔法师,也可能遇到咒语失灵的时刻。当你配置 OpenHands 遇到困难,或者 AI 的行为不符合预期时,你并非孤立无援。OpenHands 项目的维护者们提供了多种沟通和求助渠道,这体现了一个健康开源社区的生命力。
-
正式的求助信:提交 Issue
- 无论是你发现了 OpenHands 工具本身的 Bug,还是有功能上的建议,或者仅仅是遇到了无法解决的配置问题,最好的方式是在其官方 GitHub 仓库提交一个新的 Issue。这不仅能让你得到开发团队的直接帮助,你的问题和解决方案也能被社区中的其他人看到,帮助到遇到同样困境的人。
-
快捷的电子邮件
- 对于一些不适合公开讨论的问题,或者需要更直接沟通的场景,你可以通过电子邮件
contact@all-hands.dev
联系到开发团队。
- 对于一些不适合公开讨论的问题,或者需要更直接沟通的场景,你可以通过电子邮件
-
实时的社区闲聊:加入 Slack 工作区
- 许多开源项目都拥有自己的即时通讯社区,OpenHands 也不例外。通过其 README 中提供的邀请链接加入 Slack 工作区,你可以在这里与其他用户交流使用心得,向开发者们实时提问,感受社区的脉搏。
一个工具的价值,不仅在于其功能本身,更在于其背后的社区生态。完善的文档、积极的维护和热情的社区,共同构成了 OpenHands 项目的坚实后盾,确保了用户在探索 AI 编程这条新航道上,能够行稳致远。
结论:与算法共舞,软件工程的下一个十年
我们从西西弗斯的困境出发,见证了 OpenHands 这位“算法学徒”的诞生。我们深入探索了召唤它的两条路径:一条是无缝集成的自动化高速公路,另一条是精雕细琢的工匠作坊。我们学会了如何通过令牌与密钥赋予它力量,通过工作流与命令行驾驭它,更学会了如何通过“微代理”这份特殊的说明书来“教导”它,使之成为我们团队中更默契的一员。
OpenHands 的出现,并非要宣告人类程序员时代的终结。恰恰相反,它开启了一个人机协作的新纪元。在这个纪元里,开发者将从那些重复、繁琐、耗时的修复工作中解放出来,将他们宝贵的认知资源投入到更高级别的智力活动中去:系统架构的设计、用户体验的创新、复杂业务逻辑的梳理,以及对 AI 伙伴工作的审查与指导。开发者的角色,正在从“代码的生产者”悄然转变为“智慧的编排者”。
当然,今天的 AI 学徒还远非完美。它有时可能会误解问题的意图,有时可能会写出不够优雅甚至错误的代码。它仍然需要人类的监督、审查和最终决策。然而,我们不应因其尚存的瑕疵而否定其巨大的潜力。正如每一位人类学徒都需要在实践中学习和成长一样,AI 协作者也在每一次的修复任务中不断进化。
展望未来,我们可以预见,像 OpenHands 这样的工具将变得更加智能、更加普及。它们或许能理解更高层次的指令(“重构这个模块以提升性能”),能够自动编写和修复测试用例,甚至能够预测潜在的 bug 并提前进行修复。软件工程这门手艺,将在与算法的共舞中,演化出全新的形态。而我们,作为这个时代的开发者,最激动人心的任务,便是学会如何与这位日益聪慧的“算法学徒”和谐共事,共同构建下一个十年的数字世界。
参考文献
-
Chen, M., et al. (2021). Evaluating Large Language Models Trained on Code. arXiv preprint arXiv:2107.03374.
这篇开创性的论文评估了大型语言模型(如 Codex)在代码生成任务上的能力,为后来如 OpenHands 等基于 LLM 的代码工具奠定了理论和实证基础。 -
Vaswani, A., et al. (2017). Attention Is All You Need. Advances in Neural Information Processing Systems 30.
介绍了 Transformer 架构,其核心的“注意力机制”是现代所有强大 LLM(包括驱动 OpenHands 的模型)的技术基石,理解它有助于理解 AI “思考”的底层原理。 -
Brooks, F. P. (1987). No Silver Bullet: Essence and Accidents of Software Engineering. Computer, 20(4), 10-19.
软件工程领域的经典文章,论述了软件开发的内在复杂性。OpenHands 等工具正是为了解决其中的“偶然复杂性”(accidental complexity),从而让开发者能专注于“本质复杂性”(essential complexity)。 -
GitHub, Inc. (2024). GitHub Actions Documentation. Retrieved from https://docs.github.com/en/actions
OpenHands 的自动化工作流深度依赖于 GitHub Actions。理解 Actions 的工作原理、语法和生态系统,是深入使用和定制 OpenHands 的前提。