Imp is a way to build with language models in Elixir by writing programs instead of prompt strings.
We describe each task as named, typed inputs and outputs. Imp writes the prompt, calls the model, and checks the reply against that description, so the rest of our code gets a value it can trust. Programs are ordinary Elixir values: we can test them without a model, score them on examples, let an optimizer improve them, save them without credentials, and run them under supervision in an application.
The model is used where judgment is needed. Everything around it stays plain Elixir.
What we'll build
One program, from its first call to running in an application: a router for support tickets. Our company sends tickets to four squads with internal names:
- atlas owns money: charges, refunds, invoices, plans.
- harbor owns the platform: outages, errors, latency, including technical failures in payments and email delivery.
- beacon owns identity and trust: accounts, credentials, sessions, data exposure.
- quill owns the product: feature requests, how-to questions, docs.
No model knows these names. That makes the task small enough to follow and real enough to need measuring and improving. Imp ships sixty labeled tickets for it, which we'll use to measure and improve the router.
What we'll learn
- Setting up: install Imp and connect a model.
- Your first program: a signature, a prediction, and the prompt Imp wrote for us.
- Expanding signatures: types, enums, descriptions, and the structured form.
- Changing the module: chain of thought with the same signature.
- Testing without a provider: a scripted model for fast, free tests.
- Tools and agents: let the model look things up.
- Composing programs: two stages in one module.
- Measuring: examples, a metric, and a baseline.
- Improving: an optimizer, the score on held-out tickets, and what changed.
- Saving and loading: keep the improved program, never the key.
- Running it in your application: supervision, timeouts, and bounded concurrency.
- Where to go next.
Each page builds on the one before, and every output shown came from running the code on it.
Next: Setting up →