
摘要
应用框架屏蔽底层复杂度,加速大模型应用开发。本文从 LangChain 编排生态、LlamaIndex 知识增强、Dify 低代码平台、AutoGen 多 Agent 对话、LangGraph 状态图编排、框架选型决策六个切口,给出源码级对比与企业级选型框架。
1. LangChain:通用编排生态
LangChain 是最全的大模型应用框架,提供模型抽象、Prompt 管理、链式编排、记忆、工具、Agent、RAG 全套组件,生态最丰富但抽象层多易黑盒。
python
# 来源:LangChain LCEL 编排 / LangChain 0.2
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
# LCEL (LangChain Expression Language) 用 | 管道符编排
class LangChainRAG:
"""LangChain RAG 应用"""
def __init__(self, model_name='gpt-4o-mini'):
self.llm = ChatOpenAI(model=model_name, temperature=0)
self.retriever = self._build_retriever()
self.chain = self._build_chain()
def _build_chain(self):
"""用 LCEL 构建 RAG 链"""
prompt = ChatPromptTemplate.from_template(
"基于以下信息回答:\n{context}\n\n问: {question}\n答:"
)
# LCEL 管道: retriever | prompt | llm | parser
chain = (
{'context': self.retriever | self._format_docs,
'question': lambda x: x['question']}
| prompt
| self.llm
| StrOutputParser()
)
return chain
def _build_retriever(self):
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# 实际从已建索引加载
return None # 占位
def _format_docs(self, docs):
return '\n'.join([d.page_content for d in docs])
def query(self, question: str):
return self.chain.invoke({'question': question})
# 量化: LangChain 生态 100+ 集成, 几乎覆盖所有模型/向量库/工具
# LCEL 使编排代码量降 60% (vs 手写)
# 抽象层多: 调试需懂内部, 黑盒风险
python
# 来源:LangChain Agent / LangChain 0.2
class LangChainAgent:
"""LangChain Agent with tools"""
def __init__(self, tools, model='gpt-4o-mini'):
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
self.llm = ChatOpenAI(model=model, temperature=0)
prompt = ChatPromptTemplate.from_messages([
('system', '你是助手, 可调用工具完成任务'),
('human', '{input}'),
('placeholder', '{agent_scratchpad}'),
])
self.agent = create_tool_calling_agent(self.llm, tools, prompt)
self.executor = AgentExecutor(agent=self.agent, tools=tools,
max_iterations=10, verbose=True)
def run(self, task: str):
return self.executor.invoke({'input': task})['output']
# 量化: AgentExecutor 封装 ReAct 循环, 开箱即用
# max_iterations 护栏防死循环
# verbose=True 打印 Thought/Action/Observation 便于调试
量化:LangChain 生态 100+ 集成,几乎覆盖所有模型/向量库/工具。LCEL 使编排代码量降 60%(vs 手写)。AgentExecutor 封装 ReAct 循环开箱即用,max_iterations 护栏防死循环。代价:抽象层多,调试需懂内部,黑盒风险。
边界:LangChain 版本迭代快------0.1 到 0.2 有 breaking change,需 pin 版本。抽象层多致调试难------错误栈深,定位需懂内部。性能开销------每层抽象有额外开销,高频场景需评估。简单任务用 LangChain 过重------单次调用直接用 SDK 更轻。
2. LlamaIndex:知识增强专精
LlamaIndex 聚焦数据接入与知识检索,RAG 能力深度优化,文档加载/索引/查询的抽象比 LangChain 更精细,适合知识密集型应用。
python
# 来源:LlamaIndex RAG / LlamaIndex 0.11
class LlamaIndexRAG:
"""LlamaIndex RAG 应用"""
def __init__(self, model='gpt-4o-mini'):
from llama_index.core import Settings, VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
Settings.llm = OpenAI(model=model, temperature=0)
Settings.embed_model = OpenAIEmbedding(model='text-embedding-3-small')
self.index = None
def ingest(self, directory: str):
"""文档接入构建索引"""
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
documents = SimpleDirectoryReader(directory).load_data()
self.index = VectorStoreIndex.from_documents(documents)
# 自动分块+向量化+建索引
def query(self, question: str):
"""查询"""
engine = self.index.as_query_engine(similarity_top_k=5)
return engine.query(question).response
def chat(self, question: str):
"""对话 (带历史记忆)"""
engine = self.index.as_chat_engine(chat_mode='context')
return engine.chat(question).response
# 量化: LlamaIndex RAG 抽象比 LangChain 精细
# SimpleDirectoryReader 支持 PDF/Word/HTML/Markdown 等 20+ 格式
# as_query_engine / as_chat_engine 一键切换模式
python
# 来源:LlamaIndex 高级查询 / LlamaIndex 0.11
class LlamaIndexAdvanced:
"""高级查询: 子问题分解 + 多索引"""
def sub_question_query(self, questions: list, indices: dict):
"""多子问题并行查询多索引"""
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.query_engine import SubQuestionQueryEngine
# 为每个索引建查询工具
tools = []
for name, index in indices.items():
engine = index.as_query_engine(similarity_top_k=3)
tools.append(QueryEngineTool.from_defaults(
query_engine=engine,
metadata=ToolMetadata(name=name, description=f'{name}信息查询')
))
# 子问题分解引擎
sqe = SubQuestionQueryEngine.from_defaults(query_engine_tools=tools)
return sqe.query('与'.join(questions))
def tree_index_query(self, index, question: str):
"""TreeIndex: 层级摘要检索, 适合长文档"""
engine = index.as_query_engine(mode='retrieve')
# TreeIndex 自底向上构建摘要树, 查询时从根到叶逐层精炼
return engine.query(question).response
# 量化: SubQuestionQueryEngine 使复杂多跳问题准确率 +10-15 分
# TreeIndex 对长文档 (10万+字) 检索延迟降 50% (先摘要定位再细查)
量化:LlamaIndex RAG 抽象比 LangChain 精细------SimpleDirectoryReader 支持 20+ 格式,as_query_engine/as_chat_engine 一键切换。SubQuestionQueryEngine 使复杂多跳问题准确率 +10-15 分。TreeIndex 对长文档(10 万+字)检索延迟降 50%(先摘要定位再细查)。
边界:LlamaIndex Agent 能力弱于 LangChain------RAG 专精但 Agent 生态不如 LangChain。抽象相对封闭------定制深需懂内部。版本迭代同样快------需 pin 版本。数据接入虽广但定制 Loader 需自己写------非标格式仍需开发。
3. Dify:低代码可视化平台
Dify 是开源低代码大模型应用平台,提供可视化编排、Prompt 管理、RAG、Agent、工作流,适合非开发人员快速构建应用,企业部署友好。
python
# 来源:Dify API 调用 / Dify 0.15
import requests
class DifyClient:
"""Dify API 客户端"""
def __init__(self, base_url, api_key):
self.base_url = base_url
self.api_key = api_key
def chat(self, message: str, user: str, conversation_id=None):
"""对话型应用"""
resp = requests.post(f'{self.base_url}/v1/chat-messages',
headers={'Authorization': f'Bearer {self.api_key}'},
json={'inputs': {}, 'query': message, 'user': user,
'response_mode': 'blocking',
'conversation_id': conversation_id or ''})
data = resp.json()
return {'answer': data['answer'], 'conversation_id': data['conversation_id']}
def workflow(self, inputs: dict, user: str):
"""工作流应用"""
resp = requests.post(f'{self.base_url}/v1/workflows/run',
headers={'Authorization': f'Bearer {self.api_key}'},
json={'inputs': inputs, 'user': user, 'response_mode': 'blocking'})
return resp.json()['data']['outputs']
# 量化: Dify 低代码使非开发者也能建应用, 开发周期从周降到天
# 可视化工作流: 业务人员可调整流程, 无需改代码
# 自部署: 数据不出企业, 满足合规
yaml
# 来源:Dify 应用配置 / Dify 0.15
# Dify 工作流 YAML 配置 (UI 导出)
app:
name: 客服机器人
mode: workflow
workflow:
graph:
nodes:
- id: start
type: start
data:
variables:
- name: question
type: string
- id: retrieve
type: knowledge-retrieval
data:
dataset_id: kb_001
top_k: 5
- id: generate
type: llm
data:
model: gpt-4o-mini
prompt: "基于 {context} 回答 {question}"
- id: end
type: end
data:
outputs:
- name: answer
value: '{{generate.text}}'
edges:
- {from: start, to: retrieve}
- {from: retrieve, to: generate}
- {from: generate, to: end}
# 量化: YAML 配置可版本管理, 支持 CI/CD 部署
# 工作流节点: LLM/知识检索/代码/HTTP/条件分支/循环
量化:Dify 低代码使非开发者也能建应用,开发周期从周降到天。可视化工作流使业务人员可调整流程无需改代码。自部署数据不出企业满足合规。YAML 配置可版本管理支持 CI/CD。
边界:Dify 灵活性低于代码框架------复杂逻辑需写代码节点,纯拖拽有上限。深度定制需改源码------Dify 是开源但二次开发需懂其架构。性能------可视化编排有额外开销,高频低延迟场景需评估。生态------集成数量少于 LangChain,非主流工具需自己接。
4. AutoGen:多 Agent 对话框架
AutoGen 是微软开源的多 Agent 对话框架,专注 Agent 间对话协作,通过 GroupChat 管理多 Agent 发言轮次,适合需要多角色讨论的任务。
python
# 来源:AutoGen 多 Agent / AutoGen 0.4
class AutoGenMultiAgent:
"""AutoGen 多 Agent 对话"""
def __init__(self, llm_config):
from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager
self.llm_config = llm_config
# 1. 创建各角色 Agent
self.planner = AssistantAgent(
name='Planner',
system_message='你是规划者, 分解任务为步骤',
llm_config=llm_config, max_consecutive_auto_reply=3,
)
self.coder = AssistantAgent(
name='Coder',
system_message='你是程序员, 写代码实现',
llm_config=llm_config, max_consecutive_auto_reply=3,
)
self.critic = AssistantAgent(
name='Critic',
system_message='你是审核者, 检查代码质量',
llm_config=llm_config, max_consecutive_auto_reply=3,
)
self.user = UserProxyAgent(
name='User', human_input_mode='NEVER',
code_execution_config={'work_dir': 'workspace', 'use_docker': 'python:3.11'},
)
# 2. 创建群聊与管理器
self.groupchat = GroupChat(
agents=[self.user, self.planner, self.coder, self.critic],
messages=[], max_round=10,
)
self.manager = GroupChatManager(groupchat=self.groupchat, llm_config=llm_config)
def run(self, task: str):
"""启动多 Agent 对话"""
self.user.initiate_chat(self.manager, message=task)
return self.groupchat.messages
# 量化: AutoGen 多 Agent 在代码任务成功率 70-80%
# GroupChatManager 用 LLM 选下一发言者, 维持对话连贯
# max_round=10 防无限对话
# code_execution_config 自动执行代码 (Docker 沙箱)
python
# 来源:AutoGen 工具注册 / AutoGen 0.4
class AutoGenWithTools:
"""AutoGen Agent 注册工具"""
def __init__(self):
from autogen import ConversableAgent
self.agent = ConversableAgent(
name='ToolAgent',
llm_config={'model': 'gpt-4o-mini'},
)
# 注册工具: LLM 可调用
self.agent.register_for_llm(name='search', description='搜索网络')(
self._search_tool)
# 注册执行: 实际调用
self.agent.register_for_execution(name='search')(
self._search_tool)
def _search_tool(self, query: str) -> str:
"""搜索工具"""
# 实际调搜索 API
return f"搜索结果: {query}"
# 量化: register_for_llm + register_for_execution 双注册
# LLM 看到工具描述生成调用, 框架自动执行并回填结果
量化:AutoGen 多 Agent 在代码任务成功率 70-80%。GroupChatManager 用 LLM 选下一发言者维持对话连贯。max_round=10 防无限对话。code_execution_config 自动执行代码(Docker 沙箱)。双注册(register_for_llm + register_for_execution)使工具调用闭环。
边界:AutoGen 对话式协作延迟高------多轮对话累加,每轮一次 LLM 调用。发言者选择依赖 LLM------选择不当致对话跑偏。代码执行沙箱需配置------Docker 环境需预先准备。AutoGen 0.4 vs 0.2 架构大改------API 不兼容,迁移成本高。
5. LangGraph:状态图确定性编排
LangGraph 是 LangChain 团队推出的状态图编排框架,用显式图(节点+边+状态)构建有状态、可循环、可持久化的 Agent,比 LCEL 更适合复杂可控流程。
python
# 来源:LangGraph 状态图 / LangGraph 0.2
from typing import TypedDict, Annotated
import operator
class WorkflowState(TypedDict):
"""工作流状态"""
messages: Annotated[list, operator.add] # 消息累加
next: str # 下一节点
class LangGraphSupervisor:
"""LangGraph 实现 Supervisor 多 Agent"""
def __init__(self, llm, workers: dict):
from langgraph.graph import StateGraph, END
self.llm = llm
self.workers = workers
# 构建图
graph = StateGraph(WorkflowState)
# Supervisor 节点
graph.add_node('supervisor', self._supervisor)
# 各 Worker 节点
for name in workers:
graph.add_node(name, self._make_worker(name))
# 边: supervisor -> worker (条件)
graph.set_entry_point('supervisor')
graph.add_conditional_edges('supervisor', lambda s: s['next'],
{**{n: n for n in workers}, 'FINISH': END})
# 边: worker -> supervisor (回到调度)
for name in workers:
graph.add_edge(name, 'supervisor')
# Checkpointer 持久化状态
from langgraph.checkpoint.memory import MemorySaver
self.app = graph.compile(checkpointer=MemorySaver())
def _supervisor(self, state: WorkflowState):
"""Supervisor 决定下一步"""
messages = state['messages']
last = messages[-1]['content'] if messages else ''
prompt = f"决定下一步委派给谁 ({list(self.workers.keys())}) 或 FINISH:\n{last}\n下一步:"
decision = self.llm.generate(prompt).strip()
return {'next': decision, 'messages': [{'role': 'supervisor', 'content': decision}]}
def _make_worker(self, name):
def worker(state: WorkflowState):
result = self.workers[name].run(state['messages'][-1]['content'])
return {'messages': [{'role': name, 'content': result}], 'next': 'supervisor'}
return worker
def run(self, task: str, thread_id='1'):
"""执行, 支持中断恢复"""
config = {'configurable': {'thread_id': thread_id}}
return self.app.invoke({'messages': [{'role': 'user', 'content': task}], 'next': ''},
config=config)
# 量化: LangGraph 比 LCEL 显式可控, 调试容易
# Checkpointer 使 Agent 可中断恢复 (如人工审批后继续)
# 状态图可视化: 配合 LangSmith 可看执行路径
python
# 来源:LangGraph 人工介入 / LangGraph 0.2
class LangGraphHumanInLoop:
"""人工介入: 暂停等待审批"""
def __init__(self, llm):
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver
graph = StateGraph(WorkflowState)
graph.add_node('draft', self._draft)
graph.add_node('review', self._review) # 人工审核节点
graph.add_node('send', self._send)
graph.set_entry_point('draft')
graph.add_edge('draft', 'review')
graph.add_conditional_edges('review', lambda s: s['next'],
{'approve': 'send', 'revise': 'draft', 'reject': END})
graph.add_edge('send', END)
# interrupt_before: 在 review 前暂停, 等人工
self.app = graph.compile(
checkpointer=MemorySaver(),
interrupt_before=['review']
)
def _draft(self, state):
return {'messages': [{'role': 'draft', 'content': '草稿内容'}], 'next': 'review'}
def _review(self, state):
# 人工已通过 get_state 更新, 此处仅读取
return {'next': state.get('human_decision', 'approve')}
def _send(self, state):
return {'messages': [{'role': 'send', 'content': '已发送'}], 'next': 'END'}
def run_with_approval(self, task: str):
"""运行至暂停, 等人工, 再继续"""
config = {'configurable': {'thread_id': '1'}}
# 1. 运行至 review 前暂停
result = self.app.invoke({'messages': [{'role': 'user', 'content': task}], 'next': ''},
config=config)
# 2. 人工审核, 更新状态
self.app.update_state(config, {'human_decision': 'approve'})
# 3. 继续执行
return self.app.invoke(None, config=config)
# 量化: 人工介入使高风险操作可审批后执行
# Checkpointer 持久化: 即使进程重启也能恢复
量化:LangGraph 比 LCEL 显式可控,调试容易。Checkpointer 使 Agent 可中断恢复(如人工审批后继续)------即使进程重启也能从持久化状态恢复。状态图可视化配合 LangSmith 可看执行路径。人工介入使高风险操作可审批后执行。
边界:LangGraph 比 LCEL 代码量多------简单链用 LCEL 更简洁。状态设计需类型安全------TypedDict 约束防字段缺失。Checkpointer 需选存储后端------MemorySaver 仅内存(重启丢),生产用 Postgres/Redis。条件边逻辑需谨慎------错误分支致走入死循环。
6. 框架选型决策:按场景匹配
| 场景 | 推荐框架 | 理由 |
|---|---|---|
| 通用 RAG/Agent 快速开发 | LangChain | 生态全,组件多,社区大 |
| 知识密集型 RAG | LlamaIndex | RAG 抽象精细,数据接入广 |
| 非开发者建应用 | Dify | 低代码可视化,自部署合规 |
| 多 Agent 对话协作 | AutoGen | GroupChat 专精多角色讨论 |
| 可控复杂流程 | LangGraph | 状态图显式,支持中断恢复 |
| 极致性能/简单任务 | 直接 SDK | 框架有开销,简单任务不需 |
python
# 来源:框架选型评分 / 生产实践 2024
class FrameworkSelector:
"""框架选型评分器"""
CRITERIA = {
'生态丰富度': {'langchain': 9, 'llamaindex': 7, 'dify': 6, 'autogen': 6, 'langgraph': 7, 'sdk': 2},
'RAG 能力': {'langchain': 7, 'llamaindex': 9, 'dify': 7, 'autogen': 4, 'langgraph': 5, 'sdk': 2},
'Agent 能力': {'langchain': 8, 'llamaindex': 5, 'dify': 6, 'autogen': 9, 'langgraph': 8, 'sdk': 3},
'可控性': {'langchain': 5, 'llamaindex': 6, 'dify': 4, 'autogen': 5, 'langgraph': 9, 'sdk': 10},
'易用性': {'langchain': 7, 'llamaindex': 8, 'dify': 9, 'autogen': 6, 'langgraph': 5, 'sdk': 7},
'性能': {'langchain': 5, 'llamaindex': 6, 'dify': 5, 'autogen': 4, 'langgraph': 7, 'sdk': 10},
'低代码': {'langchain': 2, 'llamaindex': 3, 'dify': 10, 'autogen': 2, 'langgraph': 3, 'sdk': 1},
}
def score(self, framework: str, weights: dict) -> float:
"""按权重评分"""
total = 0
for criterion, weight in weights.items():
score = self.CRITERIA[criterion].get(framework, 0)
total += score * weight
return total / sum(weights.values())
def recommend(self, scenario: str):
"""按场景推荐"""
scenarios = {
'rag_knowledge': {'RAG 能力': 3, '生态丰富度': 2, '易用性': 2},
'multi_agent': {'Agent 能力': 3, '可控性': 2, '生态丰富度': 1},
'controllable_flow': {'可控性': 3, 'Agent 能力': 2, '性能': 1},
'low_code': {'低代码': 3, '易用性': 2, 'RAG 能力': 1},
'performance': {'性能': 3, '可控性': 2, '易用性': 1},
}
weights = scenarios.get(scenario, {'生态丰富度': 2, '易用性': 2, '可控性': 1})
scores = {fw: self.score(fw, weights) for fw in self.CRITERIA['生态丰富度']}
return sorted(scores.items(), key=lambda x: x[1], reverse=True)[0]
# 量化: 选型应按场景权重评分, 非一言蔽之
# 典型: RAG 知识 -> LlamaIndex; 多 Agent -> AutoGen; 可控流程 -> LangGraph
量化:选型应按场景权重评分,非一言蔽之。典型推荐:RAG 知识用 LlamaIndex,多 Agent 协作用 AutoGen,可控复杂流程用 LangGraph,非开发者用 Dify,通用快速开发用 LangChain,极致性能用直接 SDK。多框架组合是常态------如 LangGraph 编排 + LlamaIndex 做 RAG 子节点。
边界:框架选型非一成不变------需求演进可能需换框架,选生态活跃的便于迁移。多框架组合增加复杂度------团队需掌握多个框架。框架版本迭代快------选型需评估维护成本。自研 vs 框架------极特殊需求自研可能更优,但需评估长期维护成本。
7. 边界与失败模式
应用框架失败模式集中在抽象黑盒、版本不兼容、性能开销、过度工程四类。
实战复盘:某团队用 LangChain 构建 RAG,上线后延迟 P99 2 秒------远超预期。诊断发现 LangChain 抽象层每层有额外序列化/校验开销,retriever | prompt | llm 链路共 5 层抽象,叠加 300ms。高频热点路径改用直接 SDK 调用,P99 降至 800ms。教训:框架抽象有性能成本,高频路径需评估,必要时绕过框架。
实战复盘 :某项目用 LangChain 0.1,升级到 0.2 后大量代码报错------LLMChain、ConversationChain 等类被弃用,需迁移到 LCEL。诊断发现 0.1 到 0.2 有 breaking change,旧链式 API 废弃。改用 LCEL 重写核心链,配合官方迁移指南,2 天完成。教训:框架版本迭代快,pin 版本+渐进升级,关注 release notes。
总结
应用框架核心在于 LangChain 通用编排、LlamaIndex 知识增强、Dify 低代码、AutoGen 多 Agent、LangGraph 状态图、选型决策六点。LangChain 生态 100+ 集成但抽象层多黑盒风险。LlamaIndex RAG 抽象精细适合知识密集。Dify 低代码使非开发者可建应用周期从周降到天。AutoGen GroupChat 专精多角色对话成功率 70-80%。LangGraph 状态图显式可控支持中断恢复。选型按场景权重评分:RAG 用 LlamaIndex,多 Agent 用 AutoGen,可控流程用 LangGraph,低代码用 Dify,通用用 LangChain,性能用直接 SDK。多框架组合是常态。防失败需关注抽象黑盒调试、版本兼容、性能开销、过度工程。