Ax Stop writing prompt glue. Ax compiles typed signatures into reliable LLM calls — validation, streaming, tools, agents, audio, and optimization. TypeScript on npm today; Python, Java, C++, Go, and Rust generated and verified from the same core. typescript home home _index.md home Ax

Ax

Stop writing prompt glue.

A one-line signature declares what goes in and what comes out. Ax turns it into the prompt, the parser, the validators, and the retry loop — and hands back typed data your code can trust. The same programming model in TypeScript, Python, Java, C++, Go, and Rust.

Structured outputs Tools and agents Audio + realtime Evaluate and optimize
$ npm install @ax-llm/axon npm
TypeScript classify.ts ax()
import { ai, ax } from "@ax-llm/ax";

const llm = ai({ name: "openai" });
const classify = ax(
  "review:string -> sentiment:class \"positive, negative, neutral\""
);

const result = await classify.forward(llm, {
  review: "This product is amazing!",
});
Typed output
{
  "sentiment": "positive"
}
Type-safe, validated, auto-retried on failure

Using Claude Code or Cursor? Point your coding agent at Ax — every language ships installable, versioned skills your agent can follow.

$ npx skills add https://ax-llm.github.io/ax/typescript/ --skill '*'
Browse agent skills

Describe the input and output. Ax handles the model call.

The hero demo is the whole philosophy. A signature says what data the model receives and what typed data your app expects back. Ax uses that one contract to render prompts, call providers, parse output, validate constraints, retry with feedback, stream partial results, record traces, seed examples, and optimize behavior later.

The contract becomes the system boundary.

Instead of spreading prompt text, JSON parsing, retry logic, tool schemas, tracing, and eval metadata across your app, Ax hangs them from the signature.

ValidationStreamingToolsTracesOptimization
Signature contract network

One line becomes a running pipeline.

The signature you write is lowered into prompt rendering, streaming parsers, validators, retry feedback, and trace metadata — the same pipeline that produced the typed output above.

Signature to runtime pipeline

We didn't port Ax six times. We compiled it.

Ax is built around a portable intermediate representation. TypeScript is the reference runtime; the AxIR compiler lowers signatures, schemas, providers, generators, agents, flows, MCP, and optimizers into one shared semantic core — then emits native package surfaces for Python, Java, C++, Go, and Rust. Native names, native errors, native builders. Same behavior.

Signature syntax

TypeScript signatures.ts TypeScript
const extract = ax(
  "doc:string -> names:string[], dates:date[], amounts:number[]"
);

String signatures become AxIR contracts that the compiler can lower into prompts, schemas, validators, examples, traces, and typed outputs.

Field schema IR

TypeScript fields.ts TypeScript
const sig = f()
  .input("document", f.string().min(10))
  .output("summary", f.string().max(500))
  .output("tags", f.string().array())
  .build();

Fluent fields, media types, arrays, enums, constraints, and validators preserve field semantics across native packages.

Structured schema output

TypeScript schema.ts TypeScript
const sig = f()
  .output(z.object({
    summary: z.string(),
    score: z.number().min(1).max(10),
  }))
  .build();

Schema-backed output keeps generated code aligned with the same parse, retry, docs, telemetry, and optimization contract.

TypeScript reference runtime -> AxIR -> native APIs.

The package compiler emits language-shaped APIs instead of transpiling TypeScript. Each backend keeps native names, errors, builders, callbacks, transports, and runtime profiles while sharing the same Ax semantics.

AxIR compiler pipeline

Capability manifests keep every backend honest.

Generated package examples, API metadata, capability manifests, and conformance fixtures are checked by axir verify. That is why the language switcher in the hero is a demo, not a promise — every backend earns its place in the matrix.

Language package matrix

Built on DSPy, GEPA, RLM, and PEEK.

Ax is more than another LLM framework — it is where a serious research lineage ships. The typed signatures, validation with retry feedback, reflective optimization, runtime-backed agents, and context maps you just saw all come from these papers.

Alex L. Zhang, Tim Kraska, Omar Khattab.

External runtime loops and recursive model calls inform AxAgent's runtime state, execution boundary, and small-context turns.

arXiv 2512.24601
MITStanford

Agents built for context, tools, memory, and code.

AxAgent is designed around DSPy, RLM, and PEEK ideas: typed signatures define the job, generated code and host runtimes hold durable state, context maps drive context management, and discovery-based tools load only the schemas needed for the next action. That keeps agents useful with small models and big ones, while built-in memory, skills, child agents, telemetry, and agent.optimize(...) make them practical to operate.

TypeScript researcher.ts JS runtime session
import { agent, ai, fn } from "@ax-llm/ax";

const llm = ai({ name: "openai" });
const research = agent({
  name: "researcher",
  signature: "question:string -> answer:string, sources:string[]",
  functions: [
    fn({
      name: "search",
      description: "Search internal docs",
      parameters: "query:string -> results:string[]",
      handler: searchDocs,
    }),
  ],
  contextFields: ["largeDocument"],
});

const result = await research.forward(llm, {
  question: "What changed in the release?",
});
RLM loop

Discovery

Large tool catalogs stay out of the base prompt. The agent discovers groups and loads concrete schemas only when they matter.

Context maps

Runtime state, context maps, summaries, and checkpoints preserve orientation without replaying every token.

Memory + skills

Built-in memory, skills, MCP tools, and child agents become typed capabilities behind the same signature contract.

Optimization

agent.optimize(...) tunes instructions, examples, and agent behavior against evals, judges, and saved artifacts.

Agents navigate large tool catalogs without stuffing every schema into the prompt.

Function groups, child agents, MCP tools, memory, and runtime state are discovered and loaded as needed, which keeps even small models focused on the next useful action.

Agent function discovery tree

State grows in the runtime instead of the prompt.

Context maps, summaries, checkpoint state, and runtime references keep long-running work usable without turning every turn into a full transcript replay.

Context growth chart

Build text, voice, and realtime AI apps.

Ax treats audio as part of the same typed programming model: direct speech-to-text, direct text-to-speech, signature audio artifacts, conversational audio turns, realtime/native audio, and agent audio inputs.

Use the smallest audio surface that matches the job.

  • ai.transcribe(...) for batch speech-to-text.
  • ai.speak(...) for batch text-to-speech.
  • speech:audio for typed programs that return synthesized audio artifacts.
  • .chat() audio config for conversational or realtime audio turns.
  • Agents transcribe audio inputs before planner, executor, and responder stages.

Read the LLM guide or open media examples.

TypeScript audio.ts speech:audio
import { ai, ax } from "@ax-llm/ax";

const llm = ai({ name: "openai" });
const narrator = ax("article:string -> speech:audio, summary:string");

const result = await narrator.forward(
  llm,
  { article },
  { speech: { speak: { voice: "alloy", format: "mp3" } } }
);

Transcribe and speak

Use direct batch APIs when the app needs speech-to-text, text-to-speech, transcripts, or reusable audio artifacts.

Conversational audio

Use provider audio chat and realtime configurations when voice belongs inside the model conversation.

Agent audio

Let agents accept recordings and return spoken outputs while their internal tool loops operate on stable text.

Improve quality after it works.

GEPA, the Genetic-Pareto optimizer, tunes prompts, demos, flows, and agents against evals. Pareto frontiers make quality, latency, cost, and brevity tradeoffs explicit instead of hiding them behind one metric.

Pick the artifact that matches production reality.

Use optimized programs when quality matters, cheaper frontier points when cost dominates, and saved artifacts when the same tuned behavior needs to be deployed repeatedly.

Read optimization docs or open the optimize API.

GEPA Pareto frontier

Everything you need to build useful LLM systems.

Every capability above hangs off the same signature contract. Start with a single typed generation call, then grow into tools, agents, voice, workflows, telemetry, optimization, and native packages without switching mental models.

Structured generation ax()

Declare typed inputs and outputs, then get parsed host values with streaming, validation, retries, and traces.

Signatures s() + f()

Use concise string signatures, fluent fields, media types, enums, arrays, constraints, and Standard Schema output.

Tools and MCP fn()

Expose typed host functions, MCP servers, runtimes, flows, and child agents as callable capabilities.

Agents agent()

Build agents with tool discovery, memory, skills, child agents, context policy, and persistent runtime state.

Audio speech:audio

Transcribe speech, synthesize speech, return typed audio artifacts, and use conversational or realtime audio turns.

Workflows flow()

Compose typed steps, branches, and parallel work into explicit LLM application flows.

Optimization optimize()

Improve prompts, demos, programs, flows, and agents against evals, judges, and production tradeoffs.

Providers ai()

Use OpenAI, Responses, Claude, Gemini, OpenAI-compatible gateways, local routers, embeddings, and model catalogs.

Telemetry traces

Inspect model calls, tool calls, usage, cost, latency, errors, optimizer metrics, and agent turns.

Native packages AxIR

Use the same Ax concepts from TypeScript, Python, Java, C++, Go, and Rust package surfaces.

The operational pieces are built in, not bolted on.

Extensive test coverage, OpenTelemetry integration, cost tracking, provider routing, and enterprise-grade error handling all belong to one program story.

1000+tests
40+OTel metrics
15+LLM providers
6languages

OpenTelemetry

Distributed traces span LLM calls, function invocations, MCP calls, and agent turns.

Detailed metrics

Track latency, tokens, errors, context windows, thinking budgets, and custom labels.

Streaming and validation

Structured outputs stream through parsers, assertions, retries, and correction feedback.

Cost tracking

Estimate provider costs per request and make optimization tradeoffs concrete.

Multi-language

One semantic core spans TypeScript, Python, Java, C++, Go, and Rust package shapes.

Enterprise controls

Rate limits, sampling, redaction, provider routing, and error handling fit production workflows.

Observe the run from model call to optimized artifact.

Use the telemetry guide for the concrete spans, counters, histograms, and labels emitted by Ax programs.

Read telemetry docs.

Production telemetry loop

Declare capabilities, not prompts.

Signatures make common LLM tasks readable, testable, and portable. The contract is the unit Ax can validate, trace, optimize, and document.

Classification

Categorize text into predefined classes.

TypeScript Classification Classification
ax("text:string -> category:class \"spam, ham, promo\"")

Extraction

Pull structured data from unstructured text.

TypeScript Extraction Extraction
ax("document:string -> names:string[], dates:date[]")

Question answering

Answer questions with provided context.

TypeScript Question answering Question answering
ax("context:string, question:string -> answer:string")

Multimodal

Process images and audio alongside text.

TypeScript Multimodal Multimodal
ax("photo:image, question:string -> answer:string")

Validation

Auto-validate outputs with constraints.

TypeScript Validation Validation
ax("email:string, score:number -> valid:boolean")

Streaming

Receive structured results as they generate.

TypeScript Streaming Streaming
ax("topic:string -> chunk:string")

Translation

Translate between languages with typed IO.

TypeScript Translation Translation
ax("text:string, targetLanguage:string -> translation:string")

Workflows

Return multiple typed outputs from one call.

TypeScript Workflows Workflows
ax("doc:string -> summary:string, keyPoints:string[]")

External servers become typed Ax functions.

Use MCP servers through AxMCPClient.toFunction() in ax() generation or pass MCP clients into agents for discovery-aware tool use.

Read the MCP guide or open the tools guide.

MCP bridge

Use any model.

Pick OpenAI, Claude, Gemini, a gateway, or a local OpenAI-compatible endpoint in ai(). Your signatures, tools, traces, and outputs stay the same.

OpenAI Claude Gemini OpenAI-compatible Local
TypeScript providers.ts TypeScript
const openai = ai({ name: "openai" });
const claude = ai({ name: "anthropic" });
const local = ai({
  name: "openai",
  config: { baseURL: "http://localhost:11434/v1" },
});

Need routing, embeddings, audio, or context caching? Read the LLM guide.

Provider router map

Connect AI agents to your database.

GraphJin compiles GraphQL to efficient SQL and doubles as an MCP server, giving Ax agents direct, governed access to application data.

TypeScript ax-agent.ts TypeScript
import { AxMCPClient, AxMCPHTTPSSETransport, agent } from "@ax-llm/ax";

const transport = new AxMCPHTTPSSETransport(
  "http://localhost:8080/api/v1/mcp"
);
const mcp = new AxMCPClient(transport);
await mcp.init();

const dataAnalyst = agent({
  name: "data-analyst",
  signature: "question:string -> answer:string",
  functions: mcp.toFunction(),
});

Use GraphJin as an MCP tool inside Ax agents.

PostgreSQL, MySQL, SQLite, MongoDB, Oracle, MSSQL, and Snowflake can sit behind one data access layer for AI workflows.

PostgreSQLMySQLSQLiteMongoDBSnowflake

Write your first signature today.

One line in, typed data out — on npm now, and in five more languages straight from this repo.

Building with an AI coding agent? Install the Ax skills and let it write Ax for you.