文章目录
- 【94.Python+AI】实战:写一个"Prompt优化师"Agent------输入你的需求,输出最优Prompt
-
- 导入语
- [1 ~> 架构设计:四个模块,一个闭环](#1 ~> 架构设计:四个模块,一个闭环)
-
- [1.1 核心闭环](#1.1 核心闭环)
- [2 ~> 评分器设计:把"感觉好"变成"打得出分"](#2 ~> 评分器设计:把"感觉好"变成"打得出分")
-
- [2.1 四个评分维度](#2.1 四个评分维度)
- [2.2 迭代终止条件](#2.2 迭代终止条件)
- [3 ~> 核心实现:150行走完全流程](#3 ~> 核心实现:150行走完全流程)
- [4 ~> 加分项一:自动生成Few-Shot示例](#4 ~> 加分项一:自动生成Few-Shot示例)
-
- [4.1 加分项二:多模型横评](#4.1 加分项二:多模型横评)
- [5 ~> 工程化收尾:生成即用](#5 ~> 工程化收尾:生成即用)
- [思考 && 总结](#思考 && 总结)
- 结尾
【94.Python+AI】实战:写一个"Prompt优化师"Agent------输入你的需求,输出最优Prompt
📖 文章简介: 本文是Prompt工程板块的收官实战,手把手实现一个"Prompt优化师"Agent:输入一句大白话需求,输出经过多轮迭代打磨的最优Prompt。文章从手写Prompt的三大瓶颈切入(质量看手感、优化靠玄学、效果无度量),给出Agent的四模块架构------需求理解器、初稿生成器、效果评分器、反思迭代器,以及"生成→评分→反思→重写"的核心闭环;提供完整可运行的Python实现(基于OpenAI SDK,约150行),含评分维度设计(清晰度/约束完备性/格式明确性/可执行性四维打分)、迭代终止条件(分数达标或达到上限)、Few-Shot示例的自动生成策略(按需求场景合成正反例);并附多模型对比功能------同一Prompt在GPT、DeepSeek、通义千问上的横向实测。配以Mermaid流程图展示迭代闭环,适合学完Prompt工程理论、想把它沉淀为工具的开发者阅读参考。

🎬 个人主页: 源码骑士
❄ 专栏传送门: 《Android开发基础》《python基础课程》
⭐️热衷从源码视角拆解技术底层原理,将复杂架构讲得通俗易懂
🎬 源码骑士的简介:
5年Android Framework系统开发经验,曾主导多项系统级性能优化专项
技术栈覆盖Android系统全链路(Binder/Handler/AMS/WMS/启动流程)及Java后端全家桶(Spring + MyBatis + Redis + Oracle)
累计产出原创技术文章100+篇,文章以流程图为特色,被读者评价为"看一篇胜过啃一周源码"
导入语
前面几篇我们把Prompt工程的招式拆解得差不多了:结构化分层、思维链、Few-Shot、System Prompt设计、自动优化、模板化。但现实中还有一个尴尬的问题------道理都懂,轮到自己写,还是凭手感。 同一个需求,今天写的和上周写的质量不一样;同一份Prompt,换个模型表现就翻车;觉得"还能更好",但说不清哪里能改、怎么改。
手写Prompt的三大瓶颈就在这:质量看手感、优化靠玄学、效果无度量。
破局思路和软件工程一样------把"手艺"变成"流水线"。这篇实战我们就造这条流水线:一个"Prompt优化师"Agent,你扔给它一句大白话需求,它自己生成初稿、给自己打分、找出毛病、重写优化,循环几轮后交给你一个带评测分数的成品。全程约150行Python,每一行都讲透。
1 ~> 架构设计:四个模块,一个闭环
优化师Agent的内部结构,其实就是把人类专家优化Prompt的思考过程拆成四个工位:
| 模块 | 职责 | 对应人类动作 |
|---|---|---|
| 需求理解器 | 把大白话需求解析成结构化规格 | 写之前先问清楚需求 |
| 初稿生成器 | 按规格生成第一版Prompt | 打草稿 |
| 效果评分器 | 多维度给Prompt打分+指出具体缺陷 | 自我审查 |
| 反思迭代器 | 根据缺陷清单重写,循环直到达标 | 改稿 |
1.1 核心闭环
渲染错误: Mermaid 渲染失败: Parse error on line 6: ...否| F反思迭代器\\n针对缺陷重写 v(n+1) F --> D -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'
这个闭环的灵魂不在"生成"而在"评分"------没有可量化的评分标准,迭代就退化成随机改写。 所以评分器是整个系统里最值得花心思的模块。
2 ~> 评分器设计:把"感觉好"变成"打得出分"
2.1 四个评分维度
| 维度 | 考察什么 | 扣分项举例 |
|---|---|---|
| 清晰度 | 任务一句话能说清吗 | 目标含糊、动词缺失 |
| 约束完备性 | 该禁止的都禁止了吗 | 没说不许编造、没说边界 |
| 格式明确性 | 输出长什么样有样板吗 | 只描述"输出JSON"却不给结构 |
| 可执行性 | 模型拿着它能直接干活吗 | 依赖未提供的上下文、要求做不到的事 |
每个维度0~25分,总分100。评分不靠拍脑袋,让模型按量规(rubric)逐项检查:
python
JUDGE_PROMPT = """你是Prompt质量评审专家。按以下量规评审待评Prompt:
【量规】
1. 清晰度(0-25):任务目标是否一句话可概括、无歧义
2. 约束完备性(0-25):边界、禁区、异常情况是否都有约束
3. 格式明确性(0-25):输出结构是否有明确定义或示例
4. 可执行性(0-25):模型仅凭此Prompt能否直接完成任务
【待评Prompt】
{prompt}
【输出JSON】
{{"scores": {{"clarity": int, "constraint": int, "format": int, "executability": int}},
"total": int,
"defects": ["具体缺陷1", "具体缺陷2"]}}"""
注意输出里的defects字段------分数只是仪表盘,缺陷清单才是方向盘,迭代器拿着它才知道往哪改。
2.2 迭代终止条件
python
MAX_ROUNDS = 3 # 迭代上限:防死循环,也防边际收益递减
TARGET_SCORE = 85 # 达标线:85分以上收工
经验之谈:迭代超过3轮,分数提升通常不到5分,Token成本却翻倍------见好就收。
3 ~> 核心实现:150行走完全流程
python
import json
from openai import OpenAI
client = OpenAI()
def chat(system: str, user: str, temperature: float = 0.3) -> str:
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": system},
{"role": "user", "content": user}],
temperature=temperature,
)
return resp.choices[0].message.content
# ── 模块一:需求理解 ──
def parse_requirement(raw_need: str) -> dict:
out = chat(
"你是需求分析师。把用户的Prompt需求解析成JSON规格。",
f"需求:{raw_need}\n"
'输出JSON:{"task": "核心任务", "audience": "使用者", '
'"constraints": ["约束"], "output_format": "期望的输出格式"}',
)
return json.loads(extract_json(out)) # extract_json见第46篇的清洗技巧
# ── 模块二:初稿生成 ──
def draft_prompt(spec: dict, defects: list | None = None) -> str:
fix_hint = f"\n上一版缺陷,必须修复:{defects}" if defects else ""
return chat(
"你是顶级Prompt工程师。按规格撰写生产级System Prompt,"
"要求:角色明确、约束完整、含输出格式定义、语言精炼。",
f"规格:{json.dumps(spec, ensure_ascii=False)}{fix_hint}",
)
# ── 模块三:评分 ──
def judge(prompt: str) -> dict:
out = chat(JUDGE_PROMPT.format(prompt=prompt), "开始评审")
return json.loads(extract_json(out))
# ── 主闭环:生成 → 评分 → 迭代 ──
def optimize(raw_need: str) -> dict:
spec = parse_requirement(raw_need)
current, history = draft_prompt(spec), []
for round_no in range(1, MAX_ROUNDS + 1):
report = judge(current)
history.append({"round": round_no, "score": report["total"]})
if report["total"] >= TARGET_SCORE:
break
current = draft_prompt(spec, defects=report["defects"]) # 拿着缺陷清单改稿
return {"prompt": current, "final_score": report["total"],
"trajectory": history, "spec": spec}
跑一遍的实际效果:
bash
输入:帮我写个给餐饮店用的差评回复Prompt
输出轨迹:
round 1 → 68分 缺陷:未约束回复语气、无输出长度限制、缺品牌人设
round 2 → 84分 缺陷:缺少"涉及食品安全问题"的特殊处理分支
round 3 → 91分 ✔ 达标,输出终稿
三轮迭代,从"能用"到"能上线"------缺陷清单指哪打哪,每一步都有据可依。
4 ~> 加分项一:自动生成Few-Shot示例
Prompt定稿后,优化师顺手把示例也造了。策略是按场景合成正反例:
python
def gen_few_shot(spec: dict, prompt: str, n: int = 3) -> str:
return chat(
"你是测试数据构造专家。根据Prompt的任务,生成"
f"{n}组Few-Shot示例。要求:"
"1) 覆盖典型场景;2) 含1组边界case(容易答错的);"
"3) 输出严格符合Prompt定义的格式。",
f"Prompt:{prompt}\n规格:{json.dumps(spec, ensure_ascii=False)}",
)
关键点在那个"边界case"------普通示例模型自己也能编,容易答错的示例才有教学价值(第87篇讲过:示例的任务是教会模型处理它原本会错的输入)。
4.1 加分项二:多模型横评
终稿Prompt别急着交付,同一份Prompt在不同模型上实测一遍:
python
def cross_model_test(prompt: str, test_input: str) -> dict:
results = {}
for name, model in [("gpt", "gpt-4o-mini"),
("deepseek", "deepseek-chat"),
("qwen", "qwen-plus")]:
out = chat(prompt, test_input) if name == "gpt" else call_other(model, prompt, test_input)
results[name] = judge_output_quality(out) # 对输出再评一次分
return results
横评的价值在于破除"一模型适配"幻觉:在GPT上调到95分的Prompt,换DeepSeek可能掉到70------Prompt的兼容性也是质量指标,尤其是你的应用打算多模型热切换时(第40篇)。
5 ~> 工程化收尾:生成即用
优化师的产出物不只是一段文本,而是一个可直接入库的包:
bash
optimize() 的最终交付结构:
{
"prompt": 终稿Prompt文本,
"final_score": 91,
"trajectory": 各轮分数轨迹(审计用),
"few_shot": 自动生成的示例组,
"cross_model": 多模型实测报告
}
落地动作:
1. 终稿 + 示例 → 按第90篇规范存成 Jinja2 模板文件,版本号v1.0.0
2. 评分报告 → 写入 CHANGELOG(这版Prompt凭什么上线)
3. 模板进git → 走评审、灰度、可回滚
至此闭环:Agent负责"从需求到合格品",第90篇的模板体系负责"从合格品到可运维资产"。前者解决写得出来,后者解决管得住。
思考 && 总结
- 手写Prompt的三大瓶颈------手感、玄学、无度量,对应的解法是流水线、缺陷清单、可量化评分。 把专家的思考过程拆成四个模块,Agent才能替你干活。
- 评分器是灵魂: 清晰度、约束完备性、格式明确性、可执行性四维量规;分数是仪表盘,
defects缺陷清单才是迭代的方向盘。 - 迭代要设终止线: 分数达标或触顶(3轮)即收工,超过3轮边际收益骤降,纯属烧Token。
- Few-Shot示例自动合成的关键是边界case: 普通示例锦上添花,易错示例才教得会模型。
- 交付物是资产不是文本: 终稿存Jinja2模板带版本号,评分报告进CHANGELOG,多模型横评防"一模型适配"幻觉。
Prompt工程板块到这里正式收官。从下一篇开始,我们进入一片新大陆:向量嵌入------大模型时代所有语义检索、RAG应用的数学地基。先回答最根本的问题:Embedding到底是什么,为什么一串数字能表示"语义"?
结尾
各位小伙伴,本文的内容到这里就全部结束了,源码骑士在这里再次感谢您的阅读!
源码骑士 --- Android Framework & 全栈开发
👀 关注:跟博主一起从源码视角深耕底层原理,见证每一次成长
❤️ 点赞:让优质内容被更多人看见,让知识传递更有力量
⭐ 收藏:把核心知识点存好,在需要时随时查、随时用
💬 评论:分享你的经验或疑问,评论区一起交流避坑
🔄 一键四连:不要忘记给博主"一键四连"哦!
🗡️ 寄语:技术之路难免有困惑,但同行的人会让前进更有方向
结语:当优化Prompt这件事本身也被写成了Prompt,你就完成了从"手艺人"到"工具建造者"的跃迁------最好的工程师,永远在给自己的工作写工具。不要忘记给博主"一键四连"哦!