AI编程工程化实战:手写简易Harness让智能体安全可控

发布时间:2026/10/6 17:48:42
AI编程工程化实战:手写简易Harness让智能体安全可控 1. Harness Engineering 是什么先用大白话建立认知1.1 从一次智能体失控事故说起为什么需要安全缰绳先讲一个我自己的真实经历。有段时间我在跑一个智能体项目让它自动改代码、跑测试、提交 PR。刚开始一切很顺利模型很听话任务完成率看着也不错。直到有一天它在一个死循环里反复调用文件写入工具把同一个临时文件写了几百遍磁盘占满了还把原有的一个配置文件的编码改坏了。更离谱的是日志里显示它以为自己已经执行了测试——实际上根本没有任何测试进程被拉起来。那次事故之后我意识到真正的问题不在于模型能力不够而在于流程失控。就像一匹好马你骑着它跑起来很爽但如果没有缰绳和鞍具它一旦惊了你根本拉不住。Harness Engineering缰绳工程就是给智能体套上这套控制装备的工程实践。它解决的核心问题是当你把一个足够聪明的模型放进真实的生产代码库里如何保证它在限定范围内做正确的事并且出问题的时候你能及时拉停、看得见过程、能复现结果。这也就是所谓的AI 编程工程化的本质单次生成代码的能力只是基础稳定地、可控地、可评估地把智能体嵌进研发流程才是能落地的关键。这篇教程不绕弯子直接讲透 Harness 是什么、核心模块怎么设计再用一个真实的代码库重构小项目带你从零手写一套可运行的简易 Harness。适合刚接触智能体开发、想搞懂AI 编程到底怎么工程化落地的开发者也适合已经在调 agent、但总觉得缺了点安全感的人。1.2 一句话定义 传统软件工程的类比它对应的到底是什么用一个生活化类比你去骑马马是你的模型马术师让你做的那些事前准备——戴马嚼子、系肚带、调整马镫长度、确认活动范围——就是 Harness。它不负责教你骑马的技术它负责让马跑起来可控、让骑手安全、让意外发生时有办法处理。对应到 AI 编程领域Harness 指的是围绕智能体Agent构建的控制、管理、观测与评估体系。它不是一个模型也不是一个接口调用而是一层工程外壳。这层外壳做五件事管理模型能看到的上下文Context决定它知道什么管理模型能调用的工具Tools决定它能做什么管理任务的执行流程Workflow/Orchestration决定它按什么节奏做管理全过程日志与状态追踪Observability决定你事后能不能复盘管理结果的验收标准Evaluation决定你敢不敢让它继续跑。如果你熟悉传统软件工程其实已经见过这套结构的影子。智能体的 Harness 约等于编译器 构建系统 测试框架 监控告警四者的杂糅。编译器管语义合法性构建系统管把源文件可靠地变成产物测试框架管验证行为是否符合预期监控告警管运行期健康度。到了智能体时代这四个角色被统一收拢到一层里因为你面对的是一个会自主决策的执行者它的每一步都可能偏离预期所以必须把校验和反馈做到运行时里。1.3 AI 编程工程化与 Harness 的关系不只是脚手架这里有个常见的误解很多人把 Harness 和Agent 框架工作流引擎混为一谈。比如 LangChain、CrewAI、LangGraph 这些框架它们解决的是怎么编排调用的问题属于 Harness 的一个子集——流程编排模块。但一套完整的 Harness 远不止这个范围。我做这个对照表的时候特意参考了一次团队内部的技术评审我们发现项目失败的原因往往不在编排框架选型上而在于上下文管理和评估机制的缺失。所以先把这个边界捋清楚维度框架/脚手架Harness Engineering关注点怎么把 API 串起来怎么让系统整体可控可交付核心模块节点、边、状态机上下文裁剪、工具白名单、运行监控、质量评估失败时表现流程编排报错任务跑完但结果不可用更隐蔽交付物一个能跑的流程一套能评估的交付体系简单说脚手架回答怎么搭Harness 回答怎么放心。后者要求你在设计智能体系统的第一天就同时考虑上下文预算、工具边界、失败回滚、日志追踪和验收标准。不是功能跑通就叫工程化了而是跑通了之后仍然可解释、可回退、可改进这才叫工程化。2. 一次搞懂核心设计Harness 系统拆解的五大支柱2.1 上下文管理给智能体一份精准地图而不是整座山上下文管理是 Harness 里最容易被忽略、却最影响效果的一环。很多人在第一次做智能体时想的是把整个代码库都喂给模型让它全知全能。这个方案试过的都知道效果差还费钱。原因不复杂现代代码库动辄几十万行文件全部塞进上下文里一是 Token 预算直接爆炸二是无关信息会成为噪音让模型抓不住重点。好比你去一个陌生城市旅游给你一整本全国地图册你反而更不容易找到去市中心的路给你一张标了地铁线和地标的城区图你五分钟就到了。所以上下文管理的核心方法论是按需构建。任务目标是什么先拆出和这个目标相关的信息相关源码文件、对应的模块结构、测试用例、依赖关系、近期改动记录、项目约定风格。其余一律不进上下文。这个信息筛选动作可以靠关键词匹配、文件依赖分析、代码语义检索Code Retrieval、Git 变更记录过滤等方式实现不一定要上重型的 RAG 系统轻量级的检索往往就够用。我自己的实践是给上下文分三层任务层当前目标、约束条件、验收标准、项目层相关文件路径、模块说明、依赖关系、变更层本次要改什么、之前改过什么。每次对话往复推进时只允许这三层内容按需滚动淘汰和补入而不是无限制堆叠历史消息。这样有限制的上下文反而让模型保持住了对目标的专注度。2.2 工具治理白名单机制决定智能体能做什么工具治理是 Harness 里最需要强硬手段的地方。如果你让智能体自由调用终端命令它会有极大概率做出你不想让它做的事——比如在根目录装依赖、改全局配置、甚至删除文件。这类问题不是模型坏而是你给了它过大的权限边界。正确的思路是白名单不是黑名单。不要试图列出不能做什么而是列出只允许做什么。一个做代码重构的智能体工具白名单大概长这样工具名功能超时是否可并read_file读取指定文件内容5s是write_file写入文件内容5s否run_test运行指定测试用例30s否git_diff查看当前改动列表5s是search_symbol定位符号定义位置5s是commit_changes提交本次修改10s否每个工具都带独立的超时和失败策略而且执行在沙箱环境里比如容器或受限子进程。工具有两重校验第一重是参数校验比如 write_file 只允许写入限定目录路径不得包含..或绝对系统目录第二重是结果校验工具返回的内容要检查是否异常、是否超时、是否截断。这里补一个细节工具描述也很重要。模型靠工具描述来决定什么时候该用哪个工具描述写得太模糊它就会瞎猜。我后来形成了一套固定模板。每个工具描述里必须包含功能一句话说明 适用场景 输入参数示例 典型返回结构四要素。实测下来光把描述写规范工具调用的成功率就能提升一截。2.3 流程编排与控制流让智能体按招式而不是乱打有句老话叫练拳不练功到老一场空。智能体也是一样。如果你只给模型一堆工具不规定节奏它就会以一种极其发散的方式工作想到哪做到哪前面验证没做就急着改文件改完了又不回归测试。这种工作方式在小任务上还能凑合任务一复杂就彻底崩了。流程编排的目的就是把发散性思考装进一个有限状态机里。我常用一个四段式主循环计划 → 执行 → 校验 → 重试或收敛。计划节点模型把任务拆解成子步骤输出结构化动作序列。执行节点逐个调用工具每步记录结果。校验节点对上一步的输出做断言比如文件是否真的修改了、测试是否真的通过、输出格式是否符合预期。校验失败就进入重试逻辑超过最大重试次数则标记任务失败并拉停。关键在重试策略。大部分失败的智能体任务问题是模型在同一个错误上反复横跳测试失败了就重跑一遍还是同样失败然后换个方式乱调最后把自己带进沟里。我的经验是重试不是简单地把上一轮结果送回模型而是要在重试前执行故障归因——通过分析测试输出、对比变更内容告诉模型你上次的动作哪里有问题、为什么有问题然后再让它基于归因后的新输入重新计划。这样重试才有意义否则就是烧钱看它打转。另外控制流里还必须有强制节点。比如在修改代码文件之前必须运行过相关测试这个前置条件不能依赖模型自觉要在代码里硬性校验。自动化流程里最怕的就是软约束凡是关键节点一律硬校验。2.4 可观测性与日志没有日志的人工智能等于盲人摸象我发现很多人做智能体系统日志就记一句话任务完成或者任务失败。这种日志在出问题的时候毫无价值。因为你没法回答三个问题为什么失败它是按什么顺序做的它做每一步的时候看到了什么这三个问题就是可观测性的三个层次。第一层轨迹Trace。记录智能体每次工具调用的完整信息调了哪个工具、参数是什么、返回了什么、耗时多少。轨迹管的是做的顺序。第二层状态State。记录智能体的内部决策状态它当时依据上下文里哪些信息做了这个决策、当前计划是什么、下一步准备干什么。状态管的是它为什么这么做。第三层产物Artifact。记录每次关键动作产生的文件变更、测试输出、命令执行结果。产物管的是它到底做了哪些实事。我自己的习惯是所有中间结果都落盘成 JSON 日志并且把每一步串成一个 trace_id。这样如果任务跑飞了我可以直接把 trace 重放出来一点一点看它是在哪一步走偏的。没有这套可观测机制你调智能体系统就只能靠猜。而靠猜调系统永远调不出来。这一层我要特别强调日志系统应该在 Harness 写第一版时就同步搭建而不是等出事故之后再补。2.5 评估与验收用数据判断这次干活质量如何评估模块是整个 Harness 里最容易被当作最后再补的部分但其实应该最早设计。评估你要回答一个问题任务执行完了但它干的活到底行不行传统的代码任务通常有比较明确的客观信号测试通过率、Lint 通过数、覆盖度变化、性能基准结果。但智能体做的活往往更模糊比如重构这个模块的命名测试全绿不一定代表重构是对的。所以评估要两条腿走路硬指标测试通过、编译无错误、Git 状态干净软指标代码风格一致性、改动范围合理性、逻辑等价性。硬指标用脚本自动算软指标靠一个评审模型来打分。评审模型用固定的 rubric 模板对智能体的产出逐项评分最后合成一个总分。当总分低于阈值比如 0.85任务自动进入人工复核队列不能直接合并进主分支。记住一个原则评估不是一次性的而是持续跟踪的。同一个任务放同一套评估集上今天跑 0.9 分明天跑 0.7 分这个趋势本身就是 Harness 系统质量的晴雨表。你要用评估集驱动迭代而不是用感觉它变聪明了来驱动。说到这儿有必要单独强调一次评估集的维护和代码库本身一样重要要版本化管理。评估用例会过时项目约定会变化不跟进维护的评估集跟废纸没区别。3. 项目实战手搓一个简易代码库重构智能体 Harness3.1 项目目标与场景设定我们到底要解决什么问题理论部分说得再多不落地等于白说。下面这个实战项目我就基于真实场景简化而来假设你的团队有一个 Python 项目里面有一个legacy_module.py长期被抽着写函数命名一塌糊涂还有很多隐蔽 bug。团队想用智能体来做一次安全重构重命名函数、拆解超长函数、补充基础测试同时保证旧的逻辑行为不变。这个任务的难点在于重构类工作必须小心翼翼每一步都要验证行为等价。这就非常适合拿来做 Harness 的入门实战——它小但五脏俱全能覆盖上下文管理、工具白名单、主循环控制、评估验收这四个核心模块。我按以下顺序来搭建配置模块config.py设定路径、模型、预算、超时参数上下文构建模块context.py从代码库中提取任务相关上下文工具模块tools.py实现受限的工具集主循环模块main.py实现计划-执行-校验-重试的状态机评估模块eval.py校验测试与产出质量。因为篇幅关系每个模块我只保留最核心的代码骨架但在关键逻辑处做了完整注释。你可以直接用这版代码起步再往里面加自己的东西。整个项目不需要 GPU只要一个能调用 OpenAI API 或类似接口的环境就能跑起来。3.2 环境搭建与依赖选择为什么用这些基础组件环境方面我的建议是尽量轻装Python 3.11外加openai或其他模型 SDK、可以用兼容接口、pathspec做路径过滤、gitpython做 Git 操作再加一个简单的数据库或者存 JSON 的日志库。不引入重型 Web 框架也不会让新手在环境配置这一步就劝退。核心原因是智能体的调试本身已经够复杂了环境如果也复杂很难分清问题是出在代码还是环境上。三个目录建好harness/core主逻辑、harness/tools工具集、harness/logs运行时日志。后续代码都往这些目录里放。环境初始化先做一件事把工作目录限制在一个沙箱路径下然后在沙箱里初始化一个临时 Git 仓库所有智能体的操作都发生在这个仓库里。这样即使模型发疯它影响范围也只有这个临时仓库不会碰你的正式项目。3.3 上下文构建模块代码库索引与任务目标向量化上下文构建是整个 Harness 的信息入口。这一步做得好不好直接决定模型能不能理解我要改什么。我的实现分两步。第一步代码库索引。先 glob 出所有 Python 文件按文件大小过滤掉那些大到会撑爆 Token 的巨型文件超过 3 万字的源码在这里止损——这种文件正确做法是切分或者先人工介入拆解直接整读根本没有意义然后用关键词匹配任务目标里的核心词这里是 legacy_module 和函数名。第二步生成结构化的上下文包。上下文包是一个字典包含任务目标、文件清单、语法摘要、测试现状、变更暂存。用一个函数把上下文包渲染成纯文本塞进系统提示词里。为了减少 Token 浪费我只保留文件的功能摘录和关键函数签名源码全文进read_file工具按需读取不一次性全塞进去。注意上下文构建完成后一定打印一遍实际送入模型的提示词确认没有出现乱码、截断或者信息堆砌。机器不会像人一样知道自己没看懂它只会硬着头皮往下执行。3.4 工具注册与执行沙箱受限终端、文件读写与 Git 操作工具层我用了标准的注册表模式。所有工具罗列在一个工具表里主循环执行时从工具表里面找对应名称来调用。每个工具都有 name、description、parameters schema 和 handler 四个字段其中 handler 返回一个结构化的结果里面带success、message、data三个字段方便主循环做后续判断。以下是文件读取工具的代码骨架加了路径白名单检查。其余工具的写法一脉相通重点是每个工具都必须在入口处做参数校验和白名单校验不能信任模型传进来的原始参数。import os from pathlib import Path SAFE_ROOT Path(/tmp/harness_sandbox/workspace) def tool_read_file(params: dict) - dict: rel_path params.get(path, ) full_path (SAFE_ROOT / rel_path).resolve() # 路径穿越防御解析后的完整路径必须仍然在安全根目录下 if not str(full_path).startswith(str(SAFE_ROOT.resolve())): return {success: False, message: f路径越界: {rel_path}, data: None} try: content full_path.read_text(encodingutf-8) # 截断保护防止大文件把上下文撑爆 if len(content) 12000: content content[:12000] \n...[已截断]... return {success: True, message: OK, data: content} except FileNotFoundError: return {success: False, message: f文件不存在: {rel_path}, data: None}执行终端命令的工具要额外小心。我用的方案是subprocess.run加超时和输出上限只允许执行pytest、python -m py_compile这类白名单命令的特定前缀其他一律返回拒绝。这样模型就算起了歪念头工具层也能硬挡住。3.5 主循环控制计划-执行-校验-重试的有限状态机主循环是整个 Harness 的灵魂。我这里用一个简单的状态机来实现核心代码不长但把重试前归因这个关键逻辑写进去了。主循环的基本流程构建初始上下文调用模型生成一个任务计划循环里取出计划中的下一步动作调用对应工具校验工具返回结果成功就继续失败就进入归因流程归因流程调用模型分析失败原因生成修复后的下一步计划超过最大重试次数终止任务并标记失败。下面这是主循环的高度浓缩版。真实项目里会有更多细节但这个骨架足够展示 Harness 的运行逻辑。MAX_STEPS 30 MAX_RETRIES 3 def run_harness(initial_context: str): step 0 retries 0 plan call_planner(initial_context) # 模型产出初始计划 while step MAX_STEPS: action plan.next_action() if action is None: return {status: ok, trace: dump_trace()} result dispatch_tool(action.tool, action.params) record_trace(step, action, result) if not result[success]: retries 1 if retries MAX_RETRIES: return {status: failed, reason: 重试次数超限} analysis analyze_failure(action, result) # 归因为什么失败 plan call_planner(analysis \n initial_context) # 基于归因修订计划 else: retries 0 if needs_validation(action): validation validate_after_step(action) if not validation.passed: plan call_planner(validation.report) step 1 return {status: timeout}注意重试的触发条件。失败的判定标准要非常明确。工具调用失败、校验失败、生成结果格式非法这三种情况才触发重试。如果只是计划本身不够优但不影响正确性不触发重试直接继续走。这样避免模型陷入不断推翻自己方案的怪圈。提示状态机的每一步都必须落日志落完整的轨迹。不然代码跑出问题你将没有任何依据判断是工具 Bug、上下文缺失还是模型决策失误。3.6 评估与结果交付自动打分 变更报告生成任务跑完不一定等于干完了。评估模块要做两件事跑硬指标、生成变更报告。硬指标分三个层级。第一级项目是否还能通过全部 pytest 测试。重构类任务尤其要盯住零回归任何一个旧测试挂掉整个变更必须被标记为不合格。第二级Lint 检查是否通过静态检查能拦截掉很多看着跑了但代码质量稀烂的情况。第三级Git 状态校验确保没有把临时文件、日志文件混进提交。软指标的评分我按四个维度来做可读性变量命名是否清晰、函数粒度是否合理、范围克制改动点是否保持最小范围、测试质量新增用例是否覆盖主要分支、合规性改动是否符合项目既定风格。评分用 0~1 分小数四个维度的加权和作为总分阈值设在 0.85 以下进入人工复核队列。然后就生成变更报告。报告包括任务清单、执行轨迹摘要、变更文件清单、测试结果、评分详情。这个报告同时也是日志的一部分方便回看。整体流程闭环之后一次完整的任务执行会留下三样东西代码变更、测试结果、轨迹日志。这三样完全可审计也有这个可审计性智能体改造研发流程才谈得上落地。4. 常见问题与排查技巧实录4.1 上下文爆炸模型越来越笨怎么办这个问题的典型表现是任务刚开始时模型很聪明越往后越笨最后变成你刚才说过了吗的失忆状态。直接原因是上下文中塞进了太多历史消息和工具返回结果模型的有效注意力被稀释关键信息被淹没。我的排查思路分三步走。第一步检查日志里每轮对话的 Token 消耗看上下文总量是不是在指数增长第二步找出最大的 Token 消耗者——通常是某次工具调用返回了一坨超长日志被原样塞回了历史记录第三步做上下文裁剪。裁剪手段有三种按优先级从高到低排结果压缩工具返回长日志时先摘要再进上下文、历史折叠多轮对话中已经确认稳定的中间结果折叠为一句已完成 X 步骤结果通过校验、淘汰策略限制历史对话最大轮数超过的按重要性排序丢弃。我自己实操下来最有效的组合是工具返回摘要 历史折叠其他机制属于锦上添花。4.2 工具调用死循环卡在同一个工具上出不来死循环的典型场景模型不断调用同一个工具每次都失败但每次重新计划时又原样再来一遍。这种问题一部分原因在于模型没真正理解失败原因一部分在于 Harness 的重试机制把失败信息原样丢回给了模型等于没教它新东西。我的修复方案是在归因环节做文章。失败后不要直接把工具的报错塞回上下文而是先经过一个归因函数把报错翻译成带建议的中文或者项目语言说明例如工具 write_file 失败原因是目标路径不存在。当前目录下确实没有src/legacy_module.py请先用search_symbol确认路径再发起写入操作。这种带指引的归因信息就像给模型递了一把手电筒它再走就不会摸黑了。实测下来加上归因信息后卡死重试的次数能减少一半以上。另外状态机里做个连续 N 次同一个工具失败的熔断开关一旦触发就直接整轮终止避免无效烧钱。4.3 影子命令与幻觉工具名模型假装调用了工具模型幻觉的工具调用在新手工程里特别常见。现象是日志里记录了模型输出了一段 call_tool: write_file 但实际上工具层根本没收到这个调用——后来一查是模型在思考里写了工具名而拆解器把思考内容和工具调用搞混了导致工具层以为调用了但其实没有执行。解决方案很朴素但有奇效_强制结构化_。不要靠正则从一段自由文本里解析工具调用而是要求模型输出严格的 JSON 格式必须包含tool、params、reason三个字段并且只取最后一次满足 JSON 模式的输出作为执行指令。这样可以避免模型把一串工具名写进备注里被误判为真实调用。如果发现模型经常输出格式不合法优先检查工具描述和提示词示例是不是太模糊了。4.4 可复现性差同一任务两次结果不同模型本身有随机性加上 Harness 的信息流对输入文本顺序无比敏感所以两次运行结果不同是常态。但工程上你总得有个基线用于比对不能让评估指标像股票一样跳来跳去。几个关键优化第一推理温度调到 0 或接近 0工具调用这种场景不需要创造性第二固定上下文构建阶段的文件排序和行为顺序不要依赖哈希序或本地路径序第三关键决策点的随机性来源要消除比如不让模型自己选先看哪个文件而是由 Harness 按依赖关系定好顺序第四对跑出来的结果做重跑一致性检测同一任务在相同条件下跑三次结果差异超过阈值就把该任务标记为不稳定单独复查。4.5 成本失控一次任务烧掉大量 Token 的教训这是个财务问题也是工程问题。我自己踩过一次坑运行一个稍复杂的重构任务因为上下文一直朝着膨胀的方向堆积最终一个任务烧掉的 Token 是预期的 6 倍。排查才发现问题不是某个单次调用太贵而是循环过程中每次调用都把前面全部历史重新塞给了模型。控制成本的办法就四招。第一默认打开上下文滚动摘要功能历史对话折叠成摘要而不是整段保存第二工具返回的大块文本一律压缩超过两三千字就抽摘要第三设定单任务 Token 上限到这个上限直接终止并把当前中间结果存盘点便于之后从断点续跑第四分组统计 Token 消耗按工具类型和任务类型两个维度对照找到烧钱点精准下手。另外说一句很多模型的 Token 计费中输出比输入贵得多如果发现模型在疯狂生成大段分析文本记得提示词里约束输出尽量精简。5. 从入门到落地接入工程体系的一些经验5.1 先跑通一个最小闭环再逐步加模块Harness 系统再怎么强调完整性也不要第一次就冲到最全。我的经验是第一版只保留三样东西白名单工具、带重试的有限状态机、结构化日志。跑通一个最简单的小任务后再逐步增加上下文构建、评估打分、成本控制这些模块。加的过程中每加一个模块就回归一次之前跑过的任务确保老功能没有被新改动破坏。最小闭环的好处在于它让你快速建立这个系统能不能用的直觉。智能体系统最大的风险不是某个模块实现不到位而是整条链路从来没有完整跑通过。到达链路可用比功能齐全重要得多。5.2 用评估集驱动 Harness 的迭代演进当系统跑通之后最重要的事情是整理评估集。把过去跑过的任务、尤其是失败过的任务收集起来做成一个固定的任务集合。每次改动 Harness 的代码都在这个评估集上重跑一遍。这就像传统软件开发里的回归测试套件你改了一个工具的超时参数如果不重跑评估集很难知道它会不会让别的任务集体变慢。评估集的维护要版本化跟代码库一起提交。每加入一个评估任务附上它期望的结果、可接受的偏差范围、和判定脚本。三个月后你的评估集应该是当初的两倍大而系统整体评分趋势应该是往上走的。如果评分不升反降优先回头查最近几次改动而不是怪模型变笨了。5.3 团队协作时如何处理智能体产出的代码智能体产出的代码跟人类小同事产出的代码一样需要走完整的代码评审流程。我不建议让智能体直接拥有推送主分支的权限哪怕它跑得再好。安全的做法是智能体在隔离分支上工作产出后自动创建 PR或类似机制附上我前面说的变更报告等人工复核通过后再合入。这套流程也是很多自动化系统的标准范式技术含量不高却能拦下大量低级错误。人的复核重点放在两处第一是否改坏了原有行为看测试结果 diff 范围第二代码风格与项目习惯是否一致软指标评分只能给参考。其他交给自动化就好不要让人去一行行读智能体写的所有代码那就失去了上智能体的意义。5.4 个人体会与最后的小建议做了几个月 Harness 之后我最大的体会是这个工程领域不要求你懂多高深的算法但它逼你把工程基本功做得异常扎实。日志、容错、校验、白名单、成本核算每一样都是传统软件开发里再普通不过的东西。只有当它们围绕一个会自主行动的模型重新组织时你才会意识到原来过去给人类同事准备的研发制度其实完全可以量化成代码。最后说个实用小技巧如果你刚开始练手选任务时别选从零写一个功能选对现有代码做重构或者修一批已知 bug。因为后两类任务存在客观的验收基准——测试通过、行为不变、bug 减少。这类任务最容易让 Harness 发挥价值也最方便做效果对比。等你在这类任务上把 Harness 打磨顺了再挑战更开放的任务心理就有底了。