// HACKER NEWS — CYBERSECURITY
Imp is a full port of DSPy to the BEAM
Declarative, self-improving language-model programs for Elixir.
Imp is a full port of DSPy 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.
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.
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.
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.
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:
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:
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.
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, so any provider ReqLLM supports
works.