Skip to main content

Agents

An agent is an LLM with instructions and tools that plans, calls tools and answers until the task is done.

You create an agent once with .save(), then run it as often as you need from Python, the REST API or the aixplain app.

Try it​

pip install aixplain
from aixplain import Aixplain

aix = Aixplain(api_key="YOUR_API_KEY")

agent = aix.Agent(
name="Hello agent",
description="Answers general questions clearly and concisely.",
instructions="You are a helpful assistant. Answer in one or two sentences.",
).save()

result = agent.run("What is machine learning?")
print(result.data.output)
Show output

Get your API key from API keys in the aixplain app.

How it works​

Each run follows the same loop:

  1. The agent reads your prompt, its instructions and the descriptions of its tools.
  2. The LLM decides the next step: answer, or call a tool with specific inputs.
  3. The tool runs and its result goes back to the LLM.
  4. Steps 2 and 3 repeat until the LLM answers or a budget limit stops the run.

An agent starts as a draft. .save() stores it in your workspace and makes it callable by ID from any client.

StateMeaning
DRAFTCreated in Python, not saved yet.
ONBOARDEDSaved and callable.

Add tools​

Give an agent tools and it decides when to call them. Scope each tool to the actions the agent needs, then pass it in tools.

web_search = aix.Tool.get("tavily/tavily-web-search/tavily")
web_search.allowed_actions = ["search"]

agent = aix.Agent(
name="Research agent",
description="Researches topics on the web.",
instructions="Use web search for anything time-sensitive. Cite your sources.",
tools=[web_search],
).save()

result = agent.run("What is the latest stable Python release? One sentence.")
print([step["unit"]["name"] for step in result.data.steps])
print(result.data.output)
Show output

result.data.steps lists every model and tool call, so you can confirm the tool ran instead of guessing from the answer. Browse more tools in Tools.

Run a tool on its own​

Test a tool before you attach it. tool.run() takes the action name and its inputs.

result = web_search.run(action="search", data={"query": "Python 3.14 release notes", "num_results": 2})
for item in result.data["details"]:
print(item["title"])
Show output

Pin tool inputs​

Pin an input to a fixed value and the agent always uses it. A pinned input is hidden from the LLM. Print an action to see its inputs.

print(web_search.actions["search"])
Show output

Set the value before you create the agent. It is saved with the agent and applies to every run.

web_search.actions["search"].inputs["num_results"] = 2

agent = aix.Agent(
name="Pinned search agent",
description="Researches topics on the web.",
instructions="Use web search for anything time-sensitive.",
tools=[web_search],
).save()

fetched = aix.Agent.get(agent.id)
print(fetched.tools[0].actions["search"].inputs["num_results"].value)
Show output

To override a pinned value for one run, set it on agent.tools after .save() and before run(). The saved value stays unchanged.

agent.tools[0].actions["search"].inputs["num_results"] = 3

result = agent.run("What is the latest stable Python release? One sentence.")
for step in result.data.steps:
if step["unit"]["name"] == "Tavily Web Search":
print(step["input"])
Show output

Choose the LLM​

Agents run on GPT-5.4 by default. Pass any Marketplace LLM in llm to change it.

agent = aix.Agent(
name="Small model agent",
description="Answers quick questions on a small, low-cost model.",
instructions="Answer in one sentence.",
llm=aix.Model.get("openai/gpt-4o-mini/openai"),
).save()

result = agent.run("What is the capital of Australia?")
print([step["unit"]["name"] for step in result.data.steps])
print(result.data.output)
Show output

Set model inputs such as temperature and reasoning_effort on the model before you pass it. They are saved with the agent.

llm = aix.Model.get("openai/gpt-5.4/openai")
llm.inputs.temperature = 0.2
llm.inputs.reasoning_effort = "high"

agent = aix.Agent(
name="Careful analyst",
description="Handles multi-step analysis.",
instructions="Think through the problem, then answer briefly.",
llm=llm,
).save()

result = agent.run("A bat and a ball cost 1.10 in total. The bat costs 1.00 more than the ball. How much is the ball?")
print(result.data.output)
Show output

Pick an LLM by context window, reasoning depth, latency, cost and tool-calling reliability. Compare them in Models.

Return JSON​

Set output_format="json" and describe the shape in expected_output. A Pydantic model, a dict or a string all work.

from pydantic import BaseModel

class Review(BaseModel):
name: str
sentiment: str

agent = aix.Agent(
name="Review extractor",
description="Extracts fields from customer reviews.",
instructions="Extract the reviewer's name and the review sentiment.",
output_format="json",
expected_output=Review,
).save()

result = agent.run("Review: Onboarding was smooth and support was great. Dana")
print(result.data.output)
Show output

result.data.output is a JSON string. Parse it with Review.model_validate_json(result.data.output) or json.loads. Use output_format="markdown" for formatted text.

Add subagents​

An agent with agents=[...] delegates work to its subagents and returns one answer. There is no separate team class: it is an aix.Agent with everything on this page. In the aixplain app, an agent with subagents is called a team agent.

Use subagents when one set of instructions would have to cover very different jobs.

researcher = aix.Agent(
name="Researcher",
description="Finds facts on the web.",
instructions="Search the web and return the key facts with sources.",
tools=[web_search],
)
writer = aix.Agent(
name="Writer",
description="Writes short, clear summaries from research notes.",
instructions="Write a summary of at most three sentences from the notes you receive.",
)

team = aix.Agent(
name="Research and writing team",
description="Researches a topic, then writes a short summary.",
instructions="Have the researcher gather facts first, then have the writer summarize them.",
agents=[researcher, writer],
).save(save_subcomponents=True)

result = team.run("Summarize how the Eiffel Tower was built.")
print(sorted({step["agent"]["name"] for step in result.data.steps}))
print(result.data.output)
Show output

save(save_subcomponents=True) saves the subagents together with the parent. The parent plans the work and routes each part to the subagent whose name and description fit it best. It does not see the subagents' tools, so write distinct descriptions. Tracing and monitoring shows which subagent ran each step.

Subagents take more steps than a single agent. Set an iteration limit on the parent's budget before you save, for example team.budget.max_iterations = 30.

Plan with a separate model​

By default the parent plans with its own LLM. Pass planner to plan with another model, such as a smaller one.

team = aix.Agent(
name="Research team with planner",
description="Researches a topic, then writes a short summary.",
instructions="Have the researcher gather facts first, then have the writer summarize them.",
planner=aix.Model.get("openai/gpt-4o-mini/openai"),
agents=[researcher, writer],
).save(save_subcomponents=True)

result = team.run("Summarize the current state of fusion energy.")
print([step["unit"]["name"] for step in result.data.steps][:3])
Show output

llm and planner take a Model object or a model ID, not an asset path string.

Define tasks​

For a fixed, repeatable process, give each subagent a task. A task runs only after every task in its dependencies has finished, and the last task produces the answer.

find_facts = aix.Agent.Task(
name="find_facts",
instructions="Find three recent facts about the topic in the request.",
expected_output="Three facts with sources.",
)
write_brief = aix.Agent.Task(
name="write_brief",
instructions="Write a three-sentence brief from the facts.",
expected_output="A three-sentence brief.",
dependencies=[find_facts],
)

team = aix.Agent(
name="Briefing team",
description="Produces a short brief on a topic.",
instructions="Follow the task order.",
agents=[
aix.Agent(name="Fact finder", description="Finds recent facts on the web.",
instructions="Search the web and return facts with sources.",
tools=[web_search], tasks=[find_facts]),
aix.Agent(name="Brief writer", description="Writes short briefs.",
instructions="Write clear, short briefs.", tasks=[write_brief]),
],
).save(save_subcomponents=True)

result = team.run("Electric vehicle batteries")
print(result.data.output)
Show output

Dependencies must not form a cycle, and if one subagent has a task, every subagent needs at least one. Without tasks, the parent plans at run time and adapts to intermediate results; with tasks, the order is fixed and auditable.

Attach images and audio​

Pass images and audio for one run in attachments. Each entry is a URL or a local file path; local files are uploaded for you. Use an LLM that accepts the media type.

agent = aix.Agent(
name="Multimodal assistant",
description="Answers questions about images and audio.",
instructions="Answer from the media provided. Be concise.",
llm=aix.Model.get("google/gemini-3-5-flash/openrouter"),
).save()

IMAGE_URL = "https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg"
AUDIO_PATH = "hello.wav" # any local WAV or MP3 file, or a public URL

result = agent.run("Describe this image in one sentence.", attachments=[IMAGE_URL])
print(result.data.output)

result = agent.run("Transcribe the speech in this audio.", attachments=[AUDIO_PATH])
print(result.data.output)
Show output

Pass several entries to send them together. Media must be reachable at run time: a URL behind a login or an expired signed link is not fetched.

To keep the media in a conversation, pass a session as well. The attachment is stored on that turn, so later turns can refer back to it.

session = aix.Session(agent=agent, name="Image chat").save()

agent.run("What animal is this?", attachments=[IMAGE_URL], session=session)
result = agent.run("What color is its fur?", session=session)
print(result.data.output)
Show output

Attachments are for one run. To give an agent reference material on every run, attach files to the agent instead.

Run parameters​

agent.run() takes the prompt as its first argument and these keyword arguments.

ParameterTypeDefaultDescription
querystr or dictrequiredThe task or question. Pass it positionally.
sessionSession or strNoneRun inside a conversation. Takes a Session or a session ID. See Sessions and memory.
historylistNonePrior turns for this run only. Cannot be combined with session.
attachmentslistNoneImages and audio for this run, as URLs or local paths.
progress_formatstrNone"status" for one line, "logs" for a step timeline. None prints nothing.
progress_verbosityint11 steps, 2 adds the agent's thoughts, 3 adds full inputs and outputs.
progress_truncateboolTrueShorten long text in progress output.
timeoutint300Seconds the SDK waits. The run may continue on the server.
wait_timefloat0.5Seconds between status checks.

Output length and iteration limits are agent settings, not run parameters. Set agent.max_tokens (default 2048) and agent.budget.max_iterations, then .save().

Show progress​

Watch a run as it happens with progress_format.

result = agent.run("What is machine learning?", progress_format="logs", progress_verbosity=2)
Show output

Run without waiting​

run_async() starts a run and returns at once. Poll its URL until the result is complete.

import time

run = agent.run_async("Summarize the history of computing in two sentences.")

result = agent.poll(run.url)
while not result.completed:
time.sleep(2)
result = agent.poll(run.url)

print(result.data.output)
Show output

Start several runs, then collect each result. The runs execute in parallel on the server.

queries = [
"What is cloud computing? One sentence.",
"Explain blockchain in plain English. One sentence.",
]

runs = [agent.run_async(query) for query in queries]
for query, run in zip(queries, runs):
result = agent.poll(run.url)
while not result.completed:
time.sleep(2)
result = agent.poll(run.url)
print(f"Q: {query}\nA: {result.data.output}\n")
Show output

Save and update​

Change any attribute, then call .save() again. The agent keeps its ID, so every client that calls it gets the new version.

agent.instructions = "You are a helpful assistant. Answer in one short paragraph."
agent.output_format = "markdown"
agent.max_tokens = 4000
agent.save()

fetched = aix.Agent.get(agent.id)
print(fetched.output_format, fetched.max_tokens)
Show output

Delete an agent you no longer need with agent.delete().

Troubleshooting​

SymptomCauseFix
The agent ignores a toolThe tool's name or description does not match the taskCheck result.data.steps, then tighten the tool's description and the agent's instructions.
agent reached the maximum number of iterationsThe run hit budget.max_iterationsRaise it: agent.budget.max_iterations = 20, then agent.save().
model response was cut off because the maximum token limit was reachedThe LLM's output cap is too lowSet llm.inputs.max_tokens on the model, assign it to agent.llm, then agent.save().
The answer is cut shortThe agent's own max_tokens (default 2048) caps the final outputSet agent.max_tokens = 8000, then agent.save().
err.name_already_exists on saveAnother agent in your workspace has the same name, often a subagentUse a unique name, or delete the old agent.
must be saved before saving the agentSubagents were not savedSave the parent with .save(save_subcomponents=True).
model.Invalid id on savellm or planner got an asset path stringPass aix.Model.get(path) or the model ID.
A subagent is never usedIts description overlaps another subagent'sMake each description distinct. With tasks, check that it has one.

Skills​

Reusable instructions and scripts live on their own page: Skills.

Files​

Reference files that every run can read live on their own page: Files.

Triggers​

Scheduled and event-driven runs live on their own page: Triggers.

Session management​

Multi-turn memory lives on its own page: Sessions and memory.

Budget and governance​

Cost, time and iteration limits live on their own page: Budgets.

Tracing and monitoring​

Steps, credits and run metrics live on their own page: Tracing and monitoring.

Next steps​