agent() Agents
Use agent() to build either a short tool-using agent or a long-horizon RLM agent with a typed final response.
helper := axllm.NewAgent("question:string -> answer:string", nil)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.
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.
Actor code stages request one exact javascriptCode field. Native-capable providers use strict json_schema; providers without native schema support use validated json_object, so DeepSeek Agent execution does not depend on provider-visible tools. Generated-language distiller and executor stages make one validation correction attempt by default through validation_retries; an explicit zero disables the retry.
Core Call Shape
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
assistant := ax.NewAgent(
"question:string -> answer:string",
map[string]ax.Value{"contextFields": ax.Array()},
)Stream the answer
streamingForward() runs the distiller and the executor first, then streams the responder’s answer as field deltas. A clarification or an executor error surfaces before any delta. Each delta carries a version: merge the deltas of one version (strings append, other values replace) and start over when the version changes. The citation check runs when the answer completes; an answer that cites evidence the run never gathered is sent back for a correction, which streams as a new version, and onCitations fires after the stream ends.
// The handbook stays in the agent's runtime, out of the prompt. With
// citations on, the answer cites the evidence it used, and ids the run never
// gathered are sent back to the model for a correction.
assistant := ax.NewAgent("question:string, handbook:string -> answer:string", map[string]ax.Value{
"contextFields": ax.Array("handbook"),
"runtime": ax.Object("language", "JavaScript"),
"citations": ax.Object("onCitations", func(ids []ax.Value) { fmt.Printf("\ncited: %v\n", ids) }),
})
// The distiller and the executor run first; then the responder's answer
// streams. Merge each delta and start over when the version changes (a retry).
version := 0
for delta, err := range assistant.StreamingForward(ctx, openAIClient(), map[string]ax.Value{
"question": "I downgraded today. When does it take effect, and is my data safe if I delete the workspace?",
"handbook": handbook,
}, map[string]ax.Value{"runtime": axgoja.NewRuntime(), "max_actor_steps": 12}) {
if err != nil {
panic(err)
}
if delta.Version != version {
version = delta.Version
fmt.Println("\n[retry: starting over]")
}
if text, ok := delta.Delta["answer"].(string); ok {
fmt.Print(text)
}
}
fmt.Println()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.
assistant := axllm.NewAgent("message:string -> reply:string", map[string]axllm.Value{
"functions": axllm.Array(search),
"contextFields": []axllm.Value{},
})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(...). You rarely need to set the flag yourself: autoUpgrade (ON by default) enables discovery automatically once the inline tool docs get large, and likewise keeps oversized input values runtime-only with a truncated prompt preview when they aren’t declared in contextFields. Explicit settings always win; pass autoUpgrade: false to opt out.
assistant := ax.NewAgent(
"question:string -> answer:string",
map[string]ax.Value{"contextFields": ax.Array()},
)For the cross-language smart-default path, see the Smart Defaults Agent in the long-agent examples.
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
assistant := ax.NewAgent(
"question:string -> answer:string",
map[string]ax.Value{"contextFields": ax.Array()},
)assistant := ax.NewAgent(
"question:string -> answer:string",
map[string]ax.Value{"contextFields": ax.Array()},
)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.
client := ax.NewAxMCPClient(transport, nil)
if err := client.Init(); err != nil { panic(err) }
assistant := ax.NewAgent("request:string -> response:string", map[string]ax.Value{
"functions": client.ToFunction(),
"functionDiscovery": true,
"contextFields": []ax.Value{},
})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.
assistant := ax.NewAgent("request:string -> response:string", map[string]ax.Value{
"functions": []ax.Value{map[string]ax.Value{
"namespace": "memory",
"title": "Memory MCP",
"selectionCriteria": "Use for persistent memory lookup.",
"functions": client.ToFunction(),
}},
"functionDiscovery": true,
"contextFields": []ax.Value{},
})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.