3、Team 组队
团队是由若干 agent(或其他 Team)组成的集合,他们共同协作完成任务。
Team 拥有 members 列表,这些成员可以是 Agent 或 Team 的实例。本文主要以 agent 作为团队成员。
团队可以被视为一个树状结构,团队领导者将任务分配给子团队或直接分配给成员。 Team 的顶层称为“团队领导者”。

团队领导会根据团队成员的角色和任务性质,将任务分配给团队成员。
构建 Team
何时应该使用 Team?
一般原则是 agent 的功能范围要窄。当任务复杂,需要多种工具或繁琐的步骤时,组建一支由单一功能代理组成的团队会非常合适。
# ❌ 错误:一个Agent做太多事情
all_tool_agent = Agent(
name="All-in-One",
tools=[WebSearch, Database, Email, FileSystem, ...], # 太多工具,太多工作内容
)
# ✅ 正确:职责分离
searcher = Agent(
name="Searcher",
tools=[WebSearch],
instructions="用于网络信息搜索"
)
db_agent = Agent(
name="DB Agent",
tools=[Database],
instructions="用于数据库查询"
)
此外,如果由于任务的复杂性,单个代理的上下文限制很容易被超过,团队可以通过保持单个代理的上下文较小来解决这个问题,因为它只处理任务的一部分。
接下来我们创建一个 Team, 这个 Team 由 3 个 agent 组成
- 用于网络搜索的 search_agent, 这个 agent 绑定了 tavily 搜索工具
- 用于查询天气的 weather_agent, 这个 agent 不是真实的进行查询,会随机返回模拟数据
- 用于总结对话的 summary_agent, 这个 agent 不绑定任何工具,只是将对话历史进行总结
创建 teams.py 文件,写入以下代码
import os
import random
from agno.agent import Agent
from agno.models.openai import OpenAILike
from agno.os import AgentOS
from agno.tools.mcp import MCPTools
from agno.db.sqlite import SqliteDb
from agno.tools import tool
from agno.tools.tavily import TavilyTools
from agno.team import Team
@tool(name="get_weather", description="获取天气信息")
def get_weather(city: str) -> str:
"""返回城市 city 的天气信息.
Args:
city (str): 想要获取天气信息的城市名称.
"""
# In a real implementation, this would call a weather API
weather_conditions = ["晴", "多云", "有雨", "有雪", "有风"]
random_weather = random.choice(weather_conditions)
return f"{city} 的天气是 {random_weather}."
# 创建用于搜索的 search_agent
search_agent = Agent(
name="Search Agent",
model=OpenAILike(
api_key=os.getenv("OPENAI_API_KEY"),
id="qwen-plus"
),
role="Search Assistant",
instructions="""
You are a search assistant.
You search the internet for information.
""",
tools=[TavilyTools()],
debug_mode=True,
debug_level=2,
markdown=True,
)
# 创建一个天气查询的 agent
weather_agent = Agent(
name="Weather Agent",
tools=[get_weather],
role="Weather Assistant",
instructions="""
You are a weather assistant.
You get the weather information of a city.
""",
debug_mode=True,
debug_level=2,
markdown=True,
)
# 创建用于总结的 agent
summary_agent = Agent(
name="Summary Agent",
role="Summary Assistant",
instructions="""
You are a summary assistant.
You summarize the content of other members.
""",
debug_mode=True,
debug_level=2,
markdown=True,
)
team = Team(
name="Search and Weather Team",
members=[weather_agent, search_agent, summary_agent],
model=OpenAILike(
api_key=os.getenv("OPENAI_API_KEY"),
id="qwen-max"
),
add_history_to_context=True,
num_history_runs=30,
debug_mode=True,
db=SqliteDb(db_file="agno.db"),
debug_level=2,
)
agent_os = AgentOS(teams=[team])
app = agent_os.get_app()
在定义 Team 时,使用 members 参数传递成员信息。
与 agent 一样,团队的创建也支持以下功能:
- model: 设定“团队领导”向团队成员委派任务的模型。
- Instructions: 指导团队领导如何解决问题。团队成员的姓名、描述和角色信息将自动提供给团队领导。
- DB: 团队的会话历史记录和状态存储在数据库中。这使您的团队能够从上次中断的地方继续对话,从而实现多轮、长时间的对话。
- Knowledge: 如果团队需要查找信息,您可以为团队添加知识库。团队领导可以访问该知识库
- Tools: 如果团队领导需要能够直接使用工具,您可以将工具添加到团队中。
role 与 instructions 的配置说明
在定义团队成员 agent 时,有个 role 参数,这个在之前单独定义 agent 时没有使用过,这个 role 参数主要是描述这个 agent 的角色信息,比如在一个研发团队,有产品,前端,后端,测试,运维等,那么就可以将这些角色信息写到 role 中。 agno 会自动将这些信息转换为对应的 prompt 标签信息。instructions 是具体的行为指导,如对于后端开发人员,可以设置为: 使用 python 的 fastapi 和 postgresql 进行接口 api 开发,接口要符合安全要求等等。
-
role定义 Agent 的身份和角色定位,在系统消息中被包装在<your_role>标签中 -
instructions定义具体的工作指令和行为准则,被包装在<instructions>标签中
建议在使用 Team 时,定义好 agent 的 role 和 instructions 。这个有利于让 team leader 更准确的分配任务。
团队成员模型问题
上面在定义成员 agent 和团队时,对于 model 参数有着不同的定义
- weather_agent和summary_agent 时,并没有指定 model 参数,
- search_agent 使用的是 qwen-plus 模型。
- Team 使用的是 qwen-max 模型
在 Team 中的团队成员 agent,如果没有定义模型将会继承 Team 的模型配置,所以上面的weather_agent和summary_agent 将会使用 Team 的模型 qwen-max。
建议成员 agent 针对自己的工作内容设置自己的 model,比如有的 agent 的主要工作是画图,那么就需要配置一个可以生成图片的多模态模型,有个成员需要处理超长上下文,那就就需要配置一个上下文大的模型,而作为 Team leader 的模型,则应该配置一个善于逻辑推理,功能全面的模型,这样的配置也可以节省一些 token 的消耗。
Team 的执行
使用 uv run --env-file .env uvicorn teams:app 将脚本运行起来,之后再使用 agentOS 连接到这个fastapi 服务。
我们来看一下这个 Team 的运行情况,首先我们知道,这个团队有三个成员,可以进行天气查询与网络搜索和内容总结,我们先针对成员的能力一个一个的提问。
提问关于天气的问题, 预期将使用 weather_agent 来完成

提问特斯拉 model Y 的价格,这个问题预期需要使用 search_agent 来完成

最后总结一下上面的对话信息,预期使用 summary_agent 来完成

通过结果可以看出,这个 Team 完成的还是不错的,任务都按照预期分配给了相应的成员来完成。
我们来看一下具体的执行过程
-
首先 Team leader 会将成员信息和用户的问题带给大模型

我对 <how_to_respond> 标签的内容翻译了一下
- 您的职责是将任务委派给团队中最有可能完成用户请求的成员。
在委派任务之前,请仔细分析成员可用的工具及其角色。
您不能直接使用成员工具。您只能将任务委派给成员。
当您将任务委派给其他成员时,请确保包含以下信息:
- member_id (str):要将任务委派给的成员的 ID。请仅使用成员的 ID,不要使用团队 ID 后跟成员 ID。
- task (str):任务的清晰描述。
- 您可以同时将任务委派给多个成员。
在回复用户之前,您必须始终分析成员的回复。
在分析成员的回复后,如果您认为任务已完成,您可以停止并回复用户。
如果您对成员的回复不满意,您应该重新分配任务。 - 对于简单的问候、感谢或关于团队本身的问题,
请直接回复。
对于所有需要专业知识的工作请求、任务或问题,
请转交给相应的团队成员。
leader 的模型返回如下内容
===== assistant ======
DEBUG Tool Calls:
- ID: 'call_a99fbfb5d6b34906998097'
Name: 'delegate_task_to_member'
Arguments: 'member_id: weather-agent, task: 查询北京当前的天气情况,包括温度、湿度、风速等信息。'
agno 根据这个返回,将这个任务配发给了 weather-agent,task 为 查询北京当前的天气情况,包括温度、湿度、风速等信息。
-
团队成员 weather-agent 得到任务以后,开始执行

这里我们看到,system prompt 只包含这个 agent 自己的 prompt,这也反映出上面提到的团队使用 团队可以通过保持单个代理的上下文较小来解决单个代理的上下文限制很容易被超过的问题 。
-
weather-agent 拿到的任务是
查询北京当前的天气情况,包括温度、湿度、风速等信息, 由于我这个 agent 绑定的天气查询函数只是简单随机的返回了预定义的值["晴", "多云", "有雨", "有雪", "有风"], 所以并不能很好的完成这个任务。大模型也会不停的让 agent 去尝试调用工具。

这里显示调用了 4 次 get_weather 工具,因为拿不到温度,湿度,风速等信息,所以最后大模型给出了模棱两可的答案。
-
最后 team leader 根据 weather-agent 的最终输出,再次调用大模型给出整体最终的结果

-
在进行第二轮对话的时候,由于使用了add_history_to_context 参数,所以 leader agent 会将历史消息带到大模型对话中,并且最终完成 Team 的调用。
工具结果提前返回
上面关于天气的agent 查询过程中,由于是模拟数据,并不满足任务的需求,所以大模型会反复的尝试调用这个工具,这会增加 token 的消耗,有时我们在执行完工具调用以后,不希望大模型进行总结,直接给我返回工具调用结果即可。
我们可以通过设置 stop_after_tool_call=True 参数来控制在执行完工具调用以后直接返回结果,不用再二次调用大模型进行总结
@tool(name="get_weather", description="获取天气信息", stop_after_tool_call=True)
def get_weather(city: str) -> str:
...
这时我们看到 weather agent 只返回了函数的调用结果,并不会再重复的调用工具了

这种方式有好有坏,好处是可以节省一些 token,缺点是如果工具执行失败了或者并不符合 task 预期,agent 也不会进行重试。
复合任务的执行
上面 Team 的执行是针对单一任务的,用户和Team 的交互,一次提问只有一个任务,对于这种类型的交互,Team 可以很好的将任务派发给对应的团队成员来完成,但是有时,用户可能想在一次交互完成多个任务,比如上面的三次提问,合并为一次提问,用户可能会说:”帮我查一下北京的天气以及小米 su 7 的最新消息,并总结一下生成一份报告“,对于这类型的任务,我们来看一下 Team 是怎么执行的。
首先,Team 可以分析出要做三件事,并且根据成员的能力,将三件事派发到对应的成员 agent
Tool Calls:
- ID: 'call_6871cbbae51e4f378bccba'
Name: 'delegate_task_to_member'
Arguments: 'member_id: weather-agent, task:
查询北京当前的天气情况,包括温度、湿度、风速等信息。'
- ID: 'call_729d73f9f5c04636b5ec32'
Name: 'delegate_task_to_member'
Arguments: 'member_id: search-agent, task: 查找关于小米 su7
的最新消息,包括产品发布、市场反馈等方面的信息。'
- ID: 'call_0d8eaa753a654e0694273e'
Name: 'delegate_task_to_member'
Arguments: 'member_id: summary-agent, task:
基于从天气代理和搜索代理获取的信息,撰写一份总结报告。报告应包括北京当前的
天气概况以及关于小米 su7 的最新动态。'
Team leader 是一次性的返回需要调用的 agent,所以成员 agent 接到任务以后是一起并行执行的

但是我们的预期是,先执行天气查询和网络搜索,这两个任务没有什么关联性,可以并行执行,然后总结智能体再根据前面两个智能体的输出进行总结,但是由于这三个智能体是并行执行的,所以 summary agent 并不知道另外两个 agent 的实际输出,这里的内容其实是大模型瞎编的。

Team 的局限性
由于 Team 的执行逻辑,注定其无法有效的控制成员之间的执行顺序,并不能实现 autogen 中的RoundRobinGroupChat 团队合作,如何才能精确的控制执行流程,比如这里的流程,需要先执行 search_agent 和 weather_agent ,然后再执行 summary agent 呢? 这里提供两种解决方案。
修改 instructions
可以通过修改 Team 的 instructions 来更好的指导 leader 如何分配任务
team = Team(
name="Search and Weather Team",
members=[weather_agent, search_agent, summary_agent],
model=OpenAILike(
api_key=os.getenv("OPENAI_API_KEY"),
id="qwen-max"
),
add_history_to_context=True,
show_members_responses=True,
instructions=[
"你是一个团队的 leader,负责分析与拆分用户的任务需求,并将任务派发给对应的团队成员",
"如果任务中有包含总结相关的任务,请在别的成员完成之后再派发任务给Summary Agent 成员",
"当你觉得用户的任务都完成后请结束此次对话.",
],
db=SqliteDb(db_file="agno.db")
)
我修改 instructions, 告诉他 如果任务中有包含总结相关的任务,请在别的成员完成之后再派发任务给Summary Agent 成员, 此时再看一下任务的执行过程。

leader 第一次调用大模型时只返回了两个工具调用,这时天气查询和网络搜索 agent 开始并行干活。
之后 leader 再次调用大模型,这时大模型返回的是总结智能体的任务。

这样就可以实现任务的有序执行了。
使用 ReasoningTools
还可以使用 ReasoningTools 来让 Team 在执行任务的之前先规划好。
from agno.tools.reasoning import ReasoningTools
team = Team(
name="Search and Weather Team",
members=[weather_agent, search_agent, summary_agent],
model=OpenAILike(
api_key=os.getenv("OPENAI_API_KEY"),
id="qwen-max"
),
tools=[ReasoningTools(add_instructions=True, add_few_shot=True)],
add_history_to_context=True,
num_history_runs=30,
debug_mode=True,
db=SqliteDb(db_file="agno.db"),
debug_level=2,
)
给 team 添加了 ReasoningTools 工具以后,收到任务以后,先让模型进行 think ,注意这里并不需要像 deepseek-r1 那种有推理能力的模型,普通的大语言模型即可,它是通过构造提示词来指导模型思考的。
先获取了 think 的工具结果

查看 action 里的内容,以及可以很好的指导后续的任务执行了。
之后 team 的成员执行就会按照这个 action 来工作了。
ReasoningTools 的使用,后面再做详细的介绍。
当然无论使用修改 instrctions 还是使用 ReasoningTools, 都是通过prompt 来指导 Team 执行任务,这只是针对简单的工作流程才有效,同时也和 LLM 的能力有关,但是对于复杂的流程,Team 就有点能力不足了,此时我们就需要 workflow 登场了,workflow 可以精确的控制任务的执行过程。