关于 dspy-rlm-module
面向需要处理超出单次提示词容量上下文的开发者,介绍 DSPy 的 `dspy.RLM`。内容涵盖沙箱内的 Python 探索、递归子查询,以及将模块组合进更大的 DSPy 程序。
主要功能
- 01在沙箱中通过 Python REPL 探索
- 02递归分块与子查询
- 03配置迭代和调用上限
- 04传入自定义可调用工具
- 05与 DSPy 模块组合
适用场景
- 01处理单次提示词无法容纳的上下文
- 02使用自定义工具搜索或读取文件
- 03构建代码仓库分析程序
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ intertwine/ dspy-agent-skills --skill dspy-rlm-module安装后在 Claude Code 中输入/dspy-rlm-module确认已加载。
附带文件example_rlm.pyreference.md
详细介绍
dspy.RLM — 递归语言模型
dspy.RLM 在沙盒化的 Python REPL(通过 Deno 运行的 Pyodide/WASM)中运行 LLM,并将完整上下文作为变量供其访问。LLM 编写代码来切片、搜索、总结数据,并递归地对数据发起子查询,不断迭代,直到能够作答。当上下文太大,无法塞进单个提示词时,请使用它。
前置条件
- 已安装 Deno(用于默认的
PythonInterpreter):运行brew install deno,或参阅 https://deno.land。该解释器是在 Deno 中启动的 Pyodide-WASM 沙盒。 - 用于内部调用的子 LM——通常比外层 LM 更便宜的模型。默认为
dspy.settings.lm。
标准用法
import dspy
dspy.configure(lm=dspy.LM("openai/gpt-4o"))
sub_lm = dspy.LM("openai/gpt-4o-mini") # cheap inner model
rlm = dspy.RLM(
"context, query -> answer",
max_iterations=20,
max_llm_calls=50,
max_output_chars=10_000,
sub_lm=sub_lm,
tools=[],
verbose=False,
)
result = rlm(
context=open("huge_log.txt").read(), # can be 500k+ tokens
query="Summarize every unique error class and how many times each appeared.",
)
print(result.answer)
完整构造函数
dspy.RLM(
signature: type[Signature] | str,
max_iterations: int = 20, # REPL loop cap
max_llm_calls: int = 50, # sub-LM call cap (stops runaway recursion)
max_output_chars: int = 10_000, # truncate REPL stdout per step
verbose: bool = False, # print the REPL trace
tools: list[Callable] | None = None,
sub_lm: dspy.LM | None = None,
interpreter: CodeInterpreter | None = None, # custom sandbox
)
何时选择 RLM 而非其他方案
| 情况 | 使用 |
|---|---|
| 上下文小于 100k,答案可通过一次 LM 调用得出 | dspy.Predict / dspy.ChainOfThought |
| 需要外部工具(Web、数据库) | dspy.ReAct(tools=[...]) |
| 必须运行的数学或代码任务 | dspy.ProgramOfThought |
| 超大上下文、递归分块或数据探索循环 | dspy.RLM |
| 推理整个代码库,且 LM 需要搜索/读取文件 | 使用文件读取 tools=[...] 的 dspy.RLM |
组合使用 — 将 RLM 作为较大程序中的模块
将 RLM 封装在自己的 dspy.Module 中,并使用 GEPA 优化封装程序。GEPA 可以调整 RLM 的外层签名指令以及周围的预测器。
class RepoAuditor(dspy.Module):
def __init__(self):
super().__init__()
self.explore = dspy.RLM("repo_tree, question -> findings",
max_iterations=30, sub_lm=dspy.LM("openai/gpt-4o-mini"))
self.synth = dspy.ChainOfThought("findings, question -> report")
def forward(self, repo_tree, question):
f = self.explore(repo_tree=repo_tree, question=question).findings
return self.synth(findings=f, question=question)
然后运行:dspy.GEPA(metric=..., ...).compile(student=RepoAuditor(), trainset=..., valset=...)。
实用技巧
- 谨慎设置预算。 单次 RLM 调用可能会发起数十次子 LM 调用。在生产环境中,将
max_llm_calls控制在较低水平(20–50);研究时可调高。 - DSPy 3.2.x 中的默认标准输出上限更低。
max_output_chars现在默认为10_000;如果你的 REPL 工具会打印大型表格或文档片段,请根据需要有意调高。 - 使用低成本的
sub_lm。 外层 LM 负责协调;内部调用(总结、筛选、评分)无需使用旗舰模型。 - 通过 kwargs 传入数据,而不是放在指令中。
rlm(context=huge_string, query="...")可让 REPL 将context作为 Python 变量处理。避免将其拼接进提示词。 - 调试时设置
verbose=True。 这会打印每个 REPL 步骤——当 RLM 似乎卡住或陷入循环时尤其有用。 - 自定义工具是通过
tools=[...]传入的常规 Python 可调用对象;它们会在沙盒内开放使用。适用于read_file、grep、vector_search等。在 DSPy 3.2.x 中,这些工具通过关键字调用,因此应为其定义带名称和类型的参数,而不是仅限位置参数的签名。 - 必须安装 Deno。 缺少 Deno 是 RLM 错误的首要原因。报告问题前,请运行
which deno检查。
安全说明
默认解释器是在 Deno 沙盒中运行的 Pyodide WASM 运行时——默认无法访问文件系统、网络或子进程。如果你传入会执行 I/O 的自定义 tools,这些工具的安全性由你负责。切勿将原始的 subprocess.run 交给 RLM。
反模式
- 明明 32k-token 的提示词就够用,却仍使用 RLM——其开销不值得。
- 缺少 Deno → 难以诊断的故障。请安装它。
- 在生产路径中将
max_llm_calls留为默认值——可能导致成本失控。 - 在
context字符串中传入机密——它们会回显到 REPL 状态中。
下一步
- 使用 GEPA 封装并优化 →
dspy-gepa-optimizer。 - 完整参考 → reference.md。
评论
支持 Markdown