附录 E · 从 LangChain / AutoGen / CrewAI 迁移
如果你已经在其他框架上建过 agent,Agentao 的心智模型大部分会让你觉得"眼熟",但有几处承重点非常不同。本附录就是那本对照字典。
E.1 一页心智对照表
| 概念 | LangChain | AutoGen | CrewAI | Agentao |
|---|---|---|---|---|
| Agent 单元 | AgentExecutor(+ chain / graph) | ConversableAgent | Agent 角色 | Agentao 实例 |
| 工具 | BaseTool | 带 docstring 的函数 | tool 装饰器 | Tool ABC |
| 多 agent | LangGraph | GroupChat | Crew | 再起一个 Agentao 或 ACP 反向调另一个 |
| 记忆 | ConversationBufferMemory / 向量库 | agent 上的 memory | agent 上的 memory | MemoryManager(SQLite,项目+用户) |
| 流式 | callback / LCEL astream | register_hook | event hook | Transport + AgentEvent |
| 工具审批 | 用 interrupt 的 HITL | a_human_input_mode | human_input=True | Transport.confirm_tool |
| 外部模型上下文 | MCP 适配器 | function calling | 无 | 一等 MCP(stdio + SSE) |
| 宿主进程隔离 | 无(进程内) | 无(进程内) | 无(进程内) | ACP(子进程) |
E.2 从 LangChain 迁移
一致的部分
- 工具——样板几乎一样。LC 的
BaseTool.name/description/args_schema/_run与 Agentao 的Tool.name/description/parameters/execute一一对应 - 回调式流式——LC 的 callback handler 和 Agentao 的
Transport.emit(AgentEvent)目的相同 - 提示词拼装——LC 的 system prompt 片段 → Agentao 的
AGENTAO.md+ 技能
不同的部分
- 没有 LCEL / 图 —— Agentao 是一条执行回路,不是可组合流水线。如果你建了 chain DAG,先塌平成"一条系统提示 + 工具"。分支逻辑交给 LLM,而非框架
- 检索器不能当工具硬塞 —— 包一个薄的自定义工具,在
execute()里调你现成的.get_relevant_documents() - 记忆不是向量库 —— Agentao 的记忆是结构化键值 SQLite。如果你依赖向量召回,留着向量库——把它以 MCP 服务器或自定义工具暴露出来,让 LLM 去调
- 默认跑很久 —— LC 有
max_iterations;Agentao 也有(chat(max_iterations=))默认 100。为控本请调低
迁移食谱
- 先移工具。
_run(self, **kw)→execute(self, **kw);args_schemaPydantic →parametersJSON Schema(或用pydantic.TypeAdapter生成) - 提示词文本放
AGENTAO.md+ 技能文件。每请求的动态上下文仍放在用户消息里 AgentExecutor(..., memory=ConversationBufferMemory())换成Agentao(...);历史自动存在agent.messages- 接流式:callback handler 换成
SdkTransport(on_event=…) - RAG:向量库以 MCP 服务器或
Tool子类暴露
E.3 从 AutoGen 迁移
一致的部分
- 对话循环 —— AG 的"agent 说话,工具被调,结果返回"与 Agentao 的内循环一致
- 异步友好 —— 两者都能在
asyncio.to_thread/ 事件循环下工作
不同的部分
- 没有
GroupChat—— AG 的强项是多 agent 编排。Agentao 支持子 agent(一个Agentao启另一个,或 ACP 反向调不同服务器),但没有内置的"群聊管理"。多角色场景请模型化为"技能 + 单 agent",或自建协调器 - 工具调用仅 OpenAI 风格 —— AG 支持多家 LLM,格式各异;Agentao 统一到 OpenAI 兼容的 tool-call schema。非 OpenAI 家也得说这个格式
- 人类介入 —— AG 的
human_input_mode≈Transport.confirm_tool+Transport.ask_user - 没有
UserProxyAgent—— 用户在循环之外,通过chat()调用与 agent 通信。宿主代码就是"用户代理"
迁移食谱
- 找 AG 里最"自主"的那个 agent——它就是你的
Agentao - 其他
ConversableAgent折叠成:无状态 → 工具;塑造行为 → 技能 GroupChat管理器变成你的宿主代码(FastAPI 接口、调度循环),决定何时调agent.chat()register_function调用迁到Tool子类
E.4 从 CrewAI 迁移
一致的部分
- role / goal / backstory —— CrewAI 每 agent 的
role+goal+backstory→ Agentao 的AGENTAO.md+ 激活的技能 - 工具是独立单元 —— CrewAI
@tool≈ AgentaoTool子类
不同的部分
- 没有
Crew编排器 —— CrewAI 的显式tasks/process管线与 Agentao 风格相反。Agentao 里由 LLM 根据"工具 + 技能 + 用户消息"决定下一步。多步工作流放提示里或放宿主侧循环,不放框架配置 - 层级 vs 扁平 —— CrewAI 的
Process.hierarchical/sequential变成"一个超级 agent + 技能"或宿主侧编排 - 没有管理器 agent 抽象 —— 有的话,把它重塑成宿主代码,多次以不同提示调
agent.chat()
迁移食谱
- 挑最有用的 CrewAI agent——连带工具先移过来
Process.sequential:写一个宿主侧函数调agent.chat("step 1 …"),检查输出,再agent.chat("step 2 …")Process.hierarchical:管理器变宿主代码;worker agent 变成额外Agentao实例(隔离)或技能(仅改语气/思路时)- 移工具
memory=True换成MemoryManager(见 5.5)
E.5 决策矩阵——要不要迁
不要迁如果:
- 你重度依赖 LangGraph DAG(留 LC)或 AutoGen 的 group chat(留 AG)
- RAG 管道很深且不愿包装成 MCP
- 只要 Python 进程内,跨语言不是目标,并且老框架上运维已经成熟
想迁如果:
- 你需要可嵌入(Python SDK + 非 Python 宿主用 ACP)
- 你需要严格沙箱 + 权限(见 Part 6)
- 你需要一等 MCP 和一个小而可审的内核
- 你想要确定性生命周期(
chat()→close())而非长生命周期链
E.6 平滑迁移的模式
| 模式 | LC / AG / CrewAI | Agentao |
|---|---|---|
| "调我们 API 的工具" | BaseTool | Tool 子类 |
| "把公司政策注入提示" | system message | AGENTAO.md |
| "任务特定行为切换" | 系统提示分支 | 技能(按需激活) |
| "写操作需人审" | HITL 回调 | Transport.confirm_tool |
| "按用户区分的对话记忆" | 按用户的 ConversationBufferMemory | 按用户的 working_directory → 项目作用域记忆 |
| "文档 RAG" | retriever 工具 | MCP filesystem / 自定义 retriever 工具 |
| "取消进行中的轮" | LCEL abort / AG cancel | CancellationToken |
E.7 Headless 运行时——nonInteractivePolicy 形态变更(Week 3)
Week 3 之前的裸字符串形式不再接受。AcpClientConfig.from_dict / load_acp_client_config 在配置加载阶段直接抛 AcpConfigError——不会拖到 send_prompt 阶段才炸。
之前:
json
{
"servers": {
"my-server": {
"command": "…",
"args": [],
"env": {},
"cwd": ".",
"nonInteractivePolicy": "reject_all"
}
}
}之后:
json
{
"servers": {
"my-server": {
"command": "…",
"args": [],
"env": {},
"cwd": ".",
"nonInteractivePolicy": { "mode": "reject_all" }
}
}
}要点:
- 可以直接删掉
nonInteractivePolicy,默认等价于{"mode": "reject_all"} - 仅想针对某次调用覆盖默认值时,不要改配置,直接用
ACPManager.send_prompt/ACPManager.prompt_once的interaction_policy=kwarg。见 3.4 反向 ACP 调用 - 不提供静默兼容。如果需要批量迁移老配置,脚本里先用
AcpClientConfig.from_dictdry-run,捕获AcpConfigError,再把报错的 server 显式改写
E.8 迁移时的常见坑
- 过度抽象 —— 不需要 DAG,信 LLM + 工具
- 低估工具描述的重要性 —— Agentao 没有思维链脚手架;工具描述和 AGENTAO.md 就是行为计划,要写厚
- 把用户和项目记忆混用 —— 默认就是租户隔离(见 6.4);user 作用域仅限单用户场景
- 不开确认 —— 其他框架常常默认"什么都问"。Agentao 让你白名单——请在审过工具的爆炸半径之后再白名单
E.9 从 0.2.x 迁移到 0.3.0
working_directory= 现在是必填关键字参数。0.2.16 在省略该参数时发出的 DeprecationWarning 已被替换为构造时直接抛出的 TypeError——不再有 Path.cwd() 懒惰回退。
方案一——传入显式 Path(最简单)
python
from pathlib import Path
from agentao import Agentao
agent = Agentao(working_directory=Path("/srv/agent-workdir"), ...)绝大多数调用点只需这一处修改。传入前先解析为绝对路径,冻结值才始终可预期。
方案二——用 build_from_environment() 进行 CLI 式自动发现
python
from pathlib import Path
from agentao.embedding import build_from_environment
agent = build_from_environment(working_directory=Path("/srv/agent-workdir"))build_from_environment 会读取 .env、发现 .agentao/ 配置文件,并连接完整的 CLI 等价默认值(用户级记忆、MCP 文件配置、沙箱、回放)。显式传入 working_directory=;若省略,工厂回退到 Path.cwd()——CLI 入口点可接受,嵌入式宿主不应依赖此行为。
方案三——曾测试懒惰 cwd 默认行为的测试
在 0.2.x 中,有意不传 working_directory= 的测试会用以下方式压制警告:
python
import warnings
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
agent = Agentao(...) # 懒惰 cwd 行为在 0.3.0 中,相同的调用会抛 TypeError。将这些测试改为:
- 传入
working_directory=tmp_path(标准修法——当前测试套件的tests/test_per_session_cwd.py::_make_agent即采用此方式)。 - 若测试本身就是为了验证无参形式被拒绝,改用
pytest.raises(TypeError)断言硬中断。
本地检查命令
bash
pytest -W error::DeprecationWarning tests/此命令将所有 DeprecationWarning 转为测试失败,在 0.3.0 静默破坏之前暴露仍在发出 0.2.x 警告的调用点。
附录至此结束。