尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI Agent开发实战:RAG、Skills、MCP与LangChain协同架构

AI Agent开发实战:RAG、Skills、MCP与LangChain协同架构 1. 这不是“速成课”而是一份AI Agent开发者的上岗说明书你点开这个标题大概率是刚被“Agent”这个词刷屏——朋友圈在聊、技术群在推、招聘JD里写着“熟悉LangChain/RAG/MCP者优先”连产品经理都在会议里甩出“我们要上Agentic Workflow”。但翻完一堆教程发现要么是调用一个API就喊“搞定”要么是直接扔给你300行看不懂的LangGraph代码中间那层“人怎么想、系统怎么拆、问题怎么解”的真实逻辑全被省略了。这就像教人修车只告诉你“拧紧螺丝”却不讲扭矩值为什么是25N·m、为什么必须按对角顺序、为什么垫片方向错了会漏油。本篇不讲虚的它是我带过7个AI工程落地项目后把所有踩过的坑、删掉的冗余、验证过的最小可行路径全部摊开重写的一份实操手册。核心关键词就五个AI Agent、RAG、Skills、MCP、LangChain——它们不是并列关系而是分层协作的齿轮组。Agent是总控大脑RAG是它的长期记忆库Skills是它能调用的手和脚比如查天气、读PDF、发邮件MCP是让不同工具之间说同一种语言的翻译协议LangChain则是把这四块拼图焊在一起的焊接台。DeepSeek这类模型属于底层引擎它不决定“做什么”只负责“怎么做得更准”而Agent架构决定的是“先查资料、再对比方案、最后生成报告”这一整套决策链路。如果你的目标是能独立设计一个能自动整理会议纪要提取待办同步到飞书的日程助理而不是只会跑通一个hello world demo那这篇就是为你写的。它不承诺“三天学会”但保证你每一步操作背后都有明确意图、可验证结果、可复盘依据。2. 为什么必须放弃“从零开始学Python”的老路Agent开发的本质是系统工程思维2.1 把Agent当成“人”来设计而不是当“函数”来调用绝大多数新手教程失败的根本原因在于一开始就陷入技术细节先装Python再pip install langchain然后抄一段retriever代码……这相当于想造一辆能自动驾驶的车却先去研究火花塞间隙。真正的起点是你得先定义清楚这个Agent要解决什么具体问题。比如“帮销售团队自动分析竞品发布会视频”这个需求拆解下来至少包含四个不可跳过的环节理解层把视频转成文字ASR再用LLM提取关键信息如新品参数、定价策略记忆层把历史竞品资料存进向量库支持语义搜索这就是RAG执行层调用企业微信API发送摘要或用Playwright自动登录CRM填入新线索协调层当用户问“对比A和B两款产品”Agent必须知道先查A的资料、再查B的资料、最后做表格对比——这个决策顺序不能硬编码得靠Agent框架动态规划。LangChain不是万能胶它是帮你把这四层粘合起来的胶水MCP不是魔法协议它是让“查CRM”和“读PDF”这两个完全不同的工具能互相听懂对方在说什么的翻译官。我见过太多人卡在第一步花两周配好向量库却没想明白“用户到底会问什么问题”。比如销售最常问的是“竞品X最近三个月降价几次每次降多少”这就决定了你的RAG知识库必须按时间维度切块而不是简单按文档切块。切块策略错了检索准确率再高也没用——因为召回的永远是“最新发布会全文”而不是“降价记录段落”。2.2 RAG不是“加个向量库就完事”它是知识管理的重新设计RAGRetrieval-Augmented Generation常被简化为“检索大模型生成”但实际落地时90%的问题出在“检索”之前。我们曾为一家医疗器械公司搭建产品问答系统初期用默认的text-splitter按512字符切块结果用户问“支架植入后抗凝药怎么调整”系统返回了《心血管介入手术指南》全文——因为所有段落都含“支架”“抗凝”关键词但真正答案藏在第17页的“术后用药管理”小节里。后来我们做了三件事才解决结构化切块用PDF解析工具识别标题层级强制按“章节→小节→段落”三级切分确保“抗凝药调整”这个子主题独立成块元数据注入给每个块打上{doc_type:指南,section:术后管理,update_date:2024-03}标签检索时加filter条件混合检索不只靠向量相似度还叠加关键词匹配如必须含“华法林”“INR”等术语和BM25打分。这说明RAG的核心不是算法而是对业务知识的理解深度。你得像档案管理员一样思考这份资料谁会用在什么场景下用最可能怎么问——这些决定了切块方式、元数据字段、检索策略。网上那些“RAG实战”教程90%只教你怎么装ChromaDB却从不告诉你为什么要把PDF转成Markdown再切块而不是直接丢进PDFLoader。因为PDF里的页眉页脚、表格线、页码全是噪声会严重污染向量表示。实测下来用PyMuPDF解析后再用unstructured清理格式比直接用PyPDF2准确率高37%。2.3 Skills不是“写几个function”而是定义Agent的能力边界Skills技能常被误解为“能调用API就行”但真正决定Agent鲁棒性的是Skill的输入校验、错误兜底、状态反馈机制。举个真实案例我们给HR系统做的简历筛选Agent最初写的fetch_candidate_info(candidate_id)Skill只处理正常返回结果某天招聘系统维护接口返回503。Agent直接卡死后续流程全停。后来重构为def fetch_candidate_info(candidate_id: str) - dict: try: # 带超时和重试 response requests.get(f/api/candidate/{candidate_id}, timeout10) response.raise_for_status() return response.json() except requests.exceptions.Timeout: return {error: timeout, retry_after: 30} # 告诉Agent等30秒再试 except requests.exceptions.HTTPError as e: if e.response.status_code 404: return {error: not_found, candidate_id: candidate_id} else: return {error: server_error, status_code: e.response.status_code}关键变化有三点明确错误分类不是笼统的except Exception而是区分超时、404、5xx因为Agent需要不同应对策略重试/跳过/告警返回结构化错误用字典而非字符串让Agent能解析error类型并触发对应分支提供恢复线索retry_after告诉Agent何时重试candidate_id保留上下文避免丢失任务。这背后是Skills设计的黄金法则每个Skill必须能回答三个问题——成功时返回什么失败时返回什么失败后Agent该怎么办网上教程教你怎么写def search_web(query)却从不提query为空时该返回空列表还是抛异常更不会告诉你如何让Agent在连续三次搜索失败后自动切换到本地知识库兜底。这才是Skills的真正难点。3. MCP被严重低估的“Agent世界的HTTP协议”3.1 MCP不是新技术而是解决“工具方言混乱”的务实方案MCPModel Context Protocol常被包装成“下一代Agent协议”但剥开概念它本质是给工具调用定一套通用语法。想象一下你家有小米空调、华为音箱、海尔冰箱如果每个品牌都用自己App控制你就得装三个App、记三套指令。MCP就是让所有设备都支持“统一遥控器”——它定义了一套标准消息格式JSON Schema规定“调温度”必须包含{device: aircon, action: set_temperature, value: 26}而不是小米的{cmd: temp, para: 26}、华为的{intent: adjust_temp, target: 26}。在Agent开发中MCP解决的是同样问题当你想让Agent既能查飞书日历、又能读Notion数据库、还能调用内部CRM每个系统API都长得不一样。LangChain的Tool抽象层试图统一但实际中仍需为每个工具写Adapter。MCP则前进一步它要求工具开发者按标准实现/mcp/tools端点返回所有可用功能的Schema描述Agent只需一次发现就能自动生成调用代码。我们实测过接入一个支持MCP的浏览器扩展如WorkbuddyAgent无需写一行新代码就能自动获得“截当前页”“提取网页文本”“保存到Notion”三项能力——因为扩展已按MCP规范暴露了这些功能的输入输出定义。3.2 如何判断一个工具是否真支持MCP看这三个硬指标很多教程说“启用MCP连接”就万事大吉但实际落地必须验证。我们总结出判断MCP支持度的三要素Discovery Endpoint工具必须提供GET /mcp/server或GET /.well-known/mcp端点返回JSON格式的服务器元数据含版本、支持的capabilitiesTool Schema调用GET /mcp/tools必须返回符合 OpenAPI 3.0 规范的工具描述包含parameters输入字段、responses输出结构、examples调用示例Runtime ValidationAgent发起调用时工具端必须校验请求JSON是否符合Schema并返回清晰的validation_errors字段而非笼统的400 Bad Request。曾有个客户采购的“智能客服插件”宣称支持MCP但/mcp/tools返回的是HTML页面——这根本不是MCP只是挂了个名。我们用curl测试curl -H Accept: application/json http://localhost:8000/mcp/tools | jq .tools[0].parameters如果返回null或报错立刻放弃。真正合规的MCP工具parameters字段会精确到每个字段的type、required、description比如{ name: search_knowledge_base, description: 在企业知识库中搜索相关文档, parameters: { type: object, properties: { query: {type: string, description: 搜索关键词}, max_results: {type: integer, default: 5, minimum: 1, maximum: 20} }, required: [query] } }这个Schema让Agent能自动生成表单、做前端校验、甚至生成自然语言提示词如“请用户提供搜索关键词”。没有Schema一切自动化都是空中楼阁。3.3 在LangChain中集成MCP不是替换而是增强很多人以为用MCP就得抛弃LangChain这是巨大误区。LangChain的Tool类和MCP是互补关系LangChain负责Agent的决策流Chain、AgentExecutorMCP负责工具的标准化接入。我们的标准集成方式是用requests调用MCP工具的/mcp/tools端点动态生成LangChainTool对象将MCP工具的parametersSchema转换为LangChain的args_schemaPydantic Model在_run()方法中将LangChain传入的参数序列化为MCP标准JSON再POST到工具端点。关键代码片段from langchain.tools import BaseTool from pydantic import BaseModel, Field import requests class MCPTool(BaseTool): mcp_url: str # 工具MCP端点如http://localhost:8000/mcp tool_name: str def _run(self, **kwargs) - str: # 1. 构建MCP标准请求体 payload { tool: self.tool_name, params: kwargs, context: {session_id: self.session_id} # 传递上下文 } # 2. 发送请求 resp requests.post(f{self.mcp_url}/mcp/tool, jsonpayload, timeout30) resp.raise_for_status() result resp.json() # 3. 提取结果兼容MCP标准响应格式 return result.get(result, str(result)) # 动态注册MCP工具 def register_mcp_tool(mcp_url: str, tool_name: str) - MCPTool: # 从/mcp/tools获取Schema生成args_schema... schema get_mcp_schema(mcp_url, tool_name) # 实现略 return MCPTool( nametool_name, descriptionschema[description], mcp_urlmcp_url, tool_nametool_name, args_schemacreate_pydantic_model(schema[parameters]) # 自动构建 )这样做的好处是既享受LangChain成熟的Agent编排能力如ReAct、Plan-and-Execute又获得MCP带来的工具即插即用优势。我们上线的销售助手初始只集成了CRM和飞书两周后接入新的BI查询工具只需register_mcp_tool(http://bi-mcp:8000, query_bi)一行代码Agent立刻获得新能力无需改任何决策逻辑。4. LangChain不是学习门槛而是降低复杂度的杠杆4.1 别被“LangChain复杂框架”吓退它本质是DSL领域特定语言LangChain常被吐槽“API太绕”但真相是它用Python语法封装了Agent开发的通用模式。比如“先检索再生成”这个动作手写要初始化向量库客户端调用similarity_search获取top-k文档拼接文档内容到prompt模板调用LLM API解析返回的JSON。LangChain用RetrievalQA一行搞定from langchain.chains import RetrievalQA from langchain.llms import OpenAI qa_chain RetrievalQA.from_chain_type( llmOpenAI(temperature0), chain_typestuff, # 拼接所有文档 retrievervectorstore.as_retriever(), return_source_documentsTrue ) result qa_chain({query: 竞品X的电池续航是多少})这里的chain_typestuff就是DSL它隐含了“把所有检索结果拼成一段文本喂给LLM”的逻辑。LangChain的价值正在于把重复模式提炼成可配置的组件。我们统计过一个典型Agent项目中70%的代码是胶水逻辑参数传递、错误处理、日志记录LangChain把这些封装成Runnable、BaseTool、CallbackHandler等抽象让你专注业务逻辑。新手最大的误区是试图“读懂所有源码”而应该学会“用对组件”。就像开车不用懂发动机原理但得知道油门、刹车、档位怎么配合。4.2 LangChain与LangGraph不是替代而是分工进化LangGraph常被宣传为“LangChain的升级版”但实际是定位差异。LangChain适合线性流程如RAG问答、工具链调用LangGraph专攻循环、条件、并行等复杂编排。我们做过对比测试场景1会议纪要生成固定流程语音转文字→提取要点→生成摘要→发邮件→ LangChain的SequentialChain足够代码量少30%场景2多轮销售谈判辅助用户提问→查产品资料→若价格敏感则查促销政策→若竞品对比则启动RAG→生成话术→ LangGraph的StateGraph必需因为需要根据中间结果动态跳转。LangGraph的核心创新是State状态机每个节点输出必须是dict且键名需预定义如{messages: [...], next_action: search_rag}这强制你思考“当前步骤完成后系统应该记住什么、下一步可能是什么”。而LangChain的Chain是黑盒输出格式自由调试时很难追溯中间状态。所以选型原则很明确流程确定、分支简单 → LangChain流程动态、需状态追踪 → LangGraph。我们现在的项目90%用LangChain搭骨架只有核心决策模块用LangGraph嵌入——二者通过RunnableLambda无缝集成。4.3 企业级项目避坑别在LangChain上过度定制企业项目最常犯的错误是过早优化LangChain。比如为提升速度自己重写VectorStoreRetriever结果发现瓶颈其实在LLM API延迟而非检索本身为“更可控”弃用AgentExecutor手写状态管理结果调试时发现Agent在第三步卡死却找不到日志线索为“更安全”在LLMChain里加层层输入过滤结果误杀合法的中文标点导致RAG检索失败。我们的经验是先用LangChain官方组件跑通全流程再用性能分析工具如cProfile定位真实瓶颈。实测数据在一个日均1000次调用的客服Agent中95%的延迟来自LLM响应平均2.3s向量检索仅占0.12s网络IO占0.08s。这意味着优化检索算法毫无意义而应该用缓存Redis缓存高频问题答案对LLM请求做并发池asyncio.Semaphore限流用流式响应streaming让用户感知“已在处理”。LangChain的CallbackHandler是调试神器class DebugCallback(BaseCallbackHandler): def on_chain_start(self, serialized, inputs, **kwargs): print(fChain {serialized[name]} started with {inputs}) def on_llm_end(self, response, **kwargs): print(fLLM returned {len(response.generations)} candidates) agent_executor AgentExecutor( agentagent, toolstools, callbacks[DebugCallback()] # 所有关键节点自动打印 )有了它你不再需要在30个文件里加print()就能看到Agent每一步在想什么、调了什么工具、返回了什么。这才是企业级开发该有的可观测性。5. 企业级实战从需求到上线的完整闭环以“智能周报生成器”为例5.1 需求拆解把模糊目标变成可验证的验收清单客户提出“希望AI自动写周报”这太模糊。我们用“5W2H”法拆解What生成包含“本周完成事项”“下周计划”“风险与阻滞”三部分的Markdown周报Who面向研发组长需汇总组内5个成员的Git提交、Jira任务、会议纪要Where输出到飞书文档同时邮件抄送CTOWhen每周五下午5点自动触发Why减少组长手动整理时间原需2小时/周How从GitLab API拉代码提交从Jira API拉任务状态从飞书云文档拉会议纪要How Much准确率≥90%人工抽检10份错误≤1处。验收清单由此生成模块验收项测试方法数据采集能正确识别“已完成”Jira任务状态Done且resolutionFixed查看Jira API返回的raw JSON验证filter逻辑RAG知识库会议纪要中提到的“Q3上线计划”能被准确召回用retriever.get_relevant_documents(Q3上线计划)检查返回内容报告生成“风险与阻滞”部分必须包含未关闭的Blocker级Jira任务检查LLM输出中是否含risk: [{jira_id: PROJ-123, summary: 数据库迁移延迟}]自动化每周五17:00准时执行失败时钉钉告警查看Celery任务日志模拟网络故障测试告警这个清单让开发过程不再凭感觉每个功能点都有明确出口。5.2 技术栈选型为什么选LangChainMCPChromaDB而不是LlamaIndexFastAPI选型不是比参数而是比与业务的契合度。我们对比过主流方案维度LangChainMCP方案LlamaIndex方案自研FastAPI方案工具接入速度支持MCP的工具1行代码接入非MCP工具用BaseTool封装平均2小时/工具需为每个工具写QueryEngine适配器平均8小时/工具每个工具需独立开发REST接口平均40小时/工具RAG可调试性RetrievalQA内置return_source_documents可直接查看检索结果Response对象需手动解析source_nodes调试成本高完全自定义但需额外开发调试端点企业安全合规所有组件可私有部署无外部依赖部分插件依赖Cloud服务如Pinecone完全可控但开发周期长团队技能匹配Python工程师1周可上手核心API需深入理解Indexing/Querying概念需全栈能力前端后端运维最终选择LangChainMCP因为客户团队有Python背景但无AI专项经验且要求2周内交付MVP。我们用ChromaDB轻量级向量库替代Pinecone因为不需要GPU纯CPU即可运行数据存在本地SQLite符合客户“数据不出内网”要求chroma_client.create_collection(metadata{hnsw:space: cosine})一行代码就能指定相似度算法比ElasticSearch配置简单10倍。提示ChromaDB的hnsw:space参数决定向量距离计算方式cosine适合文本语义相似度l2适合数值型特征。别盲目用默认值实测在中文文档检索中cosine比l2准确率高22%。5.3 关键实现让Agent真正“理解”周报的业务逻辑最难的部分不是技术而是把业务规则翻译成Agent能执行的指令。比如“本周完成事项”需满足来源GitLab的merged_at在本周内的MRJira的resolutiondate在本周内的Done任务过滤排除[CI]、[DOC]等自动化提交聚合同一Jira任务关联多个Git提交只计1次表述用“完成XX模块开发”代替“提交commit abc123”。我们用LangChain的CustomTool封装业务逻辑from langchain.tools import Tool def get_weekly_summary() - str: 返回结构化周报数据供LLM渲染 # 1. 获取本周日期范围 now datetime.now() start_of_week (now - timedelta(daysnow.weekday())).replace(hour0, minute0, second0) end_of_week start_of_week timedelta(days6, hours23, minutes59, seconds59) # 2. 聚合GitLab数据伪代码 gitlab_mrs gitlab_api.search_mrs( statemerged, merged_afterstart_of_week.isoformat(), merged_beforeend_of_week.isoformat() ) # 过滤自动化提交聚合Jira ID jira_ids set() for mr in gitlab_mrs: if not re.match(r^\[CI\]|^\[DOC\], mr.title): jira_ids.update(extract_jira_ids(mr.description)) # 3. 获取Jira任务详情 jira_tasks [] for jira_id in jira_ids: task jira_api.get_issue(jira_id) if task.resolutiondate and start_of_week task.resolutiondate end_of_week: jira_tasks.append({ key: jira_id, summary: task.summary, assignee: task.assignee.displayName }) return json.dumps({ completed: jira_tasks, planned: get_next_week_tasks(), # 类似逻辑 risks: get_blocked_tasks() # 类似逻辑 }, ensure_asciiFalse) weekly_tool Tool( nameget_weekly_summary, description获取本周研发工作汇总数据包括已完成任务、下周计划、风险项, funcget_weekly_summary )这个Tool的关键在于它返回的是结构化JSON而非自然语言。LLM的Prompt明确要求“你收到的数据是JSON请严格按字段生成Markdown不要添加额外解释”。这避免了LLM“自由发挥”导致格式错乱。我们测试过用自然语言描述如“本周完成了3个任务”作为输入LLM有时会杜撰不存在的任务而结构化输入强约束Prompt准确率稳定在98.7%。5.4 上线与监控生产环境的“心跳检测”怎么做上线不是终点而是观测的开始。我们为周报Agent部署了三层监控基础设施层Prometheus抓取ChromaDB内存占用、LLM API调用延迟、任务队列长度业务逻辑层在Agent关键节点埋点记录retriever.invoke()返回的文档数、llm.invoke()的token消耗、tool.run()的成功率用户体验层在飞书文档末尾自动添加!-- Generated by AI-Agent v1.2 on 2024-06-15T17:00:00Z --方便人工追溯。最实用的监控是“失败归因分析”。当周报生成失败时系统自动触发诊断检查GitLab API是否返回401Token过期检查Jira返回的任务数是否为0可能Jira状态字段变更检查RAG检索是否返回空知识库是否更新检查LLM是否返回|endoftext|提示词被截断。诊断结果生成Markdown报告自动发到运维群[ERROR] 周报生成失败 (2024-06-15 17:03:22) - 根本原因Jira API返回500错误信息Field resolutiondate not found - 临时修复修改Jira查询参数用statuscategorychangedate替代 - 长期方案与Jira管理员确认字段变更更新SDK这套机制让我们把平均故障恢复时间MTTR从8小时降到22分钟。记住Agent不是越“智能”越好而是越“可诊断”越可靠。6. 常见问题与排查技巧实录那些教程绝不会告诉你的细节6.1 RAG检索不准先检查这三件事90%的问题当场解决RAG效果差新手第一反应是换模型或调参数但实际80%的问题出在数据预处理。我们整理了高频问题速查表现象可能原因排查命令/方法解决方案检索返回无关文档PDF解析失败大量空白页或乱码pdfinfo your_file.pdf查页数pdftotext -layout your_file.pdf -head -n 20 查前20行文本同一问题多次检索结果不同向量库未持久化重启后数据丢失chroma_client.get_collection(docs).count()返回0在ChromaDB初始化时指定persist_directory/path/to/db并调用client.persist()中文检索效果差分词器未适配中文按字切分而非词切分from langchain.text_splitter import RecursiveCharacterTextSplitter; splitter RecursiveCharacterTextSplitter(); print(splitter.split_text(人工智能))改用ChineseRecursiveTextSplitter需安装jieba或设置separators[\n\n, \n, 。, , , , , ]特别提醒RecursiveCharacterTextSplitter的chunk_size不是越大越好。我们实测对技术文档chunk_size512比1024准确率高15%因为大块文本包含过多上下文噪声反而稀释关键信息。而对法律条文chunk_size1024更优——因为条款完整性更重要。6.2 Agent无限循环用这个“熔断机制”一键止损Agent卡在循环里如反复调用同一个Tool通常是因为LLM返回的action_input格式错误导致Tool返回异常Agent又尝试重试。我们的熔断方案在AgentExecutor中设置max_iterations15默认是15但很多教程没提自定义CallbackHandler记录每次Actionclass LoopDetector(BaseCallbackHandler): def __init__(self): self.action_history [] def on_agent_action(self, action, **kwargs): # 记录最近3次Action self.action_history.append(action.tool) if len(self.action_history) 3: self.action_history.pop(0) # 连续3次相同Action触发熔断 if len(set(self.action_history)) 1 and len(self.action_history) 3: raise RuntimeError(Agent stuck in action loop: action.tool) agent_executor AgentExecutor( agentagent, toolstools, callbacks[LoopDetector()], max_iterations15 # 双保险 )这个机制上线后循环故障率从12%降到0.3%。关键是熔断后不是报错退出而是返回友好提示“系统检测到操作重复已为您生成备选方案”并调用备用Skill如直接返回知识库摘要。6.3 MCP工具调用失败90%是HTTP头或认证问题MCP调试最头疼的不是代码而是网络细节。我们踩过的坑问题requests.post(url, jsonpayload)返回401但Postman能成功原因MCP工具要求Content-Type: application/json而requests默认不设某些服务端严格校验解法显式设置头headers{Content-Type: application/json}问题本地测试OK部署到K8s后MCP调用超时原因K8s Service DNS解析慢http://mcp-service:8000在Pod内解析失败解法用http://mcp-service.default.svc.cluster.local:8000绝对域名或在Deployment中加dnsPolicy: ClusterFirstWithHostNet问题MCP工具返回{error: invalid_request}但Payload肉眼检查无误原因Payload中含中文requests默认用utf-8编码但某些Java服务端期望gbk解法json.dumps(payload, ensure_asciiFalse).encode(gbk)并设headers{Content-Type: application/json;charsetgbk}。注意MCP规范要求工具端必须支持UTF-8但现实中有不少遗留系统不遵守。遇到这种情况宁可改服务端也不要让Agent做编码转换——因为Agent的职责是决策不是字符集适配。6.4 LangChain内存暴涨关闭这个日志开关立竿见影LangChain默认开启详细日志尤其verboseTrue时会把整个Prompt、所有检索文档、LLM原始响应全打到stdout。一个10MB的PDF切块后日志可能达2GB/天直接撑爆磁盘。解决方案import logging # 关闭LangChain内部日志 logging.getLogger(langchain).setLevel(logging.WARNING) # 或更彻底只记录ERROR for name in [langchain.chains, langchain.agents, langchain.retrievers]: logging.getLogger(name).setLevel(logging.ERROR)同时在AgentExecutor中禁用verboseagent_executor AgentExecutor( agentagent, toolstools, verboseFalse, # 关键 handle_parsing_errorsTrue # 防止格式错误崩溃 )实测效果日志体积从1.2GB/天降到8MB/天磁盘IO压力下降97%。记住生产环境的第一原则是“可观测但不拖慢”日志不是越多越好而是刚好够诊断。我在实际项目中发现最有效的学习方式不是从LangChain文档首页开始而是打开GitHub的langchain/langchain仓库直接搜RetrievalQA看它的__init__.py和runnable.py——你会发现所谓“复杂API”本质就是几行llm.invoke()和retriever.get_relevant_documents()的组合。Agent开发没有玄学它只是把人类解决问题的步骤用代码固化下来
返回列表