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 这类模型真正值得关注的地方,也正是它把“写代码”推进到了“能迭代修代码”的阶段。