开源Agent框架年度横向对比:LangChain、LlamaIndex与Semantic Kernel的选型指南

一、框架繁荣背后的选择困境

2026年的开源Agent框架生态已经走出"百花齐放"的混沌期,进入了三足鼎立的格局:LangChain牢牢占据市场份额第一的位置,LlamaIndex以数据为核心构建差异化护城河,Semantic Kernel则背靠微软生态在企业级场景中快速渗透。但选择困难并未因此减少——这三个框架在API设计、抽象层次、扩展机制上的分歧仍在加深,而不是收敛。

技术选型的成本远超开发初期的学习曲线。框架选定后,团队需要围绕其生态构建工具链、监控体系、测试策略。一次不匹配的框架选择,意味着未来两年的技术债务。本文基于三个框架在2026年上半年的最新版本(LangChain 0.3.x、LlamaIndex 0.11.x、Semantic Kernel 1.5.x),从架构设计、扩展能力、生产适配三个维度进行横向对比。

二、核心架构差异:三条不同的抽象路径

三个框架的差异根植于各自对"Agent应该是什么"这一基础问题的不同回答。这种差异在各自的类层次结构中有清晰的体现:

LangChain的链式哲学植根于函数式编程思想。所有操作被抽象为Runnable接口,通过LCEL(LangChain Expression Language)的管道语法组合。这种设计在构建Demo时有极高的开发效率,但生产环境中"管道的非透明性"成为调试噩梦——当10个Runnable串联后,一个中间节点的隐藏Prompt修改可能让整个链路的输出发生不可预期的偏离。

LlamaIndex的数据优先理念则从另一个方向切入。它假设绝大多数Agent应用的核心需求是"对私有数据的检索增强",因此将文档解析、索引构建、混合检索作为第一等公民。QueryEngine的丰富程度远超另外两个框架,但Agent能力(特别是多步骤推理和工具编排)需要额外构建——它本质上是一个"检索增强框架之上嫁接的Agent系统"。

Semantic Kernel的插件模型吸取了两者的教训。Kernel不规定数据的处理方式,也不限定编排模式,而是定义一个统一的"Plugin→Function"契约。这种松散耦合的设计牺牲了开箱即用的便利性,但换来了企业级场景中最宝贵的资产——定制化能力和服务集成的便捷性。特别地,SK的Process框架(2026年新推出的业务流程引擎)在长时间运行的工作流场景中具备另两个框架尚未覆盖的能力。

三、生产级选型对比:以RAG Agent为基准实现

以下以同一个"带权限控制的文档查询Agent"为目标,展示三个框架在实现风格上的差异:

LangChain实现

"""
LangChain实现:基于LCEL的链式组合
特点:声明式管道,强于快速原型
短板:中间状态调试困难,记忆管理需要手动配置
"""
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain_community.vectorstores import Chroma
from typing import Optional

class LangChainDocAgent:
    """LangChain风格的文档查询Agent"""

    def __init__(
        self,
        vector_store: Chroma,
        model_name: str = "gpt-4o",
    ):
        self.vector_store = vector_store
        self.llm = ChatOpenAI(model=model_name, temperature=0)

        # LCEL管道:检索→权限过滤→提示→生成→解析
        self.chain = (
            {
                "context": self._retrieve_context,
                "question": RunnablePassthrough(),
                "user_role": RunnablePassthrough(),
            }
            | self._build_prompt()
            | self.llm
            | StrOutputParser()
        )

    def _retrieve_context(self, inputs: dict) -> str:
        """检索相关文档(含权限过滤)"""
        question = inputs.get("question", "")
        docs = self.vector_store.similarity_search(question, k=5)

        # 权限过滤:只返回用户有权访问的文档
        user_role = inputs.get("user_role", "guest")
        filtered = [
            d for d in docs
            if d.metadata.get("access_level", "public") in
            ("public", user_role)
        ]
        return "\n\n".join(d.page_content for d in filtered)

    def _build_prompt(self) -> ChatPromptTemplate:
        return ChatPromptTemplate.from_messages([
            ("system", (
                "你是企业文档助手。基于提供的文档片段回答问题。"
                "如果文档中没有相关信息,明确告知用户。"
            )),
            ("human", (
                "文档内容:\n{context}\n\n"
                "用户问题:{question}\n"
                "用户角色:{user_role}\n\n"
                "请回答:"
            )),
        ])

    def query(self, question: str, user_role: str = "guest") -> str:
        return self.chain.invoke({
            "question": question,
            "user_role": user_role,
        })

LlamaIndex实现

"""
LlamaIndex实现:基于QueryEngine的数据检索增强
特点:检索策略丰富,索引管理强
短板:多步推理不够原生,需额外构建AgentWorker
"""
from llama_index.core import VectorStoreIndex, Settings
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.postprocessor import SimilarityPostprocessor
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter

class LlamaIndexDocAgent:
    """LlamaIndex风格的文档查询Agent"""

    def __init__(self, documents: list, model_name: str = "gpt-4o"):
        # 全局配置
        Settings.llm = OpenAI(model=model_name, temperature=0)
        Settings.embed_model = OpenAIEmbedding()
        Settings.node_parser = SentenceSplitter(
            chunk_size=512, chunk_overlap=50
        )

        # 构建索引(支持向量+关键词混合检索)
        self.index = VectorStoreIndex.from_documents(documents)

        # 配置检索器
        self.retriever = VectorIndexRetriever(
            index=self.index,
            similarity_top_k=5,
        )

        # 后处理器:相似度阈值过滤
        self.postprocessor = SimilarityPostprocessor(
            similarity_cutoff=0.70
        )

        # 构建查询引擎
        self.query_engine = RetrieverQueryEngine.from_args(
            retriever=self.retriever,
            node_postprocessors=[self.postprocessor],
            response_mode="compact",  # 紧凑模式:合并相关片段后一次生成
        )

    def query(self, question: str, user_role: str = "guest") -> str:
        """
        查询接口

        注意:权限过滤需要在检索后通过自定义NodePostprocessor实现
        LlamaIndex没有原生的权限过滤机制,需自行扩展
        """
        response = self.query_engine.query(question)
        return str(response)

Semantic Kernel实现

"""
Semantic Kernel实现:基于Plugin的组件化设计
特点:企业级集成能力强,Process支持长时间工作流
短板:学习曲线较陡,社区资源相对较少
"""
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.functions import KernelArguments
from semantic_kernel.plugin_definition import kernel_function

class DocumentPlugin:
    """文档检索插件:封装数据访问逻辑"""

    def __init__(self, vector_store):
        self.vector_store = vector_store

    @kernel_function(
        name="search_documents",
        description="根据语义搜索相关文档片段",
    )
    async def search(
        self, query: str, user_role: str = "guest", top_k: int = 5
    ) -> str:
        """语义搜索 + 权限过滤"""
        docs = self.vector_store.similarity_search(query, k=top_k)

        # 权限过滤
        accessible = [
            d for d in docs
            if d.metadata.get("access_level", "public")
            in ("public", user_role)
        ]

        if not accessible:
            return "未找到用户可访问的相关文档。"
        return "\n---\n".join(d.page_content for d in accessible)

class SemanticKernelDocAgent:
    """Semantic Kernel风格的文档查询Agent"""

    async def initialize(self, vector_store, model_name: str = "gpt-4o"):
        """初始化Kernel和Plugin"""
        self.kernel = sk.Kernel()

        # 注册AI服务
        self.kernel.add_service(
            OpenAIChatCompletion(
                service_id="chat",
                ai_model_id=model_name,
            )
        )

        # 注册文档检索插件
        self.doc_plugin = self.kernel.add_plugin(
            DocumentPlugin(vector_store),
            plugin_name="DocumentPlugin",
        )

        # 启用自动函数调用(Auto Function Calling)
        settings = self.kernel.get_prompt_execution_settings()
        settings.function_choice_behavior = (
            sk.FunctionChoiceBehavior.Auto()
        )

    async def query(self, question: str, user_role: str = "guest") -> str:
        """
        SK查询接口
        Kernel自动决定是否调用DocumentPlugin.search_documents
        """
        prompt = """
        你是企业文档助手。如果需要参考文档,
        请调用DocumentPlugin.search_documents获取。
        
        用户角色:{{$user_role}}
        用户问题:{{$question}}
        
        请直接回答用户问题。
        """

        arguments = KernelArguments(
            user_role=user_role,
            question=question,
        )

        result = await self.kernel.invoke_prompt(
            function_name="doc_query",
            plugin_name="DocumentPlugin",
            prompt=prompt,
            arguments=arguments,
        )
        return str(result)

三个实现的差异反映了各自的设计哲学:LangChain追求声明式的简洁性;LlamaIndex在检索策略配置上提供最深的自定义空间;SK则通过函数契约实现了最松散的组件耦合。选择哪个取决于你的核心需求——如果重点是检索质量,LlamaIndex;如果追求开发速度,LangChain;如果需要深度企业集成,SK。

四、选型陷阱与适配边界

基于实际项目经验,三个框架各有明确的"不建议使用"场景:

LangChain不适合的场景: 严格的确定性输出场景(如金融合规报告)。LCEL的链式抽象中,中间步骤的副作用难以完全追溯到输入,调试成本随链长度指数增长。如果你需要在每个步骤都留下可审计的痕迹,LangChain的抽象反而成为障碍。

LlamaIndex不适合的场景: 以动态工具调用为核心的Agent场景。它的根基是"数据索引+检索",当Agent需要根据上下文动态选择10个不同工具并多步骤推理时,LlamaIndex需要额外构建相当多的胶水代码才能达到LangChain或SK的原生水平。

Semantic Kernel不适合的场景: 快速原型验证阶段。SK的企业级抽象层次较高,从零搭建一个能跑的Agent需要理解和配置Kernel、Plugin、Function、Arguments四个核心概念——对于只需要一个周末验证的Idea,这过于笨重。

一个务实的混合策略:原型阶段用LangChain快速验证,数据密集型任务用LlamaIndex构建索引管道,生产环境用SK进行企业级集成。 三个框架并非互斥,在微服务架构中各自承担不同的角色是完全可行的。

五、总结

2026年的Agent框架选型,核心判断依据从"功能丰富度"转变为"生产适配度"。三个结论:

第一,LangChain适合以开发速度为核心诉求的场景,但进入生产环境前必须建立完善的调试和监控体系来对冲其抽象成本。

第二,LlamaIndex是数据检索增强场景的最优解,其索引管理能力和检索策略的丰富度远超竞品。如果产品核心价值在"充分利用私有数据",建议以LlamaIndex为基础。

第三,Semantic Kernel在企业级集成和定制化场景中优势明显。如果目标客户是大型企业,需要深度集成Microsoft 365、Azure等服务,SK几乎是唯一选择。

无论选择哪个,都比不选框架、从零造轮子要好。框架至少提供了一致的错误处理、日志记录和社区最佳实践——这些在自有实现中往往被忽视。

更多推荐