从 Prompt Engineering 到 Loop Engineering:AI 应用开发的范式迁移
1. 为什么"把提示词写好"不够了
过去一段时间,很多 AI 应用的优化都围绕 Prompt 展开:角色设定、输出格式、few-shot 示例、约束条件、思维步骤、拒答边界、上下文拼接。Prompt Engineering 的确重要,它让模型从"能回答"变成"更像我们想要的方式回答"。
但当应用从一次问答走向真实任务,问题很快发生变化。
用户不只是问"这份合同有什么风险",而是希望系统读取合同、抽取条款、对照公司模板、标记异常、生成修改建议,并在缺少信息时追问。开发者不只是要让模型"回答得好",还要让系统知道下一步该做什么、什么时候调用工具、什么时候重新检索、什么时候承认失败、什么时候停止。
这时,单个 Prompt 已经不是系统的中心。真正的中心变成了一个循环:
- 观察当前状态。
- 判断下一步行动。
- 调用模型或工具。
- 接收结果和反馈。
- 更新状态和记忆。
- 决定继续、回退、重试或结束。
Prompt 仍然存在,但它变成了循环系统中的一个局部组件。AI 应用开发的重点,也开始从 Prompt Engineering 迁移到 Loop Engineering。
2. Prompt Engineering 解决了什么
Prompt Engineering 主要优化的是单次调用质量。它回答的问题包括:
- 如何让模型理解角色和任务边界?
- 如何把上下文组织成模型更容易使用的形式?
- 如何约束输出格式,方便后续解析?
- 如何通过示例减少歧义?
- 如何降低幻觉和无关发挥?
在 RAG 系统里,Prompt 常常承担最后一公里的约束:
text
请只根据给定上下文回答。
如果上下文没有答案,请明确说"资料中没有提供"。
回答时列出依据片段。
这类提示词非常有价值。它能把模型的生成空间压窄,让答案更可控,也让后续评估更容易。
但 Prompt Engineering 的隐含前提是:系统已经拿到了正确上下文,任务已经被正确拆解,模型只需要在这一轮里生成一个高质量输出。
真实应用里,前面的条件经常不成立。
- 检索结果可能不完整。
- 工具调用可能失败。
- 用户需求可能含糊。
- 中间结果可能需要校验。
- 多步任务可能需要动态调整计划。
- 同一个任务可能跨越多轮对话、多个文件、多个外部系统。
这些问题不是靠把 Prompt 写得更长就能解决的。它们需要系统层面的循环设计。
3. Loop Engineering 是什么
Loop Engineering 是围绕 AI 系统运行循环进行设计、实现和调优的工程方法。
它不再只问"这一轮 Prompt 怎么写",而是问:
- 系统如何表示当前任务状态?
- 模型在每一步能看到哪些信息?
- 哪些信息应该留在上下文里,哪些应该放到外部存储?
- 系统什么时候检索,什么时候调用工具,什么时候让用户补充信息?
- 每一步行动后如何判断成功、失败或不确定?
- 失败后是重试、换策略、回滚,还是终止?
- 循环如何避免无限运行、成本失控和错误累积?
一个最小的 Loop 可以写成这样:
python
state = init_state(user_request)
while not should_stop(state):
observation = observe(state)
action = decide_next_action(observation, state)
result = execute(action)
feedback = evaluate(result, state)
state = update_state(state, action, result, feedback)
return final_response(state)
这里的关键不在这段伪代码有多复杂,而在它改变了开发者的注意力。
Prompt Engineering 把模型看成一个"输入到输出"的函数。Loop Engineering 把模型看成一个"循环控制系统"里的决策器、生成器、评估器或工具使用者。
4. 从一次回答到一个循环系统
一次模型调用通常是线性的:
text
用户输入 -> Prompt 拼接 -> 模型生成 -> 返回答案
一个 Agent 或复杂 RAG 应用更像是循环的:
text
用户目标
-> 任务状态
-> 检索或工具调用
-> 模型判断
-> 中间产物
-> 校验反馈
-> 状态更新
-> 下一步行动
-> 最终交付
这两种系统的工程难点完全不同。
在线性调用里,开发者最关心的是输入质量和输出格式。调优手段通常是改 Prompt、换模型、改检索参数、补 few-shot。
在循环系统里,开发者还要关心状态漂移、错误传播、循环终止、工具幂等性、长期记忆污染、观测日志、成本预算和恢复能力。
例如,一个自动分析代码仓库的 Agent,如果第一次检索错了文件,后面生成的解释和修改建议都可能建立在错误基础上。更好的 Prompt 可以缓解这个问题,但更根本的设计是让系统具备校验和回路:
- 读取文件前先定位入口和依赖。
- 修改前先运行相关测试或静态检查。
- 修改后对比 diff,确认没有无关变更。
- 测试失败时进入调试循环,而不是继续编造成功结论。
- 无法验证时明确输出不确定性。
这就是 Loop Engineering 的味道:它把"模型生成"放回到一个可观察、可控制、可恢复的工程流程中。
5. Loop 的核心构件
一个可靠的 Loop 通常至少包含六个构件。
5.1 目标
目标定义系统要完成什么,以及什么算完成。
如果目标含糊,循环就容易发散。比如"帮我优化知识库"不是一个好目标,因为它没有说明优化什么指标。更好的目标是:"在不增加太多成本的前提下,让客服 FAQ 的 Top-3 召回命中率从 70% 提升到 85%。"
目标越清晰,后续的行动选择、评估和终止条件越容易设计。
5.2 状态
状态是循环的工作记忆。它记录当前任务进展、已知事实、已尝试动作、中间结果、失败原因和待处理问题。
状态不应该只存在于自然语言上下文里。生产系统通常需要结构化状态:
json
{
"task_id": "contract_review_001",
"phase": "clause_extraction",
"documents_loaded": ["contract.pdf", "template.md"],
"open_questions": [],
"failed_actions": [
{
"tool": "pdf_parser",
"reason": "scanned pages require OCR"
}
]
}
结构化状态可以被程序检查,也可以被模型读取。它是让 Agent 从"会聊天"走向"会做事"的基础。
5.3 行动
行动可以是模型生成,也可以是工具调用、数据库查询、代码执行、文件修改、用户追问或任务拆分。
好的行动设计需要明确输入输出 Schema、错误类型和副作用。尤其是会修改外部世界的工具,例如发邮件、下单、改数据库、提交代码,必须有权限、确认和回滚设计。
一个常见错误是把工具列表直接塞给模型,然后期待模型自己用对。更稳的方式是让系统在外层控制可用工具、调用条件和结果校验。
5.4 反馈
反馈告诉系统刚才的行动是否有效。
反馈可以来自很多地方:
- 工具返回值。
- 单元测试结果。
- 检索命中文档。
- 用户确认。
- 规则校验。
- 另一个模型的评审。
- 业务指标或线上日志。
没有反馈,Loop 只是重复调用模型。有了反馈,系统才有机会从错误中校正。
5.5 记忆
记忆决定哪些信息能跨步骤、跨会话、跨任务复用。
对 Agent 系统来说,记忆至少可以分成三类:
- 语义记忆:用户偏好、业务事实、领域知识。
- 情景记忆:过去任务的执行过程、失败原因、成功路径。
- 程序记忆:可复用的工作流、Prompt、工具用法、检查清单。
记忆不是越多越好。没有治理的记忆会变成噪声,甚至污染后续决策。工程上需要为记忆设计来源、时间、置信度、适用范围和失效机制。
5.6 终止条件
Loop 必须知道什么时候停。
常见终止条件包括:
- 目标已满足。
- 达到最大步数或成本预算。
- 连续多次失败且没有新信息。
- 需要用户输入才能继续。
- 风险超过自动执行边界。
- 验证通过,可以交付结果。
没有终止条件的 Agent 很容易陷入"再试一次"的幻觉式勤奋。看起来很努力,实际上只是在消耗 token 和时间。
6. 在 RAG 和 Agent 系统里的体现
在传统 RAG 中,开发者常常关注四件事:切分、Embedding、召回、Prompt。它们当然重要,但如果要让 RAG 进入复杂任务,就需要加入 Loop 思维。
比如用户问:"我们公司报销政策里,海外差旅住宿有没有金额上限?"
一次性 RAG 可能流程是:
text
检索相关片段 -> 拼进 Prompt -> 生成答案
Loop 化之后,流程可以更稳:
- 判断问题类型:政策问答。
- 检索报销政策、差旅政策、海外差旅补充说明。
- 检查召回片段是否覆盖"海外""住宿""金额上限"三个关键条件。
- 如果缺失关键条件,扩大检索或追问。
- 生成答案。
- 校验答案中的金额、币种、适用地区是否能在原文中找到依据。
- 输出结论和引用。
Agent 系统也是类似。一个能长期运行的 Agent 不只是"LLM + tools",而是"目标 + 状态 + 工具 + 反馈 + 记忆 + 终止条件"的组合。
框架可以帮助实现这些能力,但不能替代这些设计。无论使用 LlamaIndex、LangGraph、AutoGen,还是自己写编排层,核心问题都绕不开:循环如何被定义、观测、约束和评估。
7. 工程挑战
Loop Engineering 带来的不是魔法,而是一组更真实的工程问题。
7.1 不可控性
模型输出具有概率性,工具环境具有不确定性,用户目标也可能变化。循环系统必须承认不确定性,并把它显式建模。
例如,不要只让模型输出"下一步做什么",还可以要求它输出置信度、所依赖的事实和失败备选项。外层系统再根据这些字段决定是否执行。
7.2 可观测性
没有日志的 Agent 很难调试。
生产环境至少应该记录:
- 每一步的输入、输出和状态摘要。
- 调用过的工具和参数。
- 检索命中的文档和分数。
- 模型选择行动的理由。
- 失败、重试和终止原因。
- token、延迟和成本。
可观测性不是上线后才补的仪表盘,而是 Loop 设计的一部分。
7.3 评估
Prompt 可以用样例集评估,Loop 也需要评估,但评估对象更复杂。
你不只要评估最终答案,还要评估过程:
- 是否选对工具?
- 是否检索到关键证据?
- 是否在证据不足时追问?
- 是否避免了危险操作?
- 是否在失败时给出真实原因?
- 是否在预算内完成?
这类评估更接近工作流测试,而不是单轮问答测试。
7.4 成本
循环天然会增加调用次数。没有预算控制的 Agent 很容易把一个简单任务变成昂贵任务。
成本控制可以放在多个层面:
- 简单任务走短路径。
- 只有不确定时才触发额外检索或评审。
- 把稳定规则放到代码里,不要每次都交给模型判断。
- 对中间结果做缓存。
- 为每个任务设置最大步数、最大 token 和最大工具调用次数。
好的 Loop 不是越复杂越好,而是能在复杂度和可靠性之间找到平衡。
8. 开发者能力模型的变化
从 Prompt Engineering 到 Loop Engineering,开发者需要的能力也在变化。
以前的重点是会写 Prompt:
- 会描述角色。
- 会给示例。
- 会约束格式。
- 会组织上下文。
现在还需要会设计系统:
- 会把任务拆成可验证步骤。
- 会管理状态和记忆。
- 会设计工具边界。
- 会处理失败和重试。
- 会做过程评估。
- 会控制成本和延迟。
- 会把模型能力嵌入传统软件工程。
这不是说 Prompt 不重要。相反,Prompt 会变得更专业,因为它不再孤立存在,而是嵌入到不同节点中:规划 Prompt、检索改写 Prompt、工具选择 Prompt、答案生成 Prompt、评审 Prompt、反思 Prompt。
真正的变化是:Prompt 从"应用本身"变成了"循环里的局部策略"。
9. 一个实用的 Loop 设计清单
设计一个 AI 应用时,可以先问这组问题:
- 用户目标是什么?完成条件能否被检查?
- 任务需要哪些阶段?哪些阶段必须由模型参与?
- 每一步的状态如何表示?哪些字段必须结构化?
- 模型能调用哪些工具?工具的输入输出和错误如何定义?
- 每一步行动后,系统如何获得反馈?
- 什么时候重试?什么时候换策略?什么时候向用户追问?
- 哪些信息应该进入短期上下文?哪些应该进入长期记忆?
- 记忆如何写入、更新、删除和失效?
- 如何记录每一步,方便调试和审计?
- 如何评估最终结果和中间过程?
- 最大步数、最大成本、最大延迟是多少?
- 哪些操作需要用户确认或人工审批?
如果这些问题没有答案,系统很可能只是一个"看起来像 Agent 的聊天界面"。如果这些问题有清晰答案,即使模型能力一般,系统也会更稳定、更可调、更容易上线。
10. 结语:未来不是更长的 Prompt,而是更好的 Loop
Prompt Engineering 是 AI 应用开发的入口。它让我们学会如何和模型沟通,如何把需求转成模型可执行的文本。
但 Agent 时代的核心问题已经不只是沟通,而是控制。系统要能在多步任务中保持方向,在不确定环境中获取反馈,在失败后修正路线,在成本边界内交付结果。
这就是 Loop Engineering 的价值。
未来的优秀 AI 应用,不会只是拥有一段神奇的 Prompt。它们会拥有清晰的状态模型、可靠的工具边界、可观测的执行轨迹、可治理的记忆系统、可验证的评估机制,以及知道何时停止的循环。
Prompt 决定模型这一轮怎么说。Loop 决定系统能不能把事情做完。