上一章 推理优化与成本杠杆 量化、PagedAttention、投机解码、连续批处理——四把把成本打下来的锤子。重点不是背名词,而是知道每个手段针对哪个瓶颈、代价是什么。 I · 大模型原理 · 第 05 章 · 深入 · 约 30 分钟
Agent 工程学习站 做棵大树 出品 主站 beatree.cn 免费 · 无需登录 · 进度存本机
II 版 · Harness 工程 ◆ 第 01 章 ◆ Model + Harness = Agent
II · Harness 工程 01 / 22 入门

Harness 是什么

Model + Harness = Agent
预计阅读 24 分钟
难度 入门
关键词 Harness · 能力地图
本机状态 未读

「除模型本身以外的所有工作,都属于 Harness 的范畴」——这句话看起来像一句甩锅式的定义,实际上它划出的地盘大得惊人:从工具契约到上下文预算,从失败恢复到权限沙箱,从循环终止到评测闭环。这一章给出完整的能力地图,后面七章都挂在这张图上。

编辑部注 · 本刊读者若只读一章,请读这一章。它决定了后面所有内容在你脑子里是「一堆知识点」还是「一张地图」。

先看一个被反复引用却很少被真正拆解的等式:Model + Harness = Agent。同一个模型,套上不同的 Harness,能做出效果差异巨大的产品。理解这个等式,就理解了为什么「模型能力」不是产品效果的唯一变量——也理解了为什么这个岗位值得存在。

一、把这个等式拆开看

模型提供三种能力:理解输入、生成内容、在给定格式下输出结构化结果。它不能做的是:记住上一次对话、访问外部世界、判断自己的输出对不对、在失败后重试、控制自己做事的顺序、以及在出事之后被追责。

这些「不能做」的事情,就是 Harness 的地盘。换个更工程化的说法:

Harness 是把一个概率性的文本生成器,包装成一个 可交付(Deliverables)、可观测(Observability)、可控制、可恢复的执行系统的全部工程。

「可交付」意味着用户拿到的是结果而不是一段文字;「可观测」意味着每一步都能查;「可控制」意味着越权行为会被拦住;「可恢复」意味着中途断了能接着跑。这四件事没有一件是模型本身提供的。

Harness 能力地图 越靠上的层越贴近用户,越靠下的层越贴近模型。每一层都可能成为效果的瓶颈。 ⑥ 交付层 Deliverables 产物形态(报告 / 表格 / 代码 / 网页)、分享与权限、版本与回滚、导出与归档   ⑤ 编排层 Orchestration 任务分解、Subagent 派生、并行与串行、结果汇总、人工介入点、长任务状态机与检查点   ④ 记忆与知识层 Memory & Knowledge 长期记忆写入与召回、知识建模(实体/事实/推断)、检索与引用、冲突消解、可删除性   ③ 上下文层 Context Engineering ★ 效果上限的真正来源 预算分配、什么常驻什么按需、压缩与摘要、状态外置、顺序与前缀稳定性   ② 工具层 Tools as Contracts 工具描述、参数 schema、错误分类与回喂、结果裁剪、MCP 接入、幂等与副作用标记   ① 循环层 The Loop 思考-行动-观察循环、终止条件、轮数与预算上限、循环检测、流式解析与卡死恢复   模型 Model —— 提供理解与生成,其余全部由上面六层提供 越权防护、审计、可观测性贯穿所有层,不单独成层
图 1 Harness 能力地图。注意第 ③ 层的标注:上下文层是效果上限的真正来源——工具再多、编排再花,模型看到的上下文决定了它能做出什么判断。这也是后面第七、八章反复回到这一层的原因。
研究问题 vs 工程问题:边界在哪 唯一的判据:要不要改模型权重、结构或重新训练? 研究问题(模型侧) 必须动模型本身 · 长序列注意力效率  (FlashAttention / 稀疏) · 降低解码重复(改采样/训练) · 提升多语言 / 推理能力 · 注入全新知识(继续预训练) 工程问题(Harness 侧) 模型之外全部可改 · 工具契约与错误回喂 · 上下文预算与压缩 · 循环终止与卡死检测 · 权限沙箱与编排 · 交付形态与回滚 判据:需要动模型结构或训练 → 研究问题;否则 → 工程问题(Harness 的地盘)
图 2 同一份模型,套不同 Harness 效果差异更大,原因就在这条分界线上。凡是「改模型结构或训练才能做到」的,都不属于 Harness——这是第一章自测第 1 题的判据,也是岗位边界。
同一份模型输出,加不加 Harness 天差地别 四层包装把「一段概率性文字」变成「可交付 / 可观测 / 可控制 / 可恢复的执行系统」。 裸模型输出 一段概率性文本 × 记不住上次对话 × 调不了外部工具 × 坏了没法重试 × 越权无法拦截 × 出事没法追责 没有这四项保障, 它只是「会聊天的模型」。 包装 ① 可交付 给用户结果,不是一段文字 ② 可观测 每步留痕、可回放 ③ 可控制 越权与不可逆被拦住 ④ 可恢复 中断续跑、状态持久化
图 3 模型本身提供理解与生成,但「记不住、调不了工具、坏了不能重试、越权拦不住」这四件事它做不到。Harness 的价值不是让模型变聪明,而是把这段输出包进四层保障,变成能交付、能追责的执行系统。

二、为什么「同一模型不同效果」是常态

一个常被忽略的事实:把 GPT / Claude / DeepSeek 换进同一个 Harness,效果差异往往小于「同一个模型换一个 Harness」。原因有三:

第一,工具契约(Tool Contract) 描述的质量决定了模型会不会用、用得对不对。 同一个查询接口,描述写成「查询数据」,写成一个带参数说明、取值范例、返回结构示例的完整契约,工具调用成功率可以差出一倍。

第二,上下文里的信息决定模型能做什么判断。 如果历史全量堆进上下文,模型注意力被稀释;如果该给的信息没给(比如「这个字段昨天刚改过口径」),模型只能猜。

第三,失败处理决定系统能不能跑完。 同一个模型,遇到工具报错就整轮失败,和把错误分类后 回喂(Error Feedback) 让它换参数重试,任务完成率的差距是量级级别的。模型一次误判还可能直接造成 副作用(Side Effect)、改坏线上数据。

模型决定上限,Harness 决定你能不能摸到那个上限。而绝大多数产品离上限还差得远,所以 Harness 才是主战场。本刊编辑部

三、一个最小可用的 Harness 应该有什么

不需要一上来就建六层。但如果只有一天时间写一个能用的 Harness,下面这六件事缺一不可——它们正好对应一张 能力地图(Capability Map),其中「最小权限」就是 最小权限(Least Privilege) 原则,而工具契约还要求声明是否 幂等(Idempotency):

#必需能力缺了会怎样
1循环 + 五类终止条件要么永不停止(烧钱),要么提前放弃(完不成任务)
2工具契约 + 参数校验模型调用失败率高,且你在日志里看不出为什么
3错误分类与回喂任何一次工具报错都会让整轮任务失败
4上下文预算与压缩跑十几轮就撑满窗口,成本平方级上涨
5全链路 trace出问题只能靠猜,无法定位到底哪一步坏掉
6副作用操作确认 / 最小权限模型一次误判就可能直接改坏线上数据
minimal_harness.pypython
"""
最小可用 Harness 骨架。
刻意把六层压缩成 40 行,只为展示「Harness 到底在做什么」。
生产环境每一行都会膨胀成好几十行,但骨架不变。
"""
from dataclasses import dataclass, field
@dataclass
class Budget:
    max_turns: int = 12            # 轮数上限
    max_tokens: int = 120_000      # 累计 token 上限(成本闸)
    max_seconds: float = 300.0     # 挂钟时间上限
    turns: int = 0
    tokens: int = 0
    trace: list = field(default_factory=list)   # 全链路可观测
    def spent(self) -> bool:
        return self.turns >= self.max_turns
class Tool:
    """工具 = 契约。描述、schema、是否幂等、是否有副作用,四者必须齐全。"""
    def __init__(self, name, description, schema, handler, side_effect=False):
        self.name, self.description = name, description
        self.schema, self.handler = schema, handler
        self.side_effect = side_effect      # 有副作用的工具执行前必须确认
TOOLS = {
    "search": Tool("search", "按关键词检索站内文章,返回 [{title,url,snippet}]",
                   {"q": "string"}, lambda **kw: [{"title": "示例", "url": "…"}],
                   side_effect=False),
    "write_file": Tool("write_file", "把内容写入指定路径,会覆盖同名文件",
                       {"path": "string", "content": "string"},
                       lambda **kw: "written", side_effect=True),
}
def build_context(task: str, history: list, observations: list) -> list:
    """
    第 ③ 层的核心:决定模型看到什么。这里用最朴素的三段式,
    真实系统要在这里做预算分配、摘要压缩与状态外置。
    """
    tool_docs = "\n".join(f"- {t.name}: {t.description}" for t in TOOLS.values())
    return [
        {"role": "system", "content": f"你是任务执行器。可用工具:\n{tool_docs}"},
        {"role": "user", "content": f"任务:{task}"},
        *history,
        *observations,
    ]
def classify_error(exc: Exception) -> str:
    """错误分类决定回喂方式,这是第 ②③ 层交界处最容易被跳过的一步"""
    name = type(exc).__name__
    if name in ("TimeoutError",):
        return "TIMEOUT:可以原样重试一次,超时通常是瞬时的"
    if name in ("ValueError", "KeyError"):
        return "BAD_ARGS:参数有问题,必须改参数后重试,重试原参数无意义"
    if name in ("PermissionError",):
        return "FORBIDDEN:没有权限,重试无用,应上报请求授权"
    return "UNKNOWN:记录并交由上层决定"
def run(task: str, budget: Budget) -> dict:
    history, observations = [], []
    while not budget.spent():
        budget.turns += 1
        # 1. 组装上下文(决定模型看到什么)
        messages = build_context(task, history, observations)
        # 2. 调用模型,要求结构化输出
        plan = call_model(messages, temperature=0)      # 占位
        budget.trace.append({"turn": budget.turns, "plan": plan})
        # 3. 终止判断:模型认为完成
        if plan.get("action") == "finish":
            return {"status": "done", "result": plan.get("answer"),
                    "turns": budget.turns, "trace": budget.trace}
        # 4. 执行工具,带错误分类
        tool = TOOLS.get(plan.get("tool"))
        if tool is None:
            observations.append({"role": "user",
                                 "content": f"工具 {plan.get('tool')} 不存在,请从可用列表中选择。"})
            continue
        if tool.side_effect and not confirm(f"即将执行有副作用的操作 {tool.name},确认?"):
            observations.append({"role": "user", "content": "用户拒绝了该操作,请换方案或结束。"})
            continue
        try:
            result = tool.handler(**plan.get("args", {}))
            observations.append({"role": "tool", "content": str(result)[:2000]})
        except Exception as e:                            # 关键:错误也回喂
            observations.append({"role": "user",
                                 "content": f"工具执行失败[{classify_error(e)}]:{e}"})
    return {"status": "budget_exhausted", "turns": budget.turns, "trace": budget.trace}
这段代码里最值钱的三行
  • except Exception as e 之后把错误回喂给模型——绝大多数玩具实现会直接抛出异常终止;
  • classify_error() 把错误分成「可重试 / 必须改参数 / 重试无用」——决定后续行为的不是错误本身,而是分类;
  • tool.side_effect and not confirm(...)——在把能力交出去之前先设一道闸。

四、面试里怎么答「什么是 Harness」

这道题的标准陷阱是答成「Agent 的框架」。正确的答法是给一个判据,而不是一个描述——按六层展开时,不要忘了还有 编排(Orchestration) 这一层:

推荐的答题结构

结论:Harness 是「把概率性文本生成器包装成可交付、可观测、可控制、可恢复系统」的全部工程,判据是——这件事模型自己做不到。

机制:按六层展开:循环 / 工具 / 上下文 / 记忆与知识 / 编排 / 交付,另外权限与可观测性贯穿全层。

代价与边界:Harness 做得越厚,延迟越高、调试越难、模型升级带来的收益越可能被掩盖。所以好的 Harness 要能随模型变强而变薄——那些「为了绕开模型弱点」的补丁应该在模型升级后被主动拆掉。

实践:举一个你自己的例子(比如把某个失败率高的链路从「加提示词」改成「改错误分类 + 回喂」)。

五、常见误区与追问

5.1 误区:把 Harness 答成「Agent 框架」

错在哪:面试里说「Harness 就是 LangChain 那种框架」,把概念降维成了工具库。为什么自然:框架确实管循环和工具,容易混为一谈。判据:框架是给开发者用的基础设施;Harness 是「把模型包成可交付系统」的全部工程,含上下文、失败恢复、权限、可观测——这些框架默认不给。能说出「模型做不到的才是 Harness」,就过关。

5.2 误区:上下文越长效果越好

错在哪:无治理地堆历史,信噪比下降,模型「越跑越笨」。为什么自然:直觉上信息多总比少好。判据:真实判断依据占比从约 18% 被稀释到 10%,成本却涨十几倍。健康做法是按四类成分分配预算、把状态外部化,而不是无脑加长。

5.3 误区:工具越多越能干活

错在哪:相似工具多了,模型选错、选重、遗忘。为什么自然:功能覆盖看起来更全。判据:工具描述要求「动词开头、语义唯一、不与其它重名」。每新增一个工具,先问「它和已有工具的选择边界是否清晰」,边界不清就合并而非新增。

5.4 误区:错误回喂就是「把异常打印出来」

错在哪:回喂的是原始异常,模型看不出该改参数还是换方案。为什么自然:try/except 里直接 str(e) 最省事。判据:必须先分类(参数/格式/权限/超时/空结果…),再回喂「具体哪个字段错、合法取值是什么、是否该重试」。空结果要显式标成非错误。

5.5 误区:最小权限会拖慢开发

错在哪:为省事给工具全量权限,一次误判就改坏线上。为什么自然:加确认和权限隔离要多写代码。判据:权限在工具内部强制执行(确定性闸门),不是靠模型自觉;不可逆操作每次强制确认,确认信息必须含影响范围,如「删除 orders_2025 表,共 12 万行」。

六、自测

本章自测第 3 题最容易答错
Q1下面哪一项不属于 Harness 的职责?
C。注意力计算的效率是模型与推理框架的事(FlashAttention、MLA、稀疏注意力),Harness 无法改变模型内部的计算方式。这是「研究问题 vs 工程问题」的一个典型分界:凡是需要改模型结构或训练才能做到的,都不属于 Harness。
Q2「同一个模型套不同 Harness 效果差异巨大」,最主要原因是什么?
B。Harness 不碰权重(排除 D),温度是次要变量(排除 A)。真正的差异来自三条链路:信息够不够(上下文)、能力好不好用(工具契约)、坏了能不能修(错误恢复)。这三条正好对应能力地图的第 ③② 层与失败处理。
Q3「好的 Harness 应该能随模型变强而变薄」这句话的含义是?
D。这是很有区分度的一题。很多 Agent 系统里堆着大量「当年因为模型不会 X 所以加了一层 Y」的补丁,模型升级后这些补丁不但没用,还会压制模型的真实能力(例如强制模板化的输出格式让更强的模型也无法发挥)。能主动清理这类技术债,是资深工程师的标志。

七、小结

  • 判据比定义重要:模型做不到的,就是 Harness 的。
  • 六层地图:循环 / 工具 / 上下文 / 记忆与知识 / 编排 / 交付,权限与观测贯穿全层。
  • 上下文层是效果上限的真正来源,工具层是失败率的主要来源,编排层是长任务能否跑完的关键。
  • Harness 要能变薄:为绕开旧模型弱点而加的补丁要能被识别并拆除。

下一章从最底下那层开始:循环该怎么写,尤其是——什么时候该让它停下来。

八、参考与延伸

这一章给的是一张地图,而地图要能被验证才值得信。下面这几份材料分别回答三件事:别人怎么分层、一个真实的 Harness 长什么样、以及「效果差异」该怎么量。全站不做原文转载,这里只登记链接与「为什么值得读」。

先看总览(对齐别人的地图)

  • Anthropic · Building Effective Agents —— 目前把「Agent 到底由哪些工程部件组成」讲得最克制的一篇,全篇在做一件事:区分「编排好的工作流」与「让模型自己决策的 Agent」,并且明确主张能用前者就别写后者。先读它,再回来看本章第一节的能力地图——两张图重合的部分说明共识,不重合的那几层才是你真正需要想清楚的地方。
  • Eugene Yan · Patterns for Building LLM-based Systems & Products —— 把 RAG、缓存、护栏、评测、可观测性按「工程模式」编成一份带目录的清单,每条都写了代价而不只是好处。适合当索引用:你现在缺哪一层就翻哪一节,不必从头读;它的分类比任何一篇「Agent 入门」都更接近生产现实。

再看一个真 Harness 长什么样

  • Anthropic · Claude Code Best Practices —— 一个已经上线的编码 Agent 具体做了哪些取舍:什么情况下停下来问人、哪些操作必须先设闸门、上下文怎么组织、失败后怎么接着跑。把本章第三节那张「最小可用六件事」表对着它看,你会发现这六条全都对应着某个具体的产品决策——这比任何论证都能说明它们为什么缺一不可。

最后看效果该怎么量

  • SWE-bench —— 「同一个模型换不同 Harness,效果差异能有多大」这件事最硬的证据来源:它固定模型与任务,只允许改动 Harness 侧(提示组织、工具、循环、重试策略),榜单上的名次差异全部来自工程。要说服别人「Harness 值得投入」,拿它当论据比讲道理有效得多。
  • τ-bench(sierra-research/tau-bench) —— 面向「多轮、带业务规则约束、必须通过工具办事」的场景,并且把「结果对不对」与「过程有没有违规」分开记分。本章第一节说「可控制不等于结果正确」,这份基准是这句话的可执行版本:它专门惩罚「办成了但办得不合规」。
  • Anthropic · Writing Tools for Agents —— 放在第一章的延伸里,是因为工具契约是整张能力地图上投入产出比最高的一项,也是第三章的主题。如果你读完这一章只打算动手改一处,就先读这一篇,再回去改你的工具描述——它给的改法是当天能落地的。

◇ 面试官会怎么问

共 6 条 · 其中 2 条高频 · 先自己答一遍,再展开对照

Harness 的定义是什么?边界在哪? 高频
一句话:Agent = Model + Harness,Harness 是"除模型本身以外的所有工作"。
具体可以拆成七层:① 执行层(Agent Loop、终止条件、状态机);② 能力层(工具注册与契约、MCP 接入、工具执行与沙箱);③ 上下文层(预算分配、压缩、缓存友好组装、记忆);④ 编排层(规划、Subagent、多 Agent 通信);⑤ 治理层(权限、审计、提示注入防御、配额);⑥ 质量层(评测集、指标、trace、回归门禁);⑦ 适配层(多模型网关、参数 профиль、与训练团队的反馈回流)。
边界判断有个简单标准:如果是"让模型自己变强"的事,属于模型侧;如果是"让变强的模型能可靠地完成任务"的事,属于 Harness。

追问链

  1. 模型越来越强之后,Harness 会不会被吃掉?
  2. 这七层里你认为哪一层最难做?
加分点:答"会不会被吃掉"时给出双向判断:模型变强会吃掉通用能力,但私有上下文、工具生态、权限与安全、可评测性反而变得更重要。
为什么说 Harness 的难点不在"让它跑起来",而在"让它可评测、可回滚"?
因为"跑起来"是一次性的,"可评测、可回滚"是可持续的。
一个只在开发机上跑通过的 Agent,缺三样东西就无法成为产品:① 可观测——出了问题你拿不到完整链路(每轮的 prompt、工具调用、耗时、token),只能靠猜;② 可复现——没有 trace 就没有 replay,同一个 bug 你复现不出来,也就无法验证修好了没;③ 可安全变更——prompt 和工具描述本质上就是代码,没有版本化、灰度和一键回滚,每次改动都是在赌。
所以成熟的 Harness 有个特征:prompt 变更有版本号、有对照评测、有灰度门禁,而不是直接改线上。
你怎么判断一个 Agent 产品做得好不好?
我会看四个指标,而不是看 demo 有多惊艳:
① 真实任务成功率——在用户的真实任务分布上,能独立完成的比例是多少;
② 人工介入成本——需要用户接管、确认、纠正的次数,这直接决定它是不是负担;
③ 可恢复性——跑偏之后能不能回退、能不能断点续跑、会不会把副作用做重;
④ 单位任务成本——token 与时间的消耗。
一个重要的判断信号是:好的 Agent 产品会把"不确定性"显式暴露给用户(比如告诉你它删除了哪些文件、改了哪些内容、依据是什么),而不是假装自己一直很确定。
加分点:最后那句"把不确定性显式暴露"是品味题的高分表达。
同一份模型,A 团队的 Agent 能连续跑几十步交付一份带引用的调研报告,B 团队跑到第 8 步就散了。你会按什么顺序排查,每一步看什么数? 高频
按「信息够不够 → 能力好不好用 → 坏了能不能修」的顺序查,把「换模型」放在最后。
① 上下文:把每一步的输入按四类成分切开数 token,看真实判断依据的占比。如果第 8 步时占比已经掉到 10% 上下,问题在压缩与排序,不在模型。
② 工具契约:把这一步真正调用的那几个工具的 description 打出来,检查四层是否齐全——做什么、什么时候用、什么时候该改用别的、参数范例与返回结构。只写一句「查询数据」的工具,模型只能靠猜。
③ 失败恢复:把 trace 里每一次工具报错列出来,看它是被分类后回喂继续跑,还是直接抛异常终止了整轮。8 步里只要有一次超时没人接住,任务就断在那里。
三条都查过仍然解释不了差异,再换模型做对照——这样换模型才是结论,而不是第一步的猜测。

追问链

  1. 你怎么量化「上下文里的判断依据占比」?给一个能落地的口径。
  2. 如果 trace 里只有结果、没有过程,你会先补什么?
加分点:加分点:把「换模型」放在排查序列的最后,并且每一步都给出可观测的口径。答成「先换个更强的模型试试」,说明还没有工程视角。
给一个刚上线的 Agent 排改造优先级:工具调用错误率 15%、跑到第 20 轮的任务失败率 40%、单任务平均成本是预期的 3 倍。你先动哪一层,为什么?
先动成本,再动长任务失败率,最后动工具错误率——顺序由「改动成本 × 影响面」决定,而不是由数字大小决定。
① 成本 3 倍:先查前缀稳定性与状态外置,这一层改动最小、收益最大。把相邻两轮的请求体打印出来逐字节比对,第一个不同点若落在前 1% 以内,说明缓存基本全废;再把中间产物外部化,上下文只留指针与目录清单。
② 第 20 轮失败:查压缩触发点与终止条件。用量到 60% 就该触发阶段摘要,而不是等接口报错;确认预算耗尽时返回的是「部分结果 + 已完成步骤」,而不是一句失败。
③ 错误率 15%:最后补契约四层、schema 约束、执行前校验与错误分类回喂。
理由:成本与长任务失败是每天都在流血的事故,错误率是可以通过一轮契约改造集中偿还的工程债。

追问链

  1. 如果把顺序反过来、先修错误率,会有什么代价?
  2. 成本降下来之后,你怎么确认不是因为任务跑得更少而「看起来更便宜」?
有人说「模型越来越强,Harness 会越来越薄」。这句话哪一半对、哪一半是幻觉?
对的是「应该变薄」,错的是「会自动变薄」。
该薄的:为绕开旧模型弱点而加的补丁——强制模板化的输出格式、把答案空间裁成枚举、用反复重试掩盖一次判断失误。这些补丁在新模型上不但没用,还会压住模型的真实能力,必须主动识别并拆掉。
不会薄的:四件模型在结构上做不到的事——交付形态、可观测与审计、权限与不可逆操作的闸门、断点恢复。这些不是能力问题,是责任问题,模型再强也得由代码承担。
判据:一条 Harness 逻辑如果删掉之后模型正确率不变、账还能对上、能回滚、能追责,那它就是可以拆的补丁;删掉之后系统失去可追责性或不可恢复,它就必须留着。

追问链

  1. 你最近一次主动拆掉补丁是什么时候,怎么判断它已经没用了?
  2. 如果线上跑的还是老版本模型,这些补丁要不要拆?
加分点:答出「责任问题不会随模型变强而消失」这一层,说明你想清楚了 Harness 到底为谁存在。
答这类题的通用结构

结论先行(一句话给出取舍)→ 机制(为什么是这样,涉及哪条链路)→ 代价或边界(这么做放弃了什么)→ 你的实践或数字(真实场景里怎么落地)。 只讲机制不讲代价,是背题;只讲取舍没有数字,是空谈。

本章收尾 · Wrap up
掌握度自评
点一下给自己打分;低于 3 分建议加入复习队列
个人笔记 · Notes
    下一章 Agent Loop 与终止条件 写一个循环谁都会,难的是知道什么时候让它停下来。任务完成、轮数用尽、预算耗尽、无进展、需要人工——五类终止条件缺一不可。 II · Harness 工程 · 第 02 章 · 入门 · 约 32 分钟