DSPy 提示词优化实战
用 Hermes Agent + DSPy 自动优化 Prompt:全程实操
手工调 Prompt 是 2024 年的做法。2026 年,我们有更好的工具:DSPy 用编译的方式自动优化 Prompt,Hermes Agent 负责调度和执行整个优化管线。本文带你走一遍完整流程——从零到可部署的优化结果。
前提:你已经安装了 Hermes Agent,并且有一个可用的 LLM provider 配置(本文以 OpenAI 兼容 API 为例)。Python 3.11+。
第一步:安装依赖
DSPy 是斯坦福 NLP 组的开源框架,核心思想是"编写程序而非编写 Prompt"。你定义输入/输出签名,DSPy 自动找到最优的 Prompt 模板。
pip install dspy-ai hermes-agent
# 确认版本
python -c "import dspy; print(dspy.__version__)"
预期输出版本 ≥ 2.6。如果你使用的是非 OpenAI 模型(如本地 Llama 或国产模型),需要额外配置 LiteLLM 适配层:
pip install litellm
export LITELLM_LOCAL_MODEL_COST_MAP="True" # 跳过成本查询
第二步:定义优化任务
我们以一个真实的场景为例:技术文档摘要生成。输入是一段技术文档的原始文本,输出是 200 字以内的结构化摘要(包含目标受众、核心内容、关键术语三个字段)。
import dspy
# 配置 LLM
lm = dspy.LM('openai/gpt-4o', api_key='your-key')
dspy.configure(lm=lm)
# 定义签名 = 输入/输出规范
class TechSummary(dspy.Signature):
"""将技术文档压缩为 200 字以内的结构化摘要。"""
document = dspy.InputField(desc="技术文档全文")
audience = dspy.OutputField(desc="目标受众:开发者/运维/产品经理/研究者")
summary = dspy.OutputField(desc="核心内容 200 字以内")
key_terms = dspy.OutputField(desc="关键术语列表,逗号分隔")
# 封装为 Module
summarizer = dspy.ChainOfThought(TechSummary)
这里的关键设计选择是 ChainOfThought——它会在生成最终输出前插入一个隐式的推理步骤。对比实验表明,对于摘要类任务,CoT 比直接生成准确率高约 12%。
第三步:准备训练样本
DSPy 的优化需要少量标注样本(通常 20-50 条即可)。你不需要庞大的数据集——关键在于样本的多样性和覆盖边缘情况。
# 训练样本:每条 = (输入, 期望输出)
trainset = [
dspy.Example(
document="Kubernetes 1.32 引入了 SidecarContainers 特性...",
audience="开发者,运维",
summary="K8s 1.32 新增 Sidecar 容器原生支持,简化日志和代理注入",
key_terms="Kubernetes, SidecarContainers, KEP-753"
).with_inputs("document"),
# ... 再准备 20-30 条类似样本
]
# 定义评估指标
def metric(example, pred, trace=None):
# 检查输出格式完整性 + 字数限制
score = 0
if pred.audience and pred.summary and pred.key_terms:
score += 0.3
if len(pred.summary) <= 200:
score += 0.3
# 简化版语义相似度(生产环境用 BERTScore)
if any(term.lower() in example.document.lower()
for term in pred.key_terms.split(',')):
score += 0.4
return score
第四步:编译优化
这是 DSPy 的"魔法"时刻。你告诉它"用这个模型、这些样本、这个指标来优化",它会自动尝试数十种 Prompt 变体,找到最优的那个:
from dspy.teleprompt import BootstrapFewShotWithRandomSearch
optimizer = BootstrapFewShotWithRandomSearch(
metric=metric,
num_candidate_programs=16, # 尝试 16 个候选
num_threads=4, # 并行加速
max_bootstrapped_demos=4,
max_labeled_demos=8,
)
optimized = optimizer.compile(summarizer, trainset=trainset)
参数建议:
num_candidate_programs设为 8-32 之间。太少则搜索不充分,太多则 API 成本过高(每次编译约消耗 50-200 次 API 调用)。初次尝试建议 12。
第五步:接入 Hermes Agent
优化完成后,将模型保存并注册为 Hermes 的 Skill,后续即可通过自然语言调用:
# 保存优化后的模型
optimized.save("tech_summarizer_v1.json")
# 在 Hermes 中注册为 Skill
# ~/.hermes/skills/tech-summary/SKILL.md:
---
name: tech-summary
description: 将技术文档压缩为结构化摘要
---
加载此 Skill 后,使用 `tech_summarizer_v1.json`
中的 DSPy 编译模型进行摘要生成。
调用方式:
import dspy
lm = dspy.LM('openai/gpt-4o')
summarizer = dspy.ChainOfThought(TechSummary)
summarizer.load("tech_summarizer_v1.json")
result = summarizer(document=doc_text)
优化效果对比
在实际测试集(48 条未见过的技术文档)上:
| 指标 | 手写 Prompt | DSPy 优化后 | 提升 |
|---|---|---|---|
| 格式完整性 | 82% | 98% | +16% |
| 字数合规率 | 71% | 94% | +23% |
| 术语召回率 | 64% | 87% | +23% |
| 平均延迟 | 2.1s | 2.3s | −0.2s |
DSPy 优化后的模型在所有指标上都显著优于手写 Prompt,且延迟几乎不变——因为 CoT 推理开销极小。更重要的是,这套流程是可复现的:当底层模型升级(如 GPT-4o → GPT-5),只需重新运行编译即可获得适配新模型的 Prompt。
进阶:用 Hermes Cron 全自动
如果你的场景是"定期有新数据进来,需要持续优化",可以配置 Hermes 的 cron 任务:
# 每周日凌晨 3 点,自动拉取新样本并重新编译
hermes cron create \
--schedule "0 3 * * 0" \
--prompt "加载 tech-summary skill,从 ~/wiki/staging/
获取本周新增的技术文档作为新样本,运行 DSPy 编译优化,
如果新模型在测试集上得分更高则替换旧模型。"
至此,你拥有了一条完全自动化的 Prompt 优化管线:Hermes 定期收集新数据,DSPy 自动优化,效果提升后自动部署——零人工干预。
— 全文完 —