我停止写提示词,开始写 Python

发布: (2026年4月9日 GMT+8 17:27)
4 分钟阅读
原文: Dev.to

Source: Dev.to

Prompt 混乱

一年里,我把大语言模型当成命令行使用:输入指令,祈祷输出,微调措辞,添加 “IMPORTANT:”,像仪式一样移动句子。结果我积累了一堆提示文件:

v1.txt
v2_final.txt
v2_final_REALLY_final.txt

这些文件都没有记录为什么它们能工作。当出现问题时,我根本分不清是提示、模型还是数据出了错。没有版本控制,没有测试——只有感觉。

迎接 DSPy

DSPy(来自斯坦福 NLP)把模型翻转了:你不写提示,你写 Python

class AnalyzeStartup(dspy.Signature):
    """Analyze a startup pitch."""

    pitch: str = dspy.InputField()
    viability_score: int = dspy.OutputField()
    strengths: list[str] = dspy.OutputField()
    weaknesses: list[str] = dspy.OutputField()
    verdict: str = dspy.OutputField()

就这么简单——不需要 “You are an expert startup analyst…”,也不需要 “Respond in JSON format…”。DSPy 会把这个签名编译成提示。当你需要更好的提示时,运行优化器;DSPy 会根据有效示例重写提示。

从提示技巧到签名

之前:

“如果我把示例放在指令前面,效果会更好。有时。除非是 GPT‑4o。”

之后:
我只写一个签名。DSPy 会找出最佳的提示格式。提示成为实现细节;我关心的是输入、输出和行为——而不是措辞。

可测试的 LLM 代码

之前:
手动检查输出。

之后:

def test_startup_analyzer():
    result = startup_analyzer(pitch="We're building AI for dog grooming...")
    assert 1  0
    assert len(result.weaknesses) > 0

真实的测试写在我的测试套件里,使用断言。

一行代码切换模型

之前:
每个模型都需要单独的提示调优(GPT‑4、Claude、Gemini 等)。

之后:

# Swap models
lm = dspy.LM("openai/gpt-4o-mini")
# lm = dspy.LM("anthropic/claude-3-sonnet")
# lm = dspy.LM("gemini/gemini-2.0-flash")

dspy.configure(lm=lm)

同样的代码,换不同的模型。DSPy 负责提示的转换。

优化器完成调优

我不再手动微调提示,而是给 DSPy 提供好的输出示例,让它自行找出最佳提示:

optimizer = BootstrapFewShot(metric=my_metric, max_bootstrapped_demos=4)
optimized = optimizer.compile(StartupAnalyzer(), trainset=train_examples)

DSPy 运行实验,找到有效示例,构建提示,我只需审阅结果。

范式转变

  • 旧方式: LLM 是你用英语对话的魔盒;成功取决于提示技巧。
  • DSPy 方式: LLM 是函数调用。你声明接口,框架负责实现。

这就像在代码库中散落原始 SQL 查询与使用 ORM 的区别:前者脆弱、无类型、难以重构;后者结构化、可测试、易于维护。

更深入的探索

我写了一本关于使用 DSPy 的完整指南——实用章节、真实代码以及艰难的经验教训。它叫 Harmless DSPy;如果想先看看是否适合你,第一章是免费的。

DSPy 由 Omar Khattab 和斯坦福 NLP 团队开发。它是开源的,积极维护,已经真正改变了我使用 LLM 的方式。

0 浏览
Back to Blog

相关文章

阅读更多 »