GenAgentAnthropic

CIHex.pmDocs

HTTP-direct Anthropic backend for GenAgent, built on Req.

Provides GenAgent.Backends.Anthropic, which talks directly to the Anthropic Messages API and translates the response into the normalized GenAgent.Event values the state machine consumes.

Unlike the CLI-backed backends (gen_agent_claude, gen_agent_codex), this backend:

Prerequisites

You need an Anthropic API key. Set ANTHROPIC_API_KEY in your environment, or pass :api_key as a backend option.

Installation

def deps do
  [
    {:gen_agent, "~> 0.2.0"},
    {:gen_agent_anthropic, "~> 0.1.0"}
  ]
end

Quick start

defmodule MyApp.Assistant do
  use GenAgent

  defmodule State do
    defstruct responses: []
  end

  @impl true
  def init_agent(_opts) do
    backend_opts = [
      system: "You are a concise, helpful assistant.",
      max_tokens: 512
    ]

    {:ok, backend_opts, %State{}}
  end

  @impl true
  def handle_response(_ref, response, state) do
    {:noreply, %{state | responses: state.responses ++ [response.text]}}
  end
end

{:ok, _pid} = GenAgent.start_agent(MyApp.Assistant,
  name: "my-assistant",
  backend: GenAgent.Backends.Anthropic
)

{:ok, response} = GenAgent.ask("my-assistant", "Explain OTP gen_statem in one sentence.")
IO.puts(response.text)

Session continuation

The Anthropic API is stateless -- every request carries the full messages array. This backend tracks the conversation history on the session struct so multi-turn conversations work transparently:

# Turn 1: fresh conversation
{:ok, r1} = GenAgent.ask("my-assistant", "Remember the number 42")
# Turn 2: backend sends the full history including turn 1
{:ok, r2} = GenAgent.ask("my-assistant", "What number did I ask you to remember?")
# r2.text == "42"

Conversation history lives in session.messages as an in-order list of %{"role" => ..., "content" => ...} maps, appended on both sides of each turn (user message on dispatch, assistant message on terminal :result event).

Backend options

See GenAgent.Backends.Anthropic for the full module docs.

Why no tool use?

This backend is deliberately minimal: text in, text out. Anthropic's Messages API supports tool use, but adding it means a richer event surface, tool schema definitions, and roundtripping tool results -- all of which is better served by the Claude CLI backend (gen_agent_claude), which gets that flow from Claude Code itself.

If you want tool-using agents with Anthropic as the provider, reach for gen_agent_claude. If you want a thin HTTP client for single-turn or multi-turn text exchanges, this is the right backend.

Testing

mix test

Unit tests stub the HTTP layer via the :http_fn backend option, so no tokens are burned during mix test.

License

MIT. See LICENSE.