Doramagic 项目包 · 项目说明书

dspy 项目

DSPy:一个通过编程而非提示词来使用 LLM 的框架。

Core Programming Model: Signatures, Modules & Adapters

DSPy 框架的核心设计理念是"编程而非提示"——开发者通过组合 Python 模块来构建 AI 系统,而不是手工编写脆弱的提示字符串 (README.md)。这一抽象由三个紧密协作的核心概念支撑:Signature(签名)声明输入输出契约、Module(模块)封装可调用的计算单元、Adapter(适配器)负责把签名转换为 LM 实际消费的提示并把输出解析回结构化字段。它们...

章节 相关页面

继续阅读本节完整说明和来源证据。

概述 (Overview)

DSPy 框架的核心设计理念是"编程而非提示"——开发者通过组合 Python 模块来构建 AI 系统,而不是手工编写脆弱的提示字符串 (README.md)。这一抽象由三个紧密协作的核心概念支撑:Signature(签名)声明输入输出契约、Module(模块)封装可调用的计算单元、Adapter(适配器)负责把签名转换为 LM 实际消费的提示并把输出解析回结构化字段。它们共同把"模型调用"从一次性的字符串拼接,转化为可编译、可优化、可观察的 Python 程序。

Signatures — 声明式输入输出契约

Signature 是 DSPy 声明任务输入输出字段的基础结构。模块内部通过 Signature 类来表达"我需要哪些输入、要得到哪些输出",而字段类型则由 dspy.signatures.field 中的 OutputField 等构造器定义。DummyLM 在模拟 LM 输出时会按字段名格式化响应,例如:

[[## answer ##]]
red

(dspy/utils/dummies.py:40-58)。这种 [[## field_name ##]] 的标题约定与 chat_adapter.py 中的 field_header_pattern 正则共同保证:同一个签名既能被人阅读,也能被确定性解析。当签名字段未被正确定义类型时,会触发 IS_TYPE_UNDEFINED 常量所标记的特殊情形 (dspy/utils/constants.py)。

Modules — 可组合的程序单元

dspy.Module 是所有可执行单元的基类,前向传播通过 forward() 完成。框架通过 BaseCallback 提供对模块生命周期的钩子(on_module_start / on_module_end),从而支持优化器在编译期注入提示或示例 (dspy/utils/callback.py:1-40)。模块可嵌套组合:例如 dspy.Predict 是一个最常见的叶节点模块,其内部持有一个签名与一个适配器;上层模块(如 ReAct、ChainOfThought)则由多个 Predict 节点串联而成。社区对"Chat 模式"和"结构化输出"的支持请求(Issue #662、#1365)正是围绕这些模块的 forward() 路径展开的——当 LM 拒绝或解析失败时,模块需要决定回退策略。

Adapters — 提示格式化与字段解析

Adapter 是签名与具体 LM 调用之间的"翻译层"。基类位于 dspy/adapters/base.py,默认实现 ChatAdapterdspy/adapters/chat_adapter.py 中定义,其核心职责有二:

  1. 格式化(Format):把签名字段渲染为 LM 可读的 [[## field ##]] 标题块。DummyLM 通过 _use_example 复用已有对话中包含相同字段头的输出 (dspy/utils/dummies.py:88-100)。
  2. 解析(Parse):把 LM 文本回填到签名定义的字段。解析失败时抛出 AdapterParseError(继承自 DSPyError)(dspy/utils/exceptions.py)。

下表汇总了三类组件的职责边界:

组件关键文件主要职责
Signaturedspy/signatures/signature.py, dspy/signatures/field.py声明输入/输出字段及其语义提示
Moduledspy/primitives/module.py, dspy/predict/predict.py组合签名与适配器,提供 forward() 调用入口
Adapterdspy/adapters/base.py, dspy/adapters/chat_adapter.py在签名与 LM 之间做格式化/解析

调用流程与可观察性

下图描绘了一次典型 DSPy 调用中三类组件的协作关系:

flowchart LR
    User[用户输入] --> M[Module.forward]
    M --> Sig[Signature: 输入/输出字段]
    M --> P[dspy.Predict]
    P --> A[Adapter: ChatAdapter]
    A -- 格式化提示 --> LM[BaseLM / LiteLLM]
    LM -- 原始文本 --> A
    A -- 解析回字段或 AdapterParseError --> P
    P --> H[dspy.history]
    H --> IP[inspect_history.pretty_print_history]
    CB[BaseCallback: on_module_start/end] -.-> M
    CB2[BaseCallback: on_lm_start/end] -.-> A

调用完成后,pretty_print_history 会把最近 n 条历史以人类可读形式渲染(支持 textimage_urlinput_audio 等多模态内容),方便开发者调试提示模板 (dspy/utils/inspect_history.py)。框架同时把语言模型层的错误分为 LMProviderErrorLMTimeoutErrorLMContextWindowExceededError 等子类,并提供 is_retryable_lm_error 帮助上层模块决定是否重试 (dspy/utils/exceptions.py)。这种"分类型异常 + 回调 + 历史可观察"的设计,正是社区 Issue #338(流式输出)、#192(函数调用)等扩展请求能够安全落地的基础。

社区关切与边界

根据社区讨论,核心编程模型在以下方向仍在演进:

  • 结构化输出:Issue #1365 推动 OpenAI Structured Outputs 与 Adapter 的深度集成,使得 JSON 解析回退链路更可靠。
  • 流式 LM 输出:Issue #338 指出,模块会以任意顺序多次调用 LM,因此流式需要重新设计 Adapter 的增量解析契约。
  • Chat 模式与函数调用:Issue #662 与 #192 反映了开发者希望在签名中直接表达"工具/函数"语义,而不是手工把它们塞进提示。

理解 Signatures / Modules / Adapters 的职责边界,是参与上述讨论与编写自定义适配器的前提。

参见 (See Also)

来源:https://github.com/stanfordnlp/dspy / 项目说明书

Language Model Clients & Adapter Variants

DSPy 是一个"以编程代替提示"的基础模型框架,其核心理念是把 LM 调用抽象为可组合的 Python 模块 ([README.md:24-28]())。在这一架构里,语言模型 (LM) 客户端与适配器 (Adapter) 共同承担"用户代码 ↔ 各类 LLM 提供商"之间的桥接职责:客户端负责底层调用、错误分类与重试;适配器负责把声明式 Signature 渲染为不同模...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 异常分类

继续阅读本节完整说明和来源证据。

概述

DSPy 是一个"以编程代替提示"的基础模型框架,其核心理念是把 LM 调用抽象为可组合的 Python 模块 (README.md:24-28)。在这一架构里,语言模型 (LM) 客户端适配器 (Adapter) 共同承担"用户代码 ↔ 各类 LLM 提供商"之间的桥接职责:客户端负责底层调用、错误分类与重试;适配器负责把声明式 Signature 渲染为不同模型所需的提示格式,并将模型输出解析回结构化字段。

本文聚焦于 LM 客户端与适配器配套的错误体系测试替身历史查看回调系统以及外部工具互操作这五个支撑性子系统。

架构总览

下图展示了 LM 客户端、适配器、错误体系与回调系统在一次 DSPy 调用中的位置关系。

graph TB
    A[用户代码 / dspy.Module] --> B[BaseLM / dspy.LM 客户端]
    B --> C[Adapter 渲染与解析]
    C --> D[Provider Backend]
    D --> E[LiteLLM]
    E --> F[OpenAI / Anthropic / 其他]
    B -. 异常分类 .-> G[Error 体系]
    B -. 生命周期 .-> H[Callback 系统]
    C -. 解析失败 .-> I[AdapterParseError]

错误处理体系

DSPy 通过 DSPyError 基类提供统一的结构化异常,所有 LM 异常均继承自 LMError,并通过 default_code 暴露稳定的错误码 (dspy/utils/exceptions.py:17-65)。基类还支持 modelproviderprovider_codestatusrequest_idretry_after 等结构化元数据,便于上层做分类与告警 (dspy/utils/exceptions.py:24-58)。

异常分类

异常类语义default_code
LMProviderError提供商返回错误响应provider
LMAuthError身份认证失败auth
LMContextWindowExceededError上下文窗口超出context_window_exceeded
LMUnsupportedModelError模型不可用unsupported_model
LMTimeoutError请求超时timeout
LMServerError服务端失败server
LMTransportError网络传输失败(由子类定义)
LMUnexpectedError兜底未分类异常unexpected
AdapterParseError适配器解析失败(独立)

LMUnexpectedError 专门处理"既非已知 provider 错误又带 HTTP 状态码"的边界场景,避免被适配器当成解析错误 (dspy/utils/exceptions.py:67-76)。is_retryable_lm_error() 函数把"速率限制 + 超时 + 服务端 + 传输"四类纳入可重试集合 (dspy/utils/exceptions.py:124-134)。

社区讨论:issue #1365 与 #192 反映用户希望客户端原生支持 OpenAI Structured Outputs 与函数调用错误语义;issue #338 则讨论了 streaming 调用时如何重新分类错误。

测试与开发工具

DummyLM 继承自 BaseLM,提供三种工作模式 (dspy/utils/dummies.py:24-66):

  1. 字典列表模式:按调用顺序返回列表中的下一项,并用 ChatAdapter 渲染字段;
  2. 字典字典模式:以 prompt 末段为键查询对应输出;
  3. 示例跟随模式:通过 follow_examplesreasoning 选项在历史中复用示例或注入推理内容。

默认适配器为 ChatAdapter (dspy/utils/dummies.py:88-95),使 DummyLM 能够如实模拟真实输出格式。pretty_print_history 工具以彩色方式打印最近 n 条 prompt/输出 (dspy/utils/inspect_history.py:25-30),并支持写入文件(自动关闭 ANSI 颜色)以及 tool_calls、image_urlinput_audio 等多模态内容 (dspy/utils/inspect_history.py:35-66)。

外部工具互操作

适配器层提供与第三方工具生态的桥接函数,二者都使用 convert_input_schema_to_tool_args 作为统一入口:

社区讨论:issue #192 询问如何把 LangChain/LlamaIndex 的 function calling 迁移到 DSPy 工具体系;issue #662 关注 chat 模式下的提示格式兼容问题。

回调与基础设施

BaseCallback 定义了模块级与 LM 级的生命周期钩子:on_module_start/on_module_end 接收 call_idinstanceinputs/outputs,异常时携带 exception (dspy/utils/callback.py:13-37);on_lm_start/on_lm_end 在 LM __call__ 前后触发 (dspy/utils/callback.py:39-65),便于上层做日志、追踪或重试。

辅助层还包括:IS_TYPE_UNDEFINED 哨兵常量供适配器识别未声明类型字段 (dspy/utils/constants.py:3);print_message 为带时间戳的日志打印工具 (dspy/dsp/utils/utils.py:7-23);DPR_tokenize/strip_accents 提供检索/分词支持 (dspy/dsp/utils/dpr.py:51-82);_LazyModule 在首次属性访问时才真正 exec_module,避免重量级依赖阻塞导入 (dspy/utils/lazy_import.py:35-58)。

版本与变更

3.3.0b1 引入了 ReActV2 模块与新的 BaseLM 系统,并升级到 GEPA 0.1.1。LM 相关 API 在迭代中总体保持稳定,但异常类型与适配器解析失败语义存在微调,建议升级时关注 issue #390 的重构路线图以及 #338、#662 中提到的流式与 chat 格式问题。

See Also

来源:https://github.com/stanfordnlp/dspy / 项目说明书

Optimization & Compilation (Teleprompters)

在 DSPy 中,"Teleprompter" 是用于自动优化和编译声明式 LM 程序的组件。其核心思想是:开发者编写模块化的 Python 代码(由 dspy.Module 与 dspy.Signature 组成),由 Teleprompter 在小型训练集上自动搜索提示词、示范样例(demos)甚至模型权重,从而把"程序"编译成高质量的 LM pipeline。

章节 相关页面

继续阅读本节完整说明和来源证据。

一、概述:DSPy 中的"编译"概念

在 DSPy 中,"Teleprompter" 是用于自动优化和编译声明式 LM 程序的组件。其核心思想是:开发者编写模块化的 Python 代码(由 dspy.Moduledspy.Signature 组成),由 Teleprompter 在小型训练集上自动搜索提示词、示范样例(demos)甚至模型权重,从而把"程序"编译成高质量的 LM pipeline。

README 将 DSPy 定位为"编程而非提示"框架,并明确指出它提供"优化提示与权重的算法,无论你构建的是简单分类器、复杂 RAG 流水线还是 Agent 循环" README.md。Teleprompter 正是这一能力的承载体。

flowchart LR
    A[声明式程序<br/>dspy.Module] --> B[Teleprompter<br/>优化器]
    B --> C[训练集<br/>trainset]
    B --> D[评估指标<br/>metric]
    B --> E[优化后的程序<br/>compiled]
    C --> B
    D --> B
    E --> F[推理部署]

二、主流 Teleprompter 一览

DSPy 提供了多代优化器,覆盖从轻量随机搜索到基于反思的提示进化。下表汇总了仓库内置的核心 Teleprompter:

优化器主要思路适用场景源码入口
BootstrapFewShot用程序自举生成示范,逐步填充 demos入门级、最常用bootstrap.py
RandomSearch在自举候选池中随机采样多组 demos 并评估轻量稳健基线random_search.py
COPRO协作式提示优化,迭代生成候选指令指令敏感任务copro_optimizer.py
MIPROv2多阶段贝叶斯式优化(指令 + 示范联合搜索)复杂多步程序mipro_optimizer_v2.py
GEPA反思式提示进化,可与 RL 抗衡需深度语义反思的任务gepa/gepa.py
SIMBA简化智能体/模块微调与行为对齐Agent 风格模块simba.py

社区中长期讨论的 OpenAI 结构化输出支持(Issue #1365)以及函数调用(Issue #192)能力,会通过 Adapter 层与 Teleprompter 协同:优化器评估候选指令时,会经过同一 Adapter 完成解析与校验 dspy/utils/exceptions.py。当底层 LM 不支持某特性时,会抛出 UnsupportedFeatureError,可由优化器捕获并回退到下一候选。

三、典型优化工作流

一次标准的 compile 调用通常包含以下阶段:

  1. 准备阶段:定义 dspy.Module(如 ChainOfThought 组合)、训练集(若干 dspy.Example)、以及 metric(可调用对象,返回分数或 bool)。
  2. 实例化 Teleprompter:选择与任务规模匹配的优化器,例如 MIPROv2(metric=metric, auto="medium")
  3. 执行编译:调用 teleprompter.compile(student=program, trainset=trainset),内部循环包含「提案 → LM 调用 → 评分 → 更新」四个动作。
  4. 回写程序:优化完成后,程序内部的 Signature 指令、prompt 模板与 demos 被替换为最优候选;随后可直接用于推理。
  5. 可观测性:训练与评估期间,LM 历史可通过 pretty_print_history 调试,模块与 LM 的生命周期事件由 BaseCallback 体系暴露 dspy/utils/callback.py,便于构建自定义评估器或早停逻辑。

四、常见使用模式与失败模式

  • 从小到大:先以 BootstrapFewShot 建立基线,再视需要升级到 MIPROv2GEPA,避免一开始就在小数据集上消耗大量算力。
  • 指标设计metric 是优化的目标函数,过于宽松会导致提示退化,过于严格则在 LLM-as-judge 下成本激增。建议先用 DummyLM 跑通管道,再切换到真实 LM dspy/utils/dummies.py
  • 多轮对话/Chat 模式:社区 Issue #662 关注 Chat 模型对 DSPy 默认格式的兼容性。在 Chat 场景下,应使用 ChatAdapter 并显式声明 dspy.configure(adapter=...),确保 Teleprompter 评估时使用一致的解析路径。
  • 流式输出:Issue #338 讨论的 stream 能力目前主要影响推理阶段,对 Teleprompter 影响较小,因为优化阶段通常依赖完整响应以进行解析与打分。
  • 结构化输出回退:当 Provider 拒绝 JSON schema 时,Teleprompter 抛出的 LMProviderError 会携带 provider_codestatus 等元数据,开发者可据此决定重试、降级到文本解析或更换 Adapter dspy/utils/exceptions.py
  • 实验性 API:部分新优化器(如 GEPA 0.1.1)通过 @experimental 装饰器标记,使用前应在文档中确认其稳定性 dspy/utils/annotation.py

五、与"编程式 LM"理念的关系

Teleprompter 是 DSPy"声明式自改进 Python"(Declarative Self-improving Python)这一名称中"自改进"二字的工程实现。它将手工调参迁移到算法搜索,使程序本身成为可被持续优化的对象——这也是 README 中强调"迭代构建模块化 AI 系统"的关键支撑。配合 dspy.Module 的可组合性、Adapter 的统一协议以及 BaseCallback 的可观测性,开发者可以在不重写业务逻辑的前提下,反复运行不同 Teleprompter 来持续提升程序质量。

See Also

  • Signatures & Modules — 了解被优化的程序结构
  • Adapters — 优化器与推理共用解析协议
  • BaseLM & Providers — 优化器调用 LM 的统一入口
  • Exception Handling — 处理优化过程中的 Provider 错误

来源:https://github.com/stanfordnlp/dspy / 项目说明书

Tools, Streaming, Retrieval & Utilities

DSPy 作为"声明式自改进 Python"框架,其核心能力不仅来自签名(Signature)和模块(Module),还依赖一套围绕 Tools(工具调用)、Streaming(流式 LM 输出)、Retrieval(检索)以及通用 Utilities(工具函数) 组成的辅助层。本页重点说明这些辅助模块的源码实现、典型使用方式以及与社区关注点的对应关系。

章节 相关页面

继续阅读本节完整说明和来源证据。

1. 概览与定位

DSPy 作为"声明式自改进 Python"框架,其核心能力不仅来自签名(Signature)和模块(Module),还依赖一套围绕 Tools(工具调用)、Streaming(流式 LM 输出)、Retrieval(检索)以及通用 Utilities(工具函数) 组成的辅助层。本页重点说明这些辅助模块的源码实现、典型使用方式以及与社区关注点的对应关系。

社区中的 #192 function calling#338 Adding stream to DSPy LMs 长期是用户高互动话题;而 3.3.0b1 Release Notes 中提到的"fewer dependencies framework wide"也直接影响本页所讨论的 lazy import 机制。

来源:https://github.com/stanfordnlp/dspy / 项目说明书

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

medium 存在评分风险

风险会影响是否适合普通用户安装。

medium 来源证据:[Bug] (withdrawn) Module.save() JSON state + Retrieve.dump_state json_mode

可能影响授权、密钥配置或安全边界。

Pitfall Log / 踩坑日志

项目:stanfordnlp/dspy

摘要:发现 9 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:能力坑 - 能力判断依赖假设。

1. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://github.com/stanfordnlp/dspy | README/documentation is current enough for a first validation pass.

2. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://github.com/stanfordnlp/dspy | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://github.com/stanfordnlp/dspy | no_demo; severity=medium

4. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://github.com/stanfordnlp/dspy | no_demo; severity=medium

5. 安全/权限坑 · 来源证据:[Bug] (withdrawn) Module.save() JSON state + Retrieve.dump_state json_mode

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[Bug] (withdrawn) Module.save() JSON state + Retrieve.dump_state json_mode
  • 对用户的影响:可能影响授权、密钥配置或安全边界。
  • 证据:community_evidence:github | https://github.com/stanfordnlp/dspy/issues/9933 | 来源类型 github_issue 暴露的待验证使用条件。

6. 安全/权限坑 · 来源证据:[Feature] MCP guide — security agent over remote HTTP MCP servers (re #8957)

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[Feature] MCP guide — security agent over remote HTTP MCP servers (re #8957)
  • 对用户的影响:可能影响授权、密钥配置或安全边界。
  • 证据:community_evidence:github | https://github.com/stanfordnlp/dspy/issues/9922 | 来源类型 github_issue 暴露的待验证使用条件。

7. 安全/权限坑 · 来源证据:[Feature] Memory/retrieval poisoning defense via OWASP Agent Memory Guard

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[Feature] Memory/retrieval poisoning defense via OWASP Agent Memory Guard
  • 对用户的影响:可能阻塞安装或首次运行。
  • 证据:community_evidence:github | https://github.com/stanfordnlp/dspy/issues/9911 | 来源讨论提到 python 相关条件,需在安装/试用前复核。

8. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://github.com/stanfordnlp/dspy | issue_or_pr_quality=unknown

9. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://github.com/stanfordnlp/dspy | release_recency=unknown

来源:Doramagic 发现、验证与编译记录