LangChain—— 企业级 LLM 应用开发框架

LangChain 是目前最成熟的 LLM 应用开发框架,提供端到端的解决方案。


3.1 LangChain 核心架构

LangChain 提供完整的 LLM 应用开发工具链:

scss 复制代码
┌─────────────────────────────────────────────────────────────┐
│                     LangChain 架构                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   Chains    │  │   Agents    │  │    RAG      │        │
│  │   链式调用  │  │   智能体    │  │  检索增强   │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
│         │               │                │                 │
│         └───────────────┴────────────────┘                 │
│                         │                                   │
│  ┌──────────────────────▼──────────────────────┐           │
│  │              Core Components                │           │
│  │  • Models (LLM/Chat)  • Prompts            │           │
│  │  • Memory            • Tools               │           │
│  │  • Output Parsers    • Document Loaders    │           │
│  └─────────────────────────────────────────────┘           │
│                         │                                   │
│  ┌──────────────────────▼──────────────────────┐           │
│  │              Integrations                   │           │
│  │  200+ 第三方集成:数据库、向量库、API 等     │           │
│  └─────────────────────────────────────────────┘           │
└─────────────────────────────────────────────────────────────┘

核心组件

组件 说明 关键类
Models LLM 和 Chat 模型接口 ChatOpenAI, OpenAI
Prompts 提示词模板管理 ChatPromptTemplate
Memory 对话记忆管理 ConversationBufferMemory
Tools 工具定义与调用 Tool, StructuredTool
Output Parsers 输出解析与验证 StrOutputParser, PydanticOutputParser
Document Loaders 文档加载器 PyPDFLoader, DirectoryLoader

3.2 核心概念详解

3.2.1 LCEL(LangChain Expression Language)

LCEL 是 LangChain 的声明式语法,支持链式组合:

python 复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

# 定义组件
prompt = ChatPromptTemplate.from_template("翻译以下文本为{language}: {text}")
model = ChatOpenAI(model="gpt-4")
parser = StrOutputParser()

# 使用 | 操作符链接
chain = prompt | model | parser

# 执行
result = chain.invoke({"language": "英文", "text": "你好世界"})
print(result)  # Hello World

LCEL 核心操作符

操作符 说明 示例
` ` 管道,连接组件
invoke() 同步执行 chain.invoke({...})
ainvoke() 异步执行 await chain.ainvoke({...})
batch() 批量执行 chain.batch([{...}, {...}])
stream() 流式输出 for chunk in chain.stream({...})

3.2.2 Chains(链)

将多个组件串联成流水线:

python 复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

# 多步骤链
translate_prompt = ChatPromptTemplate.from_template(
    "将以下文本翻译成{language}: {text}"
)
summarize_prompt = ChatPromptTemplate.from_template(
    "总结以下文本的要点:\n{text}"
)

model = ChatOpenAI(model="gpt-4")

# 组合链
translate_chain = translate_prompt | model | StrOutputParser()
summarize_chain = summarize_prompt | model | StrOutputParser()

# 完整流程
text = "这是一段需要处理的长文本..."
translated = translate_chain.invoke({"language": "英文", "text": text})
summary = summarize_chain.invoke({"text": translated})

3.2.3 RAG(检索增强生成)

构建知识库问答系统:

scss 复制代码
┌─────────────────────────────────────────────────────────┐
│                    RAG 架构                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│   用户问题 ──▶ 向量检索 ──▶ 上下文组装 ──▶ LLM 生成    │
│                   │                                     │
│                   ▼                                     │
│              ┌─────────┐                               │
│              │ 向量库  │                               │
│              │(Chroma) │                               │
│              └─────────┘                               │
└─────────────────────────────────────────────────────────┘

完整 RAG 实现

python 复制代码
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_openai import ChatOpenAI
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate

# 1. 加载文档
loader = PyPDFLoader("knowledge_base.pdf")
docs = loader.load()

# 2. 文档分块
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len,
    separators=["\n\n", "\n", "。", "!", "?", ";", " ", ""]
)
splits = text_splitter.split_documents(docs)
print(f"文档分割为 {len(splits)} 个块")

# 3. 向量化存储
vectorstore = Chroma.from_documents(
    documents=splits,
    embedding=OpenAIEmbeddings(),
    persist_directory="./chroma_db"  # 持久化存储
)
retriever = vectorstore.as_retriever(
    search_type="mmr",  # 最大边际相关性
    search_kwargs={"k": 5, "fetch_k": 10}
)

# 4. 创建 RAG 链
model = ChatOpenAI(model="gpt-4", temperature=0)

prompt = ChatPromptTemplate.from_template("""
你是一个专业的问答助手。请基于以下上下文回答问题。
如果上下文中没有相关信息,请明确说明。

上下文:
{context}

问题:{input}

回答:
""")

document_chain = create_stuff_documents_chain(model, prompt)
retrieval_chain = create_retrieval_chain(retriever, document_chain)

# 5. 执行查询
response = retrieval_chain.invoke({"input": "什么是 RAG?"})
print(response["answer"])

3.2.4 Memory(记忆管理)

实现多轮对话记忆:

python 复制代码
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from typing import List

# 自定义会话存储
class InMemoryHistory(BaseChatMessageHistory):
    def __init__(self):
        self._messages: List[BaseMessage] = []

    @property
    def messages(self) -> List[BaseMessage]:
        return self._messages

    @messages.setter
    def messages(self, value: List[BaseMessage]):
        self._messages = value

    def add_message(self, message: BaseMessage) -> None:
        self._messages.append(message)

    def clear(self) -> None:
        self._messages = []

# 会话管理器
store = {}

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryHistory()
    return store[session_id]

# 创建带记忆的对话链
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个友好的AI助手,记得用户之前说过的内容。"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])

model = ChatOpenAI(model="gpt-4")
chain = prompt | model

# 包装为带记忆的链
chain_with_history = RunnableWithMessageHistory(
    chain,
    get_session_history=get_session_history,
    input_messages_key="input",
    history_messages_key="history"
)

# 多轮对话
session_id = "user_123"

# 第一轮
response1 = chain_with_history.invoke(
    {"input": "我叫张三"},
    config={"configurable": {"session_id": session_id}}
)
print(response1.content)  # 你好张三!

# 第二轮
response2 = chain_with_history.invoke(
    {"input": "你还记得我叫什么吗?"},
    config={"configurable": {"session_id": session_id}}
)
print(response2.content)  # 你叫张三

3.2.5 Tools(工具)

定义和调用外部工具:

python 复制代码
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field

# 方式一:使用 @tool 装饰器
@tool
def get_weather(city: str) -> str:
    """获取指定城市的天气信息"""
    # 实际应用中调用天气 API
    weather_data = {
        "北京": "晴天,25°C",
        "上海": "多云,28°C",
        "广州": "小雨,30°C"
    }
    return weather_data.get(city, f"未找到 {city} 的天气信息")

# 方式二:使用 Pydantic 定义参数
class SearchInput(BaseModel):
    query: str = Field(description="搜索关键词")
    num_results: int = Field(default=5, description="返回结果数量")

@tool(args_schema=SearchInput)
def search_web(query: str, num_results: int = 5) -> str:
    """在网络上搜索信息"""
    # 实际应用中调用搜索 API
    return f"搜索 '{query}' 找到 {num_results} 个结果"

# 创建 Agent 使用工具
tools = [get_weather, search_web]
model = ChatOpenAI(model="gpt-4", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个有用的助手,可以使用工具来回答问题。"),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}")
])

agent = create_tool_calling_agent(model, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 执行
result = agent_executor.invoke({"input": "北京今天天气怎么样?"})
print(result["output"])

3.3 实战案例:智能客服系统

系统架构

markdown 复制代码
用户输入 ──▶ 意图识别 ──▶ 知识库检索 ──▶ 回答生成 ──▶ 输出
               │              │              │
               ▼              ▼              ▼
           意图分类器     RAG Engine      LLM

完整实现

python 复制代码
# customer_service_bot.py
from typing import TypedDict, Annotated, Sequence
import operator
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_community.document_loaders import DirectoryLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage

# 定义状态
class AgentState(TypedDict):
    messages: Annotated[Sequence[str], operator.add]
    intent: str
    context: str
    response: str

class CustomerServiceBot:
    def __init__(self, knowledge_base_path: str):
        # 初始化 LLM
        self.llm = ChatOpenAI(model="gpt-4", temperature=0)

        # 初始化向量库
        self.embeddings = OpenAIEmbeddings()
        self.vectorstore = self._load_knowledge_base(knowledge_base_path)

        # 意图分类器
        self.intent_prompt = ChatPromptTemplate.from_template("""
        分析用户问题,判断意图类别:
        - product: 产品咨询
        - order: 订单查询
        - refund: 退款问题
        - technical: 技术支持
        - other: 其他

        用户问题:{question}
        只输出类别名称:
        """)

        # 回答生成器
        self.answer_prompt = ChatPromptTemplate.from_template("""
        你是一个专业的客服助手。请基于以下信息回答用户问题。

        意图类别:{intent}
        相关知识:{context}
        用户问题:{question}

        请提供专业、友好的回答。如果无法回答,请说明原因并建议用户联系人工客服:
        """)

    def _load_knowledge_base(self, path: str) -> Chroma:
        """加载知识库到向量数据库"""
        loader = DirectoryLoader(path, glob="**/*.md")
        documents = loader.load()

        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=500,
            chunk_overlap=50
        )
        splits = text_splitter.split_documents(documents)

        return Chroma.from_documents(
            documents=splits,
            embedding=self.embeddings,
            persist_directory="./kb_chroma"
        )

    async def classify_intent(self, question: str) -> str:
        """意图分类"""
        chain = self.intent_prompt | self.llm | StrOutputParser()
        return await chain.ainvoke({"question": question})

    async def retrieve_context(self, question: str, k: int = 3) -> str:
        """检索相关上下文"""
        docs = self.vectorstore.similarity_search(question, k=k)
        return "\n\n".join([doc.page_content for doc in docs])

    async def generate_response(
        self,
        question: str,
        intent: str,
        context: str
    ) -> str:
        """生成回答"""
        chain = self.answer_prompt | self.llm | StrOutputParser()
        return await chain.ainvoke({
            "question": question,
            "intent": intent,
            "context": context
        })

    async def chat(self, question: str) -> dict:
        """完整对话流程"""
        # 1. 意图识别
        intent = await self.classify_intent(question)

        # 2. 知识检索
        context = await self.retrieve_context(question)

        # 3. 生成回答
        response = await self.generate_response(question, intent, context)

        return {
            "intent": intent,
            "context": context,
            "response": response
        }

# 使用示例
async def main():
    bot = CustomerServiceBot("./knowledge_base")

    result = await bot.chat("我的订单什么时候能到?")
    print(f"意图:{result['intent']}")
    print(f"回答:{result['response']}")

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

3.4 LangGraph:状态化工作流

对于复杂的状态管理,LangGraph 提供了更强大的能力:

sql 复制代码
┌─────────────────────────────────────────────────────────┐
│                  LangGraph 工作流                        │
├─────────────────────────────────────────────────────────┤
│                                                         │
│   ┌─────────┐     ┌─────────┐     ┌─────────┐         │
│   │ intent  │────▶│retrieve │────▶│generate │         │
│   │ 意图识别│     │ 检索    │     │ 生成    │         │
│   └─────────┘     └─────────┘     └─────────┘         │
│                                        │               │
│                                        ▼               │
│                                   ┌─────────┐         │
│                                   │  END    │         │
│                                   └─────────┘         │
└─────────────────────────────────────────────────────────┘

完整 LangGraph 实现

python 复制代码
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver
from typing import TypedDict, Annotated
import operator

# 定义状态
class GraphState(TypedDict):
    question: str
    intent: str
    context: str
    answer: str
    iterations: int
    messages: Annotated[list, operator.add]

# 定义节点函数
def intent_node(state: GraphState) -> dict:
    """意图识别节点"""
    from langchain_openai import ChatOpenAI
    from langchain_core.prompts import ChatPromptTemplate

    model = ChatOpenAI(model="gpt-4")
    prompt = ChatPromptTemplate.from_template("""
    判断问题意图:
    - product: 产品咨询
    - order: 订单查询
    - refund: 退款问题
    - technical: 技术支持

    问题:{question}
    只输出类别:
    """)

    chain = prompt | model
    intent = chain.invoke({"question": state["question"]}).content.strip()

    return {
        "intent": intent,
        "messages": [{"role": "system", "content": f"识别意图: {intent}"}]
    }

def retrieve_node(state: GraphState) -> dict:
    """检索节点"""
    # 这里实现检索逻辑
    # 实际应用中连接向量数据库
    context = f"关于 {state['intent']} 的相关知识..."

    return {
        "context": context,
        "messages": [{"role": "system", "content": "完成知识检索"}]
    }

def generate_node(state: GraphState) -> dict:
    """生成节点"""
    from langchain_openai import ChatOpenAI
    from langchain_core.prompts import ChatPromptTemplate

    model = ChatOpenAI(model="gpt-4")
    prompt = ChatPromptTemplate.from_template("""
    基于以下信息回答问题:

    意图:{intent}
    知识:{context}
    问题:{question}

    回答:
    """)

    chain = prompt | model
    answer = chain.invoke({
        "intent": state["intent"],
        "context": state["context"],
        "question": state["question"]
    }).content

    return {
        "answer": answer,
        "iterations": state.get("iterations", 0) + 1,
        "messages": [{"role": "assistant", "content": answer}]
    }

def should_continue(state: GraphState) -> str:
    """判断是否继续"""
    if state.get("iterations", 0) >= 3:
        return END
    if "不确定" in state.get("answer", ""):
        return "retrieve"
    return END

# 构建图
workflow = StateGraph(GraphState)

# 添加节点
workflow.add_node("intent", intent_node)
workflow.add_node("retrieve", retrieve_node)
workflow.add_node("generate", generate_node)

# 添加边
workflow.set_entry_point("intent")
workflow.add_edge("intent", "retrieve")
workflow.add_edge("retrieve", "generate")

# 添加条件边
workflow.add_conditional_edges(
    "generate",
    should_continue,
    {
        "retrieve": "retrieve",
        END: END
    }
)

# 编译并添加记忆
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)

# 执行
result = app.invoke(
    {"question": "我的订单什么时候能到?", "iterations": 0},
    config={"configurable": {"thread_id": "user_123"}}
)
print(result["answer"])

3.5 部署与生产实践

3.5.1 LangServe 部署

python 复制代码
# server.py
from langserve import add_routes
from fastapi import FastAPI
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

app = FastAPI(title="LangChain Server")

# 定义链
prompt = ChatPromptTemplate.from_template("{topic}")
model = ChatOpenAI(model="gpt-4")
chain = prompt | model | StrOutputParser()

# 添加路由
add_routes(app, chain, path="/chat")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

3.5.2 LangSmith 监控

python 复制代码
import os

# 配置 LangSmith
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-api-key"
os.environ["LANGCHAIN_PROJECT"] = "your-project-name"

# 所有链的执行都会自动记录到 LangSmith

3.6 GitHub 项目推荐

项目 描述 链接
LangChain 核心框架 github.com/langchain-a...
LangGraph 状态化工作流 github.com/langchain-a...
LangServe 部署服务 github.com/langchain-a...
LangSmith 调试与监控 smith.langchain.com
LangChain Templates 应用模板 github.com/langchain-a...


欢迎关注的我的公众号《码上未来》,一起交流AI前沿技术!

扫码二维码加我微信进群聊AI

相关推荐
踩着两条虫3 小时前
VTJ.PRO 在线应用开发平台入门与项目初始化
前端·人工智能·ai编程
改一下配置文件3 小时前
OpenClaw Docker部署踩坑全记录(OpenClaw v2026.3.23)
docker·openai
程序员陆业聪4 小时前
Harness Engineering 给我的启发:用 AI 做 Android 需求,怎么不翻车
ai编程
程序员鱼皮4 小时前
我的免费 OpenClaw 零基础教程,爆了!
ai·程序员·编程·ai编程·openclaw
ApeAssistant4 小时前
AI 都能写代码了,我们还在意光标是否丝滑吗?
ai编程·intellij idea
攻城狮_老李4 小时前
从零开始理解 Agent Skills - 认识 Agent Skills
openai·agent
CaracalTiger5 小时前
Windows 环境下 OpenClaw 的安装与千问Qwen、Kimi、MiniMax、GLM国产大模型配置完全指南
运维·ide·windows·开源·github·aigc·ai编程
AI_Ming5 小时前
从0开始学AI:Transformer,原来是这回事!
人工智能·openai·ai编程
AI_Ming5 小时前
从0开始学AI:Embedding,原来是这回事!
算法·ai编程