从 Prompt 到 Loop:理清 AI Agent 工程的概念演进
如果你最近关注 AI Agent 领域,一定被各种新术语轰炸过:Prompt Engineering、Context Engineering、Harness Engineering、Loop Engineering……这些带"Engineering"后缀的概念层出不穷,让人眼花缭乱。
它们到底是什么关系?是技术演进的不同阶段,还是互相包含的层级结构?当别人在会议上说"我们在做 Loop Engineering"时,他到底在说什么?
这种困惑不止你一个人有。在和同行讨论 agent 系统时,经常出现这种状况:
- 老板说"Harness",可能指的是 Claude Code 这个产品
- 同事说"Harness",可能指的是 解决问题和评估的agent分开 这种设计模式
- 你说"Harness",可能指的是项目里的 AGENT.md 配置文件
三个人用同一个词,说的完全不是同一个东西。这篇文章的目的就是把这些边界理清楚。
这篇文章适合谁?
- 工程师:在构建 agent 系统时需要做架构决策、和团队对齐术语
- 产品/业务/管理者:想理解工程师在说什么,做技术选型时心里有底
- 研究者/学生:想了解工业界 agent 工程的概念演进,看清论文和产品之间的关系
- 任何想搞清楚概念的人:哪怕只是刷推特被术语轰炸得头晕,想找一张地图
我查阅了大量论文和工程实践文章,包括 Anthropic、LangChain、学术界的权威资料。核心发现是:这些概念不是简单的上下层级关系,而是抽象程度的演进。从 Prompt 到 Loop,解决的问题越来越宏观,但它们并非互斥,而是互相包含和补充。
读完这篇文章,你将能够:
- 在讨论中精确表达:不再笼统地说"multi-agent 系统",而是说"topology=multi, coordination=orchestration 的 harness 切片"
- 做技术判断时更清晰:无论是做架构决策还是评估别人的方案,都能用同一套框架思考
让我们开始这趟概念之旅。
一、Prompt Engineering:LLM 时代的"调参"
如果说传统机器学习的调参是需要考虑特征权重与统计边界的寻优,而深度学习时代的调参是摸索网络架构与梯度下降的动力学,那么 LLM 时代的‘调参’就是 Prompt Engineering——通过自然语言的上下文来激活知识与对齐意图。
Prompt Engineering 解决的核心问题是:面对一个具体任务,如何用一段精心设计的自然语言输入(包括指令、示例、格式约束、推理引导等),让模型在一次调用中就给出准确、符合预期的输出?
具体包含几个子问题:
- 怎么把任务讲清楚:指令的措辞、结构、强调方式,让模型准确理解你的意图,而不是字面解读后跑偏
- 要不要给示例:用 few-shot examples 展示期望的输入输出模式,借助模型的 in-context learning 能力让它快速习得任务规律
- 要不要引导推理:通过 Chain-of-Thought 等技巧让模型显式生成中间推理步骤,在数学、常识、符号推理等任务上提升准确率
- 怎么约束输出:格式(JSON / Markdown / XML)、风格、范围限制,让结果可解析、可复用、可被下游系统消费
这里也包含两部分考虑:
- 让结果更准:通过措辞、结构、示例、推理引导,把模型"一次做对"的概率拉到最高
- 让结果更稳定:通过温度控制、Schema 约束、Self-Consistency 等,降低输出的随机性,让相同输入产生可复现的结果
在模型还比较弱的时代(2022-2024),prompt 的好坏极大程度地影响了生成质量。当时 agent 的概念还没有兴起,人们更多关注的就是这个"单次调用如何更好出结果"的问题。
那个时期积累了大量"调参"技巧:
| # | 技巧 | 背后的原理 / 实证 |
|---|---|---|
| 1 | 重要信息放开头和结尾 | Transformer 注意力在长上下文中呈 U 型衰减,中间位置容易被忽略(Lost in the Middle)。2025 年先进模型依然存在:GPT-4o 在 32K 上下文时准确率从 99.3% 掉到 69.7% |
| 2 | 输出结构化数据时优先用类型/Schema 描述,而非自然语言描述 | 模型在预训练中见过大量代码与类型定义语料,对 TypeScript interface / JSON Schema / Pydantic 这类结构化描述的识别与遵守度显著优于自然语言描述 |
| 3 | 关键约束用强调标记并复述 1-2 次 | 重复关键指令能强化注意力权重,已被实证列入可测量提升 LLM 准确率的 prompt 原则之一 |
| 4 | 对推理类任务加上 CoT 引导 | 让模型显式生成中间推理步骤(Chain-of-Thought),在数学、常识、符号推理任务上大幅提升表现。最简单形式:prompt 末尾加 "Let's think step by step" |
| 5 | 对有客观正确解的任务使用 Self-Consistency | 在较高温度下采样多条推理链、对最终答案做多数投票,能显著提升准确率 |
| 6 | 给 2-5 个高质量示例(Few-shot) | 大模型具备 in-context learning 能力,无需梯度更新就能从示例中习得任务模式 |
| 7 | 要稳定/可重复的输出时把温度调到 0 | 低温使 softmax 趋近 argmax,输出趋向贪心解码、随机性显著下降。即使温度=0 仍存在一定隐藏随机性,但已经足够稳定 |
| 8 | 长上下文末尾完整重复一次核心提示词 | 打破因果语言模型"从左到右单向阅读"的注意力物理局限,使模型处理第二遍时能全局回溯。Google Research 2025 年研究证实这种 "prompt 复述" 在非 reasoning 模式下普遍提升性能 |
但很多技巧在模型强大并引入推理能力之后,变得没那么重要了。现在的 prompt 变得更简单更直观:讲清楚你想要做的事情。
当然,如果想要达到更极致的效果,或者使用一些本地模型、小模型,这些技巧仍然有价值。
但很快大家发现,单纯调 prompt 远远不够。即使 prompt 构建得再好,如果没有把必要的知识(领域知识、上下文信息)放进上下文里,最终效果还是会很差,LLM 的幻觉会很严重。
这就引出了 Context Engineering。
二、Context Engineering:给模型看什么
Context Engineering 解决的核心问题是:我有一堆信息和上下文,应该给模型看什么,以及怎么给?
具体包含两个子问题:
- 选什么内容放到 LLM 的上下文中:从海量数据中检索相关信息
- 已经选好了上下文后怎么给到模型:内容的排序、格式化
这里包含了两部分考虑:
- 让结果更准:放的内容和格式会影响 LLM 的输出质量
- 让成本更低:context window 是稀缺资源,要高效利用;还要从推理效率上考虑成本
Context Engineering 不是 Prompt Engineering
Context Engineering 和 Prompt Engineering 的区别在于:Prompt 关心"怎么说",Context 关心"给什么信息"。你的 prompt 可以写得很完美,但如果缺少必要的领域知识、业务上下文、关键信息,模型一样会产生幻觉。
这个视角的转变,在 2025 年中已经成为行业共识的关键节点。Shopify CEO Tobi Lütke 在 2025 年 6 月公开表态:
"I really like the term 'context engineering' over prompt engineering. It describes the core skill better: the art of providing all the context for the task to be plausibly solvable by the LLM." (我更喜欢 'context engineering' 这个词,而不是 'prompt engineering'。它更准确地描述了这项核心技能:为任务提供所有相关上下文,让 LLM 有可能解决这个任务的艺术。)
紧接着,Andrej Karpathy 公开背书,并给出了更工程化的定义:
"+1 for 'context engineering' over 'prompt engineering'. People associate prompts with short task descriptions you'd give an LLM in your day-to-day use. When in every industrial-strength LLM app, context engineering is the delicate art and science of filling the context window with just the right information for the next step." (+1,赞成用 'context engineering' 替代 'prompt engineering'。人们会把 prompt 联想到日常使用 LLM 时给的一小段任务描述。但在每一个工业强度的 LLM 应用里,context engineering 是一门精细的艺术与科学:为下一步把恰到好处的信息填进 context window。)
"prompt" 这个词容易让人联想到"写一句措辞精巧的指令",但真正决定模型表现的,是把哪些信息、以什么形式、按什么顺序塞进 context window——这是一个系统工程问题,而不是文学问题。Karpathy 强调:人们把 "prompt" 联想成"短小、措辞巧妙的指令",但真正的技能要宽得多——它涵盖信息检索、工具结果、对话历史、示例选择的整套组装工作。
Context Engineering 的关键维度
Context Engineering 涉及多个维度的优化,先把 6 个维度并列出来一览:
| # | 维度 | 核心关注点 |
|---|---|---|
| 1 | 外部知识的检索与组织 | 从外部知识库找内容、决定排序方式 |
| 2 | 工具定义与 Schema 设计 | 向模型描述"有哪些能力可用" |
| 3 | 对话历史与记忆管理 | 保留什么、丢弃什么、怎么跨 session 检索 |
| 4 | 格式与结构化 | 用什么格式(纯文本 / Markdown / XML / JSON)让模型认知负荷最低 |
| 5 | Token Budget 管理 | 何时压缩、何时 offload、何时读回 |
| 6 | Context Caching | 把稳定不变的内容标记为缓存前缀,命中即 0.1× 价格 |
下面逐项展开。
1. 外部知识的检索与组织
这是最典型的场景,包括:
- RAG(检索增强生成):从外部知识库检索相关内容
- 语义检索:使用向量嵌入进行相似度匹配
- Reranking:对检索结果进行二次排序
关键:
- 原文顺序 vs 相关度顺序:传统 RAG 按相似度降序排列检索结果,但这会破坏文本的逻辑流、时序进展、指代关系。保持原文顺序(OP-RAG)能用更少的 token 实现更好的效果
2. 工具定义与 Schema 设计
Context Engineering 也包含如何向模型描述可用的工具:
- Tool schema 的结构化:JSON Schema、TypeScript interface、Function signature
- Tool description 的清晰度:决定模型能否正确选择和调用工具
- 参数说明的精确性:影响工具调用的参数准确率
这部分看似是"工具定义",但本质上是在构建模型的上下文——告诉模型"有哪些能力可用"。
3. 对话历史与记忆管理
- 对话历史的压缩与过滤:保留关键信息,丢弃冗余内容
- 长期记忆的检索:从历史对话中提取相关上下文
- 工作记忆的维护:当前任务的临时状态
4. 格式与结构化
不同的格式对模型的认知负荷差异巨大:
| 格式 | 适合场景 | 注意点 |
|---|---|---|
| 纯文本 | 向量嵌入构建 | Token 利用率最高 |
| Markdown | 文档/对话 | 模型"原生认知结构",预训练语料大量存在,理解力可提升 |
| XML 标签 | 多文档边界控制 | 严格边界,防止多文档语义污染 |
| JSON / YAML | 数据交换 | 高认知负荷,容易产生"语法正确但内容幻觉"的输出 |
5. Token Budget 管理
在有限的上下文窗口内:
- 什么时候触发 compaction(压缩)
- 哪些内容 offload 到磁盘
- 如何按需读回之前的内容
6. Context Caching(上下文缓存)
在 agent 的实际运行中,绝大多数 token 是被反复重发的:system prompt、tool schemas、few-shot 示例、规则说明、长文档背景——这些内容每次工具调用都会原封不动地塞回 context window。Context caching 就是针对这一现象的工程优化:把稳定不变的内容标记为"缓存前缀",只为第一次付比较昂贵的cache write的费用,之后命中缓存,基本只需要1/10的cache read的价格。
以 Anthropic prompt caching 为例,量级差异是显著的:
| 维度 | 数值 | 备注 |
|---|---|---|
| 写入(cache write) | 1.25× base input price | 只付一次 |
| 读取(cache hit) | 0.1× base input price | 比正常 input 便宜 90% |
| 首 token 延迟(TTFT) | 下降约 85% | — |
| TTL | 默认 5 分钟,可延长至 1 小时 | — |
对一个典型的 coding agent 而言,system prompt + tool definitions 动辄上万 token,每一轮工具调用都重复发一次。如果不做 caching,这一块就是持续不断的成本黑洞;做了 caching 之后,它从"每轮都要付的过路费"变成了"一次性投入 + 极低的复用成本"。
要让缓存真正命中,工程上有几条原则:
| 原则 | 做什么 | 反面教材 |
|---|---|---|
| Stable prefix | 把不变的内容放在 context 最前面,动态内容(用户消息、工具结果、时间戳)放后面 | 任何前缀位置的字符变动都会让后面的缓存失效 |
| 避免无谓的破坏 | 检查前缀里不要混入会变的内容 | 日期、随机 ID、自增计数器这类"看似无害"的字段如果放在前缀里,会让整个缓存秒级失效——这种坑在生产中非常常见 |
Context Engineering 的局限
Context Engineering 解决的是"已经选好内容后怎么组织"的问题。它假设你需要的信息是可获取的、有边界的——但真实场景下,单靠组织上下文是远远不够的:
- Agent 怎么主动去找信息?(工具调用、检索流程)
- Agent 如何安全地运行?(沙箱、权限)
- Agent 如何跨多个 session 持续工作?(状态持久化、调度)
- 什么时候应该把上下文压缩、卸载、读回?(生命周期管理)
这些是 Context Engineering 本身回答不了的——它们关心的不是"模型这一步看什么",而是"整套系统怎么运转"。要回答这些问题,需要把视角从"单次调用的上下文"抬升到"整个 agent 系统的工程框架",这就是下一节要展开的主题。
三、Harness Engineering:Agent = Model + Harness
到了 Harness Engineering 这一层,视角发生了根本性的转变。如果说 Prompt 和 Context Engineering 关注的是"怎么跟模型说话"和"给模型看什么",那么 Harness Engineering 关注的是:如何把模型变成一个可以信赖的、能自主完成任务的 Agent。
Harness的定义简洁,却带来了混乱
按照 LangChain 的定义:Agent = Model + Harness,也就是说,模型之外的所有东西都是 Harness。这个定义很简洁,但在实践中会导致混乱:
- 你说"Harness",可能指的是 Claude Code 这个产品
- 我说"Harness",可能指的是 Initializer + Coding Agent 这种设计模式
- 他说"Harness",可能指的是他项目里的 AGENT.md 配置文件
三个人用同一个词,说的完全不是同一个东西。这就像说"软件工程"——你可能在说设计模式,也可能在说编程语言,也可能在说某个具体的代码库。
问题的根源在于:Harness 的范围太广了。
如果不对 Harness 进行分层,我们就无法精确讨论问题。
解决手段就是,将Harness再拆一拆,拆成多个可以用来讨论的概念.
Harness 的分层结构
更多推荐




所有评论(0)