Ornith-1 开源:把强化学习用在编码 Agent 的“自我修正”上

2026-06-30 23 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

DeepReinforce 团队开源了 Ornith-1,一套面向编码 Agent 任务的推理模型,采用 MIT 许可,并提供 9B、31B、35B MoE、397B MoE 四个规格。根据摘要信息,它不是从零训练出来的模型,而是在 Gemma 4 和 Qwen 3.5 这类基座上做 RL post-training,目标是让模型在编码任务里学会更像工程师一样反复检查、修改和收敛。

最醒目的数字是 SWE-bench 82.4%。对开发者来说,这个数字的意义不只是“模型会写代码”,而是它在真实仓库、真实 issue、真实测试约束下,能完成更长链路的软件修复任务。

这类编码 Agent 和普通代码模型差在哪

传统代码补全模型更像一个强大的 autocomplete:你给函数签名、注释、上下文,它补出一段代码。编码 Agent 的目标更重:它需要读仓库、定位问题、修改多个文件、运行测试、根据失败信息继续修。

Ornith-1 的摘要里提到一个关键方向:训练中不仅生成代码方案,还让模型学习“自改进”。这意味着训练信号不只奖励一次性答对,还可能鼓励模型在多轮尝试中识别错误、调整策略、重新验证。

可以把它理解成两种能力的组合:

  • 推理能力:理解 issue、调用栈、测试失败和代码结构之间的关系。
  • 行动能力:提出补丁、运行验证、根据反馈继续迭代。

这也是为什么 SWE-bench 适合衡量编码 Agent。它考的不是“写一个排序函数”,而是在现有项目中修一个 bug。

为什么 RL post-training 值得关注

Ornith-1 的路线不是从零训练,而是在已有基座模型上继续强化。这个选择很工程化:基座模型已经有通用语言、代码和推理能力,后训练阶段把注意力集中到“编码任务怎么做得更稳”。

对 Agent 场景来说,RL post-training 的价值通常体现在几个细节上:

  • 模型是否愿意先读文件,而不是凭空猜测。
  • 模型是否能根据测试失败信息调整补丁。
  • 模型是否能避免无关重构,保持变更最小。
  • 模型是否能在长上下文里记住问题约束。

这些能力很难只靠普通监督微调打磨出来。真实编码任务的反馈往往不是一句“正确/错误”,而是测试日志、异常栈、lint 报错、接口行为差异。强化学习可以把这些反馈纳入训练循环,让模型逐渐学会更可靠的开发流程。

可以这样实践:给编码 Agent 套一个最小验证循环

下面的示例不是 Ornith-1 官方接口,而是一个可以改造的最小 Agent 工作流。假设你已经有一个兼容 OpenAI Chat Completions 风格的模型服务,可以把 MODEL_NAME 换成 Ornith-1 的实际部署名称,把 BASE_URL 换成你的推理服务地址。

运行前准备:

pip install openai
export OPENAI_API_KEY="your-api-key"
export BASE_URL="http://localhost:8000/v1"
export MODEL_NAME="ornith-1-31b"

保存为 agent_patch_loop.py

import os
import subprocess
from pathlib import Path
from openai import OpenAI

client = OpenAI(
    api_key=os.environ.get("OPENAI_API_KEY", "local-key"),
    base_url=os.environ.get("BASE_URL", "http://localhost:8000/v1"),
)

MODEL = os.environ.get("MODEL_NAME", "ornith-1-31b")


def run(cmd: list[str]) -> str:
    result = subprocess.run(cmd, text=True, capture_output=True)
    return f"$ {' '.join(cmd)}\nexit={result.returncode}\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"


def ask_agent(issue: str, tree: str, test_log: str) -> str:
    prompt = f"""
你是一个谨慎的编码 Agent。请基于仓库文件列表和测试日志,输出一个 unified diff 补丁。
要求:
1. 只修改必要文件。
2. 不做无关重构。
3. 如果信息不足,说明需要查看哪些文件。
4. 输出必须是可应用的 diff。

Issue:
{issue}

Repository files:
{tree}

Test log:
{test_log}
"""
    response = client.chat.completions.create(
        model=MODEL,
        messages=[{"role": "user", "content": prompt}],
        temperature=0.2,
    )
    return response.choices[0].message.content or ""


def main() -> None:
    issue = Path("ISSUE.md").read_text(encoding="utf-8")
    tree = run(["git", "ls-files"])
    test_log = run(["pytest", "-q"])

    patch = ask_agent(issue, tree, test_log)
    Path("agent.patch").write_text(patch, encoding="utf-8")
    print("Patch written to agent.patch")
    print("Review it, then apply with: git apply agent.patch")


if __name__ == "__main__":
    main()

这个脚本故意没有自动 git apply。原因很简单:编码 Agent 越强,越应该给它清晰边界。让模型生成补丁,让人或 CI 决定是否应用,是更安全的第一步。

如果你想把它接进 CI,可以先做成“建议补丁”模式:

python agent_patch_loop.py
cat agent.patch
git apply --check agent.patch

git apply --check 能快速验证补丁格式和上下文是否匹配,但它不代表逻辑正确。真正的门槛仍然是测试、代码审查和回归验证。

选择 9B、31B、MoE 时看什么

Ornith-1 提供多个规格,这对落地很关键。不同团队的瓶颈不一样:有人缺 GPU,有人缺延迟预算,有人需要尽量高的修复率。

可以按这几个问题做选择:

  • 本地开发助手:优先考虑 9B 或 31B,重点是响应速度、部署成本和隐私边界。
  • CI 修复建议:可以尝试更大的 MoE 规格,但要控制调用频率,避免每个失败任务都烧大量推理成本。
  • 批量 issue 分析:大模型适合做复杂定位,小模型适合做快速分类和候选补丁草稿。
  • 安全敏感仓库:即使用开源模型,也要确认权重部署位置、日志保留策略和代码访问权限。

MIT 许可降低了试用门槛,但模型许可不等于生产风险消失。编码 Agent 会接触源码、配置、测试日志,甚至可能看到密钥形态的字符串。接入前要先设计隔离策略。

落地建议:先让它修小问题

不要一上来就让编码 Agent 改核心交易链路或大规模重构。更稳妥的路径是从低风险、高反馈的任务开始:

  • 修复单元测试失败。
  • 补齐边界条件。
  • 更新小范围 API 调用。
  • 处理 lint 或类型错误。
  • 为已知 bug 生成候选补丁。

衡量它是否值得引入,也别只看 benchmark。建议记录三类指标:补丁通过率、人工 review 时间、错误补丁回滚成本。SWE-bench 的高分说明 Ornith-1 在真实软件修复任务上很有竞争力,但每个团队的仓库结构、测试质量和工程约束都不同。

好的编码 Agent 不应该替代工程流程,而应该嵌进工程流程:读代码、提补丁、跑验证、等待审查。Ornith-1 这类模型真正值得关注的地方,也正是它把“写代码”推进到了“能迭代修代码”的阶段。


相关推荐