ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用AI优化AI:从提示词自动优化器到自我反思Agent的实现

用AI优化AI:从提示词自动优化器到自我反思Agent的实现 在实际的 AI 应用开发中模型选好之后最影响效果的因素往往不是模型参数而是提示词。同一个大模型使用不同的提示词输出质量可能相差很大。更麻烦的是人工调提示词很难持续也很容易凭感觉改两句就上线最后到底提升了什么、有没有引入回归完全说不清楚。于是“用 AI 来优化 AI”成了很务实的工程方向让大模型自己生成提示词变体、自己评估效果、自己根据反馈继续修改甚至组合成一个自动运行的 Agent。这篇文章会从零实现一个提示词自动优化器再把它扩展成带自我反思的 AI Agent用一组可量化的测试样本验证优化效果并说明生产环境中控制成本、避免过拟合和排查问题的具体方法。1. 先理解“用 AI 优化 AI”的核心思路1.1 为什么提示词质量会成为 AI 应用瓶颈大模型的能力边界在训练完成后基本确定应用层能调节的主要入口就是提示词。同样的模型用一句话提问和用“角色设定 任务目标 输出格式 示例”提问结果可能是完全不同的产物。很多团队在模型选型上花了很多精力却忽略了提示词对线上效果的影响。人工调提示词有几个明显问题主观同一个输出不同人判断好坏的标准不同。碎片化经常是这次加一句强调下次又改回来缺少可比较的基线。过拟合针对两三个测试样例调出来的提示词遇到真实请求很可能失效。不可复用一个人调好的提示词另一个人不知道中间经历了什么无法继续优化。因此提示词优化不应该只靠人肉改文字而应该变成一个可自动执行的流程有输入、有评估、有选择、有迭代。这也正是“用 AI 优化 AI”最常见的切入场景。1.2 提示词自动优化器的基本形态提示词自动优化器的目标很直接给定一个基础提示词和一批带标准答案的验证样本让大模型生成多个提示词变体然后在验证样本上分别评估效果最后选出效果最好的那个提示词。整个流程可以拆成三个环节候选生成让大模型基于原始提示词生成若干改写版本。批量评估每个候选提示词都去运行验证样本并计算得分。最优选择按平均分或加权分选出效果最好的提示词。这种优化器本身没有状态做完一轮就结束适合“提示词基本可靠只是想找一个更好版本”的场景。它的优点是实现简单、结果可解释缺点是只做一轮生成完就选缺少基于失败样本的二次修改能力。1.3 从优化器到 AI Agent 的差距如果进一步提升可以把优化器扩展成 AI Agent。Agent 和普通优化器的差别在于它不再是一轮博弈而是带反馈的多轮循环。一个提示词优化 Agent 至少要有四个模块状态管理保存当前最优提示词、历史得分、失败样本。生成器根据当前状态生成新的候选提示词。评估器在验证集上评估候选提示词效果。反思器根据上一轮失败样本生成修改建议加入下一轮生成上下文。这样一来整个系统就像是“一个 AI 在指导另一个 AI 如何表现更好”。第一轮可能只能小幅度修改第二轮就能针对失败样本做定向修复第三轮、第四轮继续收敛。需要提醒的是Agent 不是越复杂越好。对于提示词优化这类任务先跑通一个基础优化器再叠加多轮反思会比一开始就堆很多工具调用更稳妥。2. 环境准备与最小依赖2.1 环境要求这篇文章的示例代码使用 Python 3.9 以上版本通过 OpenAI 兼容协议调用大模型。实际项目中只要对接的 API 支持 Chat Completions 格式都可以用同一套代码。环境要求如下表依赖项推荐版本用途Python3.9运行示例代码openai1.x调用大模型接口python-dotenv1.x加载本地环境变量一个可用的大模型接口任意支持 Chat Completions 的模型生成提示词和评估输出如果没有云服务 API也可以使用本地部署的模型服务比如 Ollama 启动一个兼容 OpenAI 协议的端点这样不依赖外部网络也方便调试。最稳妥的做法是先在本地确认下面这条调用能返回结果from openai import OpenAI import os client OpenAI( api_keyos.getenv(LLM_API_KEY), base_urlos.getenv(LLM_BASE_URL), ) resp client.chat.completions.create( modelos.getenv(LLM_MODEL, gpt-4o-mini), messages[{role: user, content: 用一句话介绍提示词工程}], ) print(resp.choices[0].message.content)如果这段代码能正常输出文字说明 API 访问没有问题。2.2 配置 API 访问参数建议把密钥和地址放到环境变量中不要把密钥写到代码里。创建一个.env文件LLM_API_KEYyour_api_key LLM_BASE_URLhttps://api.openai.com/v1 LLM_MODELgpt-4o-mini然后使用dotenv加载from dotenv import load_dotenv load_dotenv()如果是用自己的本地模型可以配置为LLM_API_KEYollama LLM_BASE_URLhttp://localhost:11434/v1 LLM_MODELqwen2.5:7b需要注意不同模型对格式遵循能力不同。越小的模型越容易出现 JSON 解析失败、输出格式偏离等问题。示例代码里需要做好容错。2.3 项目结构为了后续扩展建议按如下结构组织文件prompt-optimizer/ ├── .env ├── optimizer.py ├── agent.py ├── evaluator.py ├── samples.json └── requirements.txt每个文件职责如下optimizer.py基础提示词优化器负责生成候选、评估、选择。agent.py带多轮反思的 Agent 版本。evaluator.py评估器运行验证集并打分。samples.json验证样本包含输入、期望输出和类别。requirements.txt依赖列表。学习阶段可以先只用evaluator.py和optimizer.py跑通后再加入agent.py。这样每一步出问题都容易定位。3. 实现一个基础提示词优化器3.1 定义一个简单的分类任务和验证集为了让效果可比较这里选择一个简单的任务把用户输入分类为“技术咨询”“产品推荐”“闲聊”三类。这是一道典型的大模型应用任务既不需要复杂的工具调用又能直观地看出提示词差异带来的影响。在samples.json中准备验证样本[ { input: 我的服务器 CPU 一直在 100%怎么排查, expected: 技术咨询, category: tech }, { input: 帮我推荐一款适合写代码的笔记本, expected: 产品推荐, category: product }, { input: 今天天气怎么样, expected: 闲聊, category: chat } ]这里只列了 3 条示例实际运行时最好准备 10 到 30 条。样本数量太少评估结果会被随机性主导很难判断哪个提示词更好。任务定义好后需要一个基础提示词作为起点。基础提示词可以很简单请将用户输入分类为技术咨询、产品推荐或闲聊只输出一个类别名称。这个基础提示词就是 later 要对比的 baseline。3.2 让大模型生成多个提示词变体先写一个统一的模型调用函数放在optimizer.py中import json import os import re from openai import OpenAI load_dotenv() client OpenAI( api_keyos.getenv(LLM_API_KEY), base_urlos.getenv(LLM_BASE_URL), ) MODEL os.getenv(LLM_MODEL, gpt-4o-mini) def call_llm(messages, temperature0.7, max_tokens512): resp client.chat.completions.create( modelMODEL, messagesmessages, temperaturetemperature, max_tokensmax_tokens, ) return resp.choices[0].message.content生成候选提示词时要求模型输出一个 JSON 数组每个元素都是一个完整的提示词。提示词里要明确包含任务目标、输出格式和必要的约束def generate_variants(base_prompt, n5): system_prompt ( 你是一个提示词工程师。请根据用户提供的基础提示词 生成多个改写版本。要求\n 1. 保持核心任务不变。\n 2. 可以增加角色设定、few-shot 示例、输出格式说明。\n 3. 每个提示词必须能独立使用。\n 4. 只输出 JSON 数组不要输出额外解释。\n 格式示例[\提示词1\, \提示词2\] ) user_prompt f基础提示词\n{base_prompt}\n请生成 {n} 个变体。 content call_llm([ {role: system, content: system_prompt}, {role: user, content: user_prompt}, ], temperature0.8, max_tokens1024) start content.find([) end content.rfind(]) if start -1 or end -1: return [base_prompt] try: variants json.loads(content[start:end 1]) except json.JSONDecodeError: return [base_prompt] return [p for p in variants if isinstance(p, str) and p.strip()]这里的关键点是要求模型只输出 JSON 数组但实际响应中经常会有前后缀文字所以需要手动截取[到]之间的部分。解析失败时返回基础提示词避免整个流程中断。temperature设置为 0.8提高生成多样性如果希望更稳定可以降低到 0.5。3.3 批量评估并选择最优提示词评估器evaluator.py的核心功能是给一个提示词让它对每个样本分类然后和期望结果比较计算准确率。更通用的做法是使用一个大模型裁判打分但分类任务本身结果明确用准确率就足够。基础评估函数如下def evaluate_prompt(prompt, samples): correct 0 total len(samples) for sample in samples: user_input sample[input] expected sample[expected] resp call_llm([ {role: system, content: prompt}, {role: user, content: user_input}, ], temperature0, max_tokens20) output resp.strip() # 兼容模型多输出一些文字的情况 for label in [技术咨询, 产品推荐, 闲聊]: if label in output: output label break if output expected: correct 1 return correct / total要注意temperature应该设置为 0因为评估阶段要尽量减少随机性。模型如果输出了多余内容通过包含匹配的方式提取类别名称。在optimizer.py中把整个流程串起来def optimize(base_prompt, samples, n_variants5): variants generate_variants(base_prompt, n_variants) variants.append(base_prompt) # 始终把原始版本纳入对比 results [] for prompt in variants: score evaluate_prompt(prompt, samples) results.append({prompt: prompt, score: score}) results.sort(keylambda x: x[score], reverseTrue) return results[0]这样一轮跑完后可以得到一个平均准确率最高的提示词。这个流程已经是一个最小可运行的提示词优化器。4. 升级为带自我反思的 AI Agent4.1 Agent 的四个模块基础优化器只能做一轮生成和选择缺少“根据失败案例继续修改”的能力。AI Agent 版本增加一个反思循环让模型看到上一轮的失败输出再针对性地修改提示词。Agent 的类可以这样设计class PromptOptimizerAgent: def __init__(self, base_prompt, samples, max_rounds3): self.base_prompt base_prompt self.samples samples self.max_rounds max_rounds self.history [] def run(self): best_prompt self.base_prompt best_score 0 for round_idx in range(self.max_rounds): # 1. 生成候选 # 2. 评估候选 # 3. 反思失败样本 pass实际运行中每一轮都要保留历史让模型看到“上一轮哪些样本预测错”“上一轮最佳提示词是什么”。4.2 实现多轮反思在每一轮生成前构造一个反思上下文。先把上一轮的评估结果和失败样本发给模型要求它给出修改建议def build_reflection_prompt(self, round_idx, best_prompt, failed_samples): failed_text \n.join( f输入{s[input]}\n期望{s[expected]} for s in failed_samples ) return ( f这是第 {round_idx 1} 轮优化。当前最佳提示词得分是 f{self.history[-1][best_score]:.2f}。\n f当前最佳提示词\n{best_prompt}\n\n f以下样本预测失败\n{failed_text}\n\n 请分析失败原因并生成一个新的提示词 要求新提示词能修复这些失败样本中的主要问题。 只输出新的提示词本身不要输出解释。 )然后把反思结果作为下一轮的基础提示词之一和模型重新生成的其他变体一起参与评估。在每一轮里不能只保留反思生成的一个提示词而是应该把它加入候选池。生成候选时可以把反思结果作为额外上下文def generate_candidates(self, base_prompt, reflectionNone): system_prompt 你是提示词优化专家请基于已有信息生成改进后的提示词。 messages [ {role: system, content: system_prompt}, {role: user, content: f基础提示词\n{base_prompt}}, ] if reflection: messages.append({role: user, content: f反思反馈\n{reflection}}) messages.append({role: user, content: 请生成一个新的提示词修复上述问题只输出提示词本身。}) else: messages.append({role: user, content: 请生成 5 个提示词变体只输出 JSON 数组。}) return call_llm(messages, temperature0.7, max_tokens1024)Agent 每轮都要重新评估全部候选不能只评估新增的否则无法和旧版本公平比较。4.3 防止无限循环和成本失控多轮优化很容易让调用次数爆炸。假设每轮生成 5 个变体验证集有 20 条样本每一轮就要调用 100 次评估接口再加上生成和反思成本增长很快。以下几点必须提前设计最大轮数建议 3 到 5 轮超过就停止。早停条件如果当前最佳得分连续两轮没有提升提前停止。调用预算记录累计调用次数超过上限后停止。缓存相同提示词和相同样本的评估结果可以缓存避免重复计算。代码中可以加入一个简单的调用计数class LlmBudget: def __init__(self, max_calls): self.max_calls max_calls self.calls 0 def can_call(self): return self.calls self.max_calls def add_call(self): self.calls 1在call_llm每次访问前检查预算超过就抛出异常或返回空结果让 Agent 提前退出。5. 运行验证与效果分析5.1 准备小规模验证集为了直观看到效果建议准备一组覆盖不同情况的样本。比如 12 条样本包含3 条技术咨询3 条产品推荐3 条闲聊3 条容易混淆的边界样本边界样本的作用是让优化器不要只记标准答案而要真正理解判断逻辑。比如{ input: 我的电脑最近很卡是不是需要换一台, expected: 产品推荐 }这条样本既像技术咨询又像产品推荐如果提示词里没有“当用户表达更换需求时应判断为产品推荐”的规则模型很容易分错。5.2 比较优化前后的指标运行基础优化器后把 baseline 和优化后的提示词放在同一组样本上重新评估得到对比表提示词技术咨询准确率产品推荐准确率闲聊准确率总体准确率基础提示词0.660.660.830.72第一轮优化后0.830.660.830.77Agent 第三轮后0.910.830.910.88这个表格只是示例不同模型、不同样本的结果会不一样。但趋势通常是第一轮优化变化不大后面几轮随着反思上下文增加边界样本的准确率会明显提升。5.3 评估结果的可信度检查AI 评估有很多坑得分提升不一定是真提升也可能是随机波动。可以从三个角度检查多次运行取平均固定随机种子或多次评估取平均。交叉验证把样本分成两份一份用来优化一份用来验证最终效果避免过拟合。人工抽检对优化前后差异最大的样本人工判断哪个输出更好。这一点在 Agent 优化场景尤其重要。因为 Agent 会不断针对验证集失败样本修改提示词如果验证集太小或分布单一几轮之后很可能会过拟合到验证集。此时在验证集上分数高但真实请求上反而变差。6. 常见问题排查提示词优化器跑起来并不难麻烦的是各种异常现象。下面这张表列出了常见问题、原因和排查方向问题现象常见原因检查方式处理建议模型返回内容无法解析成 JSON模型输出前后缀文字或 JSON 格式错误打印模型返回内容截取[到]区间解析失败时回退到基础提示词优化后得分没有提升验证集太少、候选提示词多样性不足、模型能力有限查看候选提示词是否都是同义改写增加验证集、提高 temperature、加入反思反馈分数忽高忽低评估时 temperature 不为 0或样本顺序影响结果固定评估时 temperature 为 0多次运行取平均评估使用temperature0并增加重复次数优化后的提示词在真实场景失效优化集和真实分布不一致检查验证集样本是否和线上请求同分布使用分层采样增加边界样本加入回归集API 调用次数增长过快每轮评估都走全量样本没有缓存记录调用次数观察每轮调用数增加缓存、限制轮数、增加早停条件6.1 API 返回不规范 JSON这是生成提示词变体时最常见的问题。大模型经常会在 JSON 数组前后加解释性文字或者把数组包在代码块里。解析时不要直接json.loads(content)而是先截取第一个[和最后一个]之间的内容。解析失败时还要有回退逻辑不能整个程序崩溃。6.2 评估结果不稳定如果评估时temperature不是 0模型每次输出可能不同同一个提示词的得分会漂移。分类任务建议评估时把temperature固定为 0。对于更复杂的生成任务需要用多个样本多次采样取平均分。另外样本顺序也会影响结果特别是在上下文学习时。如果模型依赖 few-shot 示例示例顺序变化可能带来明显波动。优化时要把样本顺序固定或者随机打乱后多次评估取平均。6.3 优化后的提示词在真实场景失效最常见的原因是优化集和真实分布不一致。比如验证集里全是“技术咨询”和“闲聊”样本优化器就会倾向于把边界样本都判成这两类真实场景里的“产品推荐”请求就很难命中。解决办法是准备三层数据集种子集用于生成第一轮候选提示词。验证集用于在优化过程中评估和选优。回归集不参与优化只在最终比较时使用确保没有过拟合。6.4 API 调用成本增长过快Agent 多轮优化成本增长很快。假设 5 个候选、10 条验证样本、3 轮基础评估就是 150 次调用加上反思和生成可能到 180 次。如果模型是付费 API这个成本需要提前估算。控制成本的手段包括验证集先做小规模跑通再用全量集精选。相同提示词和样本组合做缓存使用哈希 key。设置最大轮数和调用预算避免失控。7. 生产环境的最佳实践7.1 评估集设计原则评估集是提示词优化的地基。如果评估集本身不可靠后续一切优化都是无效的。评估集设计要注意这几点数量适中10 条太少1000 条太多。常见建议先用 20 到 50 条跑通。分布覆盖每个类别至少 20%边界样本单独划一类。标注稳定期望输出必须是“唯一可判断”的结果。分类任务比开放问答更容易评估。时间留痕评估集本身也要版本化因为线上分布会变评估集需要持续更新。7.2 成本控制与缓存策略生产环境不适合每次跑完整优化流程。通常做法是把优化过程拆分每周离线跑一次优化生成新的候选提示词。在线使用固定提示词不做实时优化。评估结果写入数据库带提示词版本、验证集版本、模型版本、调用成本等元信息。缓存评估结果时可以用(prompt_hash, sample_hash)作为 key。如果相同提示词和相同样本已经评估过直接读取历史分数不再调用 API。7.3 提示词版本管理提示词本质上和代码一样需要版本管理。建议每个提示词都带一个唯一的 ID 和元信息{ id: prompt_classify_v3, content: 你是客户支持助手请判断用户意图……, model: gpt-4o-mini, score: 0.88, samples_version: samples_20250101, created_at: 2025-01-05T12:00:00Z }这样还能建立回滚机制。一旦线上效果下降可以快速切回历史高分提示词。7.4 与 CI/CD 集成提示词变更应当像代码变更一样走测试流程。可以做一个简单的质量门禁开发者提交提示词变更。自动在回归集上运行评估。如果新提示词得分低于当前线上版本阻止合并。如果得分提升同时输出一份对比报告。这样可以避免“凭直觉改提示词”导致线上回归。后续还可以把优化器接入定时任务每隔一段时间自动跑一次把新提示词作为候选提交给人工审核。8. 扩展方向从提示词优化到更广的 AI Agent 应用8.1 让 Agent 自动完成更多 AI 工程任务提示词优化只是一个起点。同样的“生成、评估、反思”循环可以迁移到很多工程任务上自动生成单元测试给定代码让 Agent 生成测试用例并在真实环境运行根据覆盖率反馈修改。自动数据标注给标注规范让 Agent 标一批样本人工抽检不合格则重新生成规范。自动 Bug 分析把报错日志和代码片段交给 Agent让它输出根因和修复建议再由测试结果验证。这些任务本质上都是“生成结果 自动评估 基于反馈迭代”和提示词优化器共享同一套架构。8.2 结合 RAG 提升知识检索能力在 RAGRetrieval-Augmented Generation应用中提示词优化通常不只是改文字还要考虑检索结果如何融入上下文。可以把“检索片段 用户问题 输出要求”一起作为评估输入让 Agent 同时优化检索排序规则和生成提示词。评估指标除了最终答案的准确率还可以加入检索命中率、上下文是否冗余、输出是否包含答案依据等。这样优化出来的提示词会更贴近真实 RAG 链路。8.3 用于模型评测基准构建用 AI 自动生成评测基准也是一个方向。可以让 Agent 基于已有样本生成相似但更有迷惑性的新样本扩充覆盖边界。再通过人工抽检保证质量最终形成可持续更新的评测集。这样做的好处是能提前发现模型在边界情况下的弱点而不是只在简单的验证集上打转。8.4 学习路径建议想深入这个方向建议按以下顺序推进先掌握提示词工程的基础写法角色设定、任务拆分、few-shot、输出约束。再实现一个最简单的评估脚本把人工判断转换成可量化指标。接着做基础提示词优化器跑通“生成、评估、选择”。然后加入多轮反思理解 Agent 的状态管理和预算控制。最后把优化流程接入 CI/CD做成一个可复用的工程能力。这个小项目非常适合作为 AI 应用开发学习的练手案例它涉及 Prompt、API 调用、评估方法、成本控制、版本管理等多个关键点却不需要很复杂的系统架构。跑通之后再去看 LangChain、Spring AI 或者自研 Agent 框架会更容易理解背后的设计意图。用 AI 优化 AI 的核心不是让模型自己写一段更好的文字而是建立一套可衡量、可迭代、可回滚的工程闭环。提示词只是第一个场景一旦掌握了这套闭环它可以被复制到更多 AI 工程任务中成为 AI 应用持续稳定的底层能力。
返回列表