Imp 是 DSPy 到 BEAM 的完整移植版

Hacker News Top 工具

摘要

Imp 是 DSPy 到 BEAM 的完整移植版,使得在 Elixir 中能够利用 OTP 的可靠性和容错性,创建声明式的、自我改进的语言模型程序。

<a href="https:&#x2F;&#x2F;hex.pm&#x2F;packages&#x2F;imp" rel="nofollow">https:&#x2F;&#x2F;hex.pm&#x2F;packages&#x2F;imp</a><p><a href="https:&#x2F;&#x2F;dspy.ai&#x2F;current&#x2F;" rel="nofollow">https:&#x2F;&#x2F;dspy.ai&#x2F;current&#x2F;</a>
查看原文
查看缓存全文

缓存时间: 2026/09/27 22:41

deepfates/imp 来源:https://github.com/deepfates/imp

Imp

用于 Elixir 的声明式、自我改进的语言模型程序。 Imp 是 DSPy (https://dspy.ai) 到 BEAM 的完全移植。 你只需描述每个语言模型步骤的输入输出,选择其思考方式,然后让优化器根据示例进行改进。 你将获得签名、模块、优化器、智能体循环和检索功能,并以 OTP 的可靠性和并发性运行。

DSPy 将每次模型调用都变为一个声明式的、带类型的函数,你可以对其进行测量和改进。 在 BEAM 上,一个智能体就是一个进程:它维护自己的状态、接收消息,并在监督者下与你的应用程序的其他部分一起运行。 结合两者,你可以构建从单个类型化调用到多个长期运行智能体的任何应用,并通过测量来改进每个部分。

声明任务

lm = Imp.req_llm("openai:gpt-5.4-mini", api_key: System.fetch_env!("OPENAI_API_KEY"))
triage = "issue -> kind: enum[bug,feature,question], summary" |> Imp.signature("Triage a GitHub issue.") |> Imp.predict(lm: lm)
{:ok, prediction} = Imp.call(triage, %{issue: "App crashes on startup since 0.4 with ** (KeyError) key :lm not found"})
{Imp.get(prediction, :kind), Imp.get(prediction, :summary)}
#=> {"bug", "App crashes on startup since version 0.4 with a KeyError for `:lm` not found."}

你无需编写提示词或解析器。Imp 根据签名构建提示词,对照签名检查回复,并为你提供带类型的字段:kind 总是三个值之一,否则调用返回错误。 若要使同一任务先进行推理,请使用 Imp.chain_of_thought/2;若要赋予其工具,请使用 Imp.react/3。签名保持不变。

测量并改进

给 Imp 标注好的示例和一个度量标准,它就会对程序进行评分并优化。 你需要三个已标注的问题列表:trainset(优化器从中学习),valset(用于在它尝试的程序之间进行选择),以及 testset(你在优化前后用于评分的)。 strong_lm 是一个更强大的模型,GEPA 用来读取失败案例并撰写新的指令。

# 每个集合都是一个类似此例的已标注问题列表:
example = Imp.example(%{issue: "Please add a dark mode to the dashboard", kind: "feature"}) |> Imp.with_inputs([:issue])
metric = Imp.exact_match(:kind)
Imp.evaluate(triage, testset, metric).score

optimizer = Imp.Optimizer.GEPA.new(metric, reflection_lm: strong_lm, max_metric_calls: 300)
improved = Imp.optimize!(triage, optimizer, trainset, valset)
Imp.evaluate(improved, testset, metric).score

GEPA 运行程序,读取其失败之处,并重写其指令。 其他优化器会选择已验证的示例(LabeledFewShot, BootstrapFewShot),在指令和示例的组合中搜索(MIPROv2),从程序自身更好和更差的尝试中学习规则和示例(SIMBA),或训练模型的权重(微调,GRPO)。 最终得到一个新程序,其指令和示例你可以阅读、保存为 JSON,并以差异对比形式查看。

构建智能体

工具就是一个 Elixir 函数。Imp.react/3 构建一个智能体,它会调用工具直到能够回答问题。这个工具用 Req 读取网页。 Imp 依赖于 Req;如果你自己的代码也调用它(如此工具所示),请在依赖中添加 {:req, "~> 0.6"}:

fetch = Imp.tool(:fetch, "Read a web page as text.", fn %{"url" => url} ->
  Req.get!(url).body
end, schema: %{
  "type" => "object",
  "properties" => %{"url" => %{"type" => "string"}},
  "required" => ["url"]
})

researcher = Imp.react("question -> answer", [fetch], lm: lm)
question = "What version does https://raw.githubusercontent.com/elixir-lang/elixir/v1.18.0/VERSION say? " <> "Reply with just the version."
{:ok, prediction} = Imp.call(researcher, %{question: question})
Imp.get(prediction, :answer)
#=> "1.18.0"

将智能体作为进程运行

Imp.call/2 在你的进程中运行一个程序。 Imp.start_run/3 则将其作为自己的监督进程运行,这样你就可以监视它、停止它,并决定它可以进行哪些工具调用:

{:ok, run} = Imp.start_run(researcher, %{question: question}, authorize: fn call ->
  url = call.arguments["url"] || ""
  if String.starts_with?(url, "https://raw.githubusercontent.com/"), do: :allow, else: {:deny, :untrusted_host}
end)

{:ok, prediction} = Task.await(run.task, :infinity)

for event <- Imp.Run.events(run), do: event.kind
#=> [:run_started, :tools_sent, :model_request, :model_response, :tool_call,
#   :tool_result, :model_request, :model_response, :run_finished]

Imp 还包括:

  • MCP: 导入任何你批准的 MCP 服务器的工具,它们就像你自己的工具一样工作。
  • ACP: 将任何 Imp 程序作为智能体提供给 Zed 和其他 ACP 客户端。
  • OTP: 一次运行就是一个你可以监视、停止和限制的进程,并且当启动它的进程结束时,运行也就结束。
  • 模型请求会按你设定的截止时间进行切割。
  • 一个可能已经生效的工具调用会被报告为未知状态,永远不会静默重试。
  • 更多形式: RLM(用于输入远大于上下文窗口的情况),CodeAct 和思维程序(用小型沙箱表达式进行计算),以及由这些组合而成的你自己的模块。 优化器也适用于智能体。GEPA 会反思整个智能体运行过程,并重写引导它们的指令。Optimize Anything 会重写任何你可以评分的文本或 JSON,例如智能体的工具描述。

安装

{:imp, "~> 0.5"}

Imp 需要 Elixir 1.19 或更高版本,以及 C 和 C++ 编译器,用于两个依赖(jaxon 和 erlexec)中的原生代码。首次编译需要网络访问,因为 erlexec 的构建会获取 rebar3 插件。 它通过 ReqLLM (https://hex.pm/packages/req_llm) 连接模型,因此任何 ReqLLM 支持的提供商都可以使用。 Imp 0.5 是实验性的,也是它在 Hex 上的首次发布。其 API 仍可能更改,其优化器需要大规模基准测试。 欢迎提交错误报告和拉取请求。

学习

  • 入门指南 从第一步调用到监督服务器,逐步构建一个程序,并给出真实分数。
  • 来自 DSPy 将 DSPy 的名称映射到 Imp 的名称。
  • 教程 (https://github.com/deepfates/imp/tree/v0.5.0/livebooks) 是你可以离线或使用密钥运行的 Livebook 笔记本。
  • 速查表 将常用调用放在一页上。

Imp 采用 MIT 许可证。

相似文章