Auto team
AutoTeamBuilder in com.tnsai.autoteam (in tnsai-intelligence) asks an LLM to design a group of agents for a task, then builds those agents. You describe the task and hand over the tools; the LLM picks the roles, the prompts and the dependencies between agents.
AutoTeamBuilder.Result result = AutoTeamBuilder.create()
.llm(llmClient)
.toolPojos(searchTools)
.principalProvider(new LocalIdentityProvider())
.authorityScope(AuthorityScope.unrestricted(Duration.ofHours(1)))
.build("Research quantum computing advances and write a summary report");
AgentGroup group = result.group();
TeamPlan plan = result.plan();Every generated agent gets an identity from the principalProvider and the authorityScope you set, as a hand-built agent does; see Principal and authority. Without both, build throws IllegalStateException. liabilitySink(...) is optional.
Builder
| Method | Default | Meaning |
|---|---|---|
llm(client) | required | Designs the team and is the LLM of every generated agent |
toolPojos(...) | none | Objects whose @Tool methods make up the tool pool |
dynamicTool(tool), dynamicTools(list) | none | Tools built at runtime, such as MCP proxies |
maxAgents(n) | 10 | Most agents kept from the plan; must be at least 1 |
temperature(t) | 0.4 | Temperature of the two design calls, between 0 and 2 |
agentCustomizer(fn) | none | Changes each AgentBuilder before the agent is built |
principalProvider(provider) | required by build | Issues each agent's identity |
authorityScope(scope) | required by build | What each agent is allowed to do |
liabilitySink(sink) | none | Where each agent records liability |
How a team is designed
build(task) makes two LLM calls and then builds the agents:
- Decomposition. The LLM gets the task and the names of all tools, and answers with JSON: a team name, its reasoning, a suggested formation, the agents with their roles, capabilities, tool names and an
isLeadflag, and a map of which agent depends on which. If the answer has no JSON that can be parsed, the plan falls back to one "General Assistant" agent. - Cut to size. When there are more agents than
maxAgents, the firstmaxAgentsare kept. The dependency map is not trimmed. - Prompts. A second call writes a system prompt for each agent. An agent the answer leaves out gets a prompt built from its role, the task, its capabilities and its tools.
- Formation.
TopologySelectorreplaces the suggested formation, as in the table below. - Agents. Each agent gets a role named after the generated role, with the prompt as the role's goal, and the tools whose names it was given. Tool names that are not in the pool are skipped. The agents are collected in an
AgentGroup.
| Plan | Formation |
|---|---|
| One agent | PARALLEL |
| A lead agent and some dependencies | HIERARCHICAL |
| Dependencies that form a single chain | SEQUENTIAL |
| A dependency path two or more steps long | HIERARCHICAL |
| A lead agent and no dependencies | HIERARCHICAL |
| No dependencies | PARALLEL |
| Anything else | The LLM's suggestion, or PARALLEL if it is not one of the three |
The rows are checked from top to bottom. There is no way to force a formation.
Previewing the plan
plan(task) runs the same design steps and returns the TeamPlan without building any agents, so it needs no principal provider or authority scope. It still makes both LLM calls.
TeamPlan preview = AutoTeamBuilder.create()
.llm(llmClient)
.toolPojos(searchTools)
.maxAgents(5)
.plan("Build a market analysis dashboard");TeamPlan accessor | Meaning |
|---|---|
taskDescription() | The task |
teamName(), reasoning() | Written by the LLM |
agents() | One GeneratedAgentConfig per agent |
suggestedFormation() | PARALLEL, SEQUENTIAL or HIERARCHICAL |
dependencies() | Agent id to the ids it depends on |
agentCount(), hasDependencies() | Counts from the two above |
A GeneratedAgentConfig has an id, a role, a systemPrompt, toolNames, capabilities and parameters; isLead() reads the isLead parameter.
Running the team
build returns a Result with the group, the plan and the agents. An AgentGroup holds the agents but does not run a task. To run them, put them in a Team with the chosen formation:
TeamBuilder teamBuilder = Team.builder()
.name(plan.teamName())
.mission(plan.taskDescription())
.formation(TeamFormation.valueOf(plan.suggestedFormation()));
for (Agent agent : result.agents()) {
teamBuilder.member(agent, TeamRole.MEMBER);
}
Team team = teamBuilder.build();
team.start();
TeamResult teamResult = team.execute(plan.taskDescription());The plan's dependency map is not passed to the team; the formation alone decides how the members work together. See Group topologies for teams and formations.