我为什么又开始手写Agent框架了?从CrewAI和LangGraph的局限谈起

大家好呀,我是技术老金

文章首发到公众号:技术老金,每天分享AI架构与实践分享!

文章内容收录到个人网站,方便阅读:vkflow.com/


一、 引言:被"框架"困住的我们

嗨,大家好,我是技术老金。

最近,我发现自己陷入了一个有趣的困境。

当我想快速搭建一个多智能体(Multi-Agent)应用时,我首先想到了CrewAI。它就像一个精装修的公寓,角色、任务、流程都替你定义好了,拎包入住,很快就能跑起来。但只要我想稍微改动一下"房型",比如让两个Agent先碰个头,或者根据某个工具的执行结果,动态决定下一步谁来接手,我就会发现自己被困在了这精美的"枷锁"里,动弹不得。

于是,我转向了LangGraph。它就像一个堆满了顶级建材(节点、边、状态)的"毛坯房",给了我无限的自由。我可以随心所-欲地设计任何我想要的流程,循环、分支、判断,无所不能。但很快,新的问题来了:我发现我不仅要设计流程,还要亲自设计状态管理、消息传递、工具调用、错误处理......我需要从零开始,为这个毛坯房设计一整套"水电煤"系统。

我们似乎被困在了两难的境地:要么选择一个僵化的"应用级"框架,要么选择一个过于灵活的"引擎级"工具。

有没有一条中间道路?

在反复挣扎和实践后,我得出了一个结论:有。那就是在LangGraph这种强大的"引擎"之上,构建一层我们自己的、轻量级的、符合自己团队心智模型的"协作层"。

今天,我就来聊聊,我为什么放弃了直接使用现成的框架,又开始"手写"这薄薄的一层,以及这一层到底解决了什么核心问题。

二、 CrewAI的"美丽枷锁":当规范大于灵活

CrewAI的初衷是好的,它试图将构建Agent的过程,标准化为"角色(Agent)-任务(Task)-流程(Process)-船员(Crew)"这套模型。对于很多标准场景,这套模型非常高效。

但它的核心问题在于,它是一个"强干预"的框架。它为你做了太多决策,而这些决策,往往与你真实的、复杂的业务逻辑相悖。

它的主要局限在于:

  1. 僵化的线性流程:默认情况下,CrewAI的任务是串行执行的。你想实现一个"A和B并行,然后结果汇总给C"的流程,会非常别扭。
  2. 模糊的状态管理:Agent之间的数据传递,很大程度上依赖于一个全局的、非结构化的"上下文黑盒"。你很难精确地控制,在任务的某个阶段,哪些信息是可见的,哪些是不可见的。
  3. 控制权的缺失:整个流程的调度,是由CrewAI的内部机制黑盒管理的。你无法在流程中途,根据一个外部事件或一个工具的执行结果,来动态地改变整个"剧本"。

总而言之,CrewAI更像一个**"内置了固定协作模式的Agent应用",而不是一个让你设计协作模式的"框架"**。

三、 LangGraph的"自由与混沌":当引擎只是引擎

LangGraph则走向了另一个极端。它极其强大,也极其"无情"。

它给了你构建任何复杂图形(Graph)的能力,但它对"什么是Agent"、"Agent之间如何对话"这些核心问题,不提供任何默认的解决方案

使用LangGraph,你很快就会意识到:

  1. 你需要自己定义"状态":这个状态(State)里,应该包含哪些字段?当前轮到哪个Agent?消息列表应该是什么格式?这些都需要你自己来设计。
  2. 你需要自己实现"调度":当一个Agent完成了它的任务,下一个应该由谁来接手?这个核心的调度逻辑,LangGraph把它作为一个普通的"条件边"(Conditional Edge)交给了你,你需要自己编写一个复杂的函数来实现。
  3. 你需要自己管理"工具调用":Agent调用工具的请求、工具执行的结果,如何优雅地整合进你的状态流转中?LangGraph提供了模式,但没有现成的实现。

LangGraph是一个顶级的**"工作流引擎",但它本身,并不是一个 "多智能体协作框架"**。它给了你造车的顶级发动机和变速箱,但车架、底盘、方向盘,都得你自己来造。

四、 破局之道:构建我们自己的"协作层"

现在,我的思路清晰了:我们真正需要的,不是另一个庞大的框架,而是在LangGraph这个坚实底座上,构建一层薄薄的、但至关重要的"协作层"。

这一层的核心,只解决三个问题:

  1. 一个统一的"世界状态" (World State):定义一个所有Agent都认可的数据结构,用于记录全局信息、消息历史和任务状态。
  2. 一个中心化的"调度器" (Dispatcher):它本身是LangGraph中的一个特殊节点,负责读取"世界状态",并决定下一个应该被唤醒的Agent。
  3. 一套标准的"交互协议" (Interaction Protocol):定义Agent如何向状态里写入消息,以及调度器如何解析这些消息。

我们来看一个极简的伪代码实现,你马上就能明白:

python 复制代码
from typing import TypedDict, List, Literal
from langgraph.graph import StateGraph, END
from operator import itemgetter

# 1. 定义我们自己的"世界状态"
class AgentWorldState(TypedDict):
    task: str
    messages: List[tuple[str, str]] 
    next_agent: Literal["Researcher", "Writer", "FINISH"]

# 2. 定义Agent节点,展示它如何与"世界状态"交互
def researcher_agent_node(state: AgentWorldState):
    task = state['task']
    print(f"--- [Agent: 研究员] 开始工作,任务: {task} ---")
    research_result = f"这是关于'{task}'的研究成果。"
    # 注意:这里返回的是一个包含元组的列表,以支持状态的累加
    return {"messages": [("Researcher", research_result)]}

def writer_agent_node(state: AgentWorldState):
    messages = state['messages']
    print(f"--- [Agent: 作家] 开始工作 ---")
    writing_result = f"基于以下研究成果:\n{messages[-1][1]}\n\n我完成了最终报告。"
    return {"messages": [("Writer", writing_result)]}

# 3. 定义我们的核心"调度器"节点
def dispatcher_node(state: AgentWorldState):
    last_message_sender = state['messages'][-1][0] if state['messages'] else "START"
    
    if last_message_sender == "Researcher":
        return {"next_agent": "Writer"}
    elif last_message_sender == "Writer":
        return {"next_agent": "FINISH"}
    else: # START
        return {"next_agent": "Researcher"}

# 4. 在LangGraph中组装
workflow = StateGraph(AgentWorldState)
workflow.add_node("researcher", researcher_agent_node)
workflow.add_node("writer", writer_agent_node)
workflow.add_node("dispatcher", dispatcher_node) 

workflow.set_entry_point("dispatcher")

workflow.add_conditional_edges(
    "dispatcher",
    itemgetter('next_agent'),
    {
        "Researcher": "researcher",
        "Writer": "writer",
        "FINISH": END
    }
)

workflow.add_edge("researcher", "dispatcher")
workflow.add_edge("writer", "dispatcher")

# 编译
app = workflow.compile()

# 运行
inputs = {"task": "AI在软件开发中的作用", "messages": []}
for s in app.stream(inputs, {"recursion_limit": 10}):
    print(s)
    print("----")

看明白了吗?通过这层薄薄的封装,我们做到了:

  • 解耦 :Agent之间不直接对话,而是通过向messages列表追加消息来通信。
  • 中心化控制 :所有的流程走向,都由dispatcher这个唯一的"大脑"来决定。
  • 无限的扩展性 :我们可以让dispatcher变得无比智能,它可以调用一个LLM来做决策,也可以集成复杂的业务规则。

五、 老金总结:从"框架使用者"到"架构设计者"

我们之所以要"手写"这一层,不是为了重复造轮子,而是为了夺回控制权

CrewAI这样的框架,让你成为了一个熟练的"司机",但它限制了你能走的路。LangGraph给了你最强的"引擎",但它要求你成为一个"机械师",从零件开始造车。

而我们今天探讨的思路,是让你成为一个"汽车设计师"。你使用最专业的引擎(LangGraph),但你亲自设计汽车的底盘和传动系统(我们的协作层),最终组装出一辆最适合在你的业务道路上飞驰的、独一-无二的赛车。

这,或许才是AI时代,我们架构师真正的价值所在------不满足于使用工具,而是有能力、有思想地去组合与驾驭工具。

觉得有用,别忘了给老金点个赞,关注一下!

相关推荐
WSSWWWSSW38 分钟前
大语言模型提示工程与应用:大语言模型进阶提示工程技术
人工智能·语言模型·自然语言处理
说私域1 小时前
生产工具革命:定制开发开源AI智能名片S2B2C商城小程序重构商业生态的范式研究
人工智能·小程序·开源
Chaos_Wang_1 小时前
ShadowKV 机制深度解析:高吞吐长上下文 LLM 推理的 KV 缓存“影子”方案
人工智能·语言模型·自然语言处理·chatgpt·deepseek
数据饕餮1 小时前
PyTorch 深度学习实战教程-番外篇04:卷积层详解与实战指南
人工智能·pytorch·深度学习·卷积神经网络
北极的树1 小时前
GPT 5祛魅时刻:当OpenAI陷入内卷,谷歌已在布局下一个十年
人工智能
袁袁袁袁满2 小时前
基于Python爬虫实战:获取财经股票数据
爬虫·python·ai编程
大模型真好玩2 小时前
深入浅出LangChain AI Agent智能体开发教程(七)—LangChain多智能体浏览器自动化
人工智能·python·mcp
机器之心2 小时前
40年后,Dijkstra算法极限再被突破,清华段然团队更快最短路径算法摘STOC最佳论文
人工智能·openai
Goboy2 小时前
用Trae秒杀FastJSON科学计数法Bug,从周末加班到5分钟解决
人工智能·ai编程·trae
深度学习机器2 小时前
Deep Research的架构演进:从Multi Agent到Supervisor-Researcher模式的技术实践
人工智能·llm·agent