跳到主要内容

PraisonAI — 总览与阅读地图

30 秒导读: PraisonAI 是一个 Python 优先的多智能体框架——目标是让你用几行代码就组建起一支能自己研究、规划、执行任务的「AI 团队」。本章是这组文档的入口:先讲清它是什么,再给一张五层全景图,把 team.start() 从任务图到输出走一遍,最后列出 01-06 章的阅读顺序。具体机制不在本章展开,交给后续各章。


1. 这是什么(零基础也能懂)

一句话定义: PraisonAI 是一个用来「搭建并运行 AI 智能体」的 Python 库——从单个智能体,到一整支互相分工的智能体团队,核心卖点是 README 里那句 "deployed in 5 lines of code"(README.md:26)。

解决谁的什么问题: 假设你想让 AI 帮你做一件多步骤的活——先上网查资料、再整理、再写成文章。你不想自己手写「调模型 → 解析工具调用 → 把上一步结果喂给下一步」这些胶水代码。PraisonAI 把这套胶水打包好了:你只描述每个智能体是谁、要干什么,它负责把它们串起来跑。

最小示例长什么样: 三段真实的 README 代码,从单体到团队递进:

# 单个 Agent —— 给它一个目标,它自己干
from praisonaiagents import Agent
agent = Agent(instructions="You are a senior data analyst.")
agent.start("Analyze the top 3 tech trends of 2026 and format as a markdown table.")
# 多个 Agent 组队 —— 默认按顺序接力
from praisonaiagents import Agent, Agents
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = Agents(agents=[research_agent, summarise_agent])
agents.start()
# 确定性流水线 AgentFlow —— 步骤写死,一步接一步
from praisonaiagents import AgentFlow, Agent
flow = AgentFlow(steps=[Agent(instructions="Write content"),
Agent(instructions="Edit content")])
result = flow.run("Write about AI")

上面三段分别对应本框架的三种用法,依据:README.md:99-105README.md:250-257workflows/workflows.py:561-568 的类 docstring。

一句话直觉:Agent 想成一名员工,Task派给他的一张工单,AgentTeam把几名员工编成一个组、按流程叫号干活的组长。你写的是「组织架构」,框架负责「叫号执行」。

⚠ 一处必须先破的误解:仓库根目录的 ARCHITECTURE.md 大量是「愿景/规划」,不是现状。 它开篇自称「Strategic architecture document」并覆盖「2-quarter road map」(ARCHITECTURE.md:5-7),第 8 节整张 Implementation Roadmap 把 Doctor Auto-Fix、Golden-Path CLI、Graph Studio 等一律标为 Planned(ARCHITECTURE.md:379-397),还提到 TypeScript / Rust SDK 等本克隆里并不完整的东西。本组文档一律以 src/praisonai-agents/praisonaiagents 下的真实 Python 代码为准,不采信 ARCHITECTURE.md 的前瞻描述。凡与真源码冲突,以源码为准。


2. 顶层全景(它大概怎么转)

2.1 五大层怎么读这张图

从上到下是依赖方向:上层调用下层,下层不知道上层。最上面两条(编排器)是并行的两种范式,不是上下级——你要么用团队,要么用流水线。

怎么读:从上往下是「谁调用谁」;顶部两个盒子是二选一的两条编排路线。

┌─────────────────────────┐ ┌─────────────────────────┐
│ 编排器范式 A:AgentTeam │ │ 编排器范式 B:AgentFlow │
│ + Process(叫号执行) │ │ (步骤写死的确定性流水线) │
│ team.start() │ │ flow.run() │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ 都落到 │
▼ ▼
┌───────────────────────────────────────────┐
│ Task —— 工作单元(一张工单:描述+归属Agent) │
└───────────────────┬───────────────────────┘

┌───────────────────────────────────────────┐
│ Agent —— 单体(chat 主循环:指令+工具+记忆) │
└──────────┬──────────────────┬─────────────┘
▼ ▼
┌────────────────┐ ┌────────────────────────┐
│ Tools / MCP │ │ LLM 层(双路径调模型) │
│ (模型的手脚) │ │ 原生OpenAI | LiteLLM │
└────────────────┘ └────────────────────────┘
▲ ▲
┌──────────┴──────────────────┴─────────────┐
│ 外围子系统:Memory / Knowledge(RAG) / │
│ Guardrails / Session / Telemetry … │
└────────────────────────────────────────────┘

2.2 各层一句话职责

干什么在哪(相对 praisonaiagents/)本组对应章
Agent 单体一个智能体的 chat 主循环:拼提示 → 调 LLM → 解析工具调用 → 回结果agent/agent.py(Agent 类,行 219)01
Task 工作单元一张「工单」:任务描述 + 归属哪个 Agent + 上下文/下一步task/task.py(Task 类,行 21)04
编排器 A:AgentTeam + Process把多个 Agent/Task 按 sequential / hierarchical / workflow 叫号跑agents/agents.py(AgentTeam,行 554)、process/process.py(Process,行 20)04
编排器 B:AgentFlow步骤写死的确定性流水线,配 route/parallel/loop/repeat 条件workflows/workflows.py(AgentFlow,行 555)05
工具 / MCP给模型「手脚」:本地 @tool 函数、或经 MCP 挂外部工具tools/mcp/mcp.py02
LLM 层真正调模型,双路径 + 多 provider 容错llm/03
外围子系统记忆、知识、护栏、会话、遥测等可选能力memory/knowledge/guardrails/06

2.3 巧妙骨架:近 60 个子包,为何导入还很快

问题: praisonaiagents/ 下有 59 个带 __init__.py 的顶层子包(实测 find -maxdepth 2 -name __init__.py 计数),里面 litellm、rich、chromadb 这些都是重依赖。若在 import praisonaiagents 时全部加载,启动会很慢。

做法:惰性加载(lazy import)——用到才加载。 包的 __init__.py 顶部急切导入三个轻量模块:_warning_patch_logging_config(__init__.py:51,54,60),其余一律推迟。

机制由三块拼成:

部件作用位置
_LAZY_IMPORTS 字典名字 → (模块路径, 属性名) 的唯一映射表,约 300+ 条__init__.py:116-601
__getattr__(模块级)当你访问 pa.Agent 时才按表去 import,并线程安全缓存__init__.py:713,工厂在 _lazy.py:164 create_lazy_getattr_with_fallback
_custom_handler处理特例:AgentsAgentTeam 的别名、embedding 覆盖同名子包、tools/memory 等返回模块本身__init__.py:652-704

直觉:_LAZY_IMPORTS 当成一张电话簿——import praisonaiagents 只是拿到电话簿,没给任何人打电话;直到你写 pa.Agent,__getattr__ 才照着簿子拨号(真正 import agent/agent.py)。所以 README 敢标 "instantiation in around 14μs"(README.md:773)。

额外一手:warmup(include_litellm=True) 允许你主动预热重依赖,把首次调用的延迟提前付掉;默认 OpenAI 快路径不需要它(__init__.py:753-806warmup docstring)。


3. 主线一句话走通:一次 team.start()

用第 2 段的多智能体例子,把控制流从「任务图」追到「输出」,只走高层,不进代码:

怎么读:从左到右是一次 team.start() 的时间顺序;命中即往右。

team.start() ①按 process 选执行器 ②对每个任务
┌──────────┐ content ┌──────────────────┐ 逐个 ┌────────────┐
│ AgentTeam │─────────▶│ Process.sequential │─────▶│ run_task │
│ .start() │ │ /hierarchical │ 叫号 │ (单个工单) │
└──────────┘ │ /workflow(生成器) │ └─────┬──────┘
│ └──────────────────┘ │ 委派
│ ③收尾 ▼
▼ ┌────────────┐
返回最后一个任务的 .raw │ Agent.chat │
(return_dict=True 则给全量 dict) │ 真正调 LLM │
└────────────┘

分三步看,每步都有真实落点:

  1. 选执行器。 start() 判断是否 TTY 决定是否打印 Rich 面板,然后走到 run_all_tasks(),按 self.process 三选一:workflow() / sequential() / hierarchical(),每个都是 Process 上的生成器,yield 出下一个该跑的 task_id(agents/agents.py:1416-1436)。异步入口 astart() 对称地走 arun_all_tasks()(agents/agents.py:1248,1180-1240)。

  2. 逐任务委派。 拿到 task_idrun_task()execute_task(),后者把工单交给它归属的 Agent,最终落到 Agent.chat(agent/chat_mixin.py:1910)——那里才是真正拼提示、调 LLM、解析工具调用的地方(详见 01)。

  3. 收尾取值。 默认 start() 返回最后一个任务的结果文本 .raw;传 return_dict=True 则返回 {task_status, task_results} 全量字典(agents/agents.py:1268-1287astart 尾部逻辑)。

一句话: AgentTeam 只做「叫号 + 收尾」,Process 决定「叫号顺序」,真正的智力活全在 Agent.chat 里。三种 Process 的差异(顺序接力 / 经理审校 / 按 next_tasks 走任务图)在 04 展开。


4. 阅读地图(建议顺序)

先读本章 → 再按下面顺序。 前三章打「单体」地基,后三章讲「编排与外围」。

讲什么什么时候读
01 Agent 单体与 chat 主循环一个 Agent 如何把 指令+工具+记忆+LLM 变成一次回答;start/run/chat 的区别必读地基,一切的原子
02 工具系统与 MCP@tool 怎么定义、注册表怎么找、MCP(stdio/HTTP/WS/SSE)怎么安全接外部工具想让 Agent「动手」时
03 LLM 层原生 OpenAI 快路径 vs LiteLLM 多 provider 路径,失败如何容错/failover关心多模型、成本、稳定性时
04 多智能体编排Task 数据模型、AgentTeam、以及 sequential / hierarchical / workflow 三种 Process要组队、要任务依赖图时
05 AgentFlow 确定性工作流步骤写死的流水线,route/parallel/loop/repeat 与条件系统可复现的流程而非自由发挥时
06 记忆、知识与可靠性Memory、Knowledge(RAG)、Guardrails、Session、Telemetry 等外围要让 Agent 记事/查资料/受约束时

两种读者的捷径:

  • 只想跑个 demo → 读 01 + 02 就够动手。
  • 想搞懂架构取舍 → 01 → 04 → 05(对比两条编排范式)是主干。

5. 巧妙之处速览(细节交给后续章)

每条只点「妙在哪」,深挖见对应章:

  • 一张表统治所有导入。 _LAZY_IMPORTS 是「单一事实来源」,新增导出只改一处字典;__getattr__ + 线程安全缓存让近 60 个重子包按需加载(__init__.py:116_lazy.py:164)。→ 本章 §2.3

  • 改名不破坏旧代码的「静默别名」。 v1.0 把 AgentManagerAgentTeamWorkflowAgentFlow,但旧名全部保留为别名:AgentManager = AgentTeamAgents = AgentTeamPraisonAIAgents = AgentTeam(agents/agents.py:3188-3190);Agents 甚至走 _custom_handler 触发弃用警告(__init__.py:657-661)。

  • 一个「特征参数」既能传 bool 又能传 Config。 AgentTeam/AgentFlowmemory/planning/guardrails 等参数统一走「实例 > Config > 字符串 > Bool > 默认」的优先级解析,memory=Truememory=MultiAgentMemoryConfig(...) 都合法(agents/agents.py:593-605workflows/workflows.py:600-621)。→ 见 04/05

  • 两条编排范式共享同一批底层。 团队(自由叫号)和流水线(步骤写死)最终都落到同一个 Task/Agent/LLM 栈,只是「谁决定顺序」不同——这让确定性与灵活性成为可切换的两档,而非两套代码。→ §2.1

  • provider 感知的默认模型。 没显式指定模型时,按环境里存在哪个 API key 挑默认模型(OpenAI→gpt-4o-mini,Anthropic→claude-3-5-sonnet …),而非硬写死一个必然报错的默认(agent/agent.py:267-287 _PROVIDER_DEFAULT_MODELS / _resolve_default_model)。


6. 顶层代码地图(导航索引)

一张跳转表——按符号名 grep 比按行号更抗漂移。路径相对 src/praisonai-agents/praisonaiagents/

主题文件路径符号名
包入口 / 惰性加载映射__init__.py_LAZY_IMPORTS__getattr___custom_handlerwarmup
惰性加载工厂_lazy.pylazy_importcreate_lazy_getattr_with_fallback
Agent 单体agent/agent.pyAgent(行 219)
Agent 交互入口agent/execution_mixin.pyagent/chat_mixin.pystart(行 576)、chat(行 1910)
工作单元task/task.pyTask(行 21)
编排器 A:团队agents/agents.pyAgentTeam(行 554)、start(行 1462)、astart(行 1248)、run_all_tasks(行 1416)
团队别名agents/agents.pyAgentManager / Agents / PraisonAIAgents(行 3188-3190)
叫号执行process/process.pyProcess(行 20)、sequential(行 1508)、hierarchical(行 1526)、workflow(行 1096)
编排器 B:流水线workflows/workflows.pyAgentFlow(行 555)、run(行 998)、arun(行 1537)
流水线导出/别名workflows/__init__.pyAgentFlow / Workflow / Pipeline
工具 / MCPtools/decorator.pymcp/mcp.pytoolMCP
单一定位:改名总账__init__.py__all__(行 817-866,列出 v1.0 主名与静默别名)
⚠ 愿景文档(非现状)仓库根 ARCHITECTURE.md第 8 节 Implementation Roadmap(行 379-397,多为 Planned)