在大模型应用落地中,如何让模型稳定、高效地完成复杂任务?是直接调参还是优化工程链路?这篇文章将围绕 Context 与 Harness 工程 展开,带你从基础的 Prompt 到复杂的 Harness 工程,理解大模型应用的四层递进逻辑,掌握关键组件和治理方法,让你的 Agent 系统越用越强。
1. 四层递进:从简单对话到复杂 Agent 的工程演进
大模型应用工程按「边界从小到大」分为四个核心层次,后一层包含前一层,边界和能力逐步扩展。我们先通过表格理解每个层次的核心目标:
| 层次 | 解决问题 | 一句话核心目标 |
|---|---|---|
| Prompt Engineering | 怎么清晰表达需求 | 让模型听懂你想让它干什么 |
| Context Engineering | 给什么信息支撑任务 | 让模型知道该用什么信息做决策 |
| Harness Engineering | 如何稳定执行任务 | 让模型持续做对并达成目标 |
| Learning Loop | 如何持续优化能力 | 让模型越用越强,形成正向循环 |
1.1 深入理解:包含关系而非替代关系
这四个层次不是「非此即彼」的替代关系,而是层层嵌套的包含关系:
- Prompt 是 Context 的一部分:你给模型的提示词(如“按公司规范写代码”)本身就是 Context 的核心内容。
- Context 是 Harness 的一部分:Harness 要确保模型在复杂任务中稳定工作,必须包含 Context 工程(如动态筛选信息、结构化组织知识)。
- Harness 是 Learning Loop 的基础:只有先让模型“持续做对”,才能通过反馈数据让它“越干越强”。
举个例子:你让 Agent 分析项目进度,Harness 工程会包含:
1. 给模型的 Context(含项目数据、规范、历史对话);
2. Context 中又包含具体的 Prompt(如“你是项目经理,需基于以下数据分析进度”);
3. 最终通过 Harness 的校验和恢复机制确保分析结果准确,再进入 Learning Loop 优化分析模型。
1.2 为什么会演进?从单轮到复杂任务的必然
- Prompt Engineering:适合单轮对话(如“写一封请假邮件”),解决“表达不清晰”的问题。但复杂任务(如“分析季度财报并生成改进方案”)中,模型因缺乏背景信息(财报数据、公司战略)会“答非所问”。
- Context Engineering:因产品形态从“聊天机器人”升级为“Agent”(多轮对话、调工具、写代码)而诞生。核心思想:模型未必知道所有信息,系统必须主动提供“它不知道但需要的知识”。
- Harness Engineering:当模型开始“连续行动”(如调用工具、多轮交互),需要解决“失控”问题——谁来监督它?如何约束它?如何在它跑偏时拉回?前两代(Prompt/Context)只关注“输入侧”,Harness 则覆盖“整个运行系统”。
2. Agent = 模型 + Harness:落地能力的核心
Agent 的稳定交付,模型本身只决定“天花板”,而 Harness 决定“落地能力”。Harness 包含所有非模型本身的关键组件:工具(如 API、数据库)、上下文文件、记忆系统、评估机制、约束规则、恢复策略等。
为什么 Harness 如此重要?
当模型迭代放缓(如 GPT-4 之后的版本能力提升有限),优化 Harness 能显著提升落地效果。例如:同样的模型,用 Harness 做上下文压缩和工具调用,可能比单纯调提示词多完成 30% 的复杂任务。
3. Harness 六层组件:让模型“持续做对”的关键
Harness 工程按“它在干什么”分为三组六层,覆盖输入、动作、校验全流程:
3.1 输入侧:让模型看到正确的信息
1. 上下文精细化
- 核心目标:控制发给模型的上下文“质量”和“结构”,避免信息冗余。
- 关键动作:
- ① 钉死角色与目标:明确模型身份(如“你是财务分析师”)和任务目标(如“分析 2024 Q3 财报并生成风险点”)——跑偏根源往往是身份/目标不清晰。
- ② 动态筛选信息:根据任务阶段(如“先看近 3 个月数据,再关联历史战略”)筛选最相关的信息,避免“信息过载”。
- ③ 结构化组织:将规则、数据、未完成项分层排列(如“先放约束规则,再放待分析数据,最后放历史结论”),规避“中间遗忘”(Lost in Middle)。
3.2 动作侧:让模型执行正确的任务
2. 工具系统
- 核心目标:让模型知道“该用什么工具”“何时调用”“如何返回结果”。
- 关键动作:
- 定义工具列表(如“调用公司数据库查用户数据”“用 MCP 工具生成代码”);
- 规范调用格式(如 JSON 格式参数);
- 工具结果回喂:将工具返回的原始数据(如 API 响应)转化为模型可理解的自然语言(如“用户数据:{'name':'张三','age':30}”)。
3. 执行编排
- 核心目标:给模型明确的“工作顺序”,避免“想到哪做到哪”。
- 关键动作:
- 定义任务流程(如“先拉取所有数据 → 再做初步分析 → 最后生成结论”);
- 用“思考→行动→观察→再思考”(ReAct 循环)约束模型行为,确保步骤连贯。
3.3 校验侧:让模型不出错并能恢复
4. 评估与观测
- 核心目标:验证模型输出是否正确,并记录行为轨迹。
- 关键动作:
- Eval 集验证:用预设的“标准答案”(如“财报分析需包含 3 个核心指标”)校验输出是否达标;
- Trace 日志:记录模型每一步行为(如“调用了哪个工具”“用了多少 token”“决策依据是什么”),便于调试(如 LangSmith/Langfuse 工具)。
5. 约束与恢复
- 核心目标:防止模型“胡来”,出错时能自动止损。
- 关键动作:
- 硬约束:用代码/linter 强制规范(如“生成的代码必须符合公司代码规范”),而非仅靠提示词;
- 自动校验:输出前后检查格式(如“结论必须包含数据来源”)、白名单(仅允许调用特定工具);
- 恢复策略:限流重试(如 API 调用失败后自动重试 3 次)、Token 耗尽时保存进度(如“当前分析到第 5 个指标,保存结果后停止”)。
4. 上下文腐化与治理:避免模型“失忆”
当上下文窗口塞满信息,模型会出现 Context Rot(上下文腐化)——表现为“记不住前面内容”“前后结论矛盾”“忽略关键规则”。这是因为模型的注意力有限,信息过载会导致“疲劳”。
4.1 上下文腐化的治理三原则
1. 召回(RAG 技术)
- 核心:用检索增强生成(RAG)找到最相关的信息(如“分析财报时,优先查近 3 年的财报数据”),避免把无关信息塞进上下文。
2. 压缩(摘要提炼)
- 核心:用提示词约束模型生成关键摘要(如“保留‘结论’和‘数据来源’,其他内容精简 50%”),节省 Token 空间。
3. 组装(结构化存储)
- 核心:按“重要性”分层存储(如“公司规范/约束”放最前面,“历史对话”放中间,“待办事项”放最后),避免“中间遗忘”。
4.2 实战:Agent 跑久了上下文腐化怎么办?
三步治理法,从“临时缓解”到“根本解决”:
1. 上下文压缩:用专门的 Prompt 压缩历史对话(如“生成这轮对话的 3 个关键结论,保留决策依据”),腾出窗口空间;
2. Context Reset:若压缩后仍“失忆”(模型说“我忘了之前的要求”),直接清空上下文窗口,从文件系统恢复状态(如“当前任务进度:分析到第 5 个指标”);
3. 状态外化:关键是状态必须存到文件系统,而非上下文窗口!例如,将“已分析的指标列表”写入 progress.txt,下次调用时直接读取文件,避免依赖模型“记住”。
5. 记忆分层与状态外化:让 Agent 永不“失忆”
关键原则:Agent 的状态不能全放上下文窗口,必须外化到文件系统(如 Git 仓库、本地文件)。上下文窗口仅存“当前任务的关键信息”,而“历史状态、长期记忆、中间结果”需通过文件系统持久化。
5.1 记忆分层:三类生命周期不同的信息
记忆需按“生命周期”分层存储,避免混乱:
- 任务状态:写入 progress.json,记录“当前任务到哪一步了”(如“分析到第 5 个指标,待验证结论”),任务完成后归档;
- 会话中间结果:仅存本轮对话中的关键数据(如“生成的代码片段”),对话结束后丢弃;
- 长期记忆:写入 CLAUDE.md(或类似文件),包含公司规范、工具清单、历史经验等“固定知识”,每次调用时注入。
5.2 实操:分层存储的典型配置
# 项目级记忆(持久化)
.claude/
├── progress.json # 任务状态
├── commands/ # 工具调用记录
├── hooks/ # 自动化脚本(如格式化代码)
├── CLAUDE.md # 公司规范、长期规则
└── settings.json # 工具配置(如 API 密钥)
# 用户级记忆(个性化)
~/.claude/
└── settings.local.json # 本地缓存(如 API 限流参数)
核心逻辑:每次启动新的对话时,上下文窗口清空,但通过读取 progress.json 和 CLAUDE.md,模型能立刻“重启”到正确状态,避免从头开始分析。
6. Claude Code 实操配置:从理论到落地
以 Claude Code 为例,Harness 工程的实操需关注三层配置和自动化钩子:
6.1 三层配置与 Hooks 自动化
项目级配置:.claude/ 下的 CLAUDE.md 定义核心规则(如“代码必须通过 Lint 检查”),hooks/ 存放自动化脚本(如 after-tool-use 钩子自动格式化代码)。
用户级配置:~/.claude/settings.local.json 存放本地参数(如 API 密钥,不纳入版本控制)。
会话级配置:/config 动态注入临时参数(如本次分析的目标指标)。
Hooks 示例:
// hooks/after-tool-use.json
{
"event": "after-tool-use",
"command": "bun run format || true", // 工具调用后自动格式化
"block": false // 非阻塞执行,不影响主流程
}
6.2 子代理(Subagents)并行提速
当任务复杂(如“同时分析 3 个部门的财报”),可通过子代理并行处理:
- 在 agents.json 中定义分工(如“code-reviewer”“test-writer”“doc-generator”);
- 每个子代理独立使用 200K Token 上下文,互不干扰,最后汇总结果。
7. 常见问题与解答
Q1:Context Engineering 和 RAG 是什么关系?
A:RAG 是 Context Engineering 的核心技术,仅解决“召回相关信息”,而 Context 还需“压缩、组装、结构化存储”,RAG 只是其中一步。
Q2:为什么 Harness 比换模型更重要?
A:模型能力提升(如 GPT-4 到 GPT-4o)是“质变”,但 Harness 优化(如工具链、状态管理)是“量变”。在模型迭代放缓的今天,Harness 能让现有模型的能力提升 30%~50%。
Q3:如何避免 Agent 越用越“糊涂”?
A:关键是状态外化+严格分层:将任务状态、中间结果、长期记忆分别存到文件系统,上下文窗口仅存当前关键信息;同时用 Harness 的校验侧(如格式检查、白名单)防止输出错误。
小结
大模型应用工程的核心是“从简单表达到复杂落地”的四层递进:
1. Prompt 是 Context 的一部分:让模型“听懂”需求;
2. Context 是 Harness 的一部分:让模型“知道”用什么信息;
3. Harness 是 Learning Loop 的基础:让模型“持续做对”并优化;
4. 状态外化+分层存储:避免上下文腐化,让模型永不“失忆”。
掌握 Context 与 Harness 工程,你就能让大模型从“听话”到“能干”,最终实现复杂任务的稳定落地。
评论