Build a research agent
Research is naturally parallel. Three questions about a company - its financials, its recent news, its competitors - have nothing to do with each other until the end, and running them one after another wastes most of the wall-clock time.
There are two ways to build this in AXL.
| Who decides what to investigate | Survives a restart | Reach for it when | |
|---|---|---|---|
| Subagents | The model, during the run | No | The angles are not known in advance |
| Workflow | You, when you author the graph | Yes | The angles are always the same three |
This walkthrough builds the workflow version, then shows what changes if you want the open-ended one.
Fan out
Three agent nodes with no edges between them run concurrently - the engine starts every node whose dependencies are satisfied, and these have none beyond the input:
axg 1
workflow research {
input company
financials = agent researcher:
"Research {{ input.company }}'s financial position. Cite sources."
news = agent researcher:
"Find significant news about {{ input.company }} from the last 6 months. Cite sources."
competitors = agent researcher:
"Identify {{ input.company }}'s main competitors and how they differ. Cite sources."The researcher agent needs web access:
key = "researcher"
display_name = "Researcher"
description = "Researches a question and returns a sourced answer"
toolsets = ["web"]
identity = "Research thoroughly and cite every claim. Say when you could not find something."The identity includes "Say when you could not find something," which keeps a research agent that finds nothing from producing something anyway.
Merge
A node with several incoming edges waits for all of them, then reads each upstream result:
brief = agent writer:
"Write a one-page investment brief on {{ input.company }} from these findings.
Keep every source citation.
Financials: {{ financials.response }}
News: {{ news.response }}
Competitors: {{ competitors.response }}"
financials -> brief
news -> brief
competitors -> brief
brief -> return {
company: input.company,
brief: brief.response
}
}Bound the cost
Research agents can spend real money by accident - web tools plus a model that keeps finding one more thing worth checking. Put limits on the node rather than hoping:
financials = agent researcher {
prompt "Research {{ input.company }}'s financial position. Cite sources."
timeout 120
retry 2
}See Put a deadline on a step and Retry a flaky step with backoff.
Return it as an artifact
A one-page brief is fine in the run output. A twenty-page report with appendices is not - it belongs in an artifact the user downloads, which also gives it retention and provenance independent of the run.
The open-ended version
When you cannot name the angles in advance - "research whatever matters about this company" - use subagents instead. One coordinating agent decides what to investigate and delegates:
[sub_agents]
enabled = true
max_concurrent = 3
max_iterations = 8
max_budget_usd = 1.00
timeout_secs = 300
allowed_agents = ["researcher"]You trade determinism and durability for flexibility. max_budget_usd stops being optional here:
the model is choosing how much work to do, and without a ceiling it can end up spending a lot.
What you now have
- Three investigations running concurrently instead of in sequence
- A merge step that waits for all of them and keeps their citations
- Per-node timeouts and retries, so one slow source cannot hang the run
- Durable execution across restarts, with each step running exactly once
- A downloadable artifact for anything substantial
- A documented path to the open-ended version when you need it
Next
- Delegate to subagents - the model-driven alternative in full.
- Workflow how-to recipes - first-of-several, map, and loop patterns.
- Return artifacts - handing back large output.
- Observe runs - watching what a parallel run actually cost.