数据截至 (上游 commit 92c146faa529)
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-105、README.md:250-257、workflows/workflows.py:572-579 的类 docstring。
一句话直觉: 把 Agent 想成一名员工,Task 是派给他的一张工单,AgentTeam 是把几名员工编成一个组、按流程叫号干活的组长。你写的是「组织架构」,框架负责「叫号执行」。
⚠ 一处必须先破的误解:仓库根目录的
ARCHITECTURE.md大量是「愿景/规划」,不是现状。 它开篇自称「Strategic architecture document」并覆盖一份 road map(ARCHITECTURE.md:5-7),第 9 节整张 Implementation Roadmap 把 Doctor Auto-Fix、Golden-Path CLI、Graph Studio 等一律标为 Planned(ARCHITECTURE.md:527-566),还提到 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.py | 02 |
| 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:170 create_lazy_getattr_with_fallback |
_custom_handler | 处理特例:Agents 是 AgentTeam 的别名、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-806的warmupdocstring)。
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 │
└────────────┘
分三步看,每步都有真实落点:
-
选执行器。
start()判断是否 TTY 决定是否打印 Rich 面板,然后走到run_all_tasks(),按self.process三选一:workflow()/sequential()/hierarchical(),每个都是Process上的生成器,yield出下一个该跑的task_id(agents/agents.py:1899-1915)。异步入口astart()对称地走arun_all_tasks()(agents/agents.py:1547,1440-1516)。 -
逐任务委派。 拿到
task_id后run_task()→execute_task(),后者把工单交给它归属的 Agent,最终落到Agent.chat(agent/chat_mixin.py:2891)——那里才是真正拼提示、调 LLM、解析工具调用的地方(详见 01)。 -
收尾取值。 默认
start()返回最后一个任务的结果文本.raw;传return_dict=True则返回{task_status, task_results}全量字典(agents/agents.py:1741-1764的astart尾部逻辑)。
一句话: 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:170)。→ 本章 §2.3 -
改名不破坏旧代码的「静默别名」。 v1.0 把
AgentManager→AgentTeam、Workflow→AgentFlow,但旧名全部保留为别名:AgentManager = AgentTeam、Agents = AgentTeam、PraisonAIAgents = AgentTeam(agents/agents.py:3845-3847);Agents甚至走_custom_handler触发弃用警告(__init__.py:657-661)。 -
一个「特征参数」既能传 bool 又能传 Config。
AgentTeam/AgentFlow的memory/planning/guardrails等参数统一走「实例 > Config > 字符串 > Bool > 默认」的优先级解析,memory=True和memory=MultiAgentMemoryConfig(...)都合法(agents/agents.py:660-681、workflows/workflows.py:619-657)。→ 见 04/05 -
两条编排范式共享同一批底层。 团队(自由叫号)和流水线(步骤写死)最终都落到同一个
Task/Agent/LLM栈,只是「谁决定顺序」不同——这让确定性与灵活性成为可切换的两档,而非两套代码。→ §2.1 -
provider 感知的默认模型。 没显式指定模型时,按环境里存在哪个 API key 挑默认模型(OpenAI→
gpt-4o-mini,Anthropic→claude-3-5-sonnet…),而非硬写死一个必然报错的默认(agent/agent.py:359-388_PROVIDER_DEFAULT_MODELS/_resolve_default_model)。
6. 顶层代码地图(导航索引)
一张跳转表——按符号名 grep 比按行号更抗漂移。路径相对 src/praisonai-agents/praisonaiagents/。
| 主题 | 文件路径 | 符号名 |
|---|---|---|
| 包入口 / 惰性加载映射 | __init__.py | _LAZY_IMPORTS、__getattr__、_custom_handler、warmup |
| 惰性加载工厂 | _lazy.py | lazy_import、create_lazy_getattr_with_fallback |
| Agent 单体 | agent/agent.py | Agent(行 219) |
| Agent 交互入口 | agent/execution_mixin.py、agent/chat_mixin.py | start(行 576)、chat(行 1910) |
| 工作单元 | task/task.py | Task(行 21) |
| 编排器 A:团队 | agents/agents.py | AgentTeam(行 554)、start(行 1462)、astart(行 1248)、run_all_tasks(行 1416) |
| 团队别名 | agents/agents.py | AgentManager / Agents / PraisonAIAgents(行 3188-3190) |
| 叫号执行 | process/process.py | Process(行 20)、sequential(行 1508)、hierarchical(行 1526)、workflow(行 1096) |
| 编排器 B:流水线 | workflows/workflows.py | AgentFlow(行 555)、run(行 998)、arun(行 1537) |
| 流水线导出/别名 | workflows/__init__.py | AgentFlow / Workflow / Pipeline |
| 工具 / MCP | tools/decorator.py、mcp/mcp.py | tool、MCP |
| 单一定位:改名总账 | __init__.py | __all__(行 817-866,列出 v1.0 主名与静默别名) |
| ⚠ 愿景文档(非现状) | 仓库根 ARCHITECTURE.md | 第 9 节 Implementation Roadmap(行 527-566,多为 Planned) |