第23章:框架选型决策
上一章走了一遍 LangGraph、CrewAI、OpenAI Agents SDK 和几个轻量方案。都很有意思,都能用。但当你真的要做决定的时候——"这个项目用什么框架"——那些功能对比表帮不上太多忙。
因为选框架不是选功能最多的,是选最符合你当前约束的。
这一章的目标是给你一套可操作的决策框架:哪些维度重要、哪些可以忽略、什么时候该选什么、什么时候该自己写。最后的结论会是直接的,不会"各有优劣"地和稀泥。
23.1 选型的真实维度
网上的框架对比通常有两个问题:维度选错了,或者维度没有权重。
"支持哪些模型"这个维度很容易被高估。很多框架都可以通过模型适配器、OpenAI-compatible endpoint 或 LiteLLM 之类的桥接层接入多家模型,但高级能力未必可移植:托管工具、沙箱、内置 tracing、reasoning 配置、结构化输出、文件处理和缓存策略,往往仍然绑定某个模型或平台生态。真正影响选型的是以下七个维度,按实际权重排序:
维度一:控制粒度
控制粒度是最核心的维度,决定了你的系统在面对复杂需求时能不能撑得住。
低控制粒度(CrewAI 的 Process.sequential):你定义 Agent 和任务,框架决定怎么调度。快,但如果你需要"第三步根据第二步的某个字段走不同路径",你就卡住了。
高控制粒度(LangGraph 的条件边):你精确描述每个状态转移,框架只是执行引擎。慢,但能把大多数复杂流程逻辑落到显式代码里。
判断方式:把你的任务画成流程图。如果流程图里有多于一个菱形(判断节点),并且判断依据来自运行时状态,你需要高控制粒度。如果流程是线性的或者分支逻辑固定,低控制粒度足够了。
维度二:生产就绪度
生产就绪度不等于"功能多不多",等于"它在生产里能不能可靠运行"。具体体现在:
- 状态持久化:进程崩溃后能不能恢复
- 错误处理:工具失败、模型超时,系统怎么响应
- 并发安全:多个请求同时打进来会不会出问题
- 版本稳定:API 是否频繁破坏性变更
不要把"生产就绪度"理解成一个全局排行榜。更实用的判断是:框架是否已经在你的部署形态、权限模型、并发规模、可观测栈和失败恢复策略里验证过。比如 LangGraph 在状态持久化和 human-in-the-loop 上更成熟;OpenAI Agents SDK 在 handoff、guardrails、tracing、sandbox 等 OpenAI 生态能力上更顺手;CrewAI 的 Flows 已经让状态编排比早期 Crew 更清晰,但仍要用真实任务验证恢复、日志和并发边界;smolagents 更适合原型和研究,生产化通常需要自己补运行时、安全和观测。
判断方式:不要只看 GitHub Star。至少看四件事:最近三个月 changelog 是否有 breaking change;issue 里 production、concurrency、memory、timeout、crash 类问题的处理质量;官方是否有版本迁移指南;你的 PoC 是否跑过重试、超时、并发、恢复和权限失败场景。
维度三:学习曲线
学习曲线影响的是团队从零到第一个可运行 Agent 的时间,以及维护成本。
大致可以按 smolagents → CrewAI → OpenAI Agents SDK → LangGraph → 自建 理解学习曲线递增。Microsoft / Google 这类平台型框架的学习成本还取决于团队对 Azure、GCP、身份权限和部署体系的熟悉程度。
但这里有个反直觉的地方:入门快的框架,有时候在遇到复杂需求时会让你花更多时间。因为当你试图超出框架的设计边界时,你需要先理解框架的实现原理才能绕过它,而这比直接学更底层的框架还难。
CrewAI 的 verbose=True 输出的 Agent 对话,初学时能帮你理解发生了什么;但在生产里你需要解析这些日志做监控,而它们的格式是为人类可读设计的,不是为机器解析设计的。这时你要么接受局限,要么自己写日志拦截器。
判断方式:把学习曲线分成两段——"入门到 Hello World"和"Hello World 到生产"。只看第一段会误导选型。
维度四:Multi-Agent 能力
Multi-Agent 能力不是"支不支持多个 Agent",所有框架都支持。真正的差异在于:
- 控制权模型:子 Agent 是工具调用还是状态转移(OpenAI SDK 的 Handoff vs. Agents as Tools 是两种不同模型)
- 上下文隔离:不同 Agent 的上下文是完全独立还是共享的
- 异步协作:Agent A 在等 Agent B 的结果时能不能同时做其他事情
如果你的系统只需要"一个 Agent 路由到另一个 Agent",这个维度大家差不多。如果你需要复杂的层级编排(管理者 → 多个专家 → 每个专家下面还有子 Agent),LangGraph 的图结构比其他框架更自然。
维度五:可观测性集成
这个维度很多人选型时忽略,但在生产里是最高频的需求。Agent 失败时,你能不能回溯它的每一步决策?
| 框架 | 常见观测路径 | 选型时要验证 |
|---|---|---|
| LangGraph | LangSmith / OpenTelemetry | trace 是否覆盖节点状态、checkpoint、interrupt/resume |
| CrewAI | CrewAI 日志 / AgentOps / Langfuse 等集成 | trace 是否能稳定映射到 Flow、Task、Agent 和工具调用 |
| OpenAI Agents SDK | 内置 tracing / 自定义 processor / 第三方后端 | 是否能导出到现有 OTel、SIEM 或数据仓库 |
| Google ADK | Google Cloud 观测栈 | 是否满足跨云或自托管场景 |
| Microsoft Agent Framework | Azure / OpenTelemetry | 是否能接入企业已有审计、应用监控和合规日志 |
| Claude Agent SDK | 工具轨迹 / diff / 命令输出摘要 / 外部日志 | 是否能记录代码变更、权限确认和执行环境 |
| smolagents | 自行埋点 / OpenTelemetry | 是否能补齐 step、tool、sandbox、cost 级别日志 |
如果你的系统是多个框架混用,推荐用 OpenTelemetry(OTel)做统一的可观测层,不要依赖框架原生集成(第17章有详细讨论)。
维度六:Token 效率
框架本身不会消耗 Token,但框架的设计会影响你的 prompt 有多冗余。
CrewAI 的 backstory 字段是 System Prompt 的一部分——一个 200 token 的背景故事,在每次 LLM 调用时都会消耗这 200 个 token。如果你有 5 个 Agent,每个 Agent 平均被调用 10 次,就是 50 次调用 × 200 token = 10,000 个额外 input token。实际成本还要乘以模型价格、重试次数和缓存命中率。
LangGraph 的状态对象会随着执行积累,如果你没有做 state compaction,上下文会越来越长。
OpenAI Agents SDK 的 Session 机制会保留跨轮次对话历史;如果不做裁剪、摘要或外部记忆分层,长会话会持续推高输入 token。
这些不是设计缺陷,但你需要知道它们的存在,才能在设计时主动控制成本。
判断方式:在选型阶段做一次成本估算。用目标框架跑一个代表性任务,统计 input/output token 用量,乘以预期 QPS,算出月均成本。
维度七:生态与供应商依赖
生态影响两件事:工具的丰富程度(有没有现成的 MCP Server、集成插件),以及供应商绑定风险。
OpenAI Agents SDK 可以通过 LiteLLM / 自定义 model provider 接入非 OpenAI 模型 [5],但 Sandbox Agent、OpenAI 托管工具、Responses API 特性和默认 tracing 等高级能力并不等价迁移。如果哪天你需要切换到 Anthropic、Google 或本地模型,要逐项验证工具调用格式、usage 统计、trace、结构化输出和错误语义。
LangGraph 理论上模型无关,但 LangSmith 是 LangChain 的商业产品。如果你深度依赖 LangSmith 做可观测,替换框架时这部分也要一起换。
这里没有绝对的对错,只有风险是否在你的可接受范围内。
把这七个维度整理成对比表,方便对照(截至 2026.05,具体能力以当时版本 PoC 为准):
| 维度 | LangGraph | CrewAI | OpenAI Agents SDK | Google ADK | Microsoft Agent Framework | Claude Agent SDK | smolagents |
|---|---|---|---|---|---|---|---|
| 控制粒度 | 极高(节点 + 边精确控制) | 中(Flow / Task) | 中高(Handoff + Agent as Tool) | 中高(LLM Agent + Workflow Agent) | 中高(Agent + Workflow) | 中(代码任务循环) | 低到中(代码优先) |
| 生产化重点 | Checkpoint / replay / HITL | Flow 状态、企业版能力 | Tracing / Guardrails / Sandbox | GCP / Gemini 集成 | Azure / .NET / 企业集成 | 工程 workspace、权限、审计 | 自补 runtime / sandbox |
| 学习曲线 | 陡峭 | 平缓 | 平缓偏中 | 中等 | 中等 | 中等 | 平缓 |
| Multi-Agent 能力 | 强(图式编排) | 中(角色协作) | 强(Handoff 模型) | 强(A2A 生态方向) | 强(workflow + provider 集成) | 偏代码 Agent | 基础 |
| 可观测性 | LangSmith / OTel | 日志 / 第三方 / Enterprise | 内置 tracing + processor | Google Cloud | Azure / OTel | 工具轨迹 + 外部日志 | 需自建 |
| Token 效率 | 需主动管理 State | backstory / task context 有开销 | Session 需裁剪 | 需主动管理 | 需主动管理 | 长代码上下文需压缩 | 轻量但需控代码输出 |
| 生态依赖 | LangChain 生态 | CrewAI 生态 | OpenAI 生态 | Google Cloud / Gemini | Microsoft / Azure | Anthropic / Claude Code | HuggingFace |
用评估结果做最终决策
框架选型最终应该落到数据,而不是口味。建议给每个候选框架做同一个 1-2 周 PoC,并记录这些指标:
| 指标 | 为什么重要 | 怎么测 |
|---|---|---|
| 任务成功率 | 证明框架能否承载真实业务 | 用第18章的 regression eval 跑 30-100 个代表性任务 |
| 失败可诊断性 | 生产事故时能否定位根因 | 随机抽 10 个失败 trace,看能否定位到模型、工具、状态或权限问题 |
| 人工介入成本 | 决定运营负担 | 统计需要审批/转人工/重跑的比例 |
| 单任务成本 | 决定 unit economics | 按 input/output/reasoning token、工具费用、沙箱费用拆分 |
| 延迟分布 | 决定用户体验 | 记录 p50/p95/p99,不只看平均值 |
| 权限与审计 | 决定能否上线 | 检查工具调用是否带 user/tenant scope,日志是否脱敏且可追溯 |
一个框架在 demo 里"看起来聪明"没有意义;它必须在你的失败样本、权限边界和成本约束下仍然可控。
23.2 选型决策树
维度有了,怎么用?实际选型的时候,不是每个维度都同等重要——不同场景下,不同维度的权重差异巨大。
以下是一个基于场景驱动的决策树:
快速原型 / POC 的选法
快速原型阶段,目标是用最少的代码跑通核心流程,验证想法是否可行。
优先顺序:模型厂商官方 SDK / OpenAI Agents SDK / smolagents → CrewAI → LangGraph。代码库操作类任务可以把 Claude Agent SDK、OpenAI Sandbox Agent 或 smolagents + 沙箱放到第一梯队。
smolagents 适合你只需要一个能调工具的 Agent,不需要 Multi-Agent 协作:
from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel
# 5 行就能跑起来一个带搜索能力的 Agent
model = InferenceClientModel(model_id="Qwen/Qwen2.5-72B-Instruct")
agent = CodeAgent(
tools=[DuckDuckGoSearchTool()],
model=model,
)
result = agent.run("比较 LangGraph、CrewAI、OpenAI Agents SDK 的适用场景")CrewAI 适合你需要快速验证多个角色分工的协作模式:
from crewai import Agent, Task, Crew, Process
# 15 分钟内跑出一个研究 + 写作的两 Agent 流水线
researcher = Agent(role="研究员", goal="深入研究 {topic}", backstory="经验丰富的研究者")
writer = Agent(role="作家", goal="把研究变成文章", backstory="技术写作专家")
task1 = Task(description="研究 {topic}", expected_output="关键发现列表", agent=researcher)
task2 = Task(description="写 1000 字文章", expected_output="Markdown 文章", agent=writer, context=[task1])
Crew(agents=[researcher, writer], tasks=[task1, task2], process=Process.sequential).kickoff(
inputs={"topic": "AI Agent 框架对比"}
)一个重要判断:原型跑通之后,问自己一个问题——"这个框架能撑到生产吗?"如果答案是不确定,现在就开始做迁移计划,不要等到系统复杂了再迁。
需要精细状态控制的选法
如果你的任务流程有以下任一特征,就需要高控制粒度:
- 根据上一步结果动态决定走哪条路
- 需要在任意步骤暂停等待人工审批
- 长任务需要可靠的中断恢复(进程崩溃后从断点继续)
- 需要在循环里执行某个节点直到满足条件
这些场景,优先评估 LangGraph。不是因为 LangGraph 最强,而是这些场景需要精确的状态图语义。Microsoft Agent Framework、Google ADK 这类 workflow-first 平台也能覆盖一部分需求,但如果你想在 Python 里精细控制状态、checkpoint、interrupt 和 replay,LangGraph 仍是最直接的候选。
一个常见误区是用 CrewAI 的 Hierarchical Process + Manager Agent 来模拟复杂流控。这能用,但你会发现自己在 backstory 里写了很多"你应该在第二步之后判断..."——这是在用 prompt 模拟流程控制,结果是不确定性比代码控制高很多。
需要绑定企业平台的选法
如果你的组织已经深度使用某个云平台,选对应的官方方案通常是阻力最小的路。
Azure / Microsoft 生态:优先评估 Microsoft Agent Framework、Azure AI Foundry Agent Service、Copilot Studio [9]。Semantic Kernel 仍然有价值,但新 Agent 项目不应只把它当作默认答案;要看你的场景更偏工作流编排、M365 / Copilot 集成,还是应用内 SDK。
Google Cloud / Vertex AI:Google ADK。除了 Google 服务集成,ADK 对 A2A 协议和 workflow agent 的支持让它在多 Agent 互操作场景下有优势。但 ADK 版本演进较快,生产项目前要核验当前版本的兼容性、权限、审计和部署边界。
AWS / Bedrock:Strands Agents SDK、Bedrock Agents、Bedrock AgentCore 都值得评估 [10][11]。Strands 是 AWS 开源的 Agent SDK,适合代码优先的 Agent 开发;Bedrock Agents / AgentCore 更偏平台托管能力。不要只因为在 AWS 上就自动选一个框架,要看你要的是 SDK 灵活性、托管运行时,还是企业级治理能力。
绑定特定模型:如果你的组织已经决定只用某一家模型(典型场景:安全合规要求),先评估该模型厂商的官方 SDK,因为它对该模型的功能覆盖和更新响应速度最快。必要时再在 SDK 上层做一层抽象,为将来可能的切换预留空间。
一个具体案例
为了让决策树更具体,来看一个真实场景:你要为一个 SaaS 产品构建客服 Agent,需求是:
- 能回答知识库问题(RAG)
- 能查询订单状态(调用内部 API)
- 复杂问题转人工
- 运行在公司的 Azure 上
- 团队 5 人,都会 Python,没有 Agent 开发经验
决策过程:
- 控制粒度:流程相对固定(分类 → 路由 → 专业处理 → 可选转人工),没有复杂循环。中等控制粒度即可。
- 企业平台:Azure。
- 生产就绪度:对外产品,需要可靠。
- 团队经验:从零开始,学习曲线不能太陡。
结论:先做两个小 PoC,而不是直接押一个框架。
- 如果组织更重视 Azure / M365 / Copilot Studio / 企业审计集成,优先评估 Microsoft Agent Framework 或 Copilot Studio。
- 如果核心流程只是"分诊 → 专家 Agent → 工具调用 → 必要时转人工",且团队希望用 Python 快速交付,可以评估 OpenAI Agents SDK;但要验证 Azure OpenAI / OpenAI-hosted 模型接入方式、trace 出口、数据驻留和工具权限边界。
这个案例里,不建议一开始就上 LangGraph:团队没有图式编排经验,而需求复杂度暂时不需要这个控制粒度。CrewAI 可以做研究/内容类协作原型,但客服分诊更像控制权转移,不是角色共创。
最终选择哪个,要看 PoC 的三项结果:真实工单成功率、失败时可解释性、权限/审计是否满足公司要求。
23.3 Anthropic 的建议:先理解底层,再引入框架
在所有框架选型建议里,Anthropic 的这一条是我认为最容易被忽视的:先用原生 LLM API 理解底层机制;如果使用框架,也要知道框架内部到底替你做了什么 [1]。
这不是叫你不用框架。它是说:在你选定框架之前,先用原生 API 实现同样的功能,哪怕只是一个简化版。
为什么?
用原生 API 实现一个带工具调用的 Agent,大概需要写这些代码:
- 工具注册(一个字典)
- 消息历史管理(一个列表,追加每次对话)
- LLM 调用循环(while 循环,直到 stop_reason 是 "end_turn" 或工具调用为空)
- 工具派发(根据工具名调用对应函数)
- 结果注入(把工具结果追加回消息历史)
总计大约 50-80 行 Python,不依赖任何框架。写完这段代码,你会明白框架在帮你做什么:它帮你省掉了这 50-80 行样板代码,并且加了状态管理、错误处理、日志等附加能力。
明白了这一点,你对框架的 "magic" 就有了健康的态度——知道它帮你省了什么,也知道当它出问题时该去哪里找根因。
第25章有完整的原生 API 实现走读,包括工具调用、记忆管理、流式输出和基础持久化。如果你还没读过那一章,建议选型之前先读一遍。
很多团队踩坑不是因为框架不好,而是跳过了"原生 API 版本"这一步:还没弄清楚工具调用、消息历史、状态恢复和错误重试的基本语义,就把问题交给框架。结果一旦行为不符合预期,只能在框架抽象里猜。更稳的做法是先写一个 50-80 行的最小 Agent loop,再引入框架;这样你知道框架带来的净收益,也知道它引入了哪些额外复杂度。
23.4 务实路径:四个阶段,每个阶段的正确选择
把整个 Agent 项目生命周期分成四个阶段,每个阶段对应不同的工具选择。
阶段一:原生 API,理解底层(1-3 天)
目标:在你的任务上,用原生 LLM API(OpenAI 或 Anthropic)跑通最简单的 Agent 循环。不追求功能完整,追求理解机制。
应该看到的结果:
- 你知道工具调用是一个什么格式的消息,LLM 是怎么决定调哪个工具的
- 你知道多轮对话的消息历史是什么结构
- 你能解释为什么
stop_reason == "tool_use"时要继续循环
不要做的事:在这个阶段追加功能,比如加记忆、加 Guardrails。这个阶段的目标是理解,不是构建。
import anthropic
import json
client = anthropic.Anthropic()
# 定义工具
tools = [
{
"name": "get_weather",
"description": "获取指定城市的当前天气",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"}
},
"required": ["city"]
}
}
]
# 工具实现(真实项目里调用天气 API)
def get_weather(city: str) -> str:
return f"{city}:晴天,25°C,湿度 60%"
# Agent 核心循环(原生实现,约 30 行)
def run_agent(user_message: str) -> str:
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="<your-claude-model>",
max_tokens=1024,
tools=tools,
messages=messages,
)
# 收集文本输出
text_output = ""
tool_calls = []
for block in response.content:
if block.type == "text":
text_output += block.text
elif block.type == "tool_use":
tool_calls.append(block)
# 没有工具调用,对话结束
if response.stop_reason == "end_turn" or not tool_calls:
return text_output
# 把 LLM 的回应追加到消息历史
messages.append({"role": "assistant", "content": response.content})
# 执行工具,把结果追加到消息历史
tool_results = []
for tool_call in tool_calls:
if tool_call.name == "get_weather":
result = get_weather(**tool_call.input)
else:
result = f"未知工具: {tool_call.name}"
tool_results.append({
"type": "tool_result",
"tool_use_id": tool_call.id,
"content": result
})
messages.append({"role": "user", "content": tool_results})
# 继续循环,让 LLM 基于工具结果继续推理
result = run_agent("北京今天天气怎么样?适合出去跑步吗?")
print(result)这 40 行代码里,框架帮你封装了什么,现在你清楚了。
阶段二:轻量框架,验证想法(1-2 周)
目标:在阶段一理解底层的基础上,用轻量框架快速验证业务想法。这个阶段允许技术债,允许"先跑起来再说"。
框架选择:看你的场景:
- 单 Agent + 工具:模型厂商原生 API、OpenAI Agents SDK 或 smolagents
- 多 Agent 路由:OpenAI Agents SDK,或用 LangGraph 显式表达路由状态
- 角色协作流水线:CrewAI
- 代码库操作:Claude Agent SDK [12]、OpenAI Sandbox Agent,或 smolagents + 隔离沙箱
什么时候升级到阶段三的信号:
- 你开始用 prompt 模拟流程控制("你应该先做 A,再判断是否做 B...")
- 状态管理开始变得混乱(多个工具返回的结果怎么传递)
- 你需要可靠的错误恢复,但框架不支持
阶段三:状态图 / Runtime 精细化(按需进入)
目标:当阶段二的框架开始成为瓶颈时,迁移到有精确状态控制能力的方案。
典型迁移信号:
- 需要在某个节点后根据结果走不同路径(复杂条件路由)
- 需要支持人工审批的暂停/恢复
- 长任务需要进程崩溃后从断点恢复
- 需要对 Token 消耗做精细控制
迁移策略:不要一次性重写。先把最复杂的子流程用 LangGraph 实现,保持其他部分不变,然后逐步迁移。
一个值得注意的陷阱:很多团队在压力下把"迁移到 LangGraph"当成银弹。LangGraph 解决的是状态管理和流程控制的问题,不解决模型能力不够或工具设计不好的问题。在迁移之前确认问题真的属于前者。
阶段四:必要时自建(少数场景)
目标:当框架的抽象层带来的复杂度高于它解决的问题时,回到原生 API + 轻量封装。
判断标准:
- 你花在"绕过框架限制"上的时间,超过了框架帮你省的时间
- 框架引入了你不需要的依赖(比如一个 400MB 的包只是为了用它的消息循环)
- 你需要对运行时行为有精确的可预测性,框架的内部封装造成了太多不确定性
不应该自建的理由:
- "我能写得更好"(通常不是真的,尤其是边界情况的处理)
- "为了减少依赖"(管理自己的代码同样有维护成本)
- "框架更新太快"(自建一样要跟随 LLM API 的变化)
自建的合理场景:高性能需求(框架有不可接受的开销)、极端定制(框架的抽象层和你的业务逻辑不匹配到无法接受的程度)、技术积累(你的团队需要深度理解这一层)。
常见误区
误区一:框架越新越好
新框架意味着更少的社区经验,更多的未知边界条件。在生产里踩到新框架的 bug,你可能是第一个,也可能是少数几个,没有 Stack Overflow 答案,没有 GitHub issue 里的 workaround。
除非新框架解决了旧框架明确无法解决的问题,否则保守选择。
误区二:先选框架,后想需求
这是最常见的逆序决策。正确顺序是:明确任务边界 → 画出执行流程 → 确定控制粒度需求 → 根据约束选框架。反过来先选了 LangGraph,然后发现任务其实是个简单的线性流水线,不用图就能表达——这只是给自己增加了学习成本。
误区三:框架能覆盖所有问题
框架解决的是"怎么组织代码"的问题,不解决"Agent 行不行"的问题。工具设计得不好(描述模糊、参数冗余),用哪个框架结果都差。Context Engineering 做得不好,框架选得再精准也挽救不了。框架是最后才需要优化的地方,不是第一步。
误区四:一个项目只能用一个框架
可以混用,但要慎重。如果你的系统里有一个子模块需要 LangGraph 的精确控制,其他部分用 OpenAI Agents SDK,这是可以的——把 LangGraph 的子系统包装成 OpenAI Agents SDK 的一个工具调用就行。但混用会增加维护复杂度,确保这个决定是基于需求而不是"都学一下"。
误区五:选型是一次性决定
代码库的约束会变,团队规模会变,任务复杂度会变。在阶段二验证的时候,设计好抽象层,让框架选择不要散落在业务代码里。好的做法是:用一个专门的 agent_engine.py 或类似模块封装框架 API,业务代码只调用你的封装。这样换框架时,只需要替换这一个模块。
# 好的做法:封装框架 API
class AgentEngine:
"""Agent 执行引擎,隔离具体框架实现"""
def __init__(self, backend: str = "openai_sdk"):
if backend == "openai_sdk":
self._runner = OpenAIAgentRunner(...)
elif backend == "langgraph":
self._runner = LangGraphRunner(...)
# 统一接口,业务代码不感知 backend
async def run(self, task: str, context: dict) -> AgentResult:
return await self._runner.execute(task, context)
# 业务代码
engine = AgentEngine(backend="openai_sdk")
result = await engine.run("处理退款请求", {"order_id": "ORD-123"})
# 将来换框架,只改 backend 参数,业务代码不动面试高频题
问:你在项目中是如何选择 Agent 框架的?为什么没有选择自建?
参考答案框架:
- 描述约束:任务类型(线性流水线 vs 复杂状态图)、团队背景(有没有相关框架经验)、上线时间压力、平台要求(Azure / GCP / 自托管)
- 列出候选:比较至少两个框架,说明各自的适配度
- 说明决策依据:不是"哪个功能多",而是"哪个最符合这个场景的控制粒度需求和团队能力"
- 承认取舍:每个选择都有代价,能说出你接受了什么代价
自建问题的回答不是"不会自建",而是:
自建本质上是把框架的维护责任转移给自己。框架帮我处理了工具派发、消息历史管理、错误重试的边界情况——这些我当然可以自己写,但在当时的时间约束下,这不是最高价值的事情。选框架是接受现有轮子,自建是造新轮子,核心问题是:造这个轮子是否比用现有的给业务带来更多收益?在当时的判断是否。
加分点:能说清楚框架底层在做什么(证明你不是黑盒使用),能说出你遇到的框架限制和如何绕过或接受了它,能说出如果重来你是否会同样选择(有反思)。
问:项目中途发现框架选错了,你怎么处理?
这道题考察的是面对技术债务的判断力,不是考察你没选错。
回答要点:
- 先诊断,不要轻易重写:框架选错的表现是什么?是功能做不到,还是代码复杂度不可接受,还是性能问题?不同症状对应不同方案。
- 增量迁移,不要一次性重写:把最痛的部分用新框架实现,保持其他部分不变,验证新框架在真实需求下的表现。
- 建立抽象层防止再次发生:迁移完成后,把框架 API 封装在专门的模块里,防止下次又要全量改动。
问:LangGraph 和 CrewAI 的核心区别是什么?什么时候选哪个?
直接回答:
LangGraph 的核心模型是状态图——你描述状态如何流转,框架负责执行。适合需要精确流程控制的场景。
CrewAI 的核心模型是角色协作——你定义角色和任务,框架负责协调。适合有自然角色分工的任务,入门更快,控制粒度更低。
选 LangGraph:任务流程有复杂分支、循环、人工介入点,需要可靠的状态持久化。 选 CrewAI:任务有自然的"研究员 + 作家 + 编辑"类角色分工,需要快速原型,团队没有图论背景。
避免:用 CrewAI 的 Manager Agent + backstory 来模拟流程控制,这是用自然语言模拟代码逻辑,不可靠。
参考资料
[1] Building Effective Agents - Anthropic (https://www.anthropic.com/engineering/building-effective-agents)
[2] A Practical Guide to Building Agents - OpenAI (https://cdn.openai.com/business-guides-and-resources/a-practical-guide-to-building-agents.pdf)
[3] LangGraph 官方文档 (https://langchain-ai.github.io/langgraph/)
[4] CrewAI 官方文档 (https://docs.crewai.com/introduction)
[5] OpenAI Agents SDK 官方文档 (https://openai.github.io/openai-agents-python/)
[6] Google ADK 官方文档 (https://adk.dev/)
[7] Anthropic Python SDK 官方文档 (https://github.com/anthropics/anthropic-sdk-python)
[8] smolagents 官方文档 (https://huggingface.co/docs/smolagents/en/index)
[9] Microsoft Agent Framework 官方文档 (https://learn.microsoft.com/en-us/agent-framework/)
[10] Strands Agents 官方文档 (https://strandsagents.com/)
[11] Amazon Bedrock AgentCore 官方文档 (https://docs.aws.amazon.com/bedrock-agentcore/)
[12] Claude Agent SDK 官方文档 (https://code.claude.com/docs/en/agent-sdk)