agent() Agents Build agents with tools, child agents, runtime profiles, and context controls. typescript subsystems subsystems/agent website/content-src/templates/subsystem-agent.md subsystems agent() Agents

agent() Agents

Use agent() to build either a short tool-using agent or a long-horizon RLM agent with a typed final response.

TypeScript
import { agent, ai, f, fn } from '@ax-llm/ax';

const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_APIKEY! });
const search = fn('search')
  .description('Search docs')
  .arg('query', f.string('Search query'))
  .returns(f.string('Search result text'))
  .handler(async ({ query }) => `docs for ${query}`)
  .build();
const helper = agent('question:string -> answer:string', { functions: [search] });
const out = await helper.forward(llm, { question: 'How do I tune a program?' });

Agents coordinate tools, child agents, runtime sessions, memories, skills, context policies, discovery, recall, shared fields, traces, usage, and final typed responses.

Pick the path by task shape:

  • Short agents: quick tool calls, small child-agent composition, and compact final responses.
  • Long-horizon agents: RLM runtime execution, context policy, context maps, memory, skills, and optimizer artifacts.

See short agent examples and Advanced Start for the broader Ax path.

Agent tree

What It Does

agent() creates a structured agent program. The agent planner/executor/responder loop can call tools, delegate to child agents, inspect runtime state, ask for clarification, discover tools or skills, recall memory, and finish with a typed output object.

Core Call Shape

text
helper = agent(signature, options)
result = helper.forward(aiClient, inputs)

Common Patterns

  • Start with a signature that names the final answer fields.
  • Add fn() tools for host data and side effects.
  • Add child agents to the same callable list as tools.
  • Use namespaces to keep tool calls readable.
  • Enable discovery when available tools are too numerous to include in full.
  • Save and restore state around clarification.
  • Use context policies for long-running sessions.

Short agent

TypeScript
import { agent, ai } from '@ax-llm/ax';

const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_APIKEY! });
const assistant = agent('question:string -> answer:string', { contextFields: [] });
const out = await assistant.forward(llm, { question: 'What is RLM?' });
console.log(out.answer);

Namespaced tools and discovery

Use a flat functions list for small stable sets: local fn() tools, child agents, MCP clients, and runtime providers can all live beside each other. The actor sees those callables directly.

TypeScript
import { agent, f, fn } from '@ax-llm/ax';

const findPolicy = fn('findPolicy')
  .namespace('kb')
  .description('Find policy snippets')
  .arg('topic', f.string('Policy topic'))
  .returns(f.string('Snippets').array())
  .handler(async ({ topic }) => ['policy: ' + topic])
  .build();

const support = agent('message:string -> reply:string', {
  functions: [findPolicy],
  functionDiscovery: true,
  contextFields: [],
});

Use grouped functions when the catalog is large or easier to reason about by domain. Each group gives the actor a namespace plus module-level selection criteria; with functionDiscovery: true, concrete schemas are loaded only after the actor calls discover(...).

TypeScript
const research = agent('task:string -> answer:string', {
  functionDiscovery: true,
  functions: [
    { namespace: 'kb', title: 'Knowledge Base', selectionCriteria: 'Use for docs lookup.', functions: [findPolicy] },
    { namespace: 'team', title: 'Specialist Agents', functions: [writer.getFunction()] },
  ],
  contextFields: [],
});

// Actor code should call: await discover(['kb']) before using large/unknown modules.

Grouped mode keeps big catalogs out of the prompt until needed. Keep the top-level list either flat or grouped. If a child agent belongs inside a group, pass childAgent.getFunction() inside the group’s functions list.

Memory, skills, and context policy

TypeScript
const assistant = agent('task:string -> answer:string', {
  contextFields: [],
  onMemoriesSearch: async (searches, alreadyLoaded) => {
    const skip = new Set(alreadyLoaded.map((m) => m.id));
    return searchMemoryStore(searches).filter((m) => !skip.has(m.id));
  },
  onSkillsSearch: async (searches) => resolveSkillGuides(searches),
});

// Actor code can use: await recall(['user preferences']);
// Actor code can use: await discover({ skills: ['release-checklist'] });
TypeScript
const longTaskAgent = agent('repo:string, request:string -> answer:string', {
  contextFields: ['repo'],
  contextPolicy: { preset: 'checkpointed', budget: 'balanced' },
  maxRuntimeChars: 3000,
  executorModelPolicy: [{ model: 'gpt-5.4', aboveErrorTurns: 2, namespaces: ['kb', 'db'] }],
});

Connect MCP servers

MCP clients can be passed as tool providers after initialization. Use the flat form when the server exposes a small, obvious tool set.

TypeScript
import { AxJSRuntime, AxMCPClient, agent } from '@ax-llm/ax';

const mcpClient = new AxMCPClient(transport);
await mcpClient.init();

const assistant = agent('request:string -> response:string', {
  functions: [mcpClient],
  functionDiscovery: true,
  contextFields: [],
  runtime: new AxJSRuntime(),
});

Use grouped discovery when an MCP server has many tools, prompts, or resources. The group gives the actor a namespace and selection criteria before it asks to see detailed schemas.

TypeScript
const assistant = agent('request:string -> response:string', {
  functions: [
    {
      namespace: 'memory',
      title: 'Memory MCP',
      description: 'Persistent memory tools',
      selectionCriteria: 'Use for memory lookup and updates.',
      functions: [mcpClient],
    },
  ],
  functionDiscovery: true,
  contextFields: [],
});

Production Notes

Trace actor turns, tool calls, child-agent calls, clarification, discovery, recall, context growth, token usage, and final typed outputs. Keep host functions narrow and typed. Let fatal infrastructure errors bubble; let task uncertainty become clarification or a typed final answer.

See Tools, agent() API, and MCP.

Docs