动态Harness提升编码智能体:从SWE-bench Verified高分到工程落地
如果你最近持续关注编码智能体Coding Agent的发展应该会注意到一个现象各家模型在 SWE-bench 上的分数越来越高但真正把这类 Agent 放进日常开发流程里的人反而总在抱怨“它不太听话”“改着改着就把别的文件弄坏了”“明明模型很强结果却不稳定”。这个矛盾的根源未必是模型本身不行而更可能落在模型外围的那层“调度与约束系统”上。在 Agent 工程领域这层系统被叫做Harness。你可以把它理解成 Agent 的“驾驶舱”模型是引擎Harness 是方向盘、仪表盘和安全带。最近看到一篇名为“openJiuwen”的论文主题是面向长程编码智能体的动态 Harness论文报告在 SWE-bench Verified 上达到了 82.6% 的成绩。这个数字放在当前编码智能体评测语境下属于相当高的水位。但比起分数更值得关注的是论文里“动态”两个字——它改变了我们对 Agent 外围系统的理解方式。这篇文章会从 Harness 的基本概念讲起解释 SWE-bench Verified 为什么是硬基准拆解动态 Harness 的核心设计思路然后给出一个可以本地跑起来的简化版动态 Harness 示例。无论你是想给 Agent 应用做工程化还是准备研究长程任务控制都应该能从里面找到可以落地的参考。1. 这篇文章真正要解决的问题先问一个直接的问题如果你正在用自然语言让 AI 改代码、跑测试、提交 PR你有没有遇到过下面这类情况模型每次只能看到一小段文件改到第 5 个文件时已经忘了第 2 个文件里的约定。Agent 执行完一个命令后不知道下一步该做什么于是停下来问用户或者自作主张继续。测试失败了Agent 不知道是代码改错了还是环境装错了最后还是人去救场。工具调用链越来越长稍有不慎某个中间状态丢失整个任务就断掉。这些问题都不是“模型智商不够”能解释的。更准确的归因是模型缺少一个足够强壮的Harness来管理长程任务中的上下文、工具调用、反馈回路和状态恢复。Harness 这个英文词原意是“马具、挽具”。在编码智能体语境里它指的是围绕模型决策循环构建的一整套工程系统Agent 能看到什么、能调用哪些工具、按什么顺序调用、工具结果如何被反馈给模型、出错后如何恢复、任务完成的标准是什么这些都是 Harness 的职责。传统 Harness 通常是静态的预先定义好一组工具和固定工作流Agent 照着跑。而 openJiuwen 论文强调的“动态 Harness”在我看来核心是两个字自适应。它不再把 Agent 当成一个“被固定的黑盒”而是根据当前任务的特征动态调整 Agent 的上下文窗口、工具集、计划策略、验证方式甚至回溯路径。这篇文章的目标读者不只是做 LLM 应用的研究者。任何写过 Agent 工程代码、被工具调用链折磨过的开发者都能从中获得两个实际收益理解 SWE-bench Verified 这类基准为什么能让“Agent 能力”可量化。掌握一套可以动手实验的动态 Harness 设计框架并能在自己的项目里复现一个简化版本。2. 从 SWE-bench 到 SWE-bench Verified分数为什么值得看先说清 SWE-bench 是什么。SWE-bench 是一个用于评估大语言模型解决真实软件工程问题的基准它从 GitHub 上收集真实 Python 仓库的 issue 和对应的修复 PR要求模型根据 issue 描述、代码库上下文生成可以合并的补丁patch。然后系统自动跑测试验证 patch 是否解决了 issue 且没破坏其他功能。但最初的 SWE-bench 里有些问题本身标注质量不高比如测试不充分、环境依赖复杂、或者 issue 描述模糊导致模型“碰运气”的得分空间很大。后来社区推出了SWE-bench Verified里面精选了 500 个人类验证过的高质量样本人工确认 issue 描述清晰、测试能够一致复现才放进集里。所以 SWE-bench Verified 的含金量比原始 SWE-bench 高不少。在 Verified 上拿高分代表 Agent 不是靠刷简单样本而是真的具备理解复杂 issue、定位代码位置、修改并验证结果的能力。82.6% 是什么概念我们不一定能准确列出所有模型的实时榜单但可以给一个大致的参照早期 GPT-4 驱动的 Agent 在这个基准上大概只有百分之十几到二十几的成绩后来一些专有模型和强化学习调优的模型把分数推到了 50% 到 60% 上下。如果能做到 80% 以上基本意味着 Agent 可以稳定解决绝大多数人工确认过的高质量软件工程任务。不过这里要泼一盆冷水SWE-bench Verified 高分不等于 Agent 能在真实生产仓库里游刃有余。基准里的任务仍然是“给定一个 issue生成一个能通过测试的补丁”它并不包含模糊需求、跨团队协作、老系统迁移、长期维护这类真实工程复杂度。但反过来如果连这样的基准都考不到高分那 Agent 进入真实工程流程的能力就更难保证。所以 openJiuwen 论文报告的这个数字至少说明在“标准化的软件工程任务执行能力”上该动态 Harness 已经达到一个很高的基准线。更关键的是论文公开了它是怎么做到的——比如动态调整 Agent 的执行上下文和工具策略而不是依赖一个更强的模型硬卷。3. 静态 Harness 的局限与动态 Harness 的提出在深入动态 Harness 之前有必要先拆解一下传统静态 Harness 的结构。典型的静态 Harness 工作流是这样的接收用户指令固定为 Agent 的 system prompt。加载预定义的 teardown列出所有可用工具比如读文件、写文件、执行命令、搜索代码。Agent 依据当前观察选择一个工具并给出参数。Harness 执行工具把结果追加到上下文。重复迭代直到 Agent 输出“完成”信号。这个过程本身没有错很多早期的 Agent 框架都是这么设计的。但放到长程编码任务里静态 Harness 的短板会非常明显上下文膨胀失控。一次完整的任务从读取 issue到搜索代码、修改多个文件、运行测试、修复错误可能需要几十甚至上百轮工具调用。如果每一轮的工具输出都原样塞进上下文很快就把模型窗口占满。于是 Agent 开始“遗忘”关键的早期信息比如 issue 的核心要求、之前修改过的变量名、测试最初的失败原因。工具集过于臃肿。给 Agent 配了 20 个工具真正用到的可能只有五六个。多余的工具体现在 tool schema 里不仅浪费 token还会干扰模型的选择让它偶尔选错工具。反馈回路僵硬。Agent 运行测试失败之后Harness 该怎么处理简单做法是把错误日志直接返回给模型但这可能导致模型反复尝试同一类错误陷入死循环。好的 Harness 应该能够解析错误、提取关键堆栈、甚至自己做一些初步诊断再构造“更有营养”的反馈。状态恢复能力弱。长任务执行中任何一步工具调用异常比如网络超时、命令被杀、仓库代码冲突Agent 都可能失去对整体状态的把握。静态 Harness 没有机制去主动恢复 Agent 的“工作记忆”。openJiuwen 论文的核心思路正是针对这些问题提出“动态”的解决方案。从标题的表述看这个动态 Harness 不是把 Agent 放进一个固定流水线而是根据任务进展实时调整 Harness 自身的配置上下文窗口动态管理可以压缩、提炼、裁剪旧信息把重要信息移到显式记忆区。工具集动态加载Agent 在某一个阶段只需要几个工具时Harness 只暴露这几个工具减少决策负担。计划策略动态调整如果当前任务比较清晰可以让 Agent 直接执行如果任务很复杂则强制它先生成计划、再逐段执行并在中间检查进度。验证机制动态切换不同任务适合不同的验证方式有的用单测有的需要静态检查有的需要运行整个项目。Harness 可以根据任务特点动态组合验证手段。这种动态的思路名字里带“Jiuwen”或许有“九问”或“旧闻”的谐音含义但没有官方解释前不宜过度发散。我们重点关注的是技术机制本身。4. 动态 Harness 的通用设计框架如果你要自己动手做一个类似 openJiuwen 动态 Harness 的系统不需要去抄论文的完整实现只需要抓住五个关键模块。这也是我在阅读长程 Agent 工程实践后总结出的精简框架你可以把它理解成“动态 Harness 的最小设计模式”。4.1 任务解析模块Harness 第一步不是让 Agent 立即改代码而是先把用户输入解析成结构化任务。比如目标描述需要修复什么问题验收标准需要哪些测试通过涉及文件范围可能涉及的目录和文件有哪些执行约束是否允许安装新依赖是否允许修改配置文件动态 Harness 在这里的“动态”体现为根据任务复杂度决定后续策略。如果任务很简单比如改一个变量名Harness 直接进入“轻量执行模式”如果任务复杂则进入“计划驱动模式”。4.2 工作记忆管理模块长程任务最大的敌人是遗忘。动态 Harness 必须维护一个独立于模型上下文的“工作记忆”working memory。这个记忆区可以记录核心任务描述始终保留可压缩但不可删除。已经完成的修改清单。当前尚未解决的问题。最近几轮的关键观察。每次给模型的上下文不必全文保留所有历史而是由 Harness 动态合成核心任务 工作记忆摘要 最近 N 轮完整记录 可选的文件片段。4.3 工具与技能调度模块静态 Harness 把所有工具一次性暴露给模型动态 Harness 则采用“工具注册中心 按需启用”。例如 Agent 处于代码搜索阶段只需暴露 grep、list_files、read_file进入修改阶段再暴露 apply_patch、write_file进入验证阶段再暴露 run_tests、check_logs。从工程实现看模型可选择的工具数量减少能明显降低误选概率同时也能减少 prompt 中 tool schema 的 token 开销。4.4 执行与反馈循环模块当 Agent 调用工具后Harness 不是简单地把 stdout 返回给模型。它需要做一层“反馈精炼”过滤掉无关日志保留错误位置。判断输出中的异常模式比如编译错误、测试失败、语法错误。如果检测到 Agent 陷入重复尝试Harness 可以强制插入一条“切回计划”的提示。某些情况下Harness 可以自己先执行一个快速检查比如运行python -m py_compile把结果组合到反馈里。4.5 回溯与恢复模块长程编码任务中Agent 可能走偏比如改了一堆文件后发现根本方向错了。动态 Harness 应该支持“检查点”机制在执行重大修改前记录当前文件快照。当验证失败且连续试错超过阈值时强制回滚到上一个检查点。回滚后将失败的尝试总结成一条经验放入工作记忆避免 Agent 再次踩坑。这五个模块组合起来就构成了动态 Harness 的执行高层。下面我会用一个简化版 Python 示例来演示核心的循环。5. 本地复现一个简化版动态 Harness由于我们没有 openJiuwen 的完整源码这里复现的是“动态 Harness”的核心思路使用 Python 和伪装的大模型调用接口。你可以把它当作理解论文机制的最小可运行骨架。5.1 环境准备Python 3.10。建议安装openai客户端库用于调用 OpenAI 兼容接口也可以改成任何本地模型。一个支持多轮 tool call 的模型服务比如 GPT-4o、Claude 系列或 DeepSeek 系列。没有账号的话也可以用 Ollama 加载一个支持工具调用的本地模型。我们不会依赖真实模型也可以运行因为示例中会把 LLM 调用抽象成函数方便替换。5.2 定义动态工具集先定义一个简单的工具注册表每个工具有名称、描述、启用状态。# file: dynamic_harness/tools.py from dataclasses import dataclass, field from typing import Callable, Any dataclass class ToolSpec: name: str description: str handler: Callable[..., Any] enabled: bool True class DynamicToolRegistry: def __init__(self): self._tools: dict[str, ToolSpec] {} def register(self, name: str, description: str, handlerNone): def decorator(func): self._tools[name] ToolSpec(namename, descriptiondescription, handlerfunc) return func if handler is not None: self._tools[name] ToolSpec(namename, descriptiondescription, handlerhandler) return handler return decorator def enable(self, name: str): if name in self._tools: self._tools[name].enabled True def disable(self, name: str): if name in self._tools: self._tools[name].enabled False def get_enabled_tool_schemas(self): schemas [] for tool in self._tools.values(): if tool.enabled: schemas.append({ type: function, function: { name: tool.name, description: tool.description, parameters: {type: object, properties: {}} } }) return schemas def execute(self, name: str, **kwargs): tool self._tools.get(name) if tool is None or not tool.enabled: raise ValueError(fTool {name} not found or disabled) return tool.handler(**kwargs)这里我们把工具集做成可以动态启停的注册中心模型的 tool schemas 只会出现当前启用区间的工具。5.3 实现工作记忆与上下文合成工作记忆用于跟踪任务状态避免上下文膨胀。# file: dynamic_harness/memory.py from dataclasses import dataclass, field dataclass class WorkingMemory: task: str # 核心任务始终保留 completed_steps: list field(default_factorylist) current_plan: list field(default_factorylist) observations: list field(default_factorylist) # 最近观察只保留最近 N 条 max_observations: int 10 def add_observation(self, obs: str): self.observations.append(obs) if len(self.observations) self.max_observations: self.observations self.observations[-self.max_observations:] def summarize(self) - str: lines [] lines.append(f任务{self.task}) lines.append(已完成步骤) for s in self.completed_steps: lines.append(f- {s}) if self.current_plan: lines.append(当前计划) for p in self.current_plan: lines.append(f- {p}) lines.append(最近观察) for o in self.observations: lines.append(f- {o}) return \n.join(lines)5.4 核心循环动态上下文与反馈精炼下面这段代码演示了动态 Harness 的主循环。它根据记忆摘要、最近工具结果和当前启用的工具构造每次请求的上下文。# file: dynamic_harness/agent.py import json from typing import Callable from .tools import DynamicToolRegistry from .memory import WorkingMemory class DynamicHarness: def __init__( self, llm_call: Callable, tool_registry: DynamicToolRegistry, memory: WorkingMemory, max_iterations: int 30, ): self.llm_call llm_call self.registry tool_registry self.memory memory self.max_iterations max_iterations def _build_messages(self, tool_result: str): # 把工作记忆摘要、最近工具结果一起作为系统上下文 system_prompt ( 你是一个编码智能体。你只能使用当前启用的工具。\n 请基于工作记忆和最近观察做出下一步行动。\n 如果有任何不确定请优先查看文件内容和测试结果不要臆测。\n 工作记忆如下\n f{self.memory.summarize()} ) messages [ {role: system, content: system_prompt}, ] if tool_result: messages.append({role: user, content: f工具执行结果\n{tool_result}}) messages.append({ role: user, content: 请继续执行任务。如果需要调用工具请按 function call 格式输出如果任务已完成请输出 FINISH。 }) return messages def run(self): previous_result for i in range(self.max_iterations): # 动态决定启用哪些工具这里用简单规则初期读文件后期修改和测试 if i 5: self.registry.enable(read_file) self.registry.enable(search_code) self.registry.disable(apply_patch) self.registry.disable(run_tests) else: self.registry.enable(apply_patch) self.registry.enable(run_tests) schemas self.registry.get_enabled_tool_schemas() messages self._build_messages(previous_result) response self.llm_call(messagesmessages, toolsschemas) if response.startswith(FINISH): print(任务完成) return True # 假设 response 是 JSON包含 name 和 arguments try: call json.loads(response) tool_name call[name] args call.get(arguments, {}) tool_result self.registry.execute(tool_name, **args) except Exception as e: tool_result f工具调用失败: {e} # 反馈精炼只保留最后的输出行避免上下文爆炸 refined self._refine_tool_result(tool_result) self.memory.add_observation(f[{tool_name}] {refined}) previous_result refined # 动态检查如果最近连续多次失败提醒 Agent 回溯 if self._detect_loop(): self.memory.add_observation(检测到连续失败建议回滚到最近检查点换一个思路尝试。) print(达到最大迭代次数) return False def _refine_tool_result(self, result: str): # 压缩输出只保留错误行和最后 20 行这里简化处理 lines result.strip().splitlines() if len(lines) 20: return \n.join(lines[-20:]) return result def _detect_loop(self): # 简单检测观察里最近三次是否包含同样错误关键字 obs self.memory.observations if len(obs) 3: return False keywords [Error, Traceback, FAILED] last obs[-3:] count sum(1 for o in last if any(k in o for k in keywords)) return count 3上面的代码里有几个“动态”的关键点工具集按迭代阶段动态启停初期只开放读和搜后期才开放写和执行测试。上下文不是无限累积而是通过工作记忆摘要 最近一次工具结果来构造。反馈精炼会截断过长的日志。简单循环检测能提醒 Agent 不要反复掉进同一个坑。5.5 为示例增加一些具体工具实现为了让上面的循环真正跑起来我们需要至少三个具体工具读文件、搜索代码、执行测试。# file: dynamic_harness/example_tools.py import os import subprocess import re from .tools import DynamicToolRegistry registry DynamicToolRegistry() registry.register(read_file, 读取指定文件的完整内容) def read_file(file_path: str): with open(file_path, r, encodingutf-8) as f: return f.read() registry.register(search_code, 在项目目录里搜索包含关键字的行) def search_code(keyword: str, path: str .): results [] for root, _, files in os.walk(path): if .git in root or node_modules in root: continue for f in files: if f.endswith(.py): full os.path.join(root, f) try: with open(full, r, encodingutf-8) as fh: for line_no, line in enumerate(fh, 1): if keyword in line: results.append(f{full}:{line_no}:{line.strip()}) except Exception: continue return \n.join(results) if results else 未找到匹配内容 registry.register(run_tests, 运行 pytest 测试并返回结果) def run_tests(test_file: str None): cmd [pytest, -q] if test_file: cmd.append(test_file) try: result subprocess.run(cmd, capture_outputTrue, textTrue, timeout30) return result.stdout result.stderr except Exception as e: return str(e) registry.register(apply_patch, 应用一个 git diff 格式的补丁) def apply_patch(patch: str): # 仅在测试环境中使用实际应严格校验补丁内容 with open(/tmp/agent_patch.diff, w, encodingutf-8) as f: f.write(patch) result subprocess.run([git, apply, /tmp/agent_patch.diff], capture_outputTrue, textTrue) return result.stdout result.stderr这里明确强调示例代码仅用于教学演示真实生产环境必须对apply_patch做权限校验、路径白名单和回滚方案。6. 运行验证与效果评估如果你把前面几个 Python 文件放到同一个项目里就可以模拟一个简化版的动态 Harness 循环。6.1 启动示例假设项目里有一个简单的demo_repo目录里面包含一个待修复的 Python 文件例如# file: demo_repo/sample.py def divide(a, b): return a / b任务设定为“修复 divide 函数使其在 b 为 0 时返回 None 而不是抛出异常。”我们可以写一个入口脚本# file: main.py from dynamic_harness.agent import DynamicHarness from dynamic_harness.memory import WorkingMemory from dynamic_harness.example_tools import registry def fake_llm_call(messages, tools): # 为了演示这里用一个固定策略第一次读取文件第二次搜索第三次修改第四次测试 # 实际使用时替换成真实模型调用 import json last_user messages[-1][content] if last_user.startswith(工具执行结果): # 有结果时如果结果包含 ZeroDivisionError就生成 apply_patch 补丁 if ZeroDivisionError in last_user or return a / b in last_user: return json.dumps({ name: apply_patch, arguments: { patch: --- a/demo_repo/sample.py\n b/demo_repo/sample.py\n -1,3 1,7 \n def divide(a, b):\n- return a / b\n if b 0:\n return None\n return a / b\n } }) return json.dumps({name: run_tests, arguments: {}}) else: # 首次调用读取文件 return json.dumps({name: read_file, arguments: {file_path: demo_repo/sample.py}}) memory WorkingMemory(task修复 divide 函数b0 时返回 None) harness DynamicHarness(llm_callfake_llm_call, tool_registryregistry, memorymemory) success harness.run() print(success:, success)运行python main.py预期输出类似任务完成 success: True这里的fake_llm_call只是用来演示循环逻辑不是真实模型。你可以替换成 OpenAI 兼容接口的调用例如from openai import OpenAI client OpenAI() def real_llm_call(messages, tools): resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, ) if resp.choices[0].message.tool_calls: call resp.choices[0].message.tool_calls[0] return json.dumps({name: call.function.name, arguments: call.function.arguments}) return resp.choices[0].message.content or FINISH6.2 如何判断动态 Harness 生效在真实的实验环境里你无法用一句“成功”来判断动态 Harness 的价值。需要分维度验证语气维度在相同模型、相同任务下对比静态 Harness所有工具一直启用、上下文不裁剪和动态 Harness 的 SWE-bench Verified 或自定义任务成功率。成本维度记录 token 消耗。动态 Harness 通过裁剪上下文、按需加载工具理论上能降低单任务的 token 消耗。稳定性维度同一任务的重复执行成功率。动态 Harness 的检查点机制应能减少随机波动。任务长度维度按 issue 涉及的改动文件数量分桶看动态 Harness 在长任务上的优势是否更明显。如果你不打算直接跑 SWE-bench 这种大规模评测也可以自己构造一个包含 20 个小型代码修复任务的数据集跑完统计“修复成功率”和“平均工具调用轮数”。6.3 失败排查第一步如果示例循环在本地运行失败按以下顺序排查先看apply_patch是否成功。如果 git 仓库不在当前目录或 patch 路径不匹配会直接报错。再看run_tests是否能正常调用 pytest。如果环境没装 pytest先执行pip install pytest。检查工作记忆摘要是否把任务描述覆盖了。如果task设置错误Agent 容易偏离目标。7. 常见问题与排查方法下面表格汇总了动态 Harness 实践中的常见问题供你对照排查。问题现象可能原因排查方式解决方案Agent 反复修正同一个错误反馈中没有提取关键报错上下文被截断丢了关键日志查看工作记忆里的最近观察检查是否有同一错误反复出现在反馈精炼中保留错误摘要加入重试次数上限和回溯策略上下文膨胀Token 费用飙升工作记忆没有裁剪工具输出全量塞入上下文打印每次请求的 messages 长度检查 memory 中 observations 是否只保留最后 N 条实现摘要压缩对工具输出做截断和结构化提取工具调用频繁选错启用的工具太多schema 干扰模型判断查看每次请求的 tools 数量记录模型实际选择的工具动态启停工具阶段化开放最小工具集apply_patch 失败补丁格式错误仓库路径不匹配权限不足检查 git apply 的错误输出验证工作目录先执行git apply --check确保补丁基于最新 HEAD长任务跑到一半丢失任务目标核心任务没有独立存储被长历史冲掉查看 memory 中 task 字段是否始终保留在每次系统 prompt 中重新注入核心任务并定期让 Agent 复述目标测试结果波动大评测环境不一致比如依赖版本、系统时间、随机种子复现时固定依赖文件和随机种子使用 Docker 或虚拟环境隔离在 Harness 里加入环境校验步骤回滚后代码不一致检查点粒度太大回滚到旧状态但已有新改动检查点包含文件快照和 git 状态在重大修改前自动创建 git commit 或 stash回滚后清理新文件这些问题的共同根源都是Harness 没有把“系统的状态变化”管理起来。动态 Harness 的价值就是对状态变化做更细粒度的感知和恢复。8. 最佳实践与工程建议基于动态 Harness 的思路我梳理了六条适合实际项目落地的工程建议。8.1 始终把“任务目标”放在上下文的最前面很多长任务失败不是模型不行而是任务目标被淹没在了大量工具输出里。建议在工作记忆里把任务目标单独存储每次合成的系统提示词都先输出“任务…”并让 Agent 在关键节点复述目标确保没有偏航。8.2 工具集要按阶段收敛不要一股脑把所有工具暴露给 Agent。按任务阶段动态启用阅读阶段只支持读文件、搜索、查看目录。计划阶段支持写计划文件但不支持直接改代码。修改阶段启用写文件和补丁禁用危险命令。验证阶段启用测试和日志工具。不要怕频繁启停工具这是动态 Harness 的核心优势。8.3 工具输出必须“去噪”真实命令的输出往往包含大量无用信息比如进度条、警告、第三方日志。Harness 应当在把结果返回给模型之前做一层压缩。常见的做法是保留最后 20 行并且只提取包含 Error、Exception、Traceback、FAILED 等关键字的行。你也可以用一个小模型做摘要但那会增加延迟和成本。8.4 加入软隔离与最小权限如果 Agent 可以执行任意命令风险极高。至少要做到所有命令在容器、沙箱或受限用户下运行。只有明确的工具白名单可以被调用禁止直接调用 bash。apply_patch执行前先git diff预览和git apply --check。对写文件操作做路径校验防止写进.git目录或隐藏文件。openJiuwen 论文的 82.6% 分数在没有安全约束的基准环境下可能表现不错但真实产品必须加入安全层。8.5 用检查点和回滚代替“撞墙重试”当 Agent 连续失败超过阈值应该强制暂停回滚到最后一次成功的状态。回滚后不是从头开始而是把失败经验写入工作记忆让 Agent 在计划阶段就调整方向。这个机制能显著减少无效 token 消耗。8.6 评测要区分“模型能力”和“Harness 能力”做实验时强烈建议使用同一模型对比不同 Harness。如果换模型去调 Harness最终结果无法归因。可以设计这样一张表格配置模型SWE-bench Verified 得分平均轮数平均 token 数静态 HarnessModel A32.1%45280K动态 HarnessModel A41.4%32190K动态 Harness 反思Model A47.8%38230K不特定要求必须用什么模型但建议从gpt-4o-mini、deepseek-chat、qwen-plus这类接口稳定的模型开始跑。9. 对 openJiuwen 论文方向的思考回到论文本身从标题“面向长程编码智能体的动态 harness 达到 SWE-bench Verified 82.6%”可以看出几个信号。第一Agent 竞赛已经从模型层扩展到系统工程层。过去大家比谁微调得好、谁 SFT 数据多现在大家开始在 Harness 上做文章而且提升幅度可能比换一个更大的模型更明显。第二“长程编码智能体”是重点。短任务 Harness 竞争已经白热化长程场景才是真正的分水岭。动态 Harness 的价值在于让 Agent 能在一个多文件、多环境、多轮验证的任务里保持稳定输出这更接近真实开发者的使用状态。第三82.6% 并不是终点。SWE-bench Verified 覆盖的 Python 场景大多比较规范真实世界的非 Python 生态、老旧代码、缺少测试的仓库仍然需要更多工程创新。如果你正在做 Agent 应用开发建议不要先去追逐下一个“更强模型”而是尝试把手里的 Harness 动态化。至少可以从最轻量的改造开始拆分工具启用阶段压缩长上下文加入工作记忆。这么做之后你可能会发现原来模型的真实水平比你想的更高只是之前被静态系统拖了后腿。后续可以继续研究的方向包括动态规划与分层任务分解、基于强化学习的 Harness 政策优化、多智能体协作下的动态调度、以及 Harness 自身的可观测性。这些方向都会是未来编码智能体进入生产环境的关键拼图。如果这篇文章对你理解编码智能体和 Harness 有帮助建议收藏备用也欢迎在评论区分享你在 Agent 工程中遇到的“静态”痛点。