2026-10-11 17:15 UTC

deepfates claims the released Imp v0.5 β€” a full port of DSPy to the BEAM providing signatures, optimizers (GEPA, MIPROv2), supervised agent processes, and MCP/ACP support β€” makes typed, optimizable LLM programs practical in Elixir; sustained adoption would establish the BEAM as a working non-Python ecosystem for building LLM pipelines.

state: watchingheat: lowuncertainty: mediumconvergesscott: mediumllm-tooling dspy beam-ecosystem elixirdeepfates

What is this?

Imp v0.5 is a self-published library by developer deepfates that, per the release announcement, ports DSPy β€” Stanford's framework for treating LLM programs as compiled, optimizable artifacts rather than hand-written prompt chains β€” to the BEAM (Elixir/Erlang VM), including DSPy's signature/module abstractions, its flagship optimizers (GEPA, MIPROv2), supervised agent processes, and MCP/ACP protocol support. The supplied web snippets corroborate the significance of what is being ported: DSPy is described as the open-source standard for compiled prompts, and GEPA (ICLR 2026 Oral) is its reflective prompt-evolution optimizer shown to outperform RL approaches with up to 35x fewer rollouts, with production adoption at Nubank and Google. The snippets say nothing about Imp or deepfates themselves, so the port's specifics and traction rest on the case's own evidence β€” a low-heat HN post (9 points) β€” and cannot be independently confirmed here.

Why it matters to Scott

Converges with The Prompt Is Source: Imp's signatures plus GEPA/MIPROv2 make the prompt a compiled, evaluation-selected artifact rather than hand-tuned text β€” Scott's compiler-boundary and evaluation-driven-development doctrine made executable β€” and its supervised agent processes land DSPy agents squarely in the durable-supervision territory of his long-running-agents framework, now on the BEAM instead of Python. MEDIUM not high because traction is 9 HN points and the port's quality is unverified, but it joins WeaveScope as a second Elixir AI-tooling episode in the radar, making 'BEAM as non-Python LLM substrate' an emerging cluster worth tracking and giving Scott a dated receipt that prompt-as-source is propagating beyond Python.
ip:framework.the-prompt-is-sourceip:source.the-prompt-is-source-ebookip:concept.evaluation-driven-developmentip:framework.long-running-agentsradar:weavescope-elixir-agent-observabilityradar:dspy-factorio-rlm-gepa-agentsradar:supervice-agent-process-supervisorradar:concept.agent-protocolsradar:concept.mcp
queries asked of Scott's wikis
  • dspy compiled prompts prompt-as-program
  • non-python llm tooling elixir beam ecosystem
  • typed signatures structured llm programs
  • prompt optimizer eval harness CI artifacts
  • supervised agent processes fault-tolerant agents
  • MCP ACP agent protocol integration

Measured heat

now 0 pts/hpeak 11 pts/hcomments 0/hpeers p14momentum: steady2 platformsage 333h
points/hour across evidence Β· reading as of 2026-10-12 02:59:37.977291+11:00 Β· deterministic, not a model opinion

How the heat travelled

09-27 20:39 (minted)⭐ origin echo-reconstructedRelease: 'Imp is a full port of DSPy to the BEAM' β€” declarative, self-improving language-model programs for Elixir with signatures, modules,
deepfates on github (echo) Β· attributed from hn.story.49869995 Β· published time unknown
β€”
09-27 19:28first on hacker news Β· published Β· lag ?Imp is a full port of DSPy to the BEAM
mpweiher
β€”
09-27 19:28amplified on hacker news πŸ‘‘hn.story.49869995
mpweiher
peak 99 Β· 10 comments Β· 100% of case engagement
09-27 20:21our radar first saw it Β· lag ?discovery anchor: hn.story.49869995β€”
pace: p67 vs 1188 stories at the 168h mark (now 333h old) β€” ahead of agentic-retrieval-frames-benchmark (1.0x), behind anthropic-blocked-request-billing (1.0x)

Evidence (2) β€” ⭐ canonical anchor

sourceobjectauthorscorecomments
🟧 hnImp is a full port of DSPy to the BEAM
Retrieved article excerpt

Open article Β· Retrieved 2026-09-27T20:29:22.617219+00:00

# Imp

Declarative, self-improving language-model programs for Elixir.

[An imp studies a hand of cards through a lens while a smaller imp springs from its tail.](https://github.com/deepfates/imp/blob/main/assets/imp-with-cards.jpg)

Imp is a full port of [DSPy](https://dspy.ai) to the BEAM. You describe what
each language-model step takes and returns, choose how it thinks, and let an
optimizer improve it against examples of what good looks like. You get
signatures, modules, optimizers, agent loops and retrieval, running with the
reliability and concurrency of OTP.

DSPy makes each call to a model a declared, typed function that you can
measure and improve. On the BEAM, an agent is a process: it keeps its own
state, receives messages, and runs under a supervisor alongside the rest
of your application. With both, you can build anything from one typed call
to many long-running agents, and improve each part by measuring it.

## Declare a task

```
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."}
```

You never write a prompt or a parser. Imp builds the prompt from the
signature, checks the reply against it, and gives you typed fields: `kind` is
always one of the three values, or the call returns an error. To make the
same task reason first, use `Imp.chain_of_thought/2`; to give it tools, use
`Imp.react/3`. The signature stays the same.

## Measure it and improve it

Give Imp labeled examples and a metric, and it scores the program and
optimizes it. You need three lists of issues you have already labeled:
`trainset`, which the optimizer learns from; `valset`, which it uses to choose
between the programs it tries; and `testset`, which you score on before and
after. `strong_lm` is a more capable model that GEPA uses to read failures and
write new instructions.

```
# Each set is a list of labeled issues like this one:
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 runs the program, reads where it failed, and rewrites its instructions.
Other optimizers choose worked examples (LabeledFewShot, BootstrapFewShot),
search over combinations of instructions and examples (MIPROv2), learn rules
and examples from the program's own better and worse attempts (SIMBA), or
train the model's weights (fine-tuning, GRPO). The result is a new program
whose instructions and examples you can read, save as JSON, and review as a
diff.

## Build agents

A tool is an Elixir function. `Imp.react/3` builds an agent that calls tools
until it can answer. This one reads web pages with Req. Imp depends on Req;
if your own code calls it, as this tool does, add `{:req, "~> 0.6"}` to your
dependencies:

```
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"
```

## Run agents as processes

`Imp.call/2` runs a program in your process. `Imp.start_run/3` runs it as its
own supervised process instead, so you can watch it, stop it, and decide
which tool calls it may make:

```
{: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 also includes:

- **MCP:** import the tools of any MCP server you approve, and they work like
  your own.
- **ACP:** serve any Imp program as an agent to Zed and other ACP clients.
- **OTP:** a run is a process you can watch, stop and limit, and a run ends
  when the process that started it does. Model requests are cut to a
  deadline you set. A tool call that may already have taken effect is
  reported as unknown, never silently retried.
- **More shapes:** RLM for inputs far larger than a context window, CodeAct
  and program of thought, which compute with small sandboxed expressions, and your own modules
  composed from these.

The optimizers work on agents too. GEPA reflects on whole agent runs and
rewrites the instructions that steer them. Optimize Anything rewrites any
text or JSON you can score, such as an agent's tool descriptions.

## Install

```
{:imp, "~> 0.5"}
```

Imp needs Elixir 1.19 or later and a C and C++ compiler, for the native code
in two dependencies (jaxon and erlexec). The first compile needs network
access, because erlexec's build fetches rebar3 plugins. It reaches models through
[ReqLLM](https://hex.pm/packages/req_llm), so any provider ReqLLM supports
works.

Imp 0.5 is experimental and is its first release on Hex. Its API may still
change, and its optimizers need large-scale benchmarking. Bug reports and
pull requests are welcome.

## Learn

- [Getting started](https://github.com/deepfates/imp/blob/main/docs/getting-started/index.md) builds one program step by
  step, from the first call to a supervised server, with real scores.
- [Coming from DSPy](https://github.com/deepfates/imp/blob/main/docs/coming-from-dspy.md) maps DSPy's names to Imp's.
- [Tutorials](https://github.com/deepfates/imp/tree/v0.5.0/livebooks) are Livebook notebooks
  you can run offline or with a key.
- The [cheatsheet](https://github.com/deepfates/imp/blob/main/docs/cheatsheet.cheatmd) has the common calls on one page.

Imp is MIT licensed.
mpweiher9910
🟧 echo.github ⭐Release: 'Imp is a full port of DSPy to the BEAM' β€” declarative, self-improving language-model programs for Elixir with signatures, modules,deepfatesβ€”β€”

Interpretation history

Decision trace