AgentNode
nae.AgentNode ¶
AgentNode(name: Optional[str] = None, llm: Optional[Any] = None, node_prompt: str = 'you are a helpful assistant', tools: Optional[list] = None, max_tool_iterations: int = 25, input_field: str = 'messages', output_field: str = 'messages', reads: Optional[List[str]] = None, writes: Optional[Union[List[str], Dict[str, type]]] = None, reasoning_effort: Optional[str] = None, cache_ttl: Optional[int] = None, retry: bool = False)
Bases: LLMNode
An LLM agent: prompt the model over the history and return a delta.
Prepends node_prompt as a SystemMessage to the history (read from
input_field, default messages), calls the LLM, and returns only the keys
it updates. Two optional modes change what it does with the response:
- Tool-call loop (
tools=[...]): every requested tool is executed,ToolMessages are appended, and the model is re-invoked until it stops calling tools (capped bymax_tool_iterations) — all of it folded into one{"messages": [...]}delta. Cannot be combined with multi-field structuredwrites. - Structured output (
writes=[...]with two+ keys, or awrites={key: type}dict): the model is wrapped withwith_structured_output, so it returns one field per key. The dict form types each field, so values come back native ({"score": int}->9, an int) rather than stringified.
A non-default single output_field/writes key writes the final response's
content to that key instead of appending to messages (a transform node).
Examples:
from nae import AgentNode, AgenticGraph
def add(a: int, b: int) -> int: return a + b
def multiply(a: int, b: int) -> int: return a * b
agent = AgentNode(llm=llm, tools=[add, multiply]) # name inferred -> "agent"
graph = AgenticGraph(start_node=agent, end_nodes={agent})
graph.invoke(message="What is 21 + 21, then times 3?") # -> 126
Initialize an AgentNode.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Optional[str]
|
Unique identifier for the node |
None
|
llm
|
Optional[Any]
|
Language model instance to be used by this node |
None
|
node_prompt
|
str
|
System prompt/instructions for the language model |
'you are a helpful assistant'
|
tools
|
Optional[list]
|
Tools this agent can call. A |
None
|
max_tool_iterations
|
int
|
Safety cap on the internal tool-call loop; a model that keeps requesting tools beyond this raises RuntimeError. |
25
|
input_field
|
str
|
State key to read the message history from. |
'messages'
|
output_field
|
str
|
State key to write to. When "messages" (default) the produced messages are appended to the conversation; any other key receives the final response's string content instead (useful for transform nodes — that key must exist in your state schema). |
'messages'
|
reads
|
Optional[List[str]]
|
State keys this node reads (multi-key form; back-compat generalization of input_field). Each read is dispatched by VALUE type: a non-empty list of messages becomes conversation history (concatenated in order), anything else is a scalar interpolated into node_prompt via .format_map. Use reads OR input_field. |
None
|
writes
|
Optional[Union[List[str], Dict[str, type]]]
|
State keys this node writes (multi-key form; back-compat generalization of output_field). Accepts either a list[str] or a dict[str, type]. ["messages"] appends to the conversation; a single scalar key (list form) writes the final response content; two or more scalar keys switch to structured output (one field per key, no tool loop). A dict[str, type] ALWAYS uses structured output (even for one key) and types each field as given, so the node returns NATIVE-typed values (e.g. {"score": int} -> 9, an int) instead of all-str. A list[str] types every field as str. Use writes OR output_field. |
None
|
reasoning_effort
|
Optional[str]
|
Reasoning effort for reasoning-capable models (e.g. "low"/"medium"/"high" on gpt-5.x). Passed as a per-call kwarg to the LLM. (DecisionNode does not expose this — reasoning effort conflicts with structured output on current OpenAI models.) |
None
|
cache_ttl
|
Optional[int]
|
see Node — node-level result caching. |
None
|
retry
|
bool
|
see Node — node-level retry on exception. |
False
|
__call__ ¶
Process the current state and generate a response.
Runs the agent and, when tools are set, its internal tool-call loop, accumulating every message produced this turn (the AIMessage, any ToolMessages, and follow-up AIMessages) into a single delta. Returns only the delta — the state reducers append it to canonical state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
dict
|
Current conversation state containing message history |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A state delta: {"messages": [...new...], "log": [...new...]} |
Raises:
| Type | Description |
|---|---|
ValueError
|
If LLM is not set or if state is invalid |