写在前面 如果你读过本系列之前的 ReAct 模式 、Tool Use 、Memory 记忆系统 、RAG 检索增强 等文章,你会发现一个共同点——所有这些能力的”开关”,都藏在 Prompt 里 。
ReAct 的思考链靠 Prompt 驱动,Tool Use 的工具描述靠 Prompt 传递,Memory 的上下文靠 Prompt 拼接,RAG 的检索结果靠 Prompt 注入。Prompt 就像 Agent 的灵魂,写得好,Agent 聪明得像人;写得差,Agent 蠢得像块石头。
今天这篇,我们聊聊 Prompt Engineering ——不是那种”请你帮我写个 Prompt”的入门科普,而是从工程视角 出发:System Prompt 的底层原理是什么?为什么有些 Prompt 写法效果好?在 Java 生态中,Spring AI 和 LangChain4j 分别怎么管理 Prompt?企业级场景下怎么组织多层提示词架构?
一、Prompt 的本质:你和模型之间的”合约” 1.1 先搞清楚一个认知误区 很多人以为 Prompt 就是”给模型写的一段话”。这个理解没错,但太浅了。
Prompt 本质上是你和模型之间的一份合约 。你在这份合约里规定了模型的角色、行为边界、输出格式、思考方式。模型拿到这份合约后,会在它的概率空间里找到一个最符合合约描述的”人格切片”。
这就解释了为什么”你是一个有 10 年经验的 Java 架构师”和”回答以下问题”会让同一个模型给出完全不同质量的答案——不是模型变聪明了,而是你激活了不同的参数子空间。
1.2 System Prompt vs User Prompt:两种不同的”信号” 在 Chat API 中,消息分为三种角色:
1 2 3 4 5 ┌─────────────────────────────────────────────────────┐ │ System Prompt → "你是谁,怎么做事"(底层指令) │ │ User Prompt → "用户想问什么"(具体任务) │ │ Assistant Prompt → "模型之前说了什么"(对话历史) │ └─────────────────────────────────────────────────────┘
System Prompt 之所以特殊 ,是因为它在 Attention 计算中通常被赋予更高的权重。虽然 OpenAI 等厂商没有公开具体的权重机制,但从实验结果来看,System Prompt 的指令对模型行为的约束力远强于同等长度的 User Prompt。
用一个类比:User Prompt 像是”今天我想吃什么”,System Prompt 像是”我是一个素食主义者”。前者改变一次决策,后者改变所有决策。
1.3 Token 经济学:为什么 Prompt 长度很重要 每个 Prompt 都要消耗 Token,而 Token 意味着钱和延迟。理解 Token 经济学是工程化 Prompt 设计的基础:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ┌───────────────────────────────────────────────────────┐ │ Prompt 长度的三个代价 │ │ │ │ 💰 成本:每千 Token 都要花钱 │ │ - GPT-4o System Prompt 2000 Token ≈ ¥0.04/次 │ │ - 100 个并发用户 × 10 次/天 = ¥40/天 │ │ │ │ ⏱️ 延迟:Prompt 趱长,首 Token 延迟越高 │ │ - 1000 Token → ~200ms │ │ - 4000 Token → ~500ms │ │ - 16000 Token → ~1500ms │ │ │ │ 🧠 注意力稀释:信息越多,模型越容易"走神" │ │ - Lost in the Middle 现象:中间信息容易被忽略 │ │ - 关键指令应放在开头或结尾 │ └───────────────────────────────────────────────────────┘
“Lost in the Middle” 是 2023 年斯坦福的一项研究发现:当上下文很长时,模型对开头和结尾 的信息注意力最强,对中间 的信息注意力最弱。这意味着——
你的 System Prompt 如果很长,关键指令一定要放在最前面或最后面。
二、System Prompt 设计的五层架构 一个好的 System Prompt 不是随手写的几句话,而是有结构的。我把它总结为五层架构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌─────────────────────────────────────────────────────────┐ │ 第 1 层:角色定义 │ │ "你是一个企业级 Java 架构师助手" │ ├─────────────────────────────────────────────────────────┤ │ 第 2 层:能力边界 │ │ "你擅长 Spring Boot、微服务、数据库设计" │ │ "你不会提供投资建议或医疗诊断" │ ├─────────────────────────────────────────────────────────┤ │ 第 3 行为规范 │ │ "回答先给结论,再展开解释" │ │ "代码示例用 Java 21,Spring Boot 3.x" │ │ "不确定的事情明确说不确定" │ ├─────────────────────────────────────────────────────────┤ │ 第 4 层:输出格式 │ │ "用 Markdown 格式输出" │ │ "代码块标注语言" │ │ "长回答分小节" │ ├─────────────────────────────────────────────────────────┤ │ 第 5 层:动态注入 │ │ "当前用户角色:{role}" │ │ "检索到的相关文档:{context}" │ │ "可用工具列表:{tools}" │ └─────────────────────────────────────────────────────────┘
为什么要分层? 因为每一层的更新频率不同:
层级
更新频率
典型场景
角色定义
几乎不变
产品定型后就固定
能力边界
偶尔调整
新增能力或合规要求变化
行为规范
随迭代优化
发现模型回复质量问题时调整
输出格式
按场景切换
给用户的 vs 给系统的格式不同
动态注入
每次请求
用户信息、检索结果、工具列表
分层设计让你不需要每次都重写整个 Prompt,只需要替换变化的部分。
三、核心技巧:从原理到实践 3.1 Chain-of-Thought(CoT):让模型”想出来” CoT 是最经典的 Prompt 技巧。核心思想很简单:让模型先想再说 。
原理 :Transformer 的每一层都是对上一层表示的”精炼”。当你要求模型”一步步思考”时,你在给模型更多的计算步骤来处理问题——相当于从 12 层 Transformer 的思考,变成了”12 层 × N 步”的思考。
1 2 3 4 5 6 7 8 9 10 11 12 ❌ 普通 Prompt: Q: 一个商店有 23 个苹果,卖了 7 个,又进了 12 个,还剩多少? A: 28 ✅ CoT Prompt: Q: 一个商店有 23 个苹果,卖了 7 个,又进了 12 个,还剩多少? 请一步步思考。 A: - 初始:23 个 - 卖了 7 个:23 - 7 = 16 个 - 又进了 12 个:16 + 12 = 28 个 - 答案:28 个
对于 Agent 场景,CoT 的价值更大。还记得 ReAct 模式 中的 Thought-Action-Observation 循环吗?ReAct 本质上就是 CoT 的工程化实现 ——模型在执行工具调用前,先用自然语言描述自己的推理过程。
3.2 Few-shot:用例子教模型”格式” Few-shot 比”请用以下格式输出”有效 10 倍。原因很直观:模型通过示例学格式,比通过描述学格式快得多 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 System Prompt: 你是一个代码审查助手。请按以下示例的格式输出审查结果。 示例输入: public void process(String name) { String sql = "SELECT * FROM users WHERE name = '" + name + "'"; db.execute(sql); } 示例输出: 🔴 严重:SQL 注入漏洞 - 位置:process() 方法第 2 行 - 问题:直接拼接用户输入构造 SQL - 修复:使用 PreparedStatement 参数化查询 - 影响:攻击者可执行任意 SQL 请审查以下代码: {code}
关键要点 :
示例要有代表性 ,覆盖你期望的输出风格
示例要有多样性 ,包括简单和复杂的 case
示例数量通常 2-3 个 就够,太多会浪费 Token
3.3 自我一致性(Self-Consistency):多数投票 这是 2022 年 Google 提出的技术,核心思想是:同一个问题问模型多次,取多数票 。
1 2 3 4 5 6 7 8 9 温度 = 0.7 时: 第 1 次回答:答案是 A 第 2 次回答:答案是 A 第 3 次回答:答案是 B 第 4 次回答:答案是 A 第 5 次回答:答案是 A 多数票 → A(4/5)
在 Agent 场景中,这可以用于关键决策节点 ——比如让 Agent 对”是否需要调用工具”做多次判断,减少误触发。
3.4 结构化 Prompt:用 XML/JSON 约束输出 还记得 Spring AI 结构化输出 那篇文章吗?Prompt 层面的结构化约束是另一种思路——直接在 Prompt 中告诉模型”你只能输出以下格式”:
1 2 3 4 5 6 7 8 9 10 11 12 13 System Prompt: 分析用户的问题,输出以下 JSON 格式: { "intent": "分类意图", "confidence": 0.0-1.0, "entities": [ {"type": "实体类型", "value": "实体值"} ], "response_strategy": "direct|search|clarify" } 只输出 JSON,不要输出其他内容。
为什么结构化输出在 Prompt 层面很重要?
因为 Agent 的下游逻辑需要解析模型输出。如果模型返回自然语言,你需要再写一层解析逻辑;如果模型直接返回 JSON,你可以直接 JSON.parse(),省掉一层 NLU。
结构化输出 = Prompt 层面的 Schema 约束 + 生成层面的 Grammar 约束。两者配合才能实现可靠的结构化输出。
四、Prompt 与 Agent 组件的交互 Prompt 不是孤立存在的。在 Agent 架构中,Prompt 是连接各个组件的”总线”。
4.1 Prompt + Memory 当你为 Agent 添加 Memory 记忆系统 时,记忆是以 Prompt 的形式注入的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 System Prompt: 你是一个个人助手。 [长期记忆] - 用户是 Java 开发者,偏好 Spring Boot - 用户在北京,时区 UTC+8 - 用户不喜欢冗长的回答 [短期记忆 - 最近对话] 用户:帮我写个排序算法 助手:好的,这是冒泡排序... 用户:有没有更快的? 助手:快速排序更适合... [当前问题] 用户:{new_message}
这里有个关键的工程问题:记忆注入的位置和格式。
研究表明,记忆放在 System Prompt 的中间偏后 位置效果最好——既不会覆盖角色定义(开头),也不会被当前问题挤掉注意力(末尾)。
4.2 Prompt + RAG 在 RAG 场景 中,检索到的文档需要注入 Prompt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 System Prompt: 基于以下参考资料回答用户问题。 如果参考资料不足以回答,请明确说明。 不要编造参考资料中没有的信息。 --- 参考资料: [1] 文档标题:Spring Boot 自动配置原理 内容:Spring Boot 的自动配置基于 @EnableAutoConfiguration... [2] 文档标题:Spring Boot Starter 机制 内容:Starter 是一组依赖的集合... --- 用户问题:{question}
RAG Prompt 的三个陷阱 :
信息过载 :塞太多检索结果,反而让模型”迷路”。通常 Top 3-5 条结果足够。
来源冲突 :不同文档说法矛盾时,Prompt 要给模型”裁判规则”(如优先信源)。
幻觉转移 :模型可能忽略参考资料,直接用自身知识回答。需要强约束:”只基于参考资料回答”。
在 Tool Use 场景 中,工具的描述本身就是 Prompt 的一部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 System Prompt: 你可以使用以下工具: ## search_knowledge_base 描述:搜索企业知识库 参数: - query (string, 必填): 搜索关键词 - top_k (int, 可选): 返回结果数量,默认 5 使用场景:当用户询问公司内部知识时使用 ## send_email 描述:发送邮件 参数: - to (string, 必填): 收件人邮箱 - subject (string, 必填): 邮件主题 - body (string, 必填): 邮件正文 使用场景:当用户要求发送邮件时使用 --- 请根据用户的问题,判断是否需要调用工具。 如果需要,输出工具调用的 JSON 格式。 如果不需要,直接回答用户问题。
工具描述的质量直接影响调用准确率。 一个常见的坑是工具描述太简略——搜索知识库 这五个字的信息量远不如上面那段带参数说明和使用场景的描述。
五、Java 生态实战:Spring AI 与 LangChain4j 5.1 Spring AI 的 Prompt 模板引擎 Spring AI 提供了 PromptTemplate 类,基于 ST4(StringTemplate 4)模板引擎:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 import org.springframework.ai.chat.prompt.Prompt;import org.springframework.ai.chat.prompt.PromptTemplate;import org.springframework.stereotype.Service;@Service public class AgentPromptService { private static final String SYSTEM_PROMPT = """ 你是一个 {role}。 ## 能力 {capabilities} ## 行为规范 - 回答先给结论,再展开解释 - 代码示例使用 {language} {version} - 不确定的事情明确说"我不确定" ## 输出格式 {output_format} """ ; private static final String RAG_PROMPT = """ 基于以下参考资料回答用户问题。 如果参考资料不足,说明信息不完整。 --- 参考资料: {context} --- 用户问题:{question} """ ; public Prompt buildSystemPrompt (String role, String capabilities, String language, String version, String outputFormat) { PromptTemplate template = new PromptTemplate (SYSTEM_PROMPT); return new Prompt ( List.of(template.createMessage( Map.of( "role" , role, "capabilities" , capabilities, "language" , language, "version" , version, "output_format" , outputFormat ), org.springframework.ai.chat.model.ChatModelMessage.SYSTEM )) ); } public Prompt buildRagPrompt (String question, List<String> references) { String formattedContext = IntStream.range(0 , references.size()) .mapToObj(i -> "[%d] %s" .formatted(i + 1 , references.get(i))) .collect(Collectors.joining("\n\n" )); PromptTemplate template = new PromptTemplate (RAG_PROMPT); return new Prompt (template.create( Map.of("context" , formattedContext, "question" , question) )); } }
**Spring AI Prompt 的核心设计思路是”模板化 + 结构化”**。PromptTemplate 把 Prompt 当作带变量的模板,运行时填充变量。这比字符串拼接优雅得多,也更安全(避免注入攻击)。
5.2 LangChain4j 的 SystemMessage 构建 LangChain4j 的 API 风格更函数式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 import dev.langchain4j.service.SystemMessage;import dev.langchain4j.service.UserMessage;import dev.langchain4j.service.V;import dev.langchain4j.service.TokenStream;import dev.langchain4j.data.message.SystemMessage;import dev.langchain4j.data.message.UserMessage;import dev.langchain4j.data.message.AiMessage;import dev.langchain4j.data.message.ChatMessage;import dev.langchain4j.data.message.ToolExecutionResultMessage;import dev.langchain4j.memory.ChatMemory;import dev.langchain4j.memory.chat.MessageWindowChatMemory;import dev.langchain4j.model.chat.ChatLanguageModel;import dev.langchain4j.model.openai.OpenAiChatModel;import dev.langchain4j.service.AiServices;import dev.langchain4j.service.MemoryId;import dev.langchain4j.service.Result;import java.util.List;import java.util.Map;public interface CodeReviewAssistant { @SystemMessage(""" 你是一个高级 Java 代码审查专家。 ## 审查维度 1. 安全性:SQL 注入、XSS、权限绕过 2. 性能:N+1 查询、内存泄漏、锁竞争 3. 可维护性:命名、抽象、单一职责 4. 健壮性:异常处理、空指针、边界条件 ## 输出格式 对每个问题输出: - 严重等级:🔴 严重 / 🟡 警告 / 🔵 建议 - 问题描述 - 修复建议(附代码) ## 约束 - 只关注 Java/Spring Boot 代码 - 忽略代码风格问题(交给 Checkstyle) """) String review (@UserMessage String code) ; } ChatLanguageModel model = OpenAiChatModel.builder() .apiKey(System.getenv("OPENAI_API_KEY" )) .modelName("gpt-4o" ) .temperature(0.3 ) .build(); CodeReviewAssistant assistant = AiServices.create( CodeReviewAssistant.class, model ); String review = assistant.review(""" @GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { String sql = "SELECT * FROM users WHERE id = " + id; return jdbcTemplate.queryForObject(sql, User.class); } """ );System.out.println(review);
LangChain4j 的 @SystemMessage 注解方式有一个巨大优势 :System Prompt 和业务代码紧耦合,重构时不会遗漏。Spring AI 的模板方式则更灵活,适合 Prompt 需要动态组合的场景。
5.3 两种框架的 Prompt 管理对比
维度
Spring AI
LangChain4j
Prompt 定义
PromptTemplate + 字符串模板
@SystemMessage 注解
变量替换
Map<String, Object> 填充
@V 注解 + 参数绑定
多轮对话
手动管理 List<Message>
ChatMemory 自动管理
工具描述
@Tool 注解 + FunctionCallback
@Tool 注解 + ToolSpecification
灵活度
高(模板可外部化到文件/数据库)
中(注解编译期确定)
类型安全
低(Map 传参)
高(接口强类型)
适用场景
Prompt 频繁变化、需要 A/B 测试
Prompt 稳定、追求代码可维护性
我的建议 :两者可以混用。System Prompt 用 Spring AI 的模板引擎管理(方便热更新),业务接口用 LangChain4j 的注解方式(类型安全)。
六、企业级多层 Prompt 架构 在真实的企业场景中,Prompt 不是一段文字,而是一个分层的系统 。
6.1 三层 Prompt 架构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ┌───────────────────────────────────────────────────────────┐ │ Layer 1:基础层(Base Prompt) │ │ ├── 角色定义、合规约束、输出格式 │ │ ├── 存储位置:代码库 / 配置中心 │ │ └── 更新频率:月级 │ ├───────────────────────────────────────────────────────────┤ │ Layer 2:场景层(Scenario Prompt) │ │ ├── 客服场景 / 数据分析场景 / 代码审查场景 │ │ ├── 存储位置:Prompt 管理平台 │ │ └── 更新频率:周级 │ ├───────────────────────────────────────────────────────────┤ │ Layer 3:动态层(Dynamic Context) │ │ ├── RAG 检索结果、用户画像、对话历史 │ │ ├── 存储位置:内存(运行时拼接) │ │ └── 更新频率:每次请求 │ └───────────────────────────────────────────────────────────┘
6.2 代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 import org.springframework.ai.chat.prompt.Prompt;import org.springframework.ai.chat.prompt.PromptTemplate;import org.springframework.ai.chat.messages.SystemMessage;import org.springframework.ai.chat.messages.UserMessage;import org.springframework.stereotype.Service;import java.util.List;import java.util.Map;@Service public class PromptOrchestrator { private final PromptRepository promptRepository; private final UserProfileService userProfileService; private final RagService ragService; public Prompt assemble (String userId, String scenario, String userMessage) { List<ChatMessage> messages = new ArrayList <>(); String basePrompt = loadBasePrompt(); messages.add(new SystemMessage (basePrompt)); String scenarioPrompt = promptRepository.findByScenario(scenario); messages.add(new SystemMessage (scenarioPrompt)); UserProfile profile = userProfileService.getProfile(userId); List<Document> docs = ragService.retrieve(userMessage, 5 ); String dynamicContext = buildDynamicContext(profile, docs); messages.add(new SystemMessage (dynamicContext)); messages.add(new UserMessage (userMessage)); return new Prompt (messages); } private String buildDynamicContext (UserProfile profile, List<Document> docs) { StringBuilder sb = new StringBuilder (); sb.append("## 用户信息\n" ); sb.append("- 角色:" ).append(profile.getRole()).append("\n" ); sb.append("- 偏好语言:" ).append(profile.getPreferredLang()).append("\n" ); sb.append("- 历史交互次数:" ).append(profile.getInteractionCount()).append("\n\n" ); if (!docs.isEmpty()) { sb.append("## 参考资料\n" ); for (int i = 0 ; i < docs.size(); i++) { sb.append("[" ).append(i + 1 ).append("] " ); sb.append(docs.get(i).getTitle()).append("\n" ); sb.append(docs.get(i).getContent()).append("\n\n" ); } } return sb.toString(); } }
6.3 Prompt 版本管理 在生产环境中,Prompt 需要像代码一样做版本管理:
1 2 3 4 5 6 7 8 9 10 CREATE TABLE prompt_templates ( id BIGINT PRIMARY KEY AUTO_INCREMENT, scenario VARCHAR (50 ) NOT NULL , version INT NOT NULL , content TEXT NOT NULL , is_active BOOLEAN DEFAULT FALSE , metrics JSON, created_at TIMESTAMP DEFAULT NOW(), UNIQUE KEY uk_scenario_version (scenario, version) );
这样做有三个好处:
A/B 测试 :同一场景部署两个版本,对比效果
快速回滚 :新 Prompt 效果差,一键切回上一版
效果追踪 :记录每个版本的满意度、准确率等指标
七、常见陷阱与最佳实践 7.1 五个致命陷阱 陷阱 1:指令矛盾
1 2 3 ❌ 你是一个友好的助手。回答要简洁。 ... 对每个问题提供详细、全面的解释,不要遗漏任何细节。
模型收到矛盾指令后,行为会变得不可预测——有时简洁,有时冗长,完全看运气。
陷阱 2:否定指令的滥用
1 2 3 ❌ 不要输出代码 ❌ 不要提到 Java ❌ 不要太长
模型对否定指令的遵循率远低于肯定指令。原因是模型的训练数据中,”不要做 X”的样本远少于”做 Y”的样本。
更好的写法:
1 2 3 ✅ 用纯文字描述方案,不包含代码块 ✅ 使用 Python 作为示例语言 ✅ 控制在 200 字以内
陷阱 3:角色定义过于宽泛
“全栈”太宽泛,模型无法聚焦。改为:
1 2 3 ✅ 你是一个专注于 Spring Boot 后端 + Vue 3 前端的全栈开发者 擅长领域:REST API 设计、数据库优化、前端状态管理 技术栈:Java 21, Spring Boot 3.x, Vue 3, TypeScript, PostgreSQL
陷阱 4:没有给”退路”
模型遇到超出能力范围的问题会编造答案。加一句”退路”指令:
1 2 ✅ 如果你不确定答案,明确说"这个问题我不确定,建议查阅官方文档" 如果问题超出你的知识范围,建议用户咨询相关专家
陷阱 5:Prompt 过长导致性能下降
Prompt 超过 4000 Token 后,模型的指令遵循率开始下降。如果你的 Prompt 太长,考虑:
精简冗余描述
将不常用指令移到动态层
使用 Prompt 压缩技术(如摘要替代原文)
7.2 最佳实践清单 1 2 3 4 5 6 7 8 9 10 ✅ 指令用肯定句,不用否定句 ✅ 关键指令放在开头或结尾(利用注意力分布) ✅ 用分隔符区分指令和内容(如 --- 或 XML 标签) ✅ 提供 2-3 个 Few-shot 示例 ✅ 指定输出格式(Markdown / JSON / XML) ✅ 给模型"退路"(不确定时怎么说) ✅ 控制 System Prompt 在 1000-3000 Token 以内 ✅ 做 A/B 测试,用数据驱动 Prompt 优化 ✅ 版本管理 Prompt,支持快速回滚 ✅ 用低温度(0.1-0.3)处理确定性任务,高温度(0.7-1.0)处理创意任务
八、扩展思考:Prompt Engineering 的边界在哪? 8.1 Prompt 不是万能的 再好的 Prompt 也解决不了这些问题:
模型本身的能力天花板 :GPT-3.5 不可能通过 Prompt 变成 GPT-4
需要精确计算的场景 :数学计算、日期推算,模型容易出错
实时信息 :模型不知道今天的天气和股价
长文本的一致性 :超过模型上下文窗口的内容,Prompt 无法弥补
这些问题的解决方案不是更好的 Prompt,而是更好的架构 ——用工具调用解决计算问题,用 RAG 解决知识问题,用 Memory 解决上下文问题。
8.2 未来的方向
Prompt 自动生成 :让 AI 帮你写 Prompt(DSPy 框架已经在做这件事)
Prompt 优化器 :自动 A/B 测试,用遗传算法搜索最优 Prompt
多模态 Prompt :图文混合的 Prompt 设计(图片 + 文字指令)
Prompt-as-Code :Prompt 纳入 CI/CD 流水线,自动化测试和部署
总结 Prompt Engineering 不是”玄学”,而是一门工程学科 。它的核心原则可以用三句话概括:
清晰胜过聪明 :模型不需要你的文学才华,它需要你的精确指令
结构胜过长度 :一个 500 Token 的结构化 Prompt,效果远好于 3000 Token 的散文
迭代胜过完美 :没有一稿就完美的 Prompt,持续测试和优化才是正道
回到我们 AI Agent 系列的脉络:ReAct 给了 Agent 思考能力,Tool Use 给了 Agent 动手能力,Memory 给了 Agent 记忆能力,RAG 给了 Agent 知识检索能力,Planning 给了 Agent 规划能力,结构化输出 让 Agent 能”说人话”。
而 Prompt Engineering,是让这些能力协调运转 的粘合剂。
好的 Prompt 不是让模型更聪明,而是让模型的聪明用对地方。