DSPy.rb 是一个 Ruby 框架,用于以编程方式构建语言模型应用,强调类型安全、模块化和可测试性。它把软件工程实践引入 LLM 开发:不再反复调整提示词,而是用 Ruby 类型定义目标,由框架处理其余部分。
一、核心概念
-
签名(Signatures):用 Ruby 类型定义应用与 LLM 之间的接口。示例中 EmailClassifier 通过 input/output 块声明 email_content、sender 等输入,以及 category、priority(T::Enum 枚举)、confidence(Float)等输出。
-
模块(Modules):由简单构件组合复杂工作流,包括 Predict(基础 LLM 调用)、ChainOfThought(逐步推理)、ReAct(使用工具的智能体)、CodeAct(动态代码生成智能体,需安装 dspy-code_act gem)。
-
工具与工具集(Tools & Toolsets):为智能体创建类型安全的工具,支持 Sorbet。示例 CalculatorTool 使用枚举 Operation 与 sig 签名;DataToolset 展示多工具工具集,含 convert、validate 等工具及 Format 枚举。
-
类型系统与判别器:自动注入 _type 字段以支持联合类型(T.any())判别,_type 为保留字段名,反序列化时会在所有嵌套层级过滤该字段。
-
优化(Optimization):MIPROv2 提供多提示优化,含 bootstrap 采样与贝叶斯优化;GEPA 为遗传-帕累托反思式提示演化,含反馈映射、实验跟踪与遥测;评估框架支持内置与自定义指标、错误处理与批处理。
二、快速开始
安装:gem 'dspy'。配置:DSPy.configure 中设置 c.lm = DSPy::LM.new('openai/gpt-4o-mini', api_key: ENV['OPENAI_API_KEY'])。定义任务:继承 DSPy::Signature,声明 input/output。使用:analyzer = DSPy::Predict.new(SentimentAnalysis),调用 analyzer.call(text: ...) 获取结果。
三、提供商适配器
两种策略:按提供商适配器(直接 SDK 访问),如 dspy-openai(OpenAI、OpenRouter、Ollama)、dspy-anthropic(Claude)、dspy-gemini(Gemini),各自引入官方 SDK;或通过 RubyLLM 的统一适配器(多提供商推荐),使用 dspy-ruby_llm 与 ruby_llm,以 ruby_llm/ 前缀路由模型,如 ruby_llm/gemini-2.5-flash。
四、事件系统
提供结构化事件总线观察运行时行为。支持模块作用域订阅(subscribe 'lm.tokens', :track_tokens, scope: :descendants)与全局订阅(DSPy.events.subscribe),支持通配符(如 'llm.*')。事件名使用点分隔命名空间(llm.generate、react.iteration_complete),事件包含模块元数据用于过滤。
五、生命周期回调
每个 DSPy::Module 提供 Rails 风格钩子:before(forward 前运行)、around(包裹 forward 并 yield)、after(forward 返回后触发)。执行顺序为 before → around(yield 前)→ forward → around(yield 后)→ after,回调可继承并按注册顺序执行。
六、Fiber 本地 LM 上下文
可用 DSPy.with_lm 临时覆盖语言模型。LM 解析层级:实例级 LM → Fiber 本地 LM → 全局 LM。可用 configure_predictor 对智能体内部进行细粒度控制。
七、评估框架
使用 DSPy::Evals 系统测试性能。内置指标包括 exact_match、contains、numeric_difference、composite_and;自定义指标返回 true/false 或带 score、feedback 的 DSPy::Prediction。可用 DSPy::Example 提供类型化测试数据,export_scores: true 推送结果到 Langfuse。
八、GEPA 优化
安装 gem 'dspy-gepa'。创建 DSPy::Teleprompt::GEPA.new,传入 metric、reflection_lm、feedback_map 与 config(如 max_metric_calls、minibatch_size),调用 compile 得到 optimized_program。指标须返回 DSPy::Prediction.new(score:, feedback:) 以便反思模型分析失败。
九、类型化上下文模式
用 T::Struct 输入替代不透明的字符串上下文。每个字段可带 description 注解,进入 LLM 看到的 JSON schema。示例 NavigationContext 含 workflow_hint、action_log、iterations_remaining 等字段。好处:编译期类型安全、逐字段描述、易于测试、可扩展。
十、Schema 格式(BAML / TOON)
可控制 DSPy 向 LLM 描述签名结构的方式:JSON Schema(默认)、BAML(schema_format: :baml,Enhanced Prompting 模式下减少 84% token,需 sorbet-baml gem)、TOON(schema_format: :toon, data_format: :toon,表格导向,仅 Enhanced Prompting 模式)。BAML 与 TOON 仅在 structured_outputs: false 时生效。
十一、存储系统
用 DSPy::Storage::ProgramStorage 持久化与重载优化后的程序,支持检查点管理、优化历史跟踪、跨环境导入导出。
十二、Rails 集成
目录结构建议:app/entities(共享 T::Struct 类型)、app/signatures、app/tools(含 concerns)、app/modules、app/services;config/initializers 放 dspy.rb 与 feature_flags.rb;spec 下放签名、工具、模块测试与 VCR 录像。初始化器示例展示 RubyLLM.configure、DSPy.configure 与可选 Langfuse 可观测性配置。可用特性标志为不同角色选择不同模型(如选择器用轻量模型、合成器用更强模型)。
十三、Schema 驱动签名与工具模式
优先使用类型化 schema 而非字符串描述。实体作为共享类型放在 app/entities/。判断规则:若会对输出写 case 语句,应为 T::Enum;若会对其调用 .each,应为 T::Array[SomeStruct]。工具可封装预测,加入错误处理、模型选择与序列化,示例 RerankTool 展示短路 LLM 调用、限制输入大小、按工具选模型、优雅降级等模式。
限制与说明:资料未提供具体收费、价格、平台支持范围或性能数据;部分内容(如错误处理 concern 示例)在资料中未完整给出。