lostbean

lostbean

AgentObs - LLM Agent Observability for Elixir

AgentObs - LLM Agent Observability for Elixir

I’m excited to share AgentObs, a new library for instrumenting LLM agentic
applications in Elixir with rich observability!

What is AgentObs?

AgentObs provides a simple, idiomatic interface for tracking agent loops, tool
calls, LLM requests, and prompts in your Elixir applications. It uses native
:telemetry events and translates them to OpenTelemetry spans with
OpenInference semantic conventions.

Key Features:

  • :bullseye: High-level instrumentation helpers - trace_agent/3, trace_tool/3,
    trace_llm/3, trace_prompt/3
  • :robot: Optional ReqLLM integration - Automatic instrumentation with token tracking
    and streaming support
  • :electric_plug: Pluggable backend architecture - Phoenix (OpenInference), Generic
    OpenTelemetry, or custom handlers
  • :bar_chart: Rich metadata tracking - Token usage, costs, tool calls, and more
  • :rocket: Built on OTP - Supervised handlers with fault tolerance

Quick Example

defmodule MyApp.WeatherAgent do
  def get_forecast(city) do
    AgentObs.trace_agent("weather_forecast", %{input: "What's the weather in #{city}?"}, fn ->
      # Call LLM to determine tool to use
      {:ok, _response, _metadata} =
        AgentObs.trace_llm("gpt-4o", %{
          input_messages: [%{role: "user", content: "Get weather for #{city}"}]
        }, fn ->
          response = call_openai(...)
          {:ok, response, %{
            output_messages: [%{role: "assistant", content: response}],
            tokens: %{prompt: 50, completion: 25, total: 75}
          }}
        end)

      # Execute the tool
      {:ok, weather_data} =
        AgentObs.trace_tool("get_weather_api", %{arguments: %{city: city}}, fn ->
          {:ok, %{temp: 72, condition: "sunny"}}
        end)

      {:ok, "The weather in #{city} is #{weather_data.condition}", %{
        tools_used: ["get_weather_api"]
      }}
    end)
  end
end

ReqLLM Integration

For apps using ReqLLM, AgentObs provides helpers
that automatically extract tokens, tool calls, and more:

# Non-streaming
{:ok, response} =
  AgentObs.ReqLLM.trace_generate_text(
    "anthropic:claude-3-5-sonnet",
    [%{role: "user", content: "Hello!"}]
  )

# Streaming
{:ok, stream_response} =
  AgentObs.ReqLLM.trace_stream_text(
    "anthropic:claude-3-5-sonnet",
    [%{role: "user", content: "Tell me a story"}]
  )

Visualization

Use with Arize Phoenix to get beautiful trace visualization with chat messages,
token usage, and nested spans:

Links

Where Next?

Popular in Announcing Top

BartOtten
This powerful library works together with Phoenix Router to provide the ultimate routing solution. It simplifies route manipulation, givi...
New
mikehostetler
I’m falling in love with the Req Plugin pattern. It has limits, but when it works - it’s good. I ported over my Tesla based Fly Machines...
New
frerich
An application wishing to store larger amounts of data typically has two options for doing so: A new column on some table can be introd...
New
rahultumpala
Hello Elixir community, I work primarily on Java and other object oriented programming languages and often found it difficult to read an...
New
zteln
Hello Elixir community, I’ve written a small embedded key-value database in Elixir called Goblin. It’s based on the Log-Structured Merge...
New
jsm
Once is an Ecto type for locally unique 64-bits IDs generated by multiple Elixir nodes. Locally unique IDs make it easier to keep things ...
New
martosaur
Hello, I’m excited to introduce InstructorLite – a fork of the Instructor package. Instructor brought the very idea of structured LLM p...
New
tmbb
Playfair (named after: William Playfair) is a data visualization/plotting library with the goal of being able to produce publication-qual...
New
belaustegui
Announcing ErrorTracker, an Elixir-based built-in error tracking solution. Features Basic, free, built-in error tracking solution. Trac...
New
rodloboz
Sifter is a a query filtering library for Ecto. It lets frontend apps send human-readable query strings like: "elixir phoenix status:pu...
New

Other popular topics Top

JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement