pydantic-ai-go

module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: MIT

README

pydantic-ai-go

Build typed LLM agents in Go.

pydantic-ai-go provides the agent loop, tools, structured output, streaming, usage limits, model middleware, and provider integrations. It follows PydanticAI's behavior while keeping the public API idiomatic for Go.

Install

You need Go 1.25 or newer.

go get github.com/Kludex/pydantic-ai-go/ai

Set the API key for your provider:

export OPENAI_API_KEY="..."

Create an agent with a tool

Create an Agent, register a typed function, then call Run:

package main

import (
	"context"
	"fmt"
	"log"

	ai "github.com/Kludex/pydantic-ai-go/ai"
	"github.com/Kludex/pydantic-ai-go/ai/models/openai"
)

type WeatherArgs struct {
	City string `json:"city" jsonschema:"description=City name"`
}

func main() {
	model := openai.NewModel("gpt-5-mini")
	agent := ai.NewAgent[struct{}, string](
		model,
		ai.WithInstructions("You are a concise weather assistant."),
	)

	ai.AddSimpleTool(agent, "get_weather", func(
		_ context.Context,
		args WeatherArgs,
	) (string, error) {
		return fmt.Sprintf("It is 21 C and sunny in %s.", args.City), nil
	}, ai.WithDescription("Get the current weather for a city"))

	result, err := agent.Run(
		context.Background(),
		"What is the weather in Berlin?",
		struct{}{},
	)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Output)
}

The type parameters are Agent[Deps, Output].

  • Deps is application state available to tools and callbacks.
  • Output is the final result type. Use string for text.
  • WeatherArgs becomes the tool's JSON Schema.

The agent validates tool arguments before your function runs. Invalid arguments go back to the model as a retry prompt. Independent tool calls run concurrently and their results keep model order.

Use AddTool instead of AddSimpleTool when your function needs RunContext. The context contains typed dependencies, usage, history, retry state, and cancellation for the current run. Pass dependencies as the third argument to Run. One agent can serve concurrent runs safely.

Return structured data

Use a struct as the output type:

package main

import (
	"context"
	"fmt"
	"log"

	ai "github.com/Kludex/pydantic-ai-go/ai"
	"github.com/Kludex/pydantic-ai-go/ai/models/openai"
)

type City struct {
	Name       string `json:"name"`
	Country    string `json:"country"`
	Population int    `json:"population"`
}

func main() {
	agent := ai.NewAgent[struct{}, City](openai.NewModel("gpt-5-mini"))

	result, err := agent.Run(
		context.Background(),
		"Return information about Paris.",
		struct{}{},
	)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s, %s: %d\n", result.Output.Name, result.Output.Country, result.Output.Population)
}

The agent reflects a Draft 2020-12 JSON Schema from City. It validates the model response against that schema, decodes it into City, and retries invalid output.

OutputModeAuto is the default. It reads the selected model's ModelProfile; the standard profile chooses tool output because it works across providers. Use WithOutputMode(ai.OutputModeNative) to require native JSON Schema output, or OutputModePrompted to require JSON in text. See Structured output for validation and multiple output alternatives.

Stream a response

RunStream returns normalized events across all providers:

package main

import (
	"context"
	"fmt"
	"log"

	ai "github.com/Kludex/pydantic-ai-go/ai"
	"github.com/Kludex/pydantic-ai-go/ai/models/openai"
)

func main() {
	agent := ai.NewAgent[struct{}, string](openai.NewModel("gpt-5-mini"))
	stream := agent.RunStream(context.Background(), "Write a short poem.", struct{}{})

	for event, err := range stream.Events() {
		if err != nil {
			log.Fatal(err)
		}
		switch event := event.(type) {
		case ai.PartStartEvent:
			if text, ok := event.Part.(ai.TextPart); ok {
				fmt.Print(text.Content)
			}
		case ai.PartDeltaEvent:
			if text, ok := event.Delta.(ai.TextPartDelta); ok {
				fmt.Print(text.ContentDelta)
			}
		}
	}

	result := stream.Result()
	if result == nil {
		log.Fatal("stream ended without a result")
	}
	fmt.Printf("\nTokens: %d\n", result.Usage().TotalTokens())
}

Consume one stream view only. Use Events for lifecycle events or Outputs for typed partial output snapshots. Cancel the context to stop the request.

RunStream ends the run at the first output that matches the output type, so your consumer gets the final answer as soon as it starts. That output can be text, an output tool call, or a deferred tool call. When the same response also calls function tools, they still run, but their results are not sent back to the model. To run to completion while observing every event, register a listener with AddEventListener and call Run, or drive the run step by step with StartRun.

Continue a conversation

Pass the previous result's messages into the next run:

package main

import (
	"context"
	"fmt"
	"log"

	ai "github.com/Kludex/pydantic-ai-go/ai"
	"github.com/Kludex/pydantic-ai-go/ai/models/openai"
)

func main() {
	ctx := context.Background()
	agent := ai.NewAgent[struct{}, string](openai.NewModel("gpt-5-mini"))

	first, err := agent.Run(ctx, "My name is Ada.", struct{}{})
	if err != nil {
		log.Fatal(err)
	}
	second, err := agent.Run(
		ctx,
		"What is my name?",
		struct{}{},
		ai.WithMessageHistory(first.Messages()),
	)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(second.Output)
}

Use MarshalMessages and UnmarshalMessages to persist history. Their JSON format is compatible with PydanticAI.

Choose a provider

The bundled providers use the same ai.Model interface.

Provider Constructor Environment variable
OpenAI Chat Completions openai.NewModel("gpt-5-mini") OPENAI_API_KEY
OpenAI Responses openai.NewResponsesModel("gpt-5-mini") OPENAI_API_KEY
OpenAI Codex subscription openaicodex.NewModel("gpt-5.6-luna") Codex CLI or caller-owned credential source
Azure OpenAI azure.NewModel("deployment", azure.Config{}) AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY
Amazon Bedrock bedrock.NewModel("us.amazon.nova-lite-v1:0") Standard AWS SDK configuration
Amazon Bedrock Mantle bedrockmantle.NewModel("openai.gpt-5.6-luna") AWS_BEARER_TOKEN_BEDROCK or standard AWS SDK configuration
Anthropic anthropic.NewModel("claude-sonnet-4-5") ANTHROPIC_API_KEY
Google Gemini google.NewModel("gemini-2.5-flash") GOOGLE_API_KEY
DeepSeek Chat Completions deepseek.NewModel("deepseek-chat") DEEPSEEK_API_KEY
DeepSeek Responses deepseek.NewResponsesModel("deepseek-v4-flash") DEEPSEEK_API_KEY
GitHub Copilot githubcopilot.NewModel("claude-haiku-4.5") GITHUB_COPILOT_API_KEY
Cohere cohere.NewModel("command-r7b-12-2024") CO_API_KEY
Crusoe crusoe.NewModel("openai/gpt-oss-120b") CRUSOE_API_KEY
Cerebras cerebras.NewModel("gpt-oss-120b") CEREBRAS_API_KEY
Groq groq.NewModel("openai/gpt-oss-20b") GROQ_API_KEY
Hugging Face huggingface.NewModel("Qwen/Qwen3-32B") HF_TOKEN
Meta Muse meta.NewModel("muse-spark-1.3") META_API_KEY
Mistral mistral.NewModel("mistral-large-latest") MISTRAL_API_KEY
Ollama ollama.NewModel("qwen3") OLLAMA_BASE_URL, OLLAMA_API_KEY
OpenRouter openrouter.NewModel("anthropic/claude-sonnet-4.6") OPENROUTER_API_KEY
OpenAI Decisions openaidecisions.NewModel("gpt-6-luna") OPENAI_API_KEY
Snowflake Cortex snowflake.NewModel("claude-sonnet-4-6") SNOWFLAKE_ACCOUNT, SNOWFLAKE_TOKEN
Together AI together.NewModel("Qwen/Qwen3-32B") TOGETHER_API_KEY
System One decision models systemone.NewModel("clm-latest") SYSTEM_ONE_BASE_URL, optional SYSTEM_ONE_API_KEY
TypeSafe Jev typesafe.NewModel("jev-latest") TYPESAFE_API_KEY
vLLM vllm.NewModel("Qwen/Qwen3-32B") VLLM_BASE_URL, VLLM_API_KEY
xAI xai.NewModel("grok-4.3") XAI_API_KEY
Z.AI zai.NewModel("glm-5.3-flash") ZAI_API_KEY

Provider options configure caller-owned clients, endpoints, credentials, and default model settings. See Provider configuration for OpenAI-compatible endpoints and Azure API versions. See OpenAI Codex subscription for read-only CLI credentials, OAuth PKCE, and rotated credential storage. See Amazon Bedrock for AWS SDK configuration and Converse behavior.

Test an agent without network calls

Use ai/models/fakes in tests:

package weather_test

import (
	"context"
	"testing"

	ai "github.com/Kludex/pydantic-ai-go/ai"
	"github.com/Kludex/pydantic-ai-go/ai/models/fakes"
)

func TestAgent(t *testing.T) {
	agent := ai.NewAgent[struct{}, string](fakes.NewFunctionModel(func(
		_ context.Context,
		_ []ai.ModelMessage,
		_ ai.ModelRequestParams,
	) (*ai.ModelResponse, error) {
		return &ai.ModelResponse{
			Parts: []ai.ResponsePart{ai.TextPart{Content: "hello"}},
		}, nil
	}))

	result, err := agent.Run(t.Context(), "Say hello.", struct{}{})
	if err != nil {
		t.Fatal(err)
	}
	if result.Output != "hello" {
		t.Fatalf("got %q", result.Output)
	}
}

fakes.NewFunctionModel gives you complete control over each model response. fakes.NewTestModel can generate schema-valid calls for every registered tool.

API guide

You need to Use
Change one run without mutating the agent WithRunModelSettings, WithRunInstructions, and other RunOption values
Name and describe an agent for integrations WithAgentName, WithAgentDescription, and WithAgentDescriptionFunc
Attach application metadata to a run WithMetadata, AddMetadataFunc, and WithRunMetadata
Transform structured data or plain text NewOutputFunction or NewTextOutputFunction
Return one of several typed outputs NewUnionOutput and NewUnionAgent
Render instructions from typed dependencies PromptTemplate and FormatAsXML
Address and rewrite instruction blocks Stable instruction IDs
Reuse or combine tools NewTool, NewFunctionToolset, and the toolset wrappers
Delegate work to another agent ToolReturn.Usage and shared dependencies
Give tools an environment for files and commands Workspace and LocalWorkspace
Require approval or external execution WithApprovalRequired and DeferredToolResults
Connect an MCP server mcp.NewStreamableHTTPToolset, Connect, or LoadToolsets
Expose an agent through MCP An official SDK server with a typed agent tool
Stream an agent to an AG-UI frontend agui.Adapter
Stream an agent to Vercel AI UI vercel.Adapter
Serve an agent over A2A a2a.Executor
Chat in a terminal or browser cli.Run and webchat.NewHandler
Run a speech-to-speech session realtime.Open
Build a durable operation backend durable.Backend and durable.Operation
Limit usage or cost UsageLimits and pre-request token counting
Sanitize, trim, or summarize conversation history SanitizeMessages and history capabilities
Compact old provider history ModelCompactor and compaction capabilities
Send images, documents, audio, video, or uploaded files RunParts
Use native-first web tools with local fallbacks NewWebSearchCapability and NewWebFetchCapability
Configure a provider or compatible endpoint Provider configuration
Use Amazon Bedrock Converse bedrock.NewModel
Retry transient provider HTTP failures retries.Transport
Add fallback models NewFallbackModel
Limit concurrency NewConcurrencyLimiter
Enable portable prompt caching Caching, retention tiers, and stable-prefix configuration
Add agent middleware Capability and its focused hook interfaces
Wrap one model ModelWrapper and built-in decorators
Add OpenTelemetry or send telemetry to Logfire NewInstrumentation or NewInstrumentedModel
Evaluate an agent evals.NewTextTask or evals.NewTask
Generate query or document vectors embeddings.Embedder
Generate or edit images directly images.Generator
Call a model without an agent RequestModel or StreamModel
Drive a run one event at a time AgentRun

Run options are detached from agent configuration. They are safe to use in concurrent runs. See the Go package documentation for each public contract and CHECKLIST.md for remaining parity work.

Design

The agent is a plain loop:

  1. Build a model request.
  2. Ask the model for a response.
  3. Validate and execute tool calls.
  4. Repeat until a final output is valid.

Capabilities intercept these semantic boundaries. The package does not expose an internal graph API. This keeps the control flow readable and lets Go interfaces provide small extension points.

Per-run settings, tools, capabilities, output types, histories, and provider details are copied before use. One run cannot mutate another run's configuration.

Development

Run the complete local checks:

gofmt -w $(git ls-files '*.go')
go vet ./...
golangci-lint run ./...
go test ./...
scripts/coverage.sh
go test -race ./...
go test -run '^$' -bench . -benchmem ./ai

The project requires 100% statement coverage for every tested package. See the benchmark guide to compare performance changes.

Status

The API is under active development while it approaches feature parity with PydanticAI. Review CHECKLIST.md before depending on a provider-specific or advanced feature.

See the COMPATIBILITY.md version guarantees and CHANGELOG.md before you upgrade.

License

This project is licensed under the MIT License. See LICENSE.

Directories

Path Synopsis
ai
Package ai provides typed LLM agents and direct model requests.
Package ai provides typed LLM agents and direct model requests.
a2a
Package a2a adapts typed agents and remote models to the official Agent2Agent Go SDK.
Package a2a adapts typed agents and remote models to the official Agent2Agent Go SDK.
cli
Package cli runs typed agents in terminal chat sessions.
Package cli runs typed agents in terminal chat sessions.
durable
Package durable defines engine-neutral durable operation contracts.
Package durable defines engine-neutral durable operation contracts.
durable/dbos
Package dbos configures startup-registered durable operations for DBOS workflows.
Package dbos configures startup-registered durable operations for DBOS workflows.
durable/prefect
Package prefect configures callable Prefect task operations.
Package prefect configures callable Prefect task operations.
durable/temporal
Package temporal configures startup-registered durable operations for Temporal workers.
Package temporal configures startup-registered durable operations for Temporal workers.
embeddings
Package embeddings provides provider-neutral text embeddings.
Package embeddings provides provider-neutral text embeddings.
embeddings/bedrock
Package bedrock provides text embeddings through Amazon Bedrock Runtime.
Package bedrock provides text embeddings through Amazon Bedrock Runtime.
embeddings/cohere
Package cohere implements embeddings.Model against Cohere's embedding API.
Package cohere implements embeddings.Model against Cohere's embedding API.
embeddings/fakes
Package fakes provides deterministic embedding models for tests.
Package fakes provides deterministic embedding models for tests.
embeddings/google
Package google implements embeddings.Model for the Gemini API and Vertex AI.
Package google implements embeddings.Model for the Gemini API and Vertex AI.
embeddings/infer
Package infer resolves provider-prefixed embedding model names.
Package infer resolves provider-prefixed embedding model names.
embeddings/ollama
Package ollama implements embeddings.Model against Ollama's local embedding API.
Package ollama implements embeddings.Model against Ollama's local embedding API.
embeddings/openai
Package openai implements embeddings.Model against OpenAI-compatible embedding APIs.
Package openai implements embeddings.Model against OpenAI-compatible embedding APIs.
embeddings/voyageai
Package voyageai implements embeddings.Model against VoyageAI's embedding API.
Package voyageai implements embeddings.Model against VoyageAI's embedding API.
evals
Package evals adapts typed agents to github.com/Kludex/pydantic-evals-go tasks.
Package evals adapts typed agents to github.com/Kludex/pydantic-evals-go tasks.
images
Package images provides provider-neutral direct image generation.
Package images provides provider-neutral direct image generation.
images/fakes
Package fakes provides deterministic image generation models for tests.
Package fakes provides deterministic image generation models for tests.
images/google
Package google implements images.Model for Gemini and Vertex AI image models.
Package google implements images.Model for Gemini and Vertex AI image models.
images/infer
Package infer resolves provider-prefixed direct image model names.
Package infer resolves provider-prefixed direct image model names.
images/openai
Package openai implements images.Model against OpenAI-compatible Images APIs.
Package openai implements images.Model against OpenAI-compatible Images APIs.
images/xai
Package xai implements images.Model against xAI's image generation gRPC API.
Package xai implements images.Model against xAI's image generation gRPC API.
internal/schema
Package schema reflects JSON Schemas from Go structs.
Package schema reflects JSON Schemas from Go structs.
internal/thinking
Package thinking renders reasoning that a provider cannot replay through its native channel.
Package thinking renders reasoning that a provider cannot replay through its native channel.
mcp
Package mcp connects Model Context Protocol servers as agent toolsets or caller-managed sessions.
Package mcp connects Model Context Protocol servers as agent toolsets or caller-managed sessions.
models/anthropic
Package anthropic implements ai.Model against the Anthropic Messages API.
Package anthropic implements ai.Model against the Anthropic Messages API.
models/azure
Package azure configures OpenAI-compatible models for Azure OpenAI and Azure AI Foundry.
Package azure configures OpenAI-compatible models for Azure OpenAI and Azure AI Foundry.
models/bedrock
Package bedrock implements ai.Model against Amazon Bedrock's Converse API.
Package bedrock implements ai.Model against Amazon Bedrock's Converse API.
models/bedrockmantle
Package bedrockmantle implements ai.Model against Amazon Bedrock Mantle's OpenAI-compatible APIs.
Package bedrockmantle implements ai.Model against Amazon Bedrock Mantle's OpenAI-compatible APIs.
models/cerebras
Package cerebras implements ai.Model against Cerebras's OpenAI-compatible API.
Package cerebras implements ai.Model against Cerebras's OpenAI-compatible API.
models/cohere
Package cohere implements generation and shared provider configuration for Cohere.
Package cohere implements generation and shared provider configuration for Cohere.
models/crusoe
Package crusoe implements ai.Model against Crusoe Serverless Inference.
Package crusoe implements ai.Model against Crusoe Serverless Inference.
models/deepseek
Package deepseek implements generation models against the DeepSeek API.
Package deepseek implements generation models against the DeepSeek API.
models/fakes
Package fakes provides Model implementations for tests.
Package fakes provides Model implementations for tests.
models/githubcopilot
Package githubcopilot implements ai.Model against GitHub Copilot's Chat Completions API.
Package githubcopilot implements ai.Model against GitHub Copilot's Chat Completions API.
models/google
Package google implements ai.Model against the Google Gemini API.
Package google implements ai.Model against the Google Gemini API.
models/groq
Package groq implements ai.Model against Groq's Chat Completions API.
Package groq implements ai.Model against Groq's Chat Completions API.
models/huggingface
Package huggingface implements ai.Model against Hugging Face Inference Providers.
Package huggingface implements ai.Model against Hugging Face Inference Providers.
models/infer
Package infer resolves provider-prefixed generation model names.
Package infer resolves provider-prefixed generation model names.
models/meta
Package meta implements ai.Model against Meta's Model API for Muse models.
Package meta implements ai.Model against Meta's Model API for Muse models.
models/mistral
Package mistral implements ai.Model against Mistral's native Chat Completions API.
Package mistral implements ai.Model against Mistral's native Chat Completions API.
models/ollama
Package ollama implements ai.Model against Ollama's OpenAI-compatible Chat Completions API.
Package ollama implements ai.Model against Ollama's OpenAI-compatible Chat Completions API.
models/openai
Package openai implements ai.Model against the OpenAI Chat Completions API.
Package openai implements ai.Model against the OpenAI Chat Completions API.
models/openaicodex
Package openaicodex implements OpenAI Responses models authenticated with a ChatGPT/Codex subscription.
Package openaicodex implements OpenAI Responses models authenticated with a ChatGPT/Codex subscription.
models/openaidecisions
Package openaidecisions implements typed decision models over OpenAI's /v1/decisions endpoint.
Package openaidecisions implements typed decision models over OpenAI's /v1/decisions endpoint.
models/openrouter
Package openrouter implements ai.Model against OpenRouter's Chat Completions API.
Package openrouter implements ai.Model against OpenRouter's Chat Completions API.
models/snowflake
Package snowflake implements ai.Model against Snowflake Cortex Chat Completions.
Package snowflake implements ai.Model against Snowflake Cortex Chat Completions.
models/systemone
Package systemone implements typed decision models served over /v1/systemone.
Package systemone implements typed decision models served over /v1/systemone.
models/together
Package together implements ai.Model against Together AI's OpenAI-compatible API.
Package together implements ai.Model against Together AI's OpenAI-compatible API.
models/typesafe
Package typesafe implements TypeSafe Jev typed-decision models.
Package typesafe implements TypeSafe Jev typed-decision models.
models/vllm
Package vllm implements ai.Model against a vLLM OpenAI-compatible server.
Package vllm implements ai.Model against a vLLM OpenAI-compatible server.
models/xai
Package xai implements ai.Model against xAI's Responses-compatible API.
Package xai implements ai.Model against xAI's Responses-compatible API.
models/zai
Package zai implements ai.Model against Z.AI's OpenAI-compatible Chat Completions API.
Package zai implements ai.Model against Z.AI's OpenAI-compatible Chat Completions API.
realtime
Package realtime defines provider-neutral bidirectional model sessions.
Package realtime defines provider-neutral bidirectional model sessions.
realtime/azure
Package azure implements Azure OpenAI GA and Azure AI Voice Live realtime sessions.
Package azure implements Azure OpenAI GA and Azure AI Voice Live realtime sessions.
realtime/google
Package google implements Gemini Live realtime sessions with the official Google Gen AI Go SDK.
Package google implements Gemini Live realtime sessions with the official Google Gen AI Go SDK.
realtime/infer
Package infer resolves provider-prefixed realtime model identifiers.
Package infer resolves provider-prefixed realtime model identifiers.
realtime/internal/seed
Package seed renders portable history the way a realtime provider replays it.
Package seed renders portable history the way a realtime provider replays it.
realtime/openai
Package openai implements OpenAI Realtime websocket sessions.
Package openai implements OpenAI Realtime websocket sessions.
realtime/xai
Package xai implements xAI Grok Voice realtime sessions.
Package xai implements xAI Grok Voice realtime sessions.
retries
Package retries provides configurable HTTP transport retries for model providers.
Package retries provides configurable HTTP transport retries for model providers.
ui/agui
Package agui adapts typed agents to the Agent User Interaction protocol.
Package agui adapts typed agents to the Agent User Interaction protocol.
ui/vercel
Package vercel adapts typed agents to the Vercel AI UI message stream protocol.
Package vercel adapts typed agents to the Vercel AI UI message stream protocol.
webchat
Package webchat serves PydanticAI's official browser chat UI for typed agents.
Package webchat serves PydanticAI's official browser chat UI for typed agents.
cmd
pydantic-ai-go command
Command pydantic-ai-go runs terminal and browser chat interfaces.
Command pydantic-ai-go runs terminal and browser chat interfaces.
examples
a2a command
Command a2a serves an OpenAI agent through the official A2A JSON-RPC transport.
Command a2a serves an OpenAI agent through the official A2A JSON-RPC transport.
agui command
Command agui serves an OpenAI agent through an AG-UI SSE endpoint.
Command agui serves an OpenAI agent through an AG-UI SSE endpoint.
bedrock command
Command bedrock runs a minimal agent through Amazon Bedrock Converse.
Command bedrock runs a minimal agent through Amazon Bedrock Converse.
logfire command
mcp-server command
Command mcp-server exposes an agent through an MCP tool over stdio.
Command mcp-server exposes an agent through an MCP tool over stdio.
vercel-ai command
Command vercel-ai serves an OpenAI agent through the Vercel AI UI protocol.
Command vercel-ai serves an OpenAI agent through the Vercel AI UI protocol.
weather command
Command weather runs a minimal weather agent against OpenAI.
Command weather runs a minimal weather agent against OpenAI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL