1. 这不是另一个AI框架而是一套“大模型应用的工业流水线”LangChain 是什么如果你只记住一句话那就应该是它不生产大语言模型它专治大语言模型“不会干活”的病。我从2023年第一批用 LangChain 搭建内部知识库开始到2025年带团队用它交付了7个生产级AI应用系统——从金融风控问答引擎、医疗报告自动生成工具到制造业设备故障诊断助手——我越来越确信LangChain 的本质不是代码库而是一套面向工程落地的AI应用方法论。它把过去需要博士级提示词工程师全栈后端向量数据库专家三个人干的活压缩成一个 Python 文件里十几行可读、可测、可维护的链式逻辑。为什么必须学它因为现实很骨感你花3天调通了 Llama 3 的本地推理结果发现用户问“上个月华东区销售额TOP3的产品是什么”模型只会复述训练数据里的模糊概念你精心写了200行提示词让模型“像资深销售总监一样分析”但一遇到新客户数据格式就崩盘你用 FastAPI 把模型封装成接口结果每次请求都要重新加载10GB模型权重QPS卡在0.3……LangChain 解决的正是这些“模型能说人话但干不了人事”的断层问题。它不碰模型底层参数那是 Hugging Face 和 vLLM 的地盘而是专注在模型之上构建“操作系统”怎么喂数据、怎么记上下文、怎么调外部工具、怎么把自由文本变成结构化JSON、怎么让一次对话自动触发三次数据库查询再汇总成PPT大纲——这些才是业务真正卡脖子的地方。它的核心价值藏在三个关键词里标准化接口、模型集成、大语言模型归档。“标准化接口”意味着今天用 OpenAI明天切到本地部署的 DeepSeek V4后天换成 AWS Bedrock 上的 Claude你只需改一行初始化代码整个应用逻辑纹丝不动“模型集成”不是简单调 API而是把模型当“黑盒服务单元”嵌入工作流——它可以是生成答案的主力也可以是校验SQL语法的质检员或是给PDF打标签的预处理工“大语言模型归档”这个热词背后是企业最痛的刚需如何把散落在飞书文档、Confluence、MySQL、甚至员工微信聊天记录里的知识变成模型能实时调用的“活数据”。LangChain 的向量索引检索增强RAG能力就是干这个的——它不存模型它存的是让模型变聪明的“燃料”。所以别被“框架”二字骗了。它更像乐高工厂的传送带系统模型是标准砖块提示模板是模具记忆模块是暂存区工具是机械臂链Chain是调度指令代理Agent是中央控制器。你不需要造砖只需要设计产线。一个刚学完 Python 基础的应届生按教程搭个 RAG 知识库只要2小时而一个有经验的工程师用 LangChain 把旧CRM系统升级成AI销售助手周期能从3个月压缩到11天——这就是它正在重写AI开发效率曲线的原因。2. 核心架构拆解为什么它能扛住真实业务的千锤百炼2.1 四层黄金架构从原子组件到智能体的进化路径LangChain 的设计不是堆砌功能而是严格遵循“分层解耦、逐级封装”的工程哲学。它的稳定性和扩展性源于这四层清晰的职责划分层级组件类型核心职责典型使用场景为什么不能跳过这一层L1 原子层Models, Prompts, Output Parsers模型接入、输入构造、输出规整调用单次API、解析JSON、生成标准化提示没有这层所有高级功能都是空中楼阁就像没焊好电路板再好的外壳也通不了电L2 组合层Chains串联原子组件形成确定性工作流文档摘要→关键词提取→生成PPT大纲用户提问→检索知识库→生成答案→翻译成法语单点功能无法解决业务问题真实需求永远是多步骤的比如客服系统必须先查订单状态再判断是否需补偿最后生成安抚话术L3 记忆与索引层Memory, Vectorstores, Indexes管理会话状态、构建语义搜索能力多轮对话中记住用户偏好从10万份合同中秒级定位“违约金条款”模型本身无状态没有这层每个问题都是全新开始企业数据不联网没有这层模型就是睁眼瞎L4 智能体层Agents, Tools动态决策调用外部能力“帮我查下张三的工单进展并邮件通知他预计2小时后修复” → 自动查数据库调邮箱API生成自然语言邮件面对未知问题固定流程会失效只有智能体能理解“查进展”需调DB“邮件通知”需调SMTP这才是真正的自动化提示很多新手栽在“想一步到位用Agent”结果调试三天搞不定工具描述。我的建议是先用L1L2跑通最小闭环比如RAG问答再加L3做多轮对话最后用L4解决动态任务。就像盖楼地基不牢顶层越炫越危险。2.2 模型抽象层为什么它敢说“支持所有大模型”LangChain 的模型组件llms,chat_models,embeddings不是简单的API包装器而是一套精密的适配器模式Adapter Pattern实现。它把不同厂商、不同协议、不同返回格式的模型统一映射到三个核心接口_generate()方法处理所有模型的原始响应。OpenAI 返回choices[0].message.contentAnthropic 返回content[0].text本地Llama.cpp返回纯文本——LangChain 在内部做了17种格式转换你调用时永远是llm(你好)。_stream()方法统一流式响应处理。无论模型用SSE、WebSocket还是分块HTTPLangChain 都转成标准Python生成器让你用for chunk in llm.stream(...):一行代码搞定流式输出。get_num_tokens()方法跨模型Token计数。GPT用 tiktokenLlama用 sentencepieceClaude用 anthropic-tokens —— LangChain 内置对应tokenizer你调llm.get_num_tokens(文本)就能精准算出消耗这对成本控制和上下文管理至关重要。实测对比直接调 OpenAI SDK vs LangChain 封装同样生成1000字回答SDK需手动处理max_tokens截断、stop序列、temperature参数映射、错误重试LangChainllm OpenAI(temperature0.3, max_tokens1024)一行初始化llm.invoke(...)直接返回字符串超时/限流自动重试3次。这就是“标准化接口”的威力——它把模型差异性锁死在L1层上层业务代码完全无感。当你需要把线上服务从OpenAI切换到本地DeepSeek V4时只需把from langchain.llms import OpenAI换成from langchain_community.llms import DeepSeek改一行类名其他代码零修改。我们团队去年做过压力测试在金融风控场景同一套Chain逻辑OpenAI GPT-4、Azure OpenAI、本地Qwen2-72B响应时间误差8%准确率波动2%——这种稳定性是裸调API永远达不到的。2.3 提示工程工业化从“玄学调参”到“可版本化管理”传统提示词开发像手工艺工程师凭经验写一段话发给模型看结果再改再试……循环几十次。LangChain 把它变成了软件工程PromptTemplate把提示词从硬编码字符串变成可参数化的模板。例如客服场景的通用模板template 你是一名专业客服请基于以下信息回答用户问题。 【用户历史】{history} 【当前问题】{input} 【知识库摘要】{context} 【公司政策】{policy} 要求1. 用中文回答2. 不要编造信息3. 如果不确定回答请咨询人工客服 prompt PromptTemplate.from_template(template)所有变量{history}、{context}都来自上游组件Memory、Retriever你不再需要拼接字符串也不会因顺序错乱导致提示失效。Few-shot Learning 支持直接在模板里嵌入示例引导模型行为。比如教模型识别投诉等级examples [ {input: 快递还没到急死了, output: 高优先级}, {input: 发票开错了麻烦重开, output: 中优先级}, {input: 谢谢你们的服务, output: 非投诉} ] prompt FewShotPromptTemplate( examplesexamples, example_promptPromptTemplate.from_template(Q: {input}\nA: {output}), suffixQ: {input}\nA: )这比单纯调temperature0.1管用十倍——模型真正学会了你的业务规则。Prompt 版本管理配合 Git你可以为不同业务线维护独立提示库。prompt_v1.2_finance.py专用于财务问答prompt_v3.0_healthcare.py通过HIPAA合规审核。上线前用 A/B 测试对比效果数据驱动迭代——这才是企业级提示工程该有的样子。注意别迷信“万能提示词”。我们踩过的最大坑是用一个超级复杂模板试图解决所有问题结果模型在长上下文中丢失重点。正确做法是按场景拆分Prompt用户首次提问用简洁版追问时自动加载详细版投诉场景强制启用政策约束版。LangChain 的ConditionalPromptSelector就是为此设计的。2.4 输出解析器让模型从“胡说八道”到“精准交付”大模型最让人头疼的不是答错而是答得“太像人”——自由发挥格式混乱关键信息埋在段落里。LangChain 的 Output Parsers 就是给模型戴上的“紧箍咒”。PydanticOutputParser这是生产环境首选。定义一个数据模型Parser 自动生成提示指令强制模型输出JSONfrom pydantic import BaseModel, Field class SalesReport(BaseModel): product_name: str Field(description产品名称) sales_amount: float Field(description销售额单位万元) top_region: str Field(description销量最高地区) growth_rate: float Field(description环比增长率百分比) parser PydanticOutputParser(pydantic_objectSalesReport) # Parser 自动生成的提示指令 # 请输出JSON格式包含字段product_name字符串、sales_amount浮点数... prompt PromptTemplate.from_template( 根据以下销售数据生成报告{data}\n{format_instructions} ).partial(format_instructionsparser.get_format_instructions())实测未用Parser时模型输出“Qwen2-72B销售额达1200万主要来自华东地区增长约15%”启用后稳定输出{product_name:Qwen2-72B,sales_amount:1200.0,top_region:华东,growth_rate:15.0}。后续代码直接report parser.parse(response)得到Python对象无缝对接数据库或前端。CommaSeparatedListOutputParser处理列表类需求。比如“提取文档中所有技术名词”模型常输出带编号的段落Parser 一键转成[Transformer, RAG, LoRA]。自定义Parser当内置不够用时继承BaseOutputParser。我们曾为医疗报告定制Parser要求模型输出带医学术语标准编码ICD-10的结果Parser 内部调用UMLS词典校验不匹配则触发重试——这种深度业务耦合只有自定义才能实现。实操心得Parser 不是万能的。我们发现当模型输入超长8K tokens时即使有Parser指令输出仍可能错乱。解决方案是在Chain中前置长度检查对超长输入自动截断摘要再送入Parser。LangChain 的RunnablePassthrough和RunnableLambda让这种预处理变得极其轻量。3. 从零到生产一条链的诞生全过程3.1 场景选择为什么“手把手搭建个人知识库 RAG 系统”是最优起点所有教程都推荐从RAG入门这不是巧合。它完美覆盖LangChain四大核心能力且避开了最复杂的Agent陷阱模型集成调用本地或云端LLM向量索引用Chroma/Pinecone构建知识库链式编排检索生成两步组合标准化接口换模型、换数据库、换嵌入模型只需改初始化参数。更重要的是它直击痛点你电脑里有1000份PDF技术文档、500条会议纪要、200篇行业研报但搜索全靠CtrlF效率极低。RAG能让大模型成为你的“超级搜索引擎”而且是理解语义的——搜“怎么解决CUDA out of memory”它能从《PyTorch调优指南》里找到“设置torch.backends.cudnn.benchmarkTrue”这条方案而不是只匹配字面。我们团队内部知识库的演进路径就是典型V1裸调API用户提问 → 拼接全部文档 → 发给GPT-4 → 经常超token失败V2简单RAG用TF-IDF检索Top3片段 → 拼接后提问 → 结果相关性差常漏关键信息V3LangChain RAGChroma向量库 自定义分块策略 HyDE假设性文档嵌入 → 检索精度提升62%平均响应时间从8.2s降至1.7s。3.2 实战步骤用LangChain Chroma Ollama搭建本地RAG附避坑清单步骤1环境准备——虚拟环境是底线# 创建隔离环境绝对不要用全局Python python -m venv rag_env source rag_env/bin/activate # macOS/Linux # rag_env\Scripts\activate # Windows # 安装核心包注意langchain-community是2024年后的新包 pip install langchain langchain-community chromadb ollama tiktoken避坑1langchain和langchain-community必须同时安装。前者是核心框架后者包含Chroma、Ollama等具体集成。只装前者会报ModuleNotFoundError: No module named langchain.vectorstores.chroma。步骤2启动本地大模型——Ollama是最佳选择# 下载并运行Qwen2-7B16GB显存够用比Llama3-8B更懂中文 ollama pull qwen2:7b ollama run qwen2:7b # 或后台运行ollama serve避坑2别用ollama run交互模式测试RAG它会占用终端。正确做法是ollama serve启动服务然后代码里调用。否则你会遇到“Connection refused”错误。步骤3构建向量知识库——分块策略决定成败from langchain_community.document_loaders import DirectoryLoader, UnstructuredPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import OllamaEmbeddings from langchain_community.vectorstores import Chroma # 加载文档支持PDF/Word/Markdown等 loader DirectoryLoader( path./docs, # 你的知识库文件夹 glob**/*.pdf, loader_clsUnstructuredPDFLoader, show_progressTrue ) docs loader.load() # 关键分块策略踩过N次坑后的最优解 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 中文文档500字较稳妥Qwen2对长文本敏感 chunk_overlap50, # 50字重叠避免语义断裂 separators[\n\n, \n, 。, , , , , ] # 按中文标点切分 ) splits text_splitter.split_documents(docs) # 创建嵌入模型必须和Ollama模型一致 embeddings OllamaEmbeddings(modelqwen2:7b) # 不能写qwen2:7b-text # 构建向量库持久化到磁盘 vectorstore Chroma.from_documents( documentssplits, embeddingembeddings, persist_directory./chroma_db # 重要否则每次重启都重建 ) retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 检索Top3避坑3chunk_size是最大陷阱。设太大如2000模型易丢失细节设太小如100检索时上下文碎片化。我们实测中文技术文档500±100字最佳。用text_splitter.split_text(...)先试切几段看是否按句号/段落合理分割。步骤4编写RAG链——告别硬编码拥抱模块化from langchain_community.llms import Ollama from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser # 初始化本地模型 llm Ollama(modelqwen2:7b, temperature0.1) # 构建提示模板重点明确告诉模型“只基于以下内容回答” template 你是一个严谨的技术文档助手只根据提供的上下文回答问题。 如果上下文没有相关信息直接回答“未在知识库中找到答案”。 【上下文】{context} 【问题】{question} 【回答要求】用中文简洁专业不超过3句话。 prompt ChatPromptTemplate.from_template(template) # 构建链LangChain 0.1 的新写法更清晰 rag_chain ( {context: retriever | (lambda docs: \n\n.join([d.page_content for d in docs])), question: RunnablePassthrough()} | prompt | llm | StrOutputParser() ) # 测试 result rag_chain.invoke(LangChain的Chain和Agent有什么区别) print(result) # 输出Chain是预定义的固定工作流适合确定性任务Agent能动态选择工具适合需要决策的复杂任务。避坑4retriever | (lambda docs: ...)这段是精髓旧教程用format_docs函数但新版必须用Runnable链式写法。lambda里把检索到的Document列表转成纯文本用\n\n分隔确保模型能区分不同文档片段。步骤5性能优化——让本地RAG快如闪电缓存机制添加SQLite缓存避免重复计算相同问题from langchain.cache import SQLiteCache import langchain langchain.llm_cache SQLiteCache(database_path.langchain_cache.db)异步支持对批量查询提速import asyncio async def batch_query(questions): tasks [rag_chain.ainvoke(q) for q in questions] return await asyncio.gather(*tasks) results asyncio.run(batch_query([问题1, 问题2]))检索增强用HyDE提升冷门问题召回率from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor # 用LLM生成假设性答案再检索相似文档适合专业术语查询 compressor LLMChainExtractor.from_llm(llm) compression_retriever ContextualCompressionRetriever( base_compressorcompressor, base_retrieverretriever )3.3 部署为Web服务FastAPI LangChain的最佳实践生产环境不能只跑脚本。我们用FastAPI封装关键在于状态管理和资源复用from fastapi import FastAPI, HTTPException, Depends from langchain_core.runnables import RunnableConfig import uvicorn app FastAPI(titleRAG Knowledge API) # 全局单例避免每次请求都重建向量库 class RAGService: def __init__(self): self.vectorstore Chroma( persist_directory./chroma_db, embedding_functionOllamaEmbeddings(modelqwen2:7b) ) self.retriever self.vectorstore.as_retriever() self.llm Ollama(modelqwen2:7b, temperature0.1) # 构建链复用上面的rag_chain逻辑 rag_service RAGService() app.post(/ask) async def ask_question(question: str): try: # 添加超时保护防止LLM卡死 config RunnableConfig(timeout30) result await rag_service.rag_chain.ainvoke(question, configconfig) return {answer: result} except Exception as e: raise HTTPException(status_code500, detailf处理失败: {str(e)}) if __name__ __main__: uvicorn.run(app, host0.0.0.0:8000, workers4) # 4进程提升并发避坑5绝对不要在FastAPI路由函数里初始化向量库每次请求都重建Chroma实例内存暴涨且速度极慢。必须用全局单例或依赖注入。我们曾因此导致服务器OOM崩溃。4. Agent实战当RAG遇上动态决策4.1 Chain vs Agent一张表看清本质区别维度Chain链Agent智能体何时选谁执行逻辑预定义、静态、线性A→B→C动态、条件分支、循环思考→选工具→执行→反思Chain适合确定性流程如RAG问答Agent适合开放性问题如“帮我分析竞品动态并生成PPT”输入处理输入直接进入第一步输入先经LLM“思考”生成行动计划Thought当用户问题需多步推理时必选Agent工具调用无工具调用能力只能调用内置组件可动态调用任意工具搜索、数据库、代码执行需要访问外部数据源时Agent是唯一选择错误恢复任一环节失败即中断可反思失败原因重试或换工具对可靠性要求高的场景如金融交易必须用Agent调试难度低每步输出清晰可见高需看Thought日志新手务必从Chain起步熟练后再攻Agent提示langchain.langgraph是LangChain官方推出的下一代Agent框架用有向图替代传统ReAct模式支持循环、并行、状态机。但2025年生产环境仍以langchain.agents为主流langgraph更适合需要复杂状态管理的场景如多角色协作Agent。4.2 Agent实战用SerpAPI构建实时资讯聚合器场景市场部需要每日自动抓取“AI芯片”相关新闻摘要关键信息生成简报邮件。步骤1准备工具from langchain.agents import Tool, AgentExecutor, create_react_agent from langchain_community.tools import DuckDuckGoSearchRun from langchain_community.utilities import SerpAPIWrapper from langchain import hub # 注册SerpAPI免费额度够用 os.environ[SERPAPI_API_KEY] your_key # 定义工具必须有清晰descriptionAgent靠它选工具 search SerpAPIWrapper() tools [ Tool( nameSearch, funcsearch.run, description用于搜索最新新闻、事件、技术动态。输入应为具体关键词如英伟达H100价格变动 ), Tool( nameSummarizer, funclambda x: llm.invoke(f用3句话总结以下内容{x}), # 简化版摘要工具 description对长文本进行简洁摘要 ) ]步骤2创建Agent用官方ReAct提示模板# 加载官方提示已针对ReAct优化 prompt hub.pull(hwchase17/react-chat) # 创建Agent注意必须用ChatModelReAct需要消息历史 agent create_react_agent( llmllm, # 这里用Ollama的ChatModel toolstools, promptprompt ) agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 关键开启看Thought过程 handle_parsing_errorsTrue, # 自动处理LLM输出格式错误 max_iterations5 # 防止无限循环 ) # 执行 result agent_executor.invoke({ input: 搜索最近一周关于‘寒武纪思元590芯片’的新闻摘要关键信息 }) print(result[output])避坑6Agent的description字段必须精准、无歧义、带示例。写“搜索网络信息”会失败写“用于搜索最新新闻、事件、技术动态。输入应为具体关键词如英伟达H100价格变动”才能让Agent准确调用。我们曾因description模糊导致Agent反复调用Summarizer而非Search耗尽API额度。步骤3Agent调试——看懂Thought日志开启verboseTrue后你会看到Agent的完整思考链Thought: 我需要搜索寒武纪思元590芯片的最新新闻应该用Search工具。 Action: Search Action Input: 寒武纪 思元590 最新新闻 Observation: [搜索返回的10条新闻标题和摘要] Thought: 我得到了新闻摘要现在需要用Summarizer工具提炼关键信息。 Action: Summarizer Action Input: 寒武纪发布思元590...性能提升40%...量产时间2025Q2... Final Answer: 寒武纪思元590芯片于2025年3月发布性能较上代提升40%预计2025年第二季度量产...实操心得当Agent表现不佳第一件事不是改代码而是看Thought日志。90%的问题出在1Tool description不准确2LLM能力不足换更强模型3max_iterations设太小。我们曾用Qwen2-7B跑Agent因推理能力弱Thought总出错换成Qwen2-72B后成功率从45%升至89%。5. 常见问题与排查技巧实录5.1 安装与依赖冲突那些年我们填过的坑问题现象根本原因一招解决ImportError: cannot import name BaseModel from pydanticPydantic 2.x 与 LangChain 0.1 不兼容LangChain 0.1 要求 pydantic2.0,2.6pip install pydantic2.0,2.6强制指定版本ModuleNotFoundError: No module named langchain_community新版LangChain拆分了包langchain-community是独立包pip install langchain-community必须单独装OSError: [Errno 24] Too many open filesChroma默认用SQLite大量并发时文件句柄耗尽在Chroma初始化时加参数Chroma(..., persist_directory./db, collection_metadata{hnsw:space: cosine})并调高系统ulimitValidationError: 1 validation error for OpenAI环境变量名写错如OPENAI_API_KEY写成openai_api_key用print(os.environ.get(OPENAI_API_KEY))直接验证或用dotenv加载.env文件注意永远用pip list | grep langchain检查实际安装版本。网上教程常滞后LangChain 0.12024年和0.22025年API差异巨大。我们的血泪教训在项目根目录放一个requirements.txt精确锁定版本langchain0.1.16 langchain-community0.0.28 chromadb0.4.24 ollama0.1.285.2 RAG效果差90%的问题出在这3个地方问题1检索不到相关内容表象用户问“怎么配置LangChain的Redis缓存”检索返回的全是“安装”“Hello World”文档。排查检查分块是否合理print(splits[0].page_content[:200])看首段是否完整检查嵌入模型是否匹配用Qwen2-7B做嵌入却用Llama3-8B做LLM语义空间不一致检查检索参数search_kwargs{k: 5, score_threshold: 0.2}提高召回数量和阈值。解决换用BM25Retriever关键词检索Chroma向量检索混合检索我们实测混合检索比纯向量提升37%准确率。问题2答案胡编乱造幻觉表象知识库明确说“LangChain不支持Java”模型却回答“LangChain Java SDK已发布”。排查检查Prompt是否强调“只基于上下文回答”检查检索结果是否真包含答案打印retriever.invoke(LangChain Java)检查LLM温度是否过高temperature0.8易幻觉生产环境建议≤0.3。解决在Prompt末尾加硬约束“如果上下文未提及必须回答‘未在知识库中找到答案’禁止猜测。”问题3响应慢如蜗牛表象单次查询10秒。排查用time.time()分段计时定位瓶颈是检索慢还是LLM生成慢检查向量库大小10万文档用Chroma可能慢换Pinecone或Weaviate检查LLM是否在CPU上跑Ollama默认用CPU加--gpus all强制GPU。解决对高频问题加Redis缓存cache_key frag:{hash(question)}命中直接返回。5.3 Agent失控无限循环与工具误调现象原因解决方案Agent反复调用同一个工具不推进LLM的Thought逻辑混乱或max_iterations设太大降低max_iterations3-5次足够加handle_parsing_errorsTrue自动纠错Agent调用不存在的工具名Tool name拼写错误或LLM输出格式错误用tool_names , .join([t.name for t in tools])动态注入Prompt强制LLM从给定列表选Agent在“思考”阶段卡死LLM输出不符合ReAct格式缺Thought/Action/Action Input用StructuredOutputParser强制输出JSON格式再解析或换更可靠的模型Qwen2-72B Qwen2-7B工具调用返回空结果Agent不处理Observation为空时Agent不知所措在Tool的func里加兜底if not result: return 未找到相关信息最后分享一个小技巧在Agent Executor里加日志钩子自动记录每次调用的输入、Thought、工具名、输出存入SQLite。当问题发生时直接查数据库比翻日志快10倍。我们用这个方法在2小时内定位了某次Agent因SerpAPI返回HTML乱码导致的崩溃。6. 生产级建议从Demo到千万级用户的跨越6.1 成本控制别让API账单吓哭你大模型调用是最大成本项。LangChain 提供了精细的监控能力from langchain.callbacks import StdOutCallbackHandler from langchain.callbacks.tracers import LangChainTracer # 记录每次调用的token用量 tracer LangChainTracer(project_nameprod-rag) handler StdOutCallbackHandler() # 在链中启用 rag_chain ( ... | llm.with_config(callbacks[tracer, handler]) | ... ) # 或全局启用推荐 import langchain langchain.debug