<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>MCP on 小盒子的技术分享</title><link>https://xiaobox.github.io/tags/mcp/</link><description>Recent content in MCP on 小盒子的技术分享</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 11 Apr 2026 10:50:21 +0000</lastBuildDate><atom:link href="https://xiaobox.github.io/tags/mcp/index.xml" rel="self" type="application/rss+xml"/><item><title>让Agent快上100倍的秘密，其实藏在一本大一计算机教科书里</title><link>https://xiaobox.github.io/p/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/</link><pubDate>Sat, 11 Apr 2026 10:50:21 +0000</pubDate><guid>https://xiaobox.github.io/p/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/cover.jpg" alt="Featured image of post 让Agent快上100倍的秘密，其实藏在一本大一计算机教科书里" /&gt;&lt;p&gt;事情是这样的。&lt;/p&gt;
&lt;p&gt;最近我几乎每天都在用Claude Code写东西。用得越多，我越产生一种奇怪的感觉。&lt;/p&gt;
&lt;p&gt;就是你给它下完一个任务之后，它开始一步一步地干活。先是啪，读了一个文件。然后哒，想了几秒。然后啪，又打开一个文件。再想几秒。再打开一个文件。就这么一直持续下去。&lt;/p&gt;
&lt;p&gt;你坐在椅子上看着进度条一格一格地亮起来，心里清楚得不能再清楚，这十个文件它明明可以一起读的，它们之间根本没有任何依赖关系。&lt;/p&gt;
&lt;p&gt;但它就是不。它就是要一个接一个地来。&lt;/p&gt;
&lt;p&gt;一时间无语凝噎。&lt;/p&gt;
&lt;p&gt;后来我跟几个同样重度用Agent的朋友聊了一下，他们也都有这个感受。说真的我始终觉得这是现在所有Agent产品共同的一个病，不管是 &lt;code&gt;Claude Code&lt;/code&gt;、&lt;code&gt;Cursor&lt;/code&gt;、&lt;code&gt;Manus&lt;/code&gt;还是那些MCP插件，只要你让它干稍微复杂一点的活，你就会看到它在那里慢悠悠地一步一步走，像一个做事非常有耐心但完全不会一心二用的老实人。&lt;/p&gt;
&lt;p&gt;前两天跟朋友吐槽这事的时候，我又想起了两年前Berkeley那帮人写的一篇论文。论文叫LLMCompiler，2024年就发在ICML上了，现在回头看它也不算新东西。但每次我被Agent气到的时候都会想起它，觉得它的思路到今天都没过时，甚至越品越有味道。&lt;/p&gt;
&lt;p&gt;它当时就已经把这个病的根源讲得很清楚了，这个慢不是LLM的错，也不是任务复杂度的错，是我们给它用的那套调度系统，还停留在1960年代的水平。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/001-5d4b1967.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;这篇论文的名字挺干的，叫**《An LLM Compiler for Parallel Function Calling》**，ICML 2024。作者是Sehoon Kim、Amir Gholami那帮人，都在Berkeley和LBNL。它不是今年的新论文，但在我心里一直是Agent方向上最被低估的几篇之一。&lt;/p&gt;
&lt;p&gt;它在做的事其实非常cool。&lt;/p&gt;
&lt;p&gt;它在把大学一年级《计算机组成原理》那本书里的东西，原样搬到LLM的世界里。&lt;/p&gt;
&lt;p&gt;坦率的讲，你想想看过去60年整个计算机体系结构的历史，其实就是一部「怎么让本来是串行的指令跑得更并行」的历史。指令流水线、乱序执行、超标量、分支预测，这些听着就头大的名词，说到底都是在干一件事，就是让CPU不要一条指令一条指令傻乎乎地等，能同时干的活就一起干。&lt;/p&gt;
&lt;p&gt;这套东西人类已经研究得非常透了。透到什么程度呢？透到你今天买一颗普通的i5芯片，它每个时钟周期能同时发射的指令数，大概是80年代那种整栋楼的超级计算机的水平。&lt;/p&gt;
&lt;p&gt;但是。&lt;/p&gt;
&lt;p&gt;当我们把LLM当成一种新型处理器去用的时候，这套智慧全忘了。&lt;/p&gt;
&lt;p&gt;现在几乎所有的Agent框架，底层都是一个叫ReAct的东西。它是Yao等人2022年提的，全称是Reason + Act。工作方式非常朴素，想一步，做一步，看结果，再想一步，再做一步，再看结果。它是一个循环。&lt;/p&gt;
&lt;p&gt;听着很自然对吧？它确实自然。但你仔细看就会发现，这玩意从执行效率上来说，跟那种每次只能执行一条指令、做完一条才开始下一条的远古处理器，是一样的。&lt;/p&gt;
&lt;p&gt;一次一条。干等。&lt;/p&gt;
&lt;p&gt;而且这个问题在越来越多的Agent场景里暴露得越来越厉害，因为我们现在给Agent的活越来越复杂，一次要调用的工具越来越多。ReAct的串行执行就成了一个越来越重的镣铐。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;回到LLMCompiler这块。&lt;/p&gt;
&lt;p&gt;作者的思路简单粗暴，既然Agent执行工具调用的过程跟CPU执行指令长得一样，那就直接套编译器的架构好了。他们搞了三个组件。&lt;/p&gt;
&lt;p&gt;第一个叫 &lt;strong&gt;Function Calling Planner&lt;/strong&gt;，函数调用规划器。你可以把它想象成编译器里那个分析语义、构建依赖图的部分。用户给了一个问题，比如论文里举的那个例子，「微软的市值需要涨多少才能超过苹果？」，Planner要做的事情是先把这个问题拆成几个独立的任务，再搞清楚这些任务之间谁依赖谁。&lt;/p&gt;
&lt;p&gt;它会拆成三步。&lt;/p&gt;
&lt;p&gt;一，去查微软的市值。 二，去查苹果的市值。 三，用一个数学工具做减法，把差值算出来。&lt;/p&gt;
&lt;p&gt;然后它会发现一件事，任务1和任务2，彼此没有任何关系。它们完全可以同时去查。只有任务3需要等前两个都拿到结果。&lt;/p&gt;
&lt;p&gt;这就是一张 &lt;strong&gt;DAG&lt;/strong&gt;，有向无环图，编译器里最核心的数据结构之一。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/002-04810f26.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;第二个组件叫 &lt;strong&gt;Task Fetching Unit&lt;/strong&gt;，任务获取单元。这个名字直接就是从CPU里偷来的。&lt;/p&gt;
&lt;p&gt;在现代CPU里有一个东西叫指令获取单元，它的任务是一旦前一条指令把某个寄存器的值算出来了，立刻把依赖这个寄存器的下一条指令发射出去，别等一整串指令都准备好再开搞，那样太慢。&lt;/p&gt;
&lt;p&gt;LLMCompiler的Task Fetching Unit做的事完全一样。Planner一吐出DAG，它就开始扫描，发现哪些任务的依赖已经解决了，立刻往下扔。任务1和任务2没有依赖？好，同时发射，两个搜索并行执行。任务3等着1和2的结果？好，等它们回来我再把结果塞进任务3里，然后发射。&lt;/p&gt;
&lt;p&gt;整个过程是流式的。Planner一边在吐计划，执行器一边在干活，中间没有「等Planner把所有计划全想完再开始」这种停顿。论文里专门做了个消融实验，流式处理本身就贡献了一个量级的加速。&lt;/p&gt;
&lt;p&gt;第三个组件叫 &lt;strong&gt;Executor&lt;/strong&gt;，执行器。这个没啥好说的，它就是真正去调工具的那个家伙。Task Fetching Unit告诉它哪个工具可以调了，它就调。&lt;/p&gt;
&lt;p&gt;三个东西加起来，整个架构就跟一台小号的CPU一模一样。有人分析程序，有人调度，有人执行。&lt;/p&gt;
&lt;p&gt;说到这我真的有点被打动。你知道我为啥被打动吗？因为这个思路其实任何一个学过编译原理的本科生都能想到。它没有任何复杂的数学，没有什么神秘的训练技巧，就是把一个用了60年的老配方，拿来炒一道新菜。&lt;/p&gt;
&lt;p&gt;但它偏偏有效。而且效果好到离谱。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;顺着上面的再聊聊，这篇论文最让我兴奋的其实是实验结果部分。&lt;/p&gt;
&lt;p&gt;作者用了四个benchmark来测试LLMCompiler。这四个测试排起来有一个隐藏的升番结构，从最简单的场景到最复杂的场景，效果一个比一个炸。我逐个说一下。&lt;/p&gt;
&lt;p&gt;第一个叫HotpotQA。这是个很经典的多跳问答数据集，论文的Figure 1就举了一个例子，「斯科特·德瑞克森和埃德·伍德是不是同一个国籍？」这种问题。用ReAct的话就是一步一步来，先搜A，拿到结果，再搜B，拿到结果，再对比。用LLMCompiler的话，A和B可以同时搜。&lt;/p&gt;
&lt;p&gt;速度快了1.8倍。成本降了3.37倍。准确率基本一样。&lt;/p&gt;
&lt;p&gt;就这个结果拎出来看已经很能打了，但它只是开胃菜。&lt;/p&gt;
&lt;p&gt;第二个叫Movie Recommendation。这个更有意思，它每次要你从8部电影里找出跟某部电影最像的那部。也就是要对8部电影分别做独立的搜索和分析。&lt;/p&gt;
&lt;p&gt;ReAct在这里干了一件特别傻的事。论文附录里有一张图我看完直接笑出声，它显示有大约85%的样本，ReAct根本没搜完8部就结束了。它搜到第五部就停下来，觉得「我好像够了」，然后给一个答案。&lt;/p&gt;
&lt;p&gt;你敢信？？？&lt;/p&gt;
&lt;p&gt;一个号称能干活的Agent，居然连把活干完都做不到。它会提前认输。&lt;/p&gt;
&lt;p&gt;LLMCompiler在这里就完全没这个问题，因为Planner一开始就把8个任务全部规划好了，Executor必须全部执行完才能汇总。结果是速度快了3.74倍，成本降了6.73倍，准确率还反超ReAct 7个多点。&lt;/p&gt;
&lt;p&gt;第三个叫Game of 24。这游戏你们可能玩过，给你4个数字让你用加减乘除搞出24。之前最强的解法叫Tree-of-Thoughts，让LLM自己去搜索各种可能的组合。LLMCompiler在这里做了一个很骚的事，它把「Tree-of-Thoughts的一次尝试」当成一个工具，然后让Planner去并行调度这些尝试。&lt;/p&gt;
&lt;p&gt;速度快了2倍。&lt;/p&gt;
&lt;p&gt;到这里我已经觉得够牛了。&lt;/p&gt;
&lt;p&gt;但是真正让我给整不会的是第四个benchmark，WebShop。这是一个模拟网上购物的环境，你要在一堆商品里找到符合某些需求的那一个。典型的操作是搜索→看结果→再搜索→再看结果。&lt;/p&gt;
&lt;p&gt;LLMCompiler在这里直接跑出了101.7倍的加速。&lt;/p&gt;
&lt;p&gt;不是10倍，不是50倍，是一百零一点七倍。&lt;/p&gt;
&lt;p&gt;而且成功率还比ReAct高了25.7个百分点。&lt;/p&gt;
&lt;p&gt;我第一次看到这个数字的时候真的愣住了。我来回看了好几遍论文的表格，生怕自己看错了小数点。101.7x。&lt;/p&gt;
&lt;p&gt;它的原因其实非常直观。WebShop里有大量「先广撒网再选最优」的搜索动作。LLMCompiler可以一口气把所有候选搜索并行发射出去，而ReAct得一个一个搜。你想想，如果你在淘宝上找一个东西，你是一次打开十几个标签页横向对比，还是一个一个点开再返回再点开？&lt;/p&gt;
&lt;p&gt;答案很明显。&lt;/p&gt;
&lt;p&gt;但前者需要你有一个「规划」的能力，得先知道哪十几个是值得看的。这恰好就是LLMCompiler在做的事。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/003-df4faf7b.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;这块需要注意一下。LLMCompiler的意义不只是快，还有一个更深的点，它顺手救了准确率。&lt;/p&gt;
&lt;p&gt;这个我刚才提到了一嘴，但值得展开说说。作者分析了ReAct失败的案例之后发现，这些失败的绝大多数其实跟智力无关，跟纪律有关。&lt;/p&gt;
&lt;p&gt;两种典型的失败场景。一种是提前收工，它只搜了部分信息就觉得够了，开始瞎答。另一种更惨，是它会在同一个查询上无限循环，因为Wikipedia返回的信息不够精确，它就一直搜一直搜一直搜，直到context window爆掉。&lt;/p&gt;
&lt;p&gt;这两种失败加起来，贡献了ReAct绝大部分的失败样本。&lt;/p&gt;
&lt;p&gt;为啥会这样？我自己的理解是，ReAct是一种即兴架构。它没有全局视野，每一步都是基于上一步的观察临时决策的。这种即兴决策模式很像我们人脑，但它也天然带着人脑即兴决策的毛病，容易累、容易放弃、容易走进死胡同。&lt;/p&gt;
&lt;p&gt;LLMCompiler强迫模型在一开始就把所有要做的事列出来，这等于逼着它做一次系统性的规划。规划好了之后，执行阶段就只负责执行，不再思考。&lt;/p&gt;
&lt;p&gt;我觉得这里有一个非常深的启发。我们过去几年一直在迷信让LLM多想一步，搞出了Chain-of-Thought、Tree-of-Thoughts、Self-Reflection各种花活，都是在鼓励模型「思考得更细、更久、更多」。但其实有时候反过来，让它先想一次然后别再想了，反而更管用。&lt;/p&gt;
&lt;p&gt;CPU的设计哲学其实也是这样。现代CPU里最快的指令是那些不需要跳转、不需要预测、不需要动态决策的指令。凡是涉及到走一步看一步的指令，都会拖慢整条流水线。&lt;/p&gt;
&lt;p&gt;计算机硬件的人早就发现了，即兴决策是昂贵的。&lt;/p&gt;
&lt;p&gt;而这个老道理，现在又回到了AI Agent这边。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;坦率的讲，我觉得LLMCompiler这篇论文本身可能不是最大的新闻。真正的新闻是它揭示的那个更大的趋势。&lt;/p&gt;
&lt;p&gt;我们正在把整个计算机体系结构，重新发明一遍。&lt;/p&gt;
&lt;p&gt;你仔细想想这几年LLM推理和Agent方向上那些最亮眼的突破，几乎每一个都能在老教科书里找到原型。&lt;/p&gt;
&lt;p&gt;Speculative decoding，是把CPU的分支预测搬到了LLM推理。 KV cache，是把CPU的cache机制搬到了LLM推理。 Continuous batching，是把操作系统的进程调度搬到了LLM推理。 现在LLMCompiler，是把编译器的指令调度搬到了LLM Agent。&lt;/p&gt;
&lt;p&gt;每一个都在发生。每一个都带来10倍甚至100倍的加速。每一个的核心创意都不是横空出世的神来之笔，而是一句「等等，这个问题我们在硬件/OS层面已经解决过了，直接拿来用就好」。&lt;/p&gt;
&lt;p&gt;卡帕西前阵子说过一句我记了很久的话，他说LLM是一种新的计算机，一种以自然语言为指令集的计算机。这句话如果你真的认真对待，那它的所有推论都是自洽的。既然它是一种新的计算机，那我们给旧计算机发明的所有优化技巧，理论上都应该能再用一次。&lt;/p&gt;
&lt;p&gt;我有时候会觉得，我们这一代做AI的人特别幸运。我们在亲眼看一部已经拍过一遍的电影，被用新的道具重新拍摄。剧本是一样的，角色是一样的，剧情走向都是一样的。但因为道具全换了，看起来就像一部全新的片子。而且你手里只要有一本原版的剧本，你就能提前知道下一幕会发生什么。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-11-rang-agent-kuai-shang-100-bei-de-mi-mi-qi-shi-cang-zai-yi-be/004-65e386c4.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;回到这篇论文本身。&lt;/p&gt;
&lt;p&gt;我觉得它最重要的贡献其实不是那些benchmark数字，而是它开了一个非常清晰的方向。那就是Agent的慢不是不可解决的。&lt;/p&gt;
&lt;p&gt;你今天用Claude Code等十分钟，不是因为LLM笨，也不是因为你的任务太复杂。是因为底下那套调度系统还在用ReAct这种20世纪60年代级别的执行模式。只要换上哪怕一个粗糙的编译器思路，立刻就能快10倍、快100倍。&lt;/p&gt;
&lt;p&gt;其实这两年已经有不少框架在往这个方向走了，LangGraph、LlamaIndex都陆陆续续搞过类似的planner组件，多Agent框架里的并发调度也都能看到这套思路的影子。但奇怪的是，我们日常在用的那些最主流的Agent产品，Claude Code、Cursor这些，还是没有把这套东西吃得特别透。你还是经常能看到它们在那里一步一步串行地跑，跑得你抓狂。&lt;/p&gt;
&lt;p&gt;我始终觉得这是一件很可惜的事。一个两年前就该被充分吸收的好思路，到今天还只在部分框架里存在，绝大多数用户还是在吃ReAct的苦。&lt;/p&gt;
&lt;p&gt;其实之前OpenAI做过一个简化版，它叫Parallel Function Calling。但这篇论文里也明确对比了，OpenAI那个只能处理最简单的、完全独立的并行任务，一碰到有依赖关系的就歇菜了。LLMCompiler能处理有依赖的完整DAG，这是质变。而且论文在ParallelQA这个他们自己造的benchmark上，直接把OpenAI的并行函数调用给干穿了。&lt;/p&gt;
&lt;p&gt;还有一个让我很开心的点，LLMCompiler不依赖特定模型。它能跑在闭源的GPT系列上，也能跑在开源的LLaMA-2 70B上，效果都很好。这意味着你要用它，不需要求爷爷告奶奶去办一个特殊API，自己拿个开源模型搭一套就能跑。对整个开源生态是实实在在的利好。&lt;/p&gt;
&lt;p&gt;论文的代码早就开源在 &lt;a class="link" href="https://github.com/SqueezeAILab/LLMCompiler" target="_blank" rel="noopener"
 &gt;https://github.com/SqueezeAILab/LLMCompiler&lt;/a&gt; ，这两年我零零散散跑过一些例子，整体感觉是它确实好使，但对Planner的prompt质量非常敏感，稍微写粗糙一点就容易崩。这大概也是为啥它没在主流产品里全面铺开的原因之一，论文里优雅的架构，落到工程上总会多出一堆脏活。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;最后说点题外话。&lt;/p&gt;
&lt;p&gt;我一直觉得AI这个行业最迷人的地方，就在于它需要你是一个杂食动物。你得懂一点机器学习，懂一点系统，懂一点产品，懂一点用户。因为AI正在跟所有领域发生化学反应，任何一个你以为已经过时的角落，都可能突然长出一个全新的方向。&lt;/p&gt;
&lt;p&gt;LLMCompiler这篇论文就是一个典型的例子。它既不需要你是最顶尖的ML研究员，也不需要你是最强的系统工程师。它需要你有一个能从「我的LLM Agent跑得好慢啊」跳到「诶等等，CPU当年也有这个问题，是怎么解决的来着？」的跨界联想能力。&lt;/p&gt;
&lt;p&gt;我始终觉得这种联想能力，比任何单一领域的深度都重要。&lt;/p&gt;
&lt;p&gt;很多朋友问我怎么跟上AI的发展。我有时候觉得，与其拼命去看最新的模型发布，不如回头去翻翻那些老的、经典的、看起来跟AI毫无关系的书。编译原理、操作系统、计算机网络、数据库系统、图形学。这些书里有太多你以为已经过时的东西，在LLM时代突然又活了过来。&lt;/p&gt;
&lt;p&gt;你读过的每一本旧书，都可能在未来某天变成一枚重新上膛的子弹。&lt;/p&gt;
&lt;p&gt;前提是你得先把枪挂在墙上。&lt;/p&gt;
&lt;p&gt;以上。&lt;/p&gt;</description></item><item><title>全程0人工写代码！干掉低级码农的不是大模型</title><link>https://xiaobox.github.io/p/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/</link><pubDate>Tue, 24 Feb 2026 03:46:39 +0000</pubDate><guid>https://xiaobox.github.io/p/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/cover.jpg" alt="Featured image of post 全程0人工写代码！干掉低级码农的不是大模型" /&gt;&lt;h1 id="全程0人工写代码干掉低级码农的不是大模型"&gt;&lt;a href="#%e5%85%a8%e7%a8%8b0%e4%ba%ba%e5%b7%a5%e5%86%99%e4%bb%a3%e7%a0%81%e5%b9%b2%e6%8e%89%e4%bd%8e%e7%ba%a7%e7%a0%81%e5%86%9c%e7%9a%84%e4%b8%8d%e6%98%af%e5%a4%a7%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;全程0人工写代码！干掉低级码农的不是大模型
&lt;/h1&gt;&lt;p&gt;在当前全行业的 AI 辅助编程浪潮中，大多数工具仍停留在“交互式伴游”阶段，而支付巨头 Stripe 却打造了一套完全无人值守的端到端代码智能体——“小黄人”（Minions）&lt;/p&gt;
&lt;p&gt;小黄人是一个独立打工的“数字员工”。目前的惊人数据是：在 Stripe 内部，&lt;strong&gt;每周有超过 1300 个由小黄人完全生成的 Pull Requests（合并请求）被成功合并。这些代码在最终阶段会经过人类审查，但其中不包含任何人类编写的代码。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更具挑战的是，Stripe 的代码库高达数亿行，主要使用较冷门的带有 Sorbet 类型的 Ruby 语言，且包含大量 LLM 根本没见过的大型内部自研库。此外，这些代码每年要处理超过 1 万亿美元的支付量，合规与容错要求极高。&lt;/p&gt;
&lt;p&gt;Stripe 是如何让 LLM 驾驭如此庞大且复杂的企业级代码库的？核心答案在于极其强大的定制化工程脚手架。&lt;/p&gt;
&lt;p&gt;以下是小黄人能高效运转的四大核心技术拆解。&lt;/p&gt;
&lt;h3 id="1-极致标准化的预热沙盒devboxes"&gt;&lt;a href="#1-%e6%9e%81%e8%87%b4%e6%a0%87%e5%87%86%e5%8c%96%e7%9a%84%e9%a2%84%e7%83%ad%e6%b2%99%e7%9b%92devboxes" class="header-anchor"&gt;&lt;/a&gt;1 极致标准化的预热沙盒（Devboxes）
&lt;/h3&gt;&lt;p&gt;要让全自动 Agent 大规模并行工作，绝不能让它们跑在开发者杂乱的本地笔记本上。Stripe 的解法是直接复用为人类工程师打造的云端开发机（Devboxes）。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;10 秒极速“热启动”&lt;/strong&gt;：这些 Devbox 是 AWS EC2 实例。Stripe 预先配置并预热了一个资源池，里面已经克隆好了巨大的 Git 仓库，预热了 Bazel 构建缓存和类型检查缓存，甚至启动了持续运行的代码生成服务。因此，只要 10 秒钟，小黄人就能拿到一台随时可以运行测试和修改代码的机器。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;免弹窗的完全提权&lt;/strong&gt;：为了让小黄人在后台静默运行，它需要无缝执行各种 Shell 命令。因为 Devbox 运行在与生产资源和外部互联网隔离的 QA 环境中，爆炸半径被严格限制，所以系统敢于跳过人类权限确认弹窗，给予小黄人完整的执行自由。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;解决并发冲突&lt;/strong&gt;：如果用本地环境，并发运行多个 Agent 需要处理复杂的 git worktrees（这在 Stripe 的庞大代码库中无法扩展）。而在云端，工程师可以轻易地同时为 6 个不同的任务启动 6 个分配了独立 Devbox 的小黄人，实现物理级别的完美隔离&lt;/p&gt;
&lt;h3 id="2--蓝图编排blueprints将大模型装进确定性的盒子里"&gt;&lt;a href="#2--%e8%93%9d%e5%9b%be%e7%bc%96%e6%8e%92blueprints%e5%b0%86%e5%a4%a7%e6%a8%a1%e5%9e%8b%e8%a3%85%e8%bf%9b%e7%a1%ae%e5%ae%9a%e6%80%a7%e7%9a%84%e7%9b%92%e5%ad%90%e9%87%8c" class="header-anchor"&gt;&lt;/a&gt;2 “蓝图”编排（Blueprints）：将大模型装进确定性的盒子里
&lt;/h3&gt;&lt;p&gt;常规的 Agent 往往采用开放的循环机制，任由 LLM 自己决定下一步调什么工具，这极易导致出错和浪费 Token。 Stripe 创造性地引入了**“蓝图”（Blueprints）**状态机机制。蓝图将整个工作流视为一张图，将 LLM 的创造力与确定性的系统代码交织在一起：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;确定性节点 vs Agent 节点&lt;/strong&gt;：在蓝图中，像“实现具体任务”或“修复 CI 失败”是让 LLM 自由发挥的 Agent 节点；但是，像“运行配置好的 Linter”或“推送 Git 变更”则是完全不调用 LLM 的纯代码确定性节点。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;底线兜底&lt;/strong&gt;：这意味着小黄人无法绕过代码格式化等硬性规范。把大模型“关进受控的盒子里”，不仅极大地节省了 Token，还从系统层面提高了整体可靠性。各团队甚至可以编写自定义的蓝图，来处理复杂的、LLM 辅助的代码库迁移任务&lt;/p&gt;
&lt;h3 id="3-极其克制的上下文投喂规则文件与-toolshed"&gt;&lt;a href="#3-%e6%9e%81%e5%85%b6%e5%85%8b%e5%88%b6%e7%9a%84%e4%b8%8a%e4%b8%8b%e6%96%87%e6%8a%95%e5%96%82%e8%a7%84%e5%88%99%e6%96%87%e4%bb%b6%e4%b8%8e-toolshed" class="header-anchor"&gt;&lt;/a&gt;3 极其克制的上下文投喂：规则文件与 Toolshed
&lt;/h3&gt;&lt;p&gt;面对上亿行代码，如果把所有全局规则都塞给大模型，上下文窗口瞬间就会被撑爆。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;按目录生效的局部规则&lt;/strong&gt;：Stripe 几乎只使用作用于特定子目录或文件模式的规则文件。他们巧妙地复用了人类工程师为 Cursor 编写的规则格式。这样，工程师在日常开发中沉淀的最佳实践，小黄人（以及 Claude Code）在遍历文件系统时就能直接动态读取并学习。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;MCP 工具棚（Toolshed）&lt;/strong&gt;：小黄人通过模型上下文协议（MCP）获取网络信息（工单、文档、代码搜索等）。Stripe 建立了一个包含近 500 个内部与 SaaS 工具的中央服务器 Toolshed。但为了防止 Agent 分心，系统每次只会为小黄人精心挑选一个“小巧而高度相关”&lt;/p&gt;
&lt;h3 id="4-反馈左移shifting-feedback-left极速纠错循环"&gt;&lt;a href="#4-%e5%8f%8d%e9%a6%88%e5%b7%a6%e7%a7%bbshifting-feedback-left%e6%9e%81%e9%80%9f%e7%ba%a0%e9%94%99%e5%be%aa%e7%8e%af" class="header-anchor"&gt;&lt;/a&gt;4 反馈左移（Shifting Feedback Left）：极速纠错循环
&lt;/h3&gt;&lt;p&gt;无人值守 Agent 成功的关键在于能否实现自我闭环修正。Stripe 为其构建了多层极速反馈循环：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;5 秒内的本地验证&lt;/strong&gt;：在小黄人把代码推送到 CI 之前，Devbox 上的后台守护进程会通过启发式算法自动运行相关的 Linter 和类型检查。这个本地节点耗时不到 5 秒，让小黄人在本地极速完成语法纠错。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;克制的 CI 测试轮数&lt;/strong&gt;：Stripe 的 CI 拥有超过 300 万个测试用例。推送到 CI 后，系统会运行相关测试，并自动应用已有的修复脚本（Autofixes）。如果还有未修复的错误，报错会发回给小黄人。但为了平衡算力成本、时间与边际收益，小黄人最多只被允许进行 1 到 2 次的 CI 循环试错。之后无论成败，都会将其移交给人类处理，防止其陷入昂贵的死循环&lt;/p&gt;
&lt;h2 id="给我的启示"&gt;&lt;a href="#%e7%bb%99%e6%88%91%e7%9a%84%e5%90%af%e7%a4%ba" class="header-anchor"&gt;&lt;/a&gt;给我的启示
&lt;/h2&gt;&lt;p&gt;基于 Stripe 公开的这些技术细节，我得出了以下几点关于 AI 研发提效的深刻感悟：&lt;/p&gt;
&lt;p&gt;1.“&lt;strong&gt;对人类工程师有益的基础设施，对 LLM 同样有益&lt;/strong&gt;” 这是 Stripe 整个小黄人项目最核心的哲学。Stripe 并没有为了做 AI Agent 去凭空造一套新基建，而是直接将 AI 接入了他们多年打磨的 Devbox 环境、Pre-push hooks 和自动化测试管线中。这给所有企业的启示是：AI Agent 的天花板，取决于你现有工程基础设施的底座。 如果你的人类工程师本地环境经常崩溃、缺乏单测覆盖率、文档陈旧，那么大模型也一样会在这些泥坑里寸步难行。过去在人类开发者体验（Developer Productivity）上的每一分投资，都会在 AI 时代转化为巨大的复利回报。&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;放弃追求纯粹的“全能 Agent”&lt;/strong&gt;，用“蓝图”管控不确定性 目前业界过度迷恋让一个 Agent 自主解决所有问题。但 Stripe 的蓝图（Blueprints）设计极其务实：能用一行 Bash 脚本或 Linter 稳定解决的问题（如代码格式化、Git 提交流程），就绝对不让 LLM 消耗 Token 去“推理”。在企业级生产环境中，**混合架构（确定性代码逻辑 + 局部受控的 LLM 节点）**才是保证系统高可靠性（SLA）的唯一出路。&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;工程师的日常工作流正在被重塑&lt;/strong&gt; ，在 Stripe，触发小黄人的方式极度符合人体工程学：工程师可以直接在 Slack 的讨论线程里@小黄人，或者在内部的“CI 间歇性失败（Flaky test）”工单中点击一个按钮启动它。我们可以预见，未来的高级工程师将越来越像一个“包工头”：他们在值班（On-call）时并行启动几十个小黄人去处理琐碎的 Bug，自己则专注于审查 PR、设计架构，以及维护和编写能够指导小黄人的局部规则（Cursor rules）。工程师不再逐行敲击代码，而是定义意图并管理基础设施。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/001-a01d1a80.png"&gt;&lt;/p&gt;
&lt;h2 id="参考"&gt;&lt;a href="#%e5%8f%82%e8%80%83" class="header-anchor"&gt;&lt;/a&gt;参考
&lt;/h2&gt;&lt;p&gt;●https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents&lt;/p&gt;
&lt;p&gt;●https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2&lt;/p&gt;</description></item><item><title>OpenAI DevDay [2025] 概览</title><link>https://xiaobox.github.io/p/2025-10-07-openai-devday-2025-gai-lan/</link><pubDate>Tue, 07 Oct 2025 04:46:54 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-10-07-openai-devday-2025-gai-lan/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/cover.jpg" alt="Featured image of post OpenAI DevDay [2025] 概览" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;来源：https://openai.com/devday/ 本文我们针对 DevDay[2025] 中涉及的以下内容进行简要介绍&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/001-42653644.png"&gt;&lt;/p&gt;
&lt;h1 id="apps-in-chatgpt"&gt;&lt;a href="#apps-in-chatgpt" class="header-anchor"&gt;&lt;/a&gt;Apps in ChatGPT
&lt;/h1&gt;&lt;p&gt;Apps in ChatGPT 是 OpenAI 推出的一种新型交互式应用程序，用户可以直接在 ChatGPT 平台内通过自然语言与这些应用进行对话，从而提升创作、学习和生产力。&lt;/p&gt;
&lt;h2 id="交互式应用集成"&gt;&lt;a href="#%e4%ba%a4%e4%ba%92%e5%bc%8f%e5%ba%94%e7%94%a8%e9%9b%86%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;交互式应用集成
&lt;/h2&gt;&lt;p&gt;用户可以直接在 ChatGPT 对话中与新一代的应用程序进行交互。可以通过直接呼叫应用名称或在相关情境下由 ChatGPT 推荐来启动这些应用。这些应用拥有可在聊天中直接使用的交互式界面。&lt;/p&gt;
&lt;h2 id="自然语言启动"&gt;&lt;a href="#%e8%87%aa%e7%84%b6%e8%af%ad%e8%a8%80%e5%90%af%e5%8a%a8" class="header-anchor"&gt;&lt;/a&gt;自然语言启动
&lt;/h2&gt;&lt;p&gt;用户可以通过自然语言指令来使用应用。&lt;/p&gt;
&lt;p&gt;例如，直接对 Spotify 说 “&lt;strong&gt;Expedia 帮我订一张明天从北京飞往东京的机票&lt;/strong&gt;”。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/002-d6e3e14e.png"&gt;&lt;/p&gt;
&lt;p&gt;例如，直接对 Canva 说: “&lt;strong&gt;Canva 请帮我做一个宠物商店的海报，要明亮背景&lt;/strong&gt;”。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/003-31044252.png"&gt;&lt;/p&gt;
&lt;h2 id="开发者工具-apps-sdk"&gt;&lt;a href="#%e5%bc%80%e5%8f%91%e8%80%85%e5%b7%a5%e5%85%b7-apps-sdk" class="header-anchor"&gt;&lt;/a&gt;开发者工具 (Apps SDK)
&lt;/h2&gt;&lt;p&gt;OpenAI 发布了新的 Apps SDK（应用程序开发工具包）预览版，让开发者可以开始构建这些应用。该 SDK 是一个基于模型上下文协议（MCP）的开放标准。&lt;/p&gt;
&lt;p&gt;Apps SDK 是开源的，文档和示例可在 &lt;a class="link" href="https://developers.openai.com/apps-sdk" target="_blank" rel="noopener"
 &gt;https://developers.openai.com/apps-sdk&lt;/a&gt; 获取。对开发者来说，可触达超过 8 亿 ChatGPT 用户，并在未来实现变现。&lt;/p&gt;
&lt;h2 id="首批合作伙伴"&gt;&lt;a href="#%e9%a6%96%e6%89%b9%e5%90%88%e4%bd%9c%e4%bc%99%e4%bc%b4" class="header-anchor"&gt;&lt;/a&gt;首批合作伙伴
&lt;/h2&gt;&lt;p&gt;●首批上线的应用来自 Booking.com、Canva、Coursera、Expedia、Figma、Spotify 和 Zillow 等合作伙伴。&lt;/p&gt;
&lt;p&gt;●即将推出的合作伙伴包括 AllTrails、Peloton、OpenTable、Target、theFork、Uber 等，今年晚些时候上线。它们涵盖了旅行、食物外卖、教育、健身、零售和本地服务等类别，旨在使 ChatGPT 成为处理日常任务的更通用平台。&lt;/p&gt;
&lt;h2 id="安全与隐私"&gt;&lt;a href="#%e5%ae%89%e5%85%a8%e4%b8%8e%e9%9a%90%e7%a7%81" class="header-anchor"&gt;&lt;/a&gt;安全与隐私
&lt;/h2&gt;&lt;p&gt;所有应用都必须遵守 OpenAI 的使用政策。在用户首次使用某款应用时，系统会提示用户进行连接，并明确告知哪些数据可能会被共享。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/004-747704c5.png"&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/005-8f4bc3f1.png"&gt;&lt;/p&gt;
&lt;h2 id="未来规划"&gt;&lt;a href="#%e6%9c%aa%e6%9d%a5%e8%a7%84%e5%88%92" class="header-anchor"&gt;&lt;/a&gt;未来规划
&lt;/h2&gt;&lt;p&gt;未来，OpenAI 计划将应用推广到商业版、企业版和教育版 ChatGPT，并开放应用提交通道，建立专门的应用目录。同时，还将公布关于应用变现的更多细节&lt;/p&gt;
&lt;h1 id="agentkit"&gt;&lt;a href="#agentkit" class="header-anchor"&gt;&lt;/a&gt;AgentKit
&lt;/h1&gt;&lt;p&gt;AgentKit 是一套完整工具集，旨在帮助开发者和企业构建、部署和优化代理（agents）。它解决了代理开发中的碎片化问题，如复杂的编排、自定义连接器和手动评估管道。&lt;/p&gt;
&lt;h2 id="工作原理"&gt;&lt;a href="#%e5%b7%a5%e4%bd%9c%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;工作原理
&lt;/h2&gt;&lt;p&gt;AgentKit 提供了一套集成工具，用于简化创建和管理代理的过程。它包括视觉和编程界面，用于设计工作流、嵌入聊天体验以及评估性能，支持拖拽节点、版本控制和自动化优化。&lt;/p&gt;
&lt;h2 id="主要功能"&gt;&lt;a href="#%e4%b8%bb%e8%a6%81%e5%8a%9f%e8%83%bd" class="header-anchor"&gt;&lt;/a&gt;主要功能
&lt;/h2&gt;&lt;h3 id="agent-builder"&gt;&lt;a href="#agent-builder" class="header-anchor"&gt;&lt;/a&gt;Agent Builder
&lt;/h3&gt;&lt;p&gt;视觉画布，用于创建和版本化多代理工作流，支持拖拽节点、预览运行、内联评估配置，以及预构建模板。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/006-948e0346.png"&gt;&lt;/p&gt;
&lt;p&gt;可通过 &lt;a class="link" href="https://platform.openai.com/agent-builder/edit" target="_blank" rel="noopener"
 &gt;https://platform.openai.com/agent-builder/edit&lt;/a&gt; 访问使用。&lt;/p&gt;
&lt;p&gt;●截至 2025 年 10 月 7 日（当前日期），Agent Builder 暂不收费。计费将于 2025 年 11 月 1 日开始，在此之前不会产生任何费用。 这意味着在 beta 期间，你可以免费使用它，但使用过程中涉及的 API 调用（如调用模型）会按照标准 API 定价计算（不过目前整体免计费）。&lt;/p&gt;
&lt;p&gt;●从 11 月 1 日起，Agent Builder 的使用将基于 API 模型的查询定价，例如 GPT-4o 的搜索定价从每千查询 30 美元起。 定价和功能可能在从 beta 转向正式可用时调整。&lt;/p&gt;
&lt;h4 id="与-n8n-dify-的区别"&gt;&lt;a href="#%e4%b8%8e-n8n-dify-%e7%9a%84%e5%8c%ba%e5%88%ab" class="header-anchor"&gt;&lt;/a&gt;与 n8n 、Dify 的区别
&lt;/h4&gt;&lt;p&gt;以下表格对比三者的核心差异：&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/007-db6054ad.png"&gt;&lt;/p&gt;
&lt;p&gt;Agent Builder 确实像 n8n 的 “克隆” 版，更注重 OpenAI 内部优化，而 n8n 更通用、集成强；Dify 则更 AI 导向，与 Agent Builder 在代理开发上最相似，但独立于 OpenAI。 如果用过 n8n 或 Dify，切换到 Agent Builder 可能很顺手，但取决于是否需要 OpenAI 的模型深度集成。Coze 危！&lt;/p&gt;
&lt;h3 id="connector-registry"&gt;&lt;a href="#connector-registry" class="header-anchor"&gt;&lt;/a&gt;Connector Registry
&lt;/h3&gt;&lt;p&gt;中央管理面板，用于管理 OpenAI 产品中的数据和工具连接，包括预构建连接器如 Dropbox、Google Drive、Sharepoint 和 Microsoft Teams，以及第三方 MCP。&lt;/p&gt;
&lt;h3 id="chatkit"&gt;&lt;a href="#chatkit" class="header-anchor"&gt;&lt;/a&gt;ChatKit
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;不用自己建聊天 UI，就能做出专业级助手。和 OpenAI 的其他工具无缝连用。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;从整体定位看，ChatKit 作为 AgentKit 的一部分，专注于前端聊天界面的快速集成，降低了开发者构建 AI 驱动聊天应用的门槛。它强调无缝嵌入现有产品中，支持从简单聊天到复杂代理工作流的扩展，特别适合企业级应用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;简单说就是帮你快速在网站或 App 里加一个聊天窗口，让用户能和 AI 聊天办事。它不是从零自己写代码，而是像搭积木一样，轻松嵌入现有的产品里。想象一下，你想在你的网站上加个 AI 助手，能帮用户问问题、上传文件、甚至调用其他工具解决问题 ——ChatKit 就是干这个的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/008-051c36cd.png"&gt;&lt;/p&gt;
&lt;p&gt;怎么用？&lt;/p&gt;
&lt;p&gt;ChatKit 有两种用法：&lt;/p&gt;
&lt;p&gt;1.简单方式（推荐）：用 OpenAI 的 “Agent Builder”（另一个工具，像画图一样设计 AI 的工作流程）先搭好后端逻辑，然后把 ChatKit 嵌入前端。OpenAI 帮你管服务器，不用自己操心。&lt;/p&gt;
&lt;p&gt;2.高级方式：如果你想自己控制一切，用 Python 代码在自家服务器跑 ChatKit，后端连你自己的 AI 系统。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/009-ae03502c.png"&gt;&lt;/p&gt;
&lt;p&gt;核心是，它提供现成的聊天界面：用户输入文字、上传文件，AI 回应，还能显示 AI 的 “思考过程”（比如一步步推理），让一切更透明。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;搭建步骤&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更详细内容参考：https://platform.openai.com/docs/guides/chatkit&lt;/p&gt;
&lt;p&gt;1.先搭 AI ：用 Agent Builder 设计 AI 的 “工作流程”（比如，如果用户问天气，就调用天气工具）。这步生成一个 ID。&lt;/p&gt;
&lt;p&gt;2.设置聊天窗口：在你的服务器上创建 “会话”（用代码生成一个安全令牌），然后在网站前端安装 ChatKit 的 React 组件（一种网页代码框架）。加几行代码，就能看到聊天框了。&lt;/p&gt;
&lt;p&gt;3.优化调整：试用后，改改外观、加自定义按钮，或优化 AI 的提示语，让它更聪明&lt;/p&gt;
&lt;h3 id="evals-capabilities"&gt;&lt;a href="#evals-capabilities" class="header-anchor"&gt;&lt;/a&gt;Evals Capabilities
&lt;/h3&gt;&lt;p&gt;新功能包括数据集、跟踪评分、自动化提示优化，以及第三方模型支持，用于测量和改进代理性能。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/010-c85280b0.png"&gt;&lt;/p&gt;
&lt;h3 id="reinforcement-fine-tuning-rft"&gt;&lt;a href="#reinforcement-fine-tuning-rft" class="header-anchor"&gt;&lt;/a&gt;Reinforcement Fine-Tuning (RFT)
&lt;/h3&gt;&lt;p&gt;自定义工具调用和自定义评分器，用于增强模型推理，在 OpenAI o4-mini 上可用，并在 GPT-5 的私有 beta 中。&lt;/p&gt;
&lt;h1 id="sora-2--api"&gt;&lt;a href="#sora-2--api" class="header-anchor"&gt;&lt;/a&gt;Sora 2 API
&lt;/h1&gt;&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/011-b127300b.png"&gt;&lt;/p&gt;
&lt;p&gt;Sora2 API 发布了，可以这样接入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;OpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;videos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sora-2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;A video of a cool cat on a motorcycle in the night&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Video generation started:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;目前发布了两个模型：&lt;/p&gt;
&lt;p&gt;●sora-2&lt;/p&gt;
&lt;p&gt;●sora-2-pro&lt;/p&gt;
&lt;p&gt;区别是：&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/012-c931a597.png"&gt;&lt;/p&gt;
&lt;p&gt;总的来说，如果你只是玩玩或赶工，选 Sora 2；想出精品，Pro 更值。 两者都通过 API 或 app 用，内容有严格限制。&lt;/p&gt;
&lt;h2 id="使用指南"&gt;&lt;a href="#%e4%bd%bf%e7%94%a8%e6%8c%87%e5%8d%97" class="header-anchor"&gt;&lt;/a&gt;使用指南
&lt;/h2&gt;&lt;p&gt;1.提交任务：用 POST /videos 接口发请求，带上模型（sora-2）、提示语、尺寸（如 1280x720）和时长（如 8 秒）。它会给你一个任务 ID。&lt;/p&gt;
&lt;p&gt;2.检查进度：用 GET /videos/{id} 轮询状态，或者设置 webhook（一种自动通知）来收完成或失败的消息。&lt;/p&gt;
&lt;p&gt;3.写好提示：要具体！比如描述镜头类型、主体、动作、场景和光线。比如：“广角镜头，一个小孩在草地公园放红风筝，金色夕阳光线，镜头慢慢向上摇。”&lt;/p&gt;
&lt;p&gt;4.内容限制：适合 18 岁以下观众，不能用版权角色或音乐，不能生成真人（包括名人），输入图片不能有脸（以后可能有例外）。&lt;/p&gt;
&lt;p&gt;5.用图片开头：可以上传图片作为第一帧，支持 JPEG、PNG、WebP 格式，但尺寸要匹配。&lt;/p&gt;
&lt;p&gt;6.改视频（Remix）：用已生成的视频 ID 和新提示，针对性调整，比如改颜色或加元素。最好一次只改一件事，避免乱套&lt;/p&gt;
&lt;h1 id="codex-正式版发布"&gt;&lt;a href="#codex-%e6%ad%a3%e5%bc%8f%e7%89%88%e5%8f%91%e5%b8%83" class="header-anchor"&gt;&lt;/a&gt;Codex 正式版发布
&lt;/h1&gt;&lt;p&gt;全球开发者爱用它，包括初创公司如 Duolingo 和 Vanta，大厂如 Cisco 和 Rakuten。甚至 OpenAI 自己内部，几乎所有工程师都靠它干活，比 7 月时多了 50%，每周合并的代码拉取请求（PR）多了 70%，几乎每个 PR 都自动审一遍。&lt;/p&gt;
&lt;p&gt;主要新功能有：&lt;/p&gt;
&lt;p&gt;●Slack 集成：直接在 Slack 频道或线程里扔任务，比如 “帮我修这个 bug”，它自动拉上下文、选环境、云端干活，然后发链接给你 —— 想合并代码或本地改，就点开继续。超方便，不用切工具。&lt;/p&gt;
&lt;p&gt;●Codex SDK：一个工具包，能把 Codex 嵌入你的自定义流程、App 或脚本里（现在支持 TypeScript，更多语言快来了）。它优化了结构化输出和上下文管理，还带 GitHub Action，帮你塞进 CI / CD 管道（比如自动测试代码）。&lt;/p&gt;
&lt;p&gt;●管理员工具：给企业用户的新面板，能管环境、监控使用、看分析仪表盘。比如删云环境、设安全默认值、跟踪 CLI/IDE/网页的使用情况。让大团队规模化用得安心。&lt;/p&gt;
&lt;p&gt;从 2025 年 10 月 6 日起，ChatGPT Plus、Pro、Business、Edu 和 Enterprise 用户都能用 Slack 集成和 SDK。管理员工具限 Business、Edu 和 Enterprise。从 10 月 20 日起，云任务开始算使用量（之前免费）。&lt;/p&gt;
&lt;h1 id="gpt-5-pro"&gt;&lt;a href="#gpt-5-pro" class="header-anchor"&gt;&lt;/a&gt;GPT-5 Pro
&lt;/h1&gt;&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-07-openai-devday-2025-gai-lan/013-2edd2556.png"&gt;&lt;/p&gt;
&lt;p&gt;GPT-5 Pro 是 OpenAI 的 GPT-5 系列的一个 “加强版” 模型，专为处理难题设计的。它用更多计算资源 “多想一会儿”，输出更准、更靠谱。不同于普通版，它只通过 Responses API 用，支持多轮对话和未来高级功能。现在（2025 年 10 月）正式可用。&lt;/p&gt;
&lt;p&gt;核心能力：&lt;/p&gt;
&lt;p&gt;●上下文窗口大：能记住 40 万个 token 的上下文（相当于超长对话），输出最多 27.2 万 token（长文没问题）。&lt;/p&gt;
&lt;p&gt;●支持模式：文字输入输出都行，图片只能输入（比如分析图），音频和视频暂不支持。&lt;/p&gt;
&lt;p&gt;●推理模式：默认 “高强度思考”（reasoning.effort: high），带推理 token 支持，让它一步步推导问题。&lt;/p&gt;
&lt;p&gt;●工具集成：能上网搜、搜文件、生成图片，还支持 MCP（模型控制面板）。但不支持代码解释器、电脑操作、流式输出、微调或蒸馏。&lt;/p&gt;
&lt;p&gt;●其他：支持函数调用和结构化输出，适合复杂任务。&lt;/p&gt;
&lt;p&gt;总之，它像个 “深度思考者”，不光聊天，还能帮你解难题，但专注文字和图片。&lt;/p&gt;
&lt;p&gt;定价:&lt;/p&gt;
&lt;p&gt;●文字 token：输入 $15/百万 token，输出 $120/百万 token（贵！比 GPT-5 的 $1.25/百万输入贵多了）。&lt;/p&gt;
&lt;p&gt;●其他：工具调用额外收费，详情看定价页。比 o3-pro（输入 $20）也贵，适合高价值任务。&lt;/p&gt;
&lt;h1 id="gpt-realtime-mini"&gt;&lt;a href="#gpt-realtime-mini" class="header-anchor"&gt;&lt;/a&gt;GPT-Realtime-Mini
&lt;/h1&gt;&lt;p&gt;GPT-Realtime-Mini 是 OpenAI 的一个 “轻量级” 实时 AI 模型，简单说就是个能快速聊天的 “语音助手”，专为低成本、实时互动设计。它能听你说话（或看图片）、实时回复文字或语音，适合建语音 App、客服机器人或游戏对话。&lt;/p&gt;
&lt;p&gt;核心能力&lt;/p&gt;
&lt;p&gt;●实时互动：通过 WebRTC、WebSocket 或 SIP 连接，处理音频 / 文本输入，瞬间输出回应。像视频通话里的 AI 伙伴。&lt;/p&gt;
&lt;p&gt;●支持的东西：文本（输入/输出）、图像（只输入，比如描述图片）、音频（输入/输出，比如语音转文字或合成语音）。视频不支持。&lt;/p&gt;
&lt;p&gt;●记忆力：上下文窗口 32,000 tokens（够聊长对话），最大输出 4,096 tokens。&lt;/p&gt;
&lt;p&gt;●知识截止：到 2023 年 10 月 1 日（老了点，新事得靠工具补）。&lt;/p&gt;
&lt;p&gt;●其他：有 “快照” 版本，能锁住模型不乱变。没高级玩意儿如函数调用、结构化输出、微调或预测。&lt;/p&gt;
&lt;p&gt;定价（按百万 tokens）：&lt;/p&gt;
&lt;p&gt;●文本：输入 $0.60，缓存输入 $0.06，输出 $2.40。&lt;/p&gt;
&lt;p&gt;●音频：输入 $10，缓存 $0.30，输出 $20。&lt;/p&gt;
&lt;p&gt;●图像：输入 $0.80，缓存 $0.08。 总的贵在音频上，但比大模型便宜。&lt;/p&gt;
&lt;h1 id="gpt-image-1-mini"&gt;&lt;a href="#gpt-image-1-mini" class="header-anchor"&gt;&lt;/a&gt;GPT-Image-1-Mini
&lt;/h1&gt;&lt;p&gt;GPT-Image-1-Mini 是 OpenAI 推出的一款 “经济实惠版” 图像生成模型，能用文字描述或现有图片快速生成或编辑图像。它是 GPT Image 1 的 “小弟”，更便宜、更高效，适合开发者嵌入到 App 里，比如设计工具或内容平台，不用花大钱就能玩转 AI 画图。&lt;/p&gt;
&lt;p&gt;核心能力：&lt;/p&gt;
&lt;p&gt;●生成新图：输入文字提示，就能吐出高质图片。比如 “一个可爱的猫咪在太空飞翔”，它会懂上下文，画出逼真或搞怪的图。&lt;/p&gt;
&lt;p&gt;●编辑旧图：支持 “补画”（inpainting），用面具遮住部分区域改内容，比如加东西、删元素或换颜色。还能用参考图复制风格，确保一致性。&lt;/p&gt;
&lt;p&gt;●输入输出：进货是文字 + 图片，出货是新图像。能调质量（低中高）、尺寸（比如 1024×1024 或长宽 1024×1536），还有 “输入保真度” 控制输出多像原图。&lt;/p&gt;
&lt;p&gt;定价按 “token” 算（图像也转 token），超便宜：&lt;/p&gt;
&lt;p&gt;●文字输入：$2 / 百万 token。&lt;/p&gt;
&lt;p&gt;●图像输入（编辑用）：$2.50 / 百万 token。&lt;/p&gt;
&lt;p&gt;●图像输出：$8 / 百万 token。 实际一图成本：1024×1024 的低质只要 $0.005，中 $0.011，高 $0.036；大尺寸稍贵点，到 $0.052。比大模型便宜多了！&lt;/p&gt;</description></item><item><title>LangChain：是银弹，还是 “技术债”？</title><link>https://xiaobox.github.io/p/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/</link><pubDate>Tue, 23 Sep 2025 05:46:17 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/cover.jpg" alt="Featured image of post LangChain：是银弹，还是 “技术债”？" /&gt;&lt;h1 id="引言"&gt;&lt;a href="#%e5%bc%95%e8%a8%80" class="header-anchor"&gt;&lt;/a&gt;引言
&lt;/h1&gt;&lt;p&gt;当前，智能 Agent 的开发正面临两条截然不同的路径选择。一方面，高代码方式通过 SDK 和 API 编码提供灵活性，但带来了巨大的复杂性负担——开发者需要深入理解模型集成、工具调用、记忆管理和分布式协调等复杂概念，显著提高了开发门槛和维护成本。另一方面，像百炼，Dify、Coze 为代表的低代码平台以其出色的易用性迅速占领市场，通过可视化界面让用户能够快速构建 &amp;ldquo;Model+Prompt+MCP+RAG+Memory&amp;rdquo; 的标准 Agent 模式。&lt;/p&gt;
&lt;h1 id="高代码与低代码"&gt;&lt;a href="#%e9%ab%98%e4%bb%a3%e7%a0%81%e4%b8%8e%e4%bd%8e%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;高代码与低代码
&lt;/h1&gt;&lt;h2 id="高代码"&gt;&lt;a href="#%e9%ab%98%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;高代码
&lt;/h2&gt;&lt;p&gt;优势&lt;/p&gt;
&lt;p&gt;●控制粒度高：检索、重排、记忆淘汰策略、工具容错、并发/一致性都能精细掌控。&lt;/p&gt;
&lt;p&gt;●可移植/可替换：模型、向量库、存储、消息队列可按需换，避免深度锁定。&lt;/p&gt;
&lt;p&gt;●性能上限高：可针对热路径做缓存/批量化/并行/算力亲和等优化。&lt;/p&gt;
&lt;p&gt;●合规友好：易于纯内网/私有化落地，满足数据边界与审计需求。&lt;/p&gt;
&lt;p&gt;劣势&lt;/p&gt;
&lt;p&gt;●上手成本高：需要理解模型行为、工具协议、状态管理、分布式、测试/评测。&lt;/p&gt;
&lt;p&gt;●开发周期长：原型到生产的路径更长，对团队工程能力要求高。&lt;/p&gt;
&lt;p&gt;●维护复杂：提示/数据/评测/日志/灰度与回滚都要自己做治理。&lt;/p&gt;
&lt;p&gt;适用场景&lt;/p&gt;
&lt;p&gt;●对稳定性、性能、合规要求高的核心业务流程（客服、风控、运维、知识中枢）。&lt;/p&gt;
&lt;p&gt;●强定制：复杂工具链（多后端系统、定制检索策略、多段对话状态机）。&lt;/p&gt;
&lt;p&gt;●内网/私有化：外网受限、需与既有基建深度耦合（监控、鉴权、审计）。&lt;/p&gt;
&lt;h2 id="低代码"&gt;&lt;a href="#%e4%bd%8e%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;低代码
&lt;/h2&gt;&lt;p&gt;优势&lt;/p&gt;
&lt;p&gt;●速度快：原型与迭代极快，业务同学也能参与搭建与验收。&lt;/p&gt;
&lt;p&gt;●门槛低：抽象好了调用、编排、上下文缓存、简单评测与发布。&lt;/p&gt;
&lt;p&gt;●运维成本低：平台内置监控/日志/版本管理（能力视平台而定）。&lt;/p&gt;
&lt;p&gt;劣势&lt;/p&gt;
&lt;p&gt;●可扩展性受限：复杂状态机、精细化检索/重排、跨域事务一致性等较难。&lt;/p&gt;
&lt;p&gt;●性能上限有限：难做深度批处理、算力亲和、跨服务并行等工程优化。&lt;/p&gt;
&lt;p&gt;●供应商/能力锁定：某些特性依赖平台实现，迁移成本较高。&lt;/p&gt;
&lt;p&gt;●私有化差异：部分平台更偏 SaaS；若需纯内网，要筛选支持私有化/离线模型的方案。&lt;/p&gt;
&lt;p&gt;适用场景&lt;/p&gt;
&lt;p&gt;●探索/验证期：快速做 PoC、AB 实验、用户调研与演示。&lt;/p&gt;
&lt;p&gt;●中轻量业务：知识问答、表单处理、运营活动、内部助理等非关键路径。&lt;/p&gt;
&lt;p&gt;●混合团队：产品/运营可直接改提示与流程，工程只需提供数据/工具接口。&lt;/p&gt;
&lt;h2 id="场景选型"&gt;&lt;a href="#%e5%9c%ba%e6%99%af%e9%80%89%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;场景选型
&lt;/h2&gt;&lt;p&gt;高代码和低代码有各自的特点和适用场景，那我们该如何决策呢？下面是一个快速决策矩阵：&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/001-b6df3b08.png"&gt;&lt;/p&gt;
&lt;p&gt;总结来说：要“快试错”选低代码，要“硬落地”选高代码；两者并不对立，适合“原型低代码 + 核心高代码”的混合路线。&lt;/p&gt;
&lt;p&gt;具体来说：&lt;/p&gt;
&lt;p&gt;●2 周内交付可用原型、验证需求是否真实 → 低代码&lt;/p&gt;
&lt;p&gt;●承载 7×24 核心业务，SLA/审计/内网合规很硬 → 高代码&lt;/p&gt;
&lt;p&gt;●大量业务同学参与、频繁改提示与流程 → 低代码 +（必要时）接入自研工具&lt;/p&gt;
&lt;p&gt;●把 RAG/记忆/工具编排做成“组织级能力层” → 高代码（沉淀为平台/服务）&lt;/p&gt;
&lt;p&gt;●先做 Demo，再逐步把关键链路“工程化” → 低→高的混合迁移&lt;/p&gt;
&lt;p&gt;这里需要注意的是，要避免反模式：&lt;/p&gt;
&lt;p&gt;●把复杂状态机硬堆在低代码画布里，后期难以维护与回放。&lt;/p&gt;
&lt;p&gt;●过早全高代码，导致验证周期太长、需求未定先造轮子。&lt;/p&gt;
&lt;p&gt;●忽视提示/知识/评测的版本化与可回滚。&lt;/p&gt;
&lt;h2 id="混合实践"&gt;&lt;a href="#%e6%b7%b7%e5%90%88%e5%ae%9e%e8%b7%b5" class="header-anchor"&gt;&lt;/a&gt;混合实践
&lt;/h2&gt;&lt;p&gt;对于我们来说，现在正好处于一个 “混合迁移” 的阶段，我们即在使用低代码平台 Dify,也在某些具体的场景下感到了 Dify的不适。所以对于某些项目要进行必要的工程化迁移和改造，具体思路是：&lt;/p&gt;
&lt;p&gt;●前台用低代码（业务侧快速改动、AB/评测、需求验证）；&lt;/p&gt;
&lt;p&gt;●后台用高代码沉淀“能力层”（RAG 服务、工具/MCP、回溯评测、观测/追踪、策略引擎）。&lt;/p&gt;
&lt;p&gt;●平台只做编排与呈现，能力层提供稳定 API。&lt;/p&gt;
&lt;p&gt;●形成“能力可复用、前台可迭代、核心可控”的结构。&lt;/p&gt;
&lt;p&gt;一句话总结：低代码赢在速度，高代码赢在确定性；用低代码把事儿“做成”，再用高代码把事儿“做稳且做大”。&lt;/p&gt;
&lt;h1 id="langchain"&gt;&lt;a href="#langchain" class="header-anchor"&gt;&lt;/a&gt;LangChain
&lt;/h1&gt;&lt;h2 id="概念说明"&gt;&lt;a href="#%e6%a6%82%e5%bf%b5%e8%af%b4%e6%98%8e" class="header-anchor"&gt;&lt;/a&gt;概念说明
&lt;/h2&gt;&lt;p&gt;提到 LangChain 我们要先厘清一下概念，因为这里有两个概念：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一&lt;/strong&gt;，LangChain Inc. 是一家总部位于美国旧金山的前沿人工智能技术公司。公司成立于 2022 年，由 Harrison Chase 和 Ankush Gola 共同创立，2023 年正式独立成立公司实体。 公司注册于 2023 年 1 月 31 日，总部地址位于加利福尼亚州旧金山市 Decatur 街 42 号。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/002-475d5330.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二&lt;/strong&gt;，LangChain 还是一个用来开发基于 LLM 的 AI 应用框架。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/003-6dd54185.png"&gt;&lt;/p&gt;
&lt;p&gt;从 LangChain 公司官网和官方文档提供的产品架构图中可以看出，LangChain公司提供的主要产品有：&lt;/p&gt;
&lt;p&gt;●开发框架&lt;/p&gt;
&lt;p&gt;○LangChain（OSS-免费开源软件)&lt;/p&gt;
&lt;p&gt;○LangGraph（OSS-免费开源软件）&lt;/p&gt;
&lt;p&gt;●平台&lt;/p&gt;
&lt;p&gt;○LangSmith (COMMERCIAL-商业收费)&lt;/p&gt;
&lt;p&gt;○LangGraph Platform (COMMERCIAL-商业收费)&lt;/p&gt;
&lt;p&gt;在下文中如无特殊说明，LangChain 一律指代第二个概念，即开源的开发框架。&lt;/p&gt;
&lt;h2 id="大模型应用开发核心矛盾"&gt;&lt;a href="#%e5%a4%a7%e6%a8%a1%e5%9e%8b%e5%ba%94%e7%94%a8%e5%bc%80%e5%8f%91%e6%a0%b8%e5%bf%83%e7%9f%9b%e7%9b%be" class="header-anchor"&gt;&lt;/a&gt;大模型应用开发核心矛盾
&lt;/h2&gt;&lt;p&gt;当下的 LLM 本身如同一个 “博学但无手无脚的大脑”，它无法感知实时信息、无法操作外部工具、也无法与我们的私有数据交互。这个 “从 “模型能力” 到 “应用能力” 的鸿沟” 正是所有 LLM 应用开发者面临的首要难题。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/004-879f94f6.png"&gt;&lt;/p&gt;
&lt;p&gt;LangChain 不是一个 “新发明”，而是一个 “高效的连接器和编排器”。它的战略价值在于，它是当前弥合 “模型能力” 与 “应用能力” 鸿沟的最成熟的工程化解决方案之一。&lt;/p&gt;
&lt;h2 id="框架介绍"&gt;&lt;a href="#%e6%a1%86%e6%9e%b6%e4%bb%8b%e7%bb%8d" class="header-anchor"&gt;&lt;/a&gt;框架介绍
&lt;/h2&gt;&lt;p&gt;LangChain 的核心思想是“链”，它将 LLM 应用程序的各个组件连接在一起，形成一个完整的工作流。这种模块化的方法可以将复杂的人工智能系统分解为可重用的部分。LangChain 提供了一系列工具和抽象，帮助开发人员将 LLM 与外部数据源（如数据库、API等）连接起来，从而创建功能更强大的应用程序。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/005-e22fbc6c.png"&gt;&lt;/p&gt;
&lt;h3 id="langchain-能够解决的五类问题"&gt;&lt;a href="#langchain-%e8%83%bd%e5%a4%9f%e8%a7%a3%e5%86%b3%e7%9a%84%e4%ba%94%e7%b1%bb%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;LangChain 能够解决的五类问题
&lt;/h3&gt;&lt;p&gt;LangChain 能够解决五个核心领域（按复杂度递增）&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/006-677c7dd2.png"&gt;&lt;/p&gt;
&lt;h4 id="1-模型与提示i--o-层"&gt;&lt;a href="#1-%e6%a8%a1%e5%9e%8b%e4%b8%8e%e6%8f%90%e7%a4%bai--o-%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;1. 模型与提示（I / O 层）
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;要解决什么？&lt;/strong&gt; 稳定、可替换地调用任意 LLM，并拿到可解析、可复用的输出。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：BaseChatModel、ChatPromptTemplate、OutputParser、LCEL invoke/stream/batch。&lt;/p&gt;
&lt;p&gt;一般来说入门 LangChain 都是从第一层起步：prompt | llm | parser&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你是精炼的中文助手。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;用一句话解释：&lt;/span&gt;&lt;span class="si"&gt;{topic}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL 是什么？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="2-链式编排流程层"&gt;&lt;a href="#2-%e9%93%be%e5%bc%8f%e7%bc%96%e6%8e%92%e6%b5%81%e7%a8%8b%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;2. 链式编排（流程层）
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;要解决什么？&lt;/strong&gt; 把多个步骤（清洗→生成→解析→后处理）按顺序 / 并行可靠执行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：Runnable 统一协议、| 管道、并行 map、重试与超时、缓存&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;适用&lt;/strong&gt;：流程确定、依赖明确的任务（如格式转换、规则后处理、批处理）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()[:&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt; &lt;span class="c1"&gt;# 预处理：清理&amp;amp;截断&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 后处理：补全句号&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;用简洁中文回答。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;把这些要点合成一句话：&lt;/span&gt;&lt;span class="si"&gt;{q}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pre&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL, Runnable, invoke/batch/stream&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="3-检索增强生成-rag数据层"&gt;&lt;a href="#3-%e6%a3%80%e7%b4%a2%e5%a2%9e%e5%bc%ba%e7%94%9f%e6%88%90-rag%e6%95%b0%e6%8d%ae%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;3. 检索增强生成 RAG（数据层）
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;要解决什么？&lt;/strong&gt; 当模型 “知道的不够”，要从外部资料中取对内容。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：Loader/TextSplitter → Embeddings → VectorStore → Retriever（可带重排 / 压缩）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai langchain-community faiss-cpu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1) 准备示例知识（演示使用；实际替换为你的文档）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;texts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;LCEL 是 LangChain 的可组合执行协议，用 | 串联组件（prompt、llm、parser）。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;RAG（检索增强生成）通过向量检索把外部资料接入模型，以降低幻觉并注入最新知识。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_texts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2) RAG Prompt（把检索到的资料塞进上下文）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你是知识助手，必须基于提供的资料回答。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;问题：&lt;/span&gt;&lt;span class="si"&gt;{question}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;资料：&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{context}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;请用中文简洁作答，并在句末用[]引用关键词。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3) 组合：question → retriever → prompt → llm → parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;format_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;什么是 RAG？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="4-智能代理自主层"&gt;&lt;a href="#4-%e6%99%ba%e8%83%bd%e4%bb%a3%e7%90%86%e8%87%aa%e4%b8%bb%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;4. 智能代理（自主层）
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;要解决什么？&lt;/strong&gt; 目标不完全明确、步骤不固定，需要选择工具、反复试探（行动 - 观察 - 反思）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：BaseTool/工具调用、函数调用、AgentExecutor（或用 LangGraph 做有状态策略）、记忆 / 护栏。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolMessage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1) 定义一个可被模型调用的工具（OpenAI Tool Calling）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;精确乘法&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2) 绑定工具，让模型自行决定是否调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3) 行动-观察-再思考（最小一次循环）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;msgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你是严谨助手，涉及计算必须调用工具，不要心算。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;先算 12×34，再把结果乘以 2，给出最终数值即可。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 行动：模型决定要不要调用工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 观察：执行工具并把结果回传给模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ToolMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;tool_call_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 再思考：基于工具结果给最终答案&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="5-评估与观测质量层"&gt;&lt;a href="#5-%e8%af%84%e4%bc%b0%e4%b8%8e%e8%a7%82%e6%b5%8b%e8%b4%a8%e9%87%8f%e5%b1%82" class="header-anchor"&gt;&lt;/a&gt;5. 评估与观测（质量层）
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;要解决什么？&lt;/strong&gt; 度量 “是否正确/有用/鲁棒”，以及在真实流量中看得见链路与瓶颈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：基准指标（EM/F1/检索命中率）、LLM 判分、回放/对比、LangSmith（或自建追踪）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.evaluation&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_evaluator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 被评对象：最小 QA 链（LCEL）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用一句话回答：&lt;/span&gt;&lt;span class="si"&gt;{q}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL 是什么？&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL 是 LangChain 的统一执行协议，用 | 将组件串联成可组合管道。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# LangChain 自带评估器：按“准确&amp;amp;简洁”两条标准打分+给理由&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;evaluator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_evaluator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;labeled_criteria&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;criteria&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;accuracy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;是否与参考一致且不捏造&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;conciseness&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;是否一句话且清晰&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;grade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;evaluator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evaluate_strings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prediction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;答案：&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;评分：&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;score&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;理由：&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;reason&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;总结如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/007-736d8f55.png"&gt;&lt;/p&gt;
&lt;h3 id="架构图"&gt;&lt;a href="#%e6%9e%b6%e6%9e%84%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;架构图
&lt;/h3&gt;&lt;p&gt;LangChain 是一个以组合性为核心哲学的大语言模型应用开发框架&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/008-1b4ddddf.jpg"&gt;&lt;/p&gt;
&lt;p&gt;其设计理念是 “通过组合性构建LLM应用”，具体来说：&lt;/p&gt;
&lt;p&gt;1.可组合性 (Composability)：所有组件都是 Runnable，可以像乐高积木一样组合；使用 LCEL（LangChain Expression Language）轻松构建复杂流程&lt;/p&gt;
&lt;p&gt;2.标准化接口 (Standardization)：统一的输入输出接口；一致的同步/异步/批处理/流式处理方法&lt;/p&gt;
&lt;p&gt;3.可扩展性 (Extensibility)：通过继承基类轻松添加新实现；插件化架构，易于集成第三方服务&lt;/p&gt;
&lt;p&gt;4.类型安全 (Type Safety)：使用泛型和类型提示；编译时类型检查，减少运行时错误&lt;/p&gt;
&lt;h3 id="架构层次"&gt;&lt;a href="#%e6%9e%b6%e6%9e%84%e5%b1%82%e6%ac%a1" class="header-anchor"&gt;&lt;/a&gt;架构层次
&lt;/h3&gt;&lt;p&gt;LangChain 采用严格的分层架构，从底层的核心抽象到上层的应用组件，确保了良好的模块化和可扩展性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;⚡ text片段LangChain
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;├── langchain-core/ # 核心抽象层
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;│ ├── language_models/ # 基础模型抽象
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;│ ├── runnables/ # LCEL 核心
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;│ ├── prompts/ # 提示抽象
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;│ └── ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;├── langchain/ # 主实现层
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;│ ├── llms/ # LLM 实现
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;│ ├── chat_models/ # Chat 实现
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;│ ├── chains/ # 链实现
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;│ └── ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;└── langchain-community/ # 社区集成
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; └── partners/ # 第三方集成
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; ├── openai/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; ├── anthropic/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; └── ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="模块结构"&gt;&lt;a href="#%e6%a8%a1%e5%9d%97%e7%bb%93%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;模块结构
&lt;/h3&gt;&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/009-2bd9f481.png"&gt;&lt;/p&gt;
&lt;p&gt;LangChain 主要包含以下模块：&lt;/p&gt;
&lt;p&gt;1.核心语言模型模块&lt;/p&gt;
&lt;p&gt;○llms/ - 传统 LLM（85+ 个实现）&lt;/p&gt;
&lt;p&gt;○chat_models/ - 对话模型（35+ 个实现）&lt;/p&gt;
&lt;p&gt;○embeddings/ - 嵌入模型（51+ 个实现）&lt;/p&gt;
&lt;p&gt;2.输入输出模块&lt;/p&gt;
&lt;p&gt;○prompts/ - 提示模板&lt;/p&gt;
&lt;p&gt;○output_parsers/ - 输出解析器（23+ 种）&lt;/p&gt;
&lt;p&gt;○prompt_values/ - 提示值处理&lt;/p&gt;
&lt;p&gt;3.数据处理模块&lt;/p&gt;
&lt;p&gt;○document_loaders/ - 文档加载器（166+ 种）&lt;/p&gt;
&lt;p&gt;○document_transformers/ - 文档转换器&lt;/p&gt;
&lt;p&gt;○text_splitter.py - 文本分割&lt;/p&gt;
&lt;p&gt;○indexes/ - 索引管理&lt;/p&gt;
&lt;p&gt;4.存储与检索模块&lt;/p&gt;
&lt;p&gt;○vectorstores/ - 向量数据库（76+ 种）&lt;/p&gt;
&lt;p&gt;○retrievers/ - 检索器（78+ 种）&lt;/p&gt;
&lt;p&gt;○memory/ - 记忆管理（39+ 种）&lt;/p&gt;
&lt;p&gt;○storage/ - 存储抽象&lt;/p&gt;
&lt;p&gt;○docstore/ - 文档存储&lt;/p&gt;
&lt;p&gt;5.链与编排模块&lt;/p&gt;
&lt;p&gt;○chains/ - 各种链（144+ 个文件）&lt;/p&gt;
&lt;p&gt;○runnables/ - 可运行组件&lt;/p&gt;
&lt;p&gt;○agents/ - 智能体（146+ 个文件）&lt;/p&gt;
&lt;p&gt;6.工具与集成模块&lt;/p&gt;
&lt;p&gt;○tools/ - 工具集（186+ 种）&lt;/p&gt;
&lt;p&gt;○agent_toolkits/ - 工具包&lt;/p&gt;
&lt;p&gt;○utilities/ - 实用工具（59+ 个）&lt;/p&gt;
&lt;p&gt;○utils/ - 辅助函数&lt;/p&gt;
&lt;p&gt;7.回调与监控模块&lt;/p&gt;
&lt;p&gt;○callbacks/ - 回调处理器（46+ 种）&lt;/p&gt;
&lt;p&gt;○tracers/ - 追踪器&lt;/p&gt;
&lt;p&gt;○evaluation/ - 评估工具（32+ 个）&lt;/p&gt;
&lt;p&gt;8.特殊功能模块&lt;/p&gt;
&lt;p&gt;○chat_loaders/ - 聊天记录加载&lt;/p&gt;
&lt;p&gt;○graphs/ - 图处理&lt;/p&gt;
&lt;p&gt;○sql_database.py - SQL 数据库支持&lt;/p&gt;
&lt;p&gt;○cache.py - 缓存管理&lt;/p&gt;
&lt;h3 id="runnable-抽象"&gt;&lt;a href="#runnable-%e6%8a%bd%e8%b1%a1" class="header-anchor"&gt;&lt;/a&gt;Runnable 抽象
&lt;/h3&gt;&lt;p&gt;LangChain 的架构精髓在于 Runnable 接口 —— 一个&amp;quot;可以被调用、批处理、流化、转换和组合的工作单元&amp;quot; 。这个抽象提供了六种核心执行模式：&lt;/p&gt;
&lt;p&gt;●invoke/ainvoke: 单次同步/异步执行&lt;/p&gt;
&lt;p&gt;●batch/abatch: 并行同步/异步批处理执行&lt;/p&gt;
&lt;p&gt;●stream/astream: 同步/异步流式输出执行&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/010-de897147.png"&gt;&lt;/p&gt;
&lt;p&gt;所有组件都实现 Runnable 接口，从检索器到代理系统 ，确保了组件间的无缝互操作性，使得 LangChain 组件具有极高的可组合性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;⚡ 代码片段# 示例：链式组合
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chain = prompt | model | parser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="lcel声明式表达语言"&gt;&lt;a href="#lcel%e5%a3%b0%e6%98%8e%e5%bc%8f%e8%a1%a8%e8%be%be%e8%af%ad%e8%a8%80" class="header-anchor"&gt;&lt;/a&gt;LCEL：声明式表达语言
&lt;/h3&gt;&lt;p&gt;LangChain Expression Language (LCEL) 是框架的&amp;quot;声明式方法构建生产级程序&amp;quot; 。通过管道操作符（|）实现组件的优雅组合，天然支持异步、批处理和流式操作，这使得基于LCEL的程序能够更好地扩展以处理更高的并发负载。&lt;/p&gt;
&lt;p&gt;LCEL 不仅仅是语法糖。它是一种声明式的编程范式。开发者只需声明 “数据如何流动”，而框架负责处理底层的执行、流式传输、并行化和日志记录。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1) Prompt：定义输入模板&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你是精炼、可靠的中文助手。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;用一句话回答：&lt;/span&gt;&lt;span class="si"&gt;{question}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2) LLM：任意 OpenAI 兼容服务均可（公有云/企业网关/vLLM 等）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 换成你的模型名即可&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;YOUR_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 也可用环境变量 OPENAI_API_KEY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http://localhost:8000/v1&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# 选填：本地或内网的 OpenAI 兼容地址&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3) Parser：把模型返回的消息对象转成纯字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# LCEL：像搭乐高一样用“|”把组件串起来&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——最简单的单次调用（演示用）——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL 是什么？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——可选：流式演示（边生成边打印）——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;给出一条使用 LCEL 的建议&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——可选：批量演示（一次处理多条）——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;一句话解释 LangChain&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;一句话解释 LCEL 的优势&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="schema-与类型系统"&gt;&lt;a href="#schema-%e4%b8%8e%e7%b1%bb%e5%9e%8b%e7%b3%bb%e7%bb%9f" class="header-anchor"&gt;&lt;/a&gt;Schema 与类型系统
&lt;/h3&gt;&lt;p&gt;LangChain 的类型系统建立在 Python 的类型提示和 Pydantic模型之上，提供了一套完整的类型定义来支持 LLM 应用开发。LangChain 的类型系统具有以下特点：&lt;/p&gt;
&lt;p&gt;1.强类型: 基于 Python 类型提示和 Pydantic，提供编译时和运行时类型检查&lt;/p&gt;
&lt;p&gt;2.可组合: 通过 Runnable 接口实现组件的灵活组合&lt;/p&gt;
&lt;p&gt;3.可序列化: 所有核心类型都继承自 Serializable&lt;/p&gt;
&lt;p&gt;4.灵活性: 支持多种 Schema 定义方式（Pydantic、TypedDict、JSON Schema）&lt;/p&gt;
&lt;p&gt;5.流式支持: 原生支持同步、异步、批处理和流式处理&lt;/p&gt;
&lt;p&gt;6.标准化: 统一的输入输出类型定义，便于组件互操作&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Pydantic 由 Samuel Colvin 创建，核心思想是：“使用类型注解定义数据模型，Pydantic 自动帮你验证和转换数据。” 它基于 Python 3.6+ 的类型提示系统（如 str, int, List, Optional 等），通过定义继承自 BaseModel 的类，来描述期望的数据结构。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;想象一下，你正在指挥一个非常聪明但有点 “随心所欲” 的机器人。如果你只是模糊地说 “给我找点关于猫的资料”，它可能会给你一篇科学论文，一张猫的图片，或者一段猫叫的音频。这太不可预测了。LangChain 的 Schema 和类型系统，就像是给这个机器人的一套精确的 “指令图纸” 和 “数据表格”。它让你能够用一种机器人能精确理解的方式下达指令，并要求它以你想要的、规整的格式返回结果。下面我们通过几个场景和代码例子，来看看这些 “图纸” 和 “表格” 是怎么工作的。&lt;/p&gt;
&lt;h4 id="场景-1-从简单的闲聊到有角色区分的对话"&gt;&lt;a href="#%e5%9c%ba%e6%99%af-1-%e4%bb%8e%e7%ae%80%e5%8d%95%e7%9a%84%e9%97%b2%e8%81%8a%e5%88%b0%e6%9c%89%e8%a7%92%e8%89%b2%e5%8c%ba%e5%88%86%e7%9a%84%e5%af%b9%e8%af%9d" class="header-anchor"&gt;&lt;/a&gt;场景 1: 从简单的闲聊到有角色区分的对话
&lt;/h4&gt;&lt;p&gt;一开始，我们和 AI 的交互很简单，就是 “一问一答”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最基础的类型: Text (字符串): 这就是最原始的交互方式。&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;⚡ 代码片段# 这其实就是最基础的文本 Schema
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;my_question = &amp;#34;你好，你叫什么名字？&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;ai_response = &amp;#34;我是AI助手。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但这很快就不够用了。在一个持续的对话中，AI 需要知道哪句话是谁说的，才能更好地理解上下文。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;进阶类型: ChatMessage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ChatMessage 就是为了解决这个问题而生的 “对话表格”。它规定了每条消息都应该有 role (角色) 和 content (内容) 两列。主要角色有：&lt;/p&gt;
&lt;p&gt;○SystemMessage: 系统指令。给 AI 设定一个 “人设” 或总体的行为准则。&lt;/p&gt;
&lt;p&gt;○HumanMessage: 你的话。&lt;/p&gt;
&lt;p&gt;○AIMessage: AI 的话。&lt;/p&gt;
&lt;p&gt;每个元素都有明确的role 和content。 这让 AI 不再混乱，能够更好地进行多轮对话。&lt;/p&gt;
&lt;h4 id="场景-2-我需要-ai-给我一个结构化的数据而不是一段话"&gt;&lt;a href="#%e5%9c%ba%e6%99%af-2-%e6%88%91%e9%9c%80%e8%a6%81-ai-%e7%bb%99%e6%88%91%e4%b8%80%e4%b8%aa%e7%bb%93%e6%9e%84%e5%8c%96%e7%9a%84%e6%95%b0%e6%8d%ae%e8%80%8c%e4%b8%8d%e6%98%af%e4%b8%80%e6%ae%b5%e8%af%9d" class="header-anchor"&gt;&lt;/a&gt;场景 2: 我需要 AI 给我一个结构化的数据，而不是一段话
&lt;/h4&gt;&lt;p&gt;假设你想让 AI 帮你生成用户信息，并存入数据库。如果你只对它说 “生成一个用户，名叫张三，25 岁，邮箱是 &lt;a class="link" href="mailto:zhangsan@email.com" &gt;zhangsan@email.com&lt;/a&gt;”，它可能会返回：&lt;/p&gt;
&lt;p&gt;●&amp;quot; 好的，用户信息如下：姓名：张三，年龄：25，邮箱：zhangsan@email.com&amp;quot;&lt;/p&gt;
&lt;p&gt;●&amp;quot; 张三，25 岁，邮箱 &lt;a class="link" href="mailto:zhangsan@email.com" &gt;zhangsan@email.com&lt;/a&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;●&amp;quot; 这是一个名叫张三的用户，他今年 25 岁了，你可以通过 &lt;a class="link" href="mailto:zhangsan@email.com" &gt;zhangsan@email.com&lt;/a&gt; 联系到他。&amp;quot;&lt;/p&gt;
&lt;p&gt;这些都是字符串，程序很难处理！我们需要的是一个干净的、可以直接用的 JSON 对象。这时，我们就要给 AI 一张 “图纸”，告诉它我们想要的输出格式。在 LangChain 中，最常用的 “绘图工具” 就是Pydantic 库。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# 伪代码，演示核心逻辑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.pydantic_v1&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;JsonOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 用 Pydantic 画一张“图纸”，定义你想要的输出结构&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;classUserProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用户的全名&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用户的年龄&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用户的电子邮件地址&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;is_active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用户账户是否活跃&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 创建一个输出解析器，告诉它要用哪张“图纸”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JsonOutputParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pydantic_object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 在提示中，告诉AI要按照“图纸”的格式来回答&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 根据下面的用户信息，生成一个JSON对象。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 用户信息：&lt;/span&gt;&lt;span class="si"&gt;{user_info}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;{format_instructions}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user_info&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 把“图纸”的说明书（格式指令）插入到提示中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;partial_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;format_instructions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_format_instructions&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 创建模型并链接所有部分&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# model = ChatOpenAI(temperature=0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# chain = prompt | model | parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# response = chain.invoke({&amp;#34;user_info&amp;#34;: &amp;#34;创建一个用户，名叫李四，30岁，邮箱是 lisi@email.com，账户是活跃的。&amp;#34;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 期望的 response 会是一个干净的 Python 字典，而不是字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# print(response)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 输出:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# {&amp;#39;name&amp;#39;: &amp;#39;李四&amp;#39;, &amp;#39;age&amp;#39;: 30, &amp;#39;email&amp;#39;: &amp;#39;lisi@email.com&amp;#39;, &amp;#39;is_active&amp;#39;: True}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;看到妙处了吗？通过定义UserProfile 这个 Schema，我们强制 AI 的输出符合我们预设的结构，让它的输出变得 100% 可预测和可用。&lt;/p&gt;
&lt;h4 id="场景-3-让-ai-使用我们定义的工具"&gt;&lt;a href="#%e5%9c%ba%e6%99%af-3-%e8%ae%a9-ai-%e4%bd%bf%e7%94%a8%e6%88%91%e4%bb%ac%e5%ae%9a%e4%b9%89%e7%9a%84%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;场景 3: 让 AI 使用我们定义的工具
&lt;/h4&gt;&lt;p&gt;假设你想让 AI 能够查询天气。AI 本身是不知道今天天气的，但你可以提供一个查询天气的函数（工具）给它。但是，AI 怎么知道这个函数是干嘛的？需要哪些参数？&lt;/p&gt;
&lt;p&gt;LangChain 的 @tool 装饰器可以自动读取你函数的 “类型提示”(Type Hinting) 和文档字符串 (docstring)，并把它们变成一份 AI 能看懂的 “工具说明书”。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# 伪代码，演示核心逻辑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="k"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;celsius&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 根据城市名称查询实时天气。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; :param city: 城市的名字，例如：北京
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; :param unit: 温度单位，可以是 &amp;#39;celsius&amp;#39; (摄氏度) 或 &amp;#39;fahrenheit&amp;#39; (华氏度)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这里的代码会真实地去调用天气API&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;北京现在的天气是 25°{unit}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;上海&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;上海现在的天气是 28°{unit}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;抱歉，我查询不到 {city} 的天气。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 当你把这个工具提供给一个支持工具调用的AI模型时，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# LangChain会自动生成类似这样的“说明书”给AI看：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Tool Name: search_weather&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Tool Description: 根据城市名称查询实时天气。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Tool Arguments:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# - name: city, type: string, description: 城市的名字，例如：北京&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# - name: unit, type: string, description: 温度单位，可以是 &amp;#39;celsius&amp;#39; (摄氏度) 或 &amp;#39;fahrenheit&amp;#39; (华氏度)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 当你问AI：“北京今天天气怎么样？”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# AI会分析你的问题，发现需要查询天气，然后查看它手上的“工具说明书”。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 它会找到 search_weather 工具，并自动生成调用参数：{&amp;#34;city&amp;#34;: &amp;#34;北京&amp;#34;, &amp;#34;unit&amp;#34;: &amp;#34;celsius&amp;#34;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 然后执行函数，得到结果，最后把结果用自然语言告诉你。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的 city: str 和 unit: str 就是 Schema 的一部分，它明确规定了工具需要什么类型的输入。文档字符串 &amp;ldquo;&amp;rdquo;&amp;quot;&amp;hellip;&amp;quot;&amp;quot;&amp;quot; 则成了 AI 理解工具功能的关键。&lt;/p&gt;
&lt;h3 id="核心抽象组件"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e6%8a%bd%e8%b1%a1%e7%bb%84%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;核心抽象组件
&lt;/h3&gt;&lt;p&gt;LangChain 的架构围绕以下几个基本抽象组件构建，这些抽象组件共同构成了 LangChain 的核心架构，让开发者能够快速构建复杂的 LLM 应用。每个组件都有明确的职责，通过 Runnable 接口相互连接，形成了一个强大而灵活的框架。&lt;/p&gt;
&lt;h4 id="language-models-语言模型"&gt;&lt;a href="#language-models-%e8%af%ad%e8%a8%80%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;Language Models (语言模型)
&lt;/h4&gt;&lt;p&gt;提供文本生成、对话、推理等核心 AI 能力&lt;/p&gt;
&lt;p&gt;●BaseLanguageModel: 所有语言模型的基类,它继承自 RunnableSerializable，并定义了语言模型交互的通用接口 。它通过其 generate_prompt() 方法接受 PromptValue 对象 。&lt;/p&gt;
&lt;p&gt;●BaseChatModel: 对话模型（GPT-4、Claude）- 处理消息序列&lt;/p&gt;
&lt;p&gt;●BaseLLM: 文本生成模型 - 处理字符串输入输出&lt;/p&gt;
&lt;h4 id="prompts-提示模板"&gt;&lt;a href="#prompts-%e6%8f%90%e7%a4%ba%e6%a8%a1%e6%9d%bf" class="header-anchor"&gt;&lt;/a&gt;Prompts (提示模板)
&lt;/h4&gt;&lt;p&gt;输入构造层，支持变量替换、少样本示例、消息格式化&lt;/p&gt;
&lt;p&gt;●BasePromptTemplate: 动态构造模型输入&lt;/p&gt;
&lt;p&gt;●ChatPromptTemplate: 构造对话消息序列&lt;/p&gt;
&lt;p&gt;●PromptTemplate: 构造文本提示&lt;/p&gt;
&lt;h4 id="messages-消息"&gt;&lt;a href="#messages-%e6%b6%88%e6%81%af" class="header-anchor"&gt;&lt;/a&gt;Messages (消息)
&lt;/h4&gt;&lt;p&gt;对话交互的基本单元&lt;/p&gt;
&lt;p&gt;●BaseMessage: 所有消息的基类&lt;/p&gt;
&lt;p&gt;●HumanMessage: 用户消息&lt;/p&gt;
&lt;p&gt;●AIMessage: AI 回复&lt;/p&gt;
&lt;p&gt;●SystemMessage: 系统指令&lt;/p&gt;
&lt;p&gt;●ToolMessage: 工具调用结果&lt;/p&gt;
&lt;h4 id="documents-文档"&gt;&lt;a href="#documents-%e6%96%87%e6%a1%a3" class="header-anchor"&gt;&lt;/a&gt;Documents (文档)
&lt;/h4&gt;&lt;p&gt;知识存储的基本单元，是 RAG（检索增强生成）的基础数据结构&lt;/p&gt;
&lt;p&gt;●Document: 包含 page_content（内容）和 metadata（元数据）&lt;/p&gt;
&lt;p&gt;●用于表示任何文本数据：网页、PDF、数据库记录等&lt;/p&gt;
&lt;h4 id="retrievers-检索器"&gt;&lt;a href="#retrievers-%e6%a3%80%e7%b4%a2%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;Retrievers (检索器)
&lt;/h4&gt;&lt;p&gt;知识检索层，RAG 架构的核心组件&lt;/p&gt;
&lt;p&gt;●BaseRetriever: 是文档检索系统的抽象基类，它实现了 Runnable 接口以实现可组合性。它定义了基于查询检索相关文档的标准接口。&lt;/p&gt;
&lt;p&gt;●连接向量数据库、搜索引擎、数据库等&lt;/p&gt;
&lt;h4 id="vector-stores-向量存储"&gt;&lt;a href="#vector-stores-%e5%90%91%e9%87%8f%e5%ad%98%e5%82%a8" class="header-anchor"&gt;&lt;/a&gt;Vector Stores (向量存储)
&lt;/h4&gt;&lt;p&gt;语义搜索的基础设施&lt;/p&gt;
&lt;p&gt;●VectorStore: 向量数据库的抽象接口&lt;/p&gt;
&lt;p&gt;●存储和检索文档的向量表示&lt;/p&gt;
&lt;p&gt;●支持相似度搜索、混合搜索等&lt;/p&gt;
&lt;h4 id="embeddings-嵌入"&gt;&lt;a href="#embeddings-%e5%b5%8c%e5%85%a5" class="header-anchor"&gt;&lt;/a&gt;Embeddings (嵌入)
&lt;/h4&gt;&lt;p&gt;文本向量化，提供了嵌入模型的抽象接口，定义了将文本转换为向量表示的方法。它要求实现 embed&lt;em&gt;documents() 和 embed&lt;/em&gt;query() 方法。是语义搜索和相似度计算的基础。&lt;/p&gt;
&lt;p&gt;●Embeddings: 将文本转换为向量表示&lt;/p&gt;
&lt;p&gt;●支持各种嵌入模型（OpenAI、Hugging Face 等）&lt;/p&gt;
&lt;h4 id="output-parsers-输出解析器"&gt;&lt;a href="#output-parsers-%e8%be%93%e5%87%ba%e8%a7%a3%e6%9e%90%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;Output Parsers (输出解析器)
&lt;/h4&gt;&lt;p&gt;结构化输出，确保模型输出符合预期格式&lt;/p&gt;
&lt;p&gt;●BaseOutputParser: 解析模型输出为结构化数据&lt;/p&gt;
&lt;p&gt;●PydanticOutputParser: 解析为 Pydantic 模型&lt;/p&gt;
&lt;p&gt;●JsonOutputParser: 解析为 JSON&lt;/p&gt;
&lt;h4 id="tools-工具"&gt;&lt;a href="#tools-%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;Tools (工具)
&lt;/h4&gt;&lt;p&gt;BaseTool 是供智能体（Agents）使用的工具（Tools）的抽象基础，继承自 RunnableSerializable，并为与外部系统交互提供了标准化接口 。是 Function Calling 和 Agent 的基础。&lt;/p&gt;
&lt;p&gt;●BaseTool: 定义模型可调用的外部功能&lt;/p&gt;
&lt;p&gt;●让模型能执行计算、查询数据库、调用 API 等&lt;/p&gt;
&lt;h4 id="callbacks-回调"&gt;&lt;a href="#callbacks-%e5%9b%9e%e8%b0%83" class="header-anchor"&gt;&lt;/a&gt;Callbacks (回调)
&lt;/h4&gt;&lt;p&gt;观察和控制执行流程，提供执行过程的可见性&lt;/p&gt;
&lt;p&gt;●BaseCallbackHandler: 监听和响应执行事件&lt;/p&gt;
&lt;p&gt;●用于日志记录、调试、监控、流式输出等&lt;/p&gt;
&lt;h4 id="memorycache-记忆缓存"&gt;&lt;a href="#memorycache-%e8%ae%b0%e5%bf%86%e7%bc%93%e5%ad%98" class="header-anchor"&gt;&lt;/a&gt;Memory/Cache (记忆/缓存)
&lt;/h4&gt;&lt;p&gt;状态管理，对话历史管理、会话状态保持&lt;/p&gt;
&lt;p&gt;●BaseCache: 缓存 LLM 响应，避免重复调用&lt;/p&gt;
&lt;p&gt;●BaseStore: 键值存储抽象&lt;/p&gt;
&lt;h4 id="对照表"&gt;&lt;a href="#%e5%af%b9%e7%85%a7%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;对照表
&lt;/h4&gt;&lt;p&gt;这里是一个快速对照表，来将上文的 LangChain 模块与核心抽象组件之间做个对应。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;模块就像房间（客厅/厨房/卧室），抽象就像插座与标准接口（任意电器都能插上电并协同工作）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;●主要模块 = 按 “职能分区” 的功能板块（编排、模型、检索、Agent、记忆、部署等），回答 “系统里有哪些能力”。&lt;/p&gt;
&lt;p&gt;●核心抽象 = 跨模块通用的接口 / 基类（如 Runnable、BaseChatModel、BaseRetriever…），回答 “各模块如何被替换与拼装”。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/011-934b9b80.png"&gt;&lt;/p&gt;
&lt;h3 id="agent"&gt;&lt;a href="#agent" class="header-anchor"&gt;&lt;/a&gt;Agent
&lt;/h3&gt;&lt;p&gt;LangChain 框架完全可以构建 Agent，并且这是它自诞生以来最核心、最吸引人的功能之一。经典的 Agent（如 ReAct 范式）通过 AgentExecutor 实现一个 “思考 -&amp;gt; 行动 -&amp;gt; 观察” 的循环。LLM 在这个循环中扮演决策者，决定下一步调用哪个工具（Tool）。对于绝大多数单 Agent 任务，LangChain 的原生 Agent 完全够用。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/012-a42c3765.png"&gt;&lt;/p&gt;
&lt;p&gt;但是，当 Agent 的逻辑变得极其复杂，例如：&lt;/p&gt;
&lt;p&gt;1.需要循环和分支： 当流程不是线性，而是需要在多个步骤之间来回跳转。&lt;/p&gt;
&lt;p&gt;2.需要多 Agent 协作： 例如，一个 “分析师 Agent” 生成报告，交给 “代码生成 Agent” 编写代码，再由 “测试 Agent” 进行验证，如果测试失败，流程需要返回给 “分析师 Agent” 重新分析。&lt;/p&gt;
&lt;p&gt;3.需要持久化的状态管理： 在复杂的交互中，需要精确控制每一步的状态。&lt;/p&gt;
&lt;p&gt;这时 LangGraph 框架应运而生。它将 Agent 的工作流显式地定义为一个 状态图 (State Graph)。每个节点是一个工作单元（一个 LLM 调用或一个工具调用），每条边是状态的转移。它不是取代了 LangChain Agent，而是为构建更强大、更可控的 “状态化 Agent 系统” 提供了新的范式。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/013-f494e8e1.png"&gt;&lt;/p&gt;
&lt;h3 id="langgraph"&gt;&lt;a href="#langgraph" class="header-anchor"&gt;&lt;/a&gt;LangGraph
&lt;/h3&gt;&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/014-5f5786ef.png"&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;LangGraph 可以独立使用，但它也可以无缝集成到任何 LangChain 产品中。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;LangGraph 提供了比 LangChain 更底层、更灵活的控制能力，特别适合需要状态管理、人机协作和复杂流程编排的场景。而 LangChain 则更适合快速原型开发和简单的链式处理任务。两者可以协同使用：LangChain 的组件可以作为 LangGraph 的节点，但 LangGraph 也可以完全独立于 LangChain 使用。&lt;/p&gt;
&lt;p&gt;如果不用 LangGraph 开发，选择其他框架，推荐使用 CrewAI。&lt;/p&gt;
&lt;h4 id="langgraph-架构"&gt;&lt;a href="#langgraph-%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;LangGraph 架构
&lt;/h4&gt;&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/015-8a05667b.png"&gt;&lt;/p&gt;
&lt;p&gt;LangGraph 的执行流程遵循以下算法：&lt;/p&gt;
&lt;p&gt;&lt;img alt="mermaid diagram" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/016-0df3480e.png"&gt;&lt;/p&gt;
&lt;p&gt;LangChain 与 LangGraph 适用场景对比：&lt;/p&gt;
&lt;p&gt;&lt;img alt="mermaid diagram" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/017-346dca23.png"&gt;&lt;/p&gt;
&lt;p&gt;LangChain 与 LangGraph 代码对比&lt;/p&gt;
&lt;p&gt;LangChain（使用 AgentExecutor）:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_tool_calling_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== Tools ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Return a*b.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt; %H:%M:%S&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Return current local time formatted by fmt.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_time&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== LLM ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== Agent ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;You are a concise tool-using agent. Use the tools when helpful. Reply in Chinese.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{input}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_tool_calling_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== Demo ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;先用 multiply 计算 7×12，再调用 get_time 给出当前时间。答案只要一行。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Final:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我来画出详细的流程图，展示这个 LangChain Agent 的执行过程：&lt;/p&gt;
&lt;p&gt;&lt;img alt="mermaid diagram" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/018-03e5067a.png"&gt;&lt;/p&gt;
&lt;p&gt;LangGraph 代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# pip install -U langgraph langchain langchain-openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Sequence&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing_extensions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AnyMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt; &lt;span class="c1"&gt;# END 表示图的终点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.prebuilt&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt; &lt;span class="c1"&gt;# 预置的“工具节点”和“是否需要走工具”的路由函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ===== 工具定义：用 @tool 自动生成 JSON Schema，便于模型函数调用 =====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 定义乘法工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt; %H:%M:%S&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 定义获取时间工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_time&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 工具列表（给模型/工具节点用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ===== 绑定工具到模型：让 LLM 知道有哪些可调用的函数（工具） =====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bind_tools(...) 的效果：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1) 把 tools 的参数签名/描述转成 JSON Schema 给模型；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2) 让模型在需要时产生 tool_calls（函数调用）结构，而不是直接“胡说答案”。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ===== 定义“状态”的数据结构：LangGraph 的节点之间传的就是这个 State =====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;classS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AnyMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 一串消息（人类/AI/工具消息），作为“对话上下文”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ===== 定义一个“模型节点”：输入 State，调用 LLM，输出一条 AI 消息 =====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;agent_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 关键：把现有 messages（含用户、人类消息、工具结果等）喂给 LLM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ai_msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# 可能返回带 tool_calls 的 AIMessage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ai_msg&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="c1"&gt;# LangGraph 会把这条消息合并到全局 state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ===== 搭建“有向图”：节点 + 边，决定执行路径 =====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 新建一个“状态图”，S 是状态类型（结构）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——① 注册节点（起名叫 &amp;#34;agent&amp;#34; 和 &amp;#34;tools&amp;#34;）——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 把上面的函数包装成一个图节点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# 预置的工具节点：会读取 AI 的 tool_calls 并执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——② 设置“入口节点”：从哪个节点开始跑——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# ★ 从 &amp;#34;agent&amp;#34; 开始（也就是先问一次模型）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解释：这句相当于“第一步进图先走哪个节点”。如果不设，编译时会报错或不知道从哪开始。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——③ 配置“条件边”：根据模型输出决定接下来走哪条边——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 从 &amp;#34;agent&amp;#34; 节点出来时&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 用预置的判断函数：看 AIMessage 是否包含 tool_calls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# 如果需要工具→去 &amp;#34;tools&amp;#34;；否则→直接结束&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解释：tools_condition 会检查最新一条 AI 消息。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# - 若模型产生了函数调用（tool_calls），返回路由键 &amp;#34;tools&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# - 若没有需要的工具调用，返回路由键 &amp;#34;end&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 这行把路由键映射为真正的边：“tools”→去 tools 节点，“end”→走到 END（图的终点）。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——④ 把工具节点执行完后的边接回“agent”，形成闭环——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解释：当 tools 节点执行完所有函数调用，会把结果（ToolMessage）追加到 state.messages，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 然后回到 &amp;#34;agent&amp;#34; 再问一次模型。直到模型不再发起新的 tool_calls。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ——⑤ 编译成可运行的“应用”对象——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解释：compile() 会把上面定义的节点/边/合并策略等打包成可执行的图（可 invoke/stream）。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ===== 运行：给一条人类消息，按图的“入口节点”开始执行 =====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;73&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;先用 multiply 计算 7×12，再调用 get_time 报当前时间。只要一行中文。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解释：invoke 会：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# step1: 进入入口 &amp;#34;agent&amp;#34; → LLM 读到 HumanMessage，判断要不要调用工具；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# step2: 如果需要工具 → 路由到 &amp;#34;tools&amp;#34; 执行（得到 ToolMessage）→ 回到 &amp;#34;agent&amp;#34;；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# step3: 重复 step1~2，直到不需要工具 → 按条件边路由到 END → 返回最终状态。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;79&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 打印最后一条 AI 的自然语言回复&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;LangGraph 详细执行流程：&lt;/p&gt;
&lt;p&gt;&lt;img alt="mermaid diagram" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/019-ad88b6b3.png"&gt;&lt;/p&gt;
&lt;h2 id="竞品"&gt;&lt;a href="#%e7%ab%9e%e5%93%81" class="header-anchor"&gt;&lt;/a&gt;竞品
&lt;/h2&gt;&lt;p&gt;如果不使用 LangChain 开发 AI/LLM 应用，以下是主要的替代框架选择：&lt;/p&gt;
&lt;p&gt;以下是按要求整理的表格内容：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;框架&lt;/th&gt;
 &lt;th&gt;定位/标签&lt;/th&gt;
 &lt;th&gt;语言/平台&lt;/th&gt;
 &lt;th&gt;核心优势关键词&lt;/th&gt;
 &lt;th&gt;典型场景&lt;/th&gt;
 &lt;th&gt;🔎RAG&lt;/th&gt;
 &lt;th&gt;👥Agent&lt;/th&gt;
 &lt;th&gt;🏢企业&lt;/th&gt;
 &lt;th&gt;🎯输出控制&lt;/th&gt;
 &lt;th&gt;🪶轻量&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;LlamaIndex&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;RAG 与数据检索专家&lt;/td&gt;
 &lt;td&gt;Py/TS&lt;/td&gt;
 &lt;td&gt;多索引策略、查询路由、强检索、结构/非结构数据&lt;/td&gt;
 &lt;td&gt;知识库问答、文档分析、RAG&lt;/td&gt;
 &lt;td&gt;★★★★★&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;多智能体团队协作&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;角色/任务、顺序/并行/层级协作、社区活跃&lt;/td&gt;
 &lt;td&gt;多智能体系统、内容流水线、任务分解&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★★★&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Semantic Kernel&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;企业级 AI 编排&lt;/td&gt;
 &lt;td&gt;C#/Py/Java&lt;/td&gt;
 &lt;td&gt;技能/规划器、Azure 深度集成、微软背书&lt;/td&gt;
 &lt;td&gt;企业应用、复杂规划、微软技术栈&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★★★★&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Haystack&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;NLP/搜索系统专家&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;Pipeline 清晰、文档处理强、评测完善、重隐私&lt;/td&gt;
 &lt;td&gt;QA 系统、语义搜索、信息抽取&lt;/td&gt;
 &lt;td&gt;★★★★☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★★☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;自动化对话与代码生成&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;代码生成/执行、多 Agent 对话、自动化流程、人机协作&lt;/td&gt;
 &lt;td&gt;代码生成、数据分析自动化、技术任务&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★★☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Guidance&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;精确输出控制&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;模板语言、强格式约束、轻量高效&lt;/td&gt;
 &lt;td&gt;结构化输出、格式化生成、提示工程&lt;/td&gt;
 &lt;td&gt;★☆☆☆☆&lt;/td&gt;
 &lt;td&gt;★☆☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★★★★&lt;/td&gt;
 &lt;td&gt;★★★★☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;还有一些新兴 / 特色框架：&lt;/p&gt;
&lt;p&gt;以下是按要求整理的表格内容：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;框架&lt;/th&gt;
 &lt;th&gt;定位/标签&lt;/th&gt;
 &lt;th&gt;语言/平台&lt;/th&gt;
 &lt;th&gt;核心优势关键词&lt;/th&gt;
 &lt;th&gt;典型场景&lt;/th&gt;
 &lt;th&gt;🔎RAG&lt;/th&gt;
 &lt;th&gt;👥Agent&lt;/th&gt;
 &lt;th&gt;🏢企业&lt;/th&gt;
 &lt;th&gt;🎯输出控制&lt;/th&gt;
 &lt;th&gt;🪶轻量&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;LiteLLM&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;统一 LLM API&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;100+ 模型统一接口、超轻量、零依赖&lt;/td&gt;
 &lt;td&gt;简单 LLM 调用、多模型切换、原型&lt;/td&gt;
 &lt;td&gt;★☆☆☆☆&lt;/td&gt;
 &lt;td&gt;★☆☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★★★&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;DSPy&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;声明式/自动提示优化&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;可学习模块、自动调参、学术完善&lt;/td&gt;
 &lt;td&gt;指标导向优化、研究/实验&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;txtai&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;轻量 Transformers 框架&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;HF 生态、内置向量库、性能好&lt;/td&gt;
 &lt;td&gt;轻量语义搜索、嵌入式应用&lt;/td&gt;
 &lt;td&gt;★★★☆☆&lt;/td&gt;
 &lt;td&gt;★☆☆☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★★☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;MetaGPT&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;“AI 软件公司”模拟&lt;/td&gt;
 &lt;td&gt;Py&lt;/td&gt;
 &lt;td&gt;角色分工、项目级生成、代码产出&lt;/td&gt;
 &lt;td&gt;自动化软件开发、代码生成&lt;/td&gt;
 &lt;td&gt;★☆☆☆☆&lt;/td&gt;
 &lt;td&gt;★★★★☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;td&gt;★★☆☆☆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;在实际开发中，如不用 LangChain， 选型范围会缩小到最流行的几个竞品，比如：&lt;/p&gt;
&lt;p&gt;●🦙 LlamaIndex：原名 GPT-Index，是一个开源的数据框架，专门用于构建大型语言模型 (LLM) 应用。它主要解决了如何将 LLM 与外部数据有效连接的问题，使开发者能够创建更强大的知识密集型应用。&lt;/p&gt;
&lt;p&gt;●🚢 CrewAI：多智能体团队协作框架，CrewAI 是一个轻量、快速的 Python 框架，完全从零构建，与 LangChain 或其他代理框架完全无关。它为开发者提供高级别的简洁性和精确的底层控制，非常适合创建适用于任何场景的自主 AI 代理。&lt;/p&gt;
&lt;p&gt;●🔧 Haystack：一个端到端的大型语言模型（LLM）框架，它允许你构建由 LLM、Transformer 模型、向量搜索等功能驱动的应用程序。&lt;/p&gt;
&lt;p&gt;●🚀 AutoGen：用于创建能够自主行动或与人类协作的多智能体AI应用的框架&lt;/p&gt;
&lt;p&gt;需要注意的是：这些框架不是互斥的，可以组合使用（如 LlamaIndex + CrewAI）&lt;/p&gt;
&lt;h2 id="推荐学习路径"&gt;&lt;a href="#%e6%8e%a8%e8%8d%90%e5%ad%a6%e4%b9%a0%e8%b7%af%e5%be%84" class="header-anchor"&gt;&lt;/a&gt;推荐学习路径
&lt;/h2&gt;&lt;h3 id="掌握灵魂-lcel-langchain-expression-language"&gt;&lt;a href="#%e6%8e%8c%e6%8f%a1%e7%81%b5%e9%ad%82-lcel-langchain-expression-language" class="header-anchor"&gt;&lt;/a&gt;掌握灵魂 ——LCEL (LangChain Expression Language)
&lt;/h3&gt;&lt;p&gt;这是当前 LangChain 的绝对核心，也是最佳实践的开端。忘记很多旧的、高阶的 Chain 对象，从 LCEL 开始。&lt;/p&gt;
&lt;p&gt;实践: 构建你第一个，也是最重要的 LCEL 链：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段from&lt;/span&gt; &lt;span class="n"&gt;langchain_core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 定义提示模板 (Prompt)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;请给我讲一个关于&lt;/span&gt;&lt;span class="si"&gt;{topic}&lt;/span&gt;&lt;span class="s2"&gt;的笑话。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 初始化模型 (Model)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 定义输出解析器 (Parser)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;output_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 使用管道符 | 链接起来&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;output_parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 5. 执行链&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;程序员&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个 | 管道符就是 “数据流” 的体现。invoke 的输入字典首先流入 prompt 变成一个完整的提示，然后流入 model 得到模型的响应，最后流入 output_parser 提取出字符串结果。&lt;/p&gt;
&lt;h3 id="构建最核心的应用-rag"&gt;&lt;a href="#%e6%9e%84%e5%bb%ba%e6%9c%80%e6%a0%b8%e5%bf%83%e7%9a%84%e5%ba%94%e7%94%a8-rag" class="header-anchor"&gt;&lt;/a&gt;构建最核心的应用 ——RAG
&lt;/h3&gt;&lt;p&gt;理解了 LCEL 后，构建一个基础的 RAG 应用来贯穿大部分核心组件。&lt;/p&gt;
&lt;p&gt;实践:&lt;/p&gt;
&lt;p&gt;1.加载 (Load): 使用 TextLoader 或 PyPDFLoader 加载一个本地文件。&lt;/p&gt;
&lt;p&gt;2.分割 (Split): 使用 RecursiveCharacterTextSplitter 将文档分割成块 (Chunks)。&lt;/p&gt;
&lt;p&gt;3.存储 (Store): 使用 OpenAIEmbeddings 创建嵌入，并使用 FAISS 或 Chroma 等向量数据库进行存储。&lt;/p&gt;
&lt;p&gt;4.检索 (Retrieve): 从向量数据库创建一个 retriever 对象。&lt;/p&gt;
&lt;p&gt;5.生成 (Generate): 使用 LCEL 将检索到的内容、用户问题和模型调用组合成一个完整的 RAG 链。这比使用旧的 RetrievalQA 链更能让你理解内部原理。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/020-f489b51e.png"&gt;&lt;/p&gt;
&lt;h3 id="进入高阶-agents"&gt;&lt;a href="#%e8%bf%9b%e5%85%a5%e9%ab%98%e9%98%b6-agents" class="header-anchor"&gt;&lt;/a&gt;进入高阶 ——Agents
&lt;/h3&gt;&lt;p&gt;当你的应用需要与外部世界交互（如调用 API、查询数据库）时，才需要 Agent。&lt;/p&gt;
&lt;p&gt;实践:&lt;/p&gt;
&lt;p&gt;1.定义一两个简单的 Tool，例如一个用于数学计算的工具，一个用于获取当前日期的工具。&lt;/p&gt;
&lt;p&gt;2.选择一个 Agent 类型 (如 create&lt;em&gt;openai&lt;/em&gt;tools_agent)。&lt;/p&gt;
&lt;p&gt;3.使用 AgentExecutor 来运行它，观察它如何根据你的问题选择工具、执行并返回结果。&lt;/p&gt;
&lt;h2 id="常见陷阱与挑战"&gt;&lt;a href="#%e5%b8%b8%e8%a7%81%e9%99%b7%e9%98%b1%e4%b8%8e%e6%8c%91%e6%88%98" class="header-anchor"&gt;&lt;/a&gt;常见陷阱与挑战
&lt;/h2&gt;&lt;h3 id="抽象泄漏-leaky-abstraction"&gt;&lt;a href="#%e6%8a%bd%e8%b1%a1%e6%b3%84%e6%bc%8f-leaky-abstraction" class="header-anchor"&gt;&lt;/a&gt;抽象泄漏 (Leaky Abstraction)
&lt;/h3&gt;&lt;p&gt;定义: 一个 “抽象” 旨在隐藏底层实现的复杂性。当这个抽象无法完全隐藏底层细节，导致你必须理解底层是如何工作的才能正确地使用它或排查问题时，就发生了 “抽象泄漏”。&lt;/p&gt;
&lt;p&gt;LangChain 中的具体例子 (以旧版的 RetrievalQA 链为例):&lt;/p&gt;
&lt;p&gt;●美好的抽象: RetrievalQA 链看起来很简单，你只需要给它一个 llm 和一个 retriever，它就能帮你完成 RAG。你期望它能 “神奇地” 工作。&lt;/p&gt;
&lt;p&gt;●泄漏的现实:&lt;/p&gt;
&lt;p&gt;a.Prompt 在哪里？ 你发现问答效果不好。为什么？因为 RetrievalQA 内部使用了一个默认的、隐藏的 Prompt 模板 (类似 &amp;ldquo;Use the following pieces of context to answer the user&amp;rsquo;s question&amp;hellip;&amp;quot;)。这个默认模板可能不适合你的模型（比如某些中文模型），或者不符合你的业务场景。&lt;/p&gt;
&lt;p&gt;b.文档如何组合？ 当 retriever 返回了 4 个文档块 (Chunks) 时，这些文档是如何被塞进最终的 Prompt 里的？是简单拼接吗？如果超过了模型的上下文窗口怎么办？RetrievalQA 有一个 chain&lt;em&gt;type 参数（如 stuff, map&lt;/em&gt;reduce）来控制这个行为。&lt;/p&gt;
&lt;p&gt;问题的根源: 为了解决上述问题，你被迫去阅读 LangChain 的源码，去理解 RetrievalQA 内部隐藏的 Prompt 和文档组合逻辑。这时，RetrievalQA 这个本应让你省心的 “高级抽象”，反而成了你理解和调试的障碍。抽象 “泄漏” 了底层的实现细节。&lt;/p&gt;
&lt;p&gt;如何应对？&lt;/p&gt;
&lt;p&gt;拥抱 LCEL: LCEL 在很大程度上解决了这个问题。通过 prompt | model | parser 的方式， Prompt 是显式的，数据流是清晰的。你可以完全控制每一个环节，没有 “魔法” 和隐藏的逻辑。这是一种更 “白盒” 的构建方式，虽然初看起来代码多了一点，但可控性和可调试性大大增强。当然还有一种方案就是 “取其精华，去其糟粕”，LangChain 框架引入后，只用必要的部分组件，其余需要灵活处理的部分，全手写。&lt;/p&gt;
&lt;h3 id="调试的-黑盒感"&gt;&lt;a href="#%e8%b0%83%e8%af%95%e7%9a%84-%e9%bb%91%e7%9b%92%e6%84%9f" class="header-anchor"&gt;&lt;/a&gt;调试的 “黑盒感”
&lt;/h3&gt;&lt;p&gt;问题: 链的最终输出不符合预期，但中间过程完全不可见，不知道是 Prompt 错了、检索出的文档错了，还是模型理解错了。&lt;/p&gt;
&lt;p&gt;解决方案: LangSmith。这是解决此问题的标准答案。设置环境变量 LANGCHAIN&lt;em&gt;TRACING&lt;/em&gt;V2=&amp;ldquo;true&amp;rdquo; 即可开始追踪。用不了 LangSmith 的话，也可以用开源的 langfuse 替代。&lt;/p&gt;
&lt;h3 id="对简单任务过度设计"&gt;&lt;a href="#%e5%af%b9%e7%ae%80%e5%8d%95%e4%bb%bb%e5%8a%a1%e8%bf%87%e5%ba%a6%e8%ae%be%e8%ae%a1" class="header-anchor"&gt;&lt;/a&gt;对简单任务过度设计
&lt;/h3&gt;&lt;p&gt;问题: 你的任务只是需要根据一个模板调用一次 OpenAI API。这种情况下，引入 LangChain 的 LLMChain 相比直接使用 openai 库的 client.chat.completions.create()，增加了不必要的复杂性。&lt;/p&gt;
&lt;p&gt;解决方案: 保持务实。如果你的应用逻辑非常简单，就是一个单一的 LLM 调用，那么直接使用原生 SDK 可能更清晰、更轻量。当且仅当你需要编排多个步骤（如 RAG）、管理记忆、或使用 Agents 时，LangChain 的价值才能最大化。&lt;/p&gt;
&lt;h2 id="langchain-的版本演进"&gt;&lt;a href="#langchain-%e7%9a%84%e7%89%88%e6%9c%ac%e6%bc%94%e8%bf%9b" class="header-anchor"&gt;&lt;/a&gt;LangChain 的版本演进
&lt;/h2&gt;&lt;p&gt;&lt;img alt="mermaid diagram" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/021-327dd488.png"&gt;&lt;/p&gt;
&lt;h3 id="v10-alpha和-v0x-的关键差异"&gt;&lt;a href="#v10-alpha%e5%92%8c-v0x-%e7%9a%84%e5%85%b3%e9%94%ae%e5%b7%ae%e5%bc%82" class="header-anchor"&gt;&lt;/a&gt;v1.0 alpha：和 v0.x 的关键差异
&lt;/h3&gt;&lt;p&gt;v1.0 alpha（2025-09）是 LangChain 的一次 “面向长期” 的大改版&lt;/p&gt;
&lt;p&gt;核心变化&lt;/p&gt;
&lt;p&gt;●消息模型统一：新增 .content_blocks（标准化的 “内容块” 视图），把不同厂商的 “推理、引用、服务端工具调用、多模态” 等表示成 同一种类型，减少 provider 差异带来的胶水代码；对旧 .content 后向兼容。&lt;/p&gt;
&lt;p&gt;●Agent 重心调整：create_agent() 成为默认入口，底层基于 LangGraph 的图式运行时（持久化、流式、人审 / 中断、错误处理更规范）。&lt;/p&gt;
&lt;p&gt;●包面积极度收敛：langchain 更聚焦 “标准接口 + 预置 Agent / 链”；历史面迁到 langchain-legacy，便于兼容老代码再慢慢重构。&lt;/p&gt;
&lt;p&gt;●默认行为与平台要求：&lt;/p&gt;
&lt;p&gt;○Python 需 ≥3.10；Chat 模型返回类型固定为 AIMessage；OpenAI Responses API 的默认输出版本调整（可用 LC&lt;em&gt;OUTPUT&lt;/em&gt;VERSION=v0 退回）；Anthropic max_tokens 默认值上调。&lt;/p&gt;
&lt;p&gt;○JS / TS 侧：核心原语（createAgent、ToolNode、tool、消息类型）直接从 langchain 导出；Node.js 需 ≥20；大量老子路径导出清理。&lt;/p&gt;
&lt;h4 id="三个常见场景"&gt;&lt;a href="#%e4%b8%89%e4%b8%aa%e5%b8%b8%e8%a7%81%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;三个常见场景
&lt;/h4&gt;&lt;p&gt;1.“会用工具、可结构化返回” 的 Agent&lt;/p&gt;
&lt;p&gt;v0.x（典型写法）：构建 Agent + Executor，再自己管结构化解析 / 二次调用&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段&lt;/span&gt;&lt;span class="c1"&gt;# 旧式（示意）：AgentExecutor + 自行处理结构化输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initialize_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initialize_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;zero-shot-react-description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;What&amp;#39;s the weather in SF?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 再用正则/二次调用或手写解析把 result 转成 Weather(...)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;v1.0 alpha（新写法）：一个入口 create_agent，在主循环里直接产出结构化结果（避免多一次 LLM 调用、少走弯路）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段from&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;create_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;openai:gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 也可传入已实例化 model&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Weather&lt;/span&gt; &lt;span class="c1"&gt;# 结构化输出内建&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Weather in SF?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;structured_response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# -&amp;gt; Weather(...)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2.“跨厂商、多模态/推理/引用” 的消息处理&lt;/p&gt;
&lt;p&gt;v0.x：不同厂商字段名不同（如 reasoning、thinking、citations、server tool 等），常见一堆 if provider == &amp;hellip; 的分支。&lt;/p&gt;
&lt;p&gt;v1.0 alpha：直接读 .content_blocks（统一、强类型），必要时再序列化回标准块。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;⚡ python片段from langchain_core.messages import AIMessage
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;msg = some_llm.invoke(&amp;#34;Explain with sources &amp;amp; brief reasoning&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;# v1 统一读取：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;for block in msg.content_blocks:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; if block[&amp;#34;type&amp;#34;] == &amp;#34;reasoning&amp;#34;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; use_reasoning(block[&amp;#34;reasoning&amp;#34;])
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; if block[&amp;#34;type&amp;#34;] == &amp;#34;text&amp;#34; and &amp;#34;annotations&amp;#34; in block:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt; use_citations(block[&amp;#34;annotations&amp;#34;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3.“工具错误/人审/长对话摘要” 的生产级控制&lt;/p&gt;
&lt;p&gt;v0.x：这些能力多靠自写回调或外层控制流拼起来。&lt;/p&gt;
&lt;p&gt;v1.0 alpha：内置 Middleware 三钩子（before&lt;em&gt;model / modify&lt;/em&gt;model&lt;em&gt;request / after&lt;/em&gt;model）+ 现成中间件（摘要、人审、Anthropic Prompt Caching），还能 “跳转 / 中断”。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="n"&gt;python片段from&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;middleware&lt;/span&gt; &lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SummarizationMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HumanInTheLoopMiddleware&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;openai:gpt-4o&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SummarizationMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_tokens_before_summary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HumanInTheLoopMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_configs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;write_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;allow_approve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="langsmith--"&gt;&lt;a href="#langsmith--" class="header-anchor"&gt;&lt;/a&gt;LangSmith 🦜️⚒️
&lt;/h1&gt;&lt;p&gt;●解决 LLM 应用开发中最头疼的调试、追踪和评估问题，这是其商业化的核心（收费）。一个应用越复杂，就越离不开 LangSmith，形成用户粘性。&lt;/p&gt;
&lt;p&gt;●LangSmith = LLM 应用的 “一体化可观测 + 评测平台”：用来给 Agent / RAG / 多模态应用做 全链路追踪（Tracing）、 离 / 在线评测（Evals）、 监控告警、 成本与时延看板、Prompt 协作等；既可配合 LangChain / LangGraph，也支持非 LangChain 项目、OTEL 接入。&lt;/p&gt;
&lt;p&gt;可以开源免费的 langfuse 替代 LangSmith&lt;/p&gt;
&lt;h1 id="langserve-"&gt;&lt;a href="#langserve-" class="header-anchor"&gt;&lt;/a&gt;LangServe 🦜️🏓
&lt;/h1&gt;&lt;p&gt;●打通 “最后一公里”，让开发者能一键将用 LangChain 构建的应用 API 化&lt;/p&gt;
&lt;p&gt;●LangServe 可以把 LangChain 的 Runnable/Chain 一键暴露成 REST API 的开源库，基于 FastAPI + Pydantic，自带 /invoke、/batch、/stream、/stream&lt;em&gt;log、/stream&lt;/em&gt;events 等端点、自动推断 I / O Schema、内置 Playground，并可把追踪接到 LangSmith&lt;/p&gt;
&lt;p&gt;收费吗？&lt;/p&gt;
&lt;p&gt;库本身不收费。但其许可证限制： 不得把 LangServe 作为托管 / 托管式服务提供给第三方（SaaS）。也就是说，你可以用它部署自己的应用，但不能把 “LangServe 平台” 卖给其他公司用。另外，LangChain 官方更推荐新项目用 LangGraph Platform（LangServe 只接受社区 bug 修，不再收新特性）。如果要 “托管式平台”，那是另一条产品线（付费）&lt;/p&gt;
&lt;h1 id="langchain-的使用争议"&gt;&lt;a href="#langchain-%e7%9a%84%e4%bd%bf%e7%94%a8%e4%ba%89%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;LangChain 的使用争议
&lt;/h1&gt;&lt;p&gt;关于 LangChain 最开始的时候是一片盛赞，几乎全是正面评价，但随着开发者使用的深入，不断有负面评价出现。&lt;/p&gt;
&lt;p&gt;LangChain 在使用上的主要争议，或者说让开发者后来“抛弃” 它的主要原因有：&lt;/p&gt;
&lt;p&gt;1.API 频繁改、文档滞后，维护成本高&lt;/p&gt;
&lt;p&gt;○2023–2025 年间最常见吐槽：接口 / 导入路径经常变、语义化版本执行不严、文档跟不上，导致线上项目要反复改代码与迁移；社区讨论与帖子里这一点重复被提及。官方后来在 0.2 才引入 “版本化文档”以缓解这个痛点。Reddit&lt;/p&gt;
&lt;p&gt;2.抽象层过重/“抽象泄漏”&lt;/p&gt;
&lt;p&gt;○本来想简化 LLM 应用，但 层层抽象（Chains/Agents/Memory/Tools…） 让简单事变复杂；当跨供应商（OpenAI/Anthropic）或多模态/工具调用时，还是要理解底层差异并写分支， 抽象并未完全 “挡住细节”，很多人因此更倾向 “直接调 API / 自己拼装”。&lt;/p&gt;
&lt;p&gt;3.性能 / 成本开销与 “隐形调用”&lt;/p&gt;
&lt;p&gt;○经验帖里常见：token 使用低效、默认批量/重试/校验带来额外请求与延迟；默认设置偏原型友好，不一定适合生产（缓存、批处理、上下文裁剪都要自己细调）。DEV Community&lt;/p&gt;
&lt;p&gt;4.调试与可观测性难（不用配套工具时）&lt;/p&gt;
&lt;p&gt;○没接追踪时，多层封装中的报错 / 耗时难以定位，“像在雾里调试”；不少团队因此上了自家的可观测或放弃高阶封装。&lt;/p&gt;
&lt;p&gt;5.学习曲线与 “过度框架化”&lt;/p&gt;
&lt;p&gt;○许多工程团队反映：学习成本与收益不匹配，做简单的 RAG / 工作流时，直接 SDK + 少量自写代码更快可控；把 LangChain 当工具库（utility）用反而更顺。&lt;/p&gt;
&lt;p&gt;6.生态分拆、选择困难与 “框架漂移”&lt;/p&gt;
&lt;p&gt;○LangChain/ LangGraph/ LangServe/ LangSmith 产品边界不断演进；多数对比文章建议：流程化任务用 LangChain，复杂状态 / 多轮 agent 用 LangGraph—— 很多团队索性选更贴合场景的替代或 “手写”。DEV Community&lt;/p&gt;
&lt;p&gt;上面这些点，不是说 LangChain “不能用”，而是在规模化、稳定性要求高的团队里，可预期性 / 可控性往往比 “快速堆组件” 更重要。&lt;/p&gt;
&lt;h2 id="负面评价"&gt;&lt;a href="#%e8%b4%9f%e9%9d%a2%e8%af%84%e4%bb%b7" class="header-anchor"&gt;&lt;/a&gt;负面评价
&lt;/h2&gt;&lt;p&gt;这里我引用一些具体的负面评价，通过开发者真实的体验和文章来了解一下 LangChain 的问题。&lt;/p&gt;
&lt;h3 id="为什么我们不再使用-langchain-来构建我们的ai代理"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e6%88%91%e4%bb%ac%e4%b8%8d%e5%86%8d%e4%bd%bf%e7%94%a8-langchain-%e6%9d%a5%e6%9e%84%e5%bb%ba%e6%88%91%e4%bb%ac%e7%9a%84ai%e4%bb%a3%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;为什么我们不再使用 langchain 来构建我们的AI代理
&lt;/h3&gt;&lt;p&gt;●来源： &lt;a class="link" href="https://octomind.dev/blog/why-we-no-longer-use-langchain-for-building-our-ai-agents" target="_blank" rel="noopener"
 &gt;https://octomind.dev/blog/why-we-no-longer-use-langchain-for-building-our-ai-agents&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;●结论：作者最初喜欢 LangChain 因为其丰富组件和易用性，但后来因其抽象复杂、灵活性差而不推荐。&lt;/p&gt;
&lt;h4 id="初期为何喜欢使用-langchain"&gt;&lt;a href="#%e5%88%9d%e6%9c%9f%e4%b8%ba%e4%bd%95%e5%96%9c%e6%ac%a2%e4%bd%bf%e7%94%a8-langchain" class="header-anchor"&gt;&lt;/a&gt;初期为何喜欢使用 LangChain
&lt;/h4&gt;&lt;p&gt;作者在项目初期选择 LangChain，主要因为它具备以下优点：&lt;/p&gt;
&lt;p&gt;●丰富的工具和组件：LangChain 提供了大量现成的模块，能快速搭建 LLM 应用。&lt;/p&gt;
&lt;p&gt;●易于集成：框架承诺“让开发者一个下午就能从想法变成可运行代码”，适合原型开发和快速试错。&lt;/p&gt;
&lt;p&gt;●人气高、社区活跃：2023 年 LangChain 热度很高，生态完善，容易找到资料和支持。&lt;/p&gt;
&lt;p&gt;这些特性让作者在项目早期能专注于业务逻辑，而不用过多关心底层实现细节。&lt;/p&gt;
&lt;h4 id="后期为何不再推荐-langchain"&gt;&lt;a href="#%e5%90%8e%e6%9c%9f%e4%b8%ba%e4%bd%95%e4%b8%8d%e5%86%8d%e6%8e%a8%e8%8d%90-langchain" class="header-anchor"&gt;&lt;/a&gt;后期为何不再推荐 LangChain
&lt;/h4&gt;&lt;p&gt;随着项目复杂度提升，作者逐渐发现 LangChain 带来的问题：&lt;/p&gt;
&lt;p&gt;1.抽象层级过多，代码复杂&lt;/p&gt;
&lt;p&gt;○LangChain 引入了大量抽象（如 Prompt 模板、输出解析器、链等），让简单任务变得繁琐。&lt;/p&gt;
&lt;p&gt;○代码难以理解和维护，调试时需要花大量时间研究框架内部逻辑。&lt;/p&gt;
&lt;p&gt;2.灵活性不足，难以定制&lt;/p&gt;
&lt;p&gt;○框架对底层细节封装过度，开发者很难根据实际需求修改或扩展功能。&lt;/p&gt;
&lt;p&gt;○当需求超出 LangChain 设计假设时，反而成为限制，必须“将需求转化为适合 LangChain 的方案”，而不是直接实现业务逻辑。&lt;/p&gt;
&lt;p&gt;3.适应快速变化的 AI 领域能力有限&lt;/p&gt;
&lt;p&gt;○AI 和 LLM 领域变化极快，LangChain 的抽象和设计难以跟上新技术和新需求。&lt;/p&gt;
&lt;p&gt;○框架的“嵌套抽象”导致开发者需要理解庞大的堆栈和内部机制，增加了认知负担。&lt;/p&gt;
&lt;p&gt;4.团队协作和维护成本高&lt;/p&gt;
&lt;p&gt;○团队成员需要花大量时间理解和调试 LangChain，而不是专注于功能开发。&lt;/p&gt;
&lt;p&gt;○框架的复杂性让代码维护变得困难，影响开发效率。&lt;/p&gt;
&lt;h4 id="反思与建议"&gt;&lt;a href="#%e5%8f%8d%e6%80%9d%e4%b8%8e%e5%bb%ba%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;反思与建议
&lt;/h4&gt;&lt;p&gt;作者认为，虽然 LangChain 在原型阶段有用，但长期来看，直接用基础库（如 OpenAI API）开发更简单、灵活。大多数 LLM 应用只需少量核心组件，无需复杂框架。对于 AI Agent 等复杂场景，建议在 Agent 模式成熟前保持简单，避免过度依赖抽象。&lt;/p&gt;
&lt;p&gt;“一旦我们删除了它，我们就不再需要将我们的需求转化为适合 LangChain 的解决方案。我们只需编写代码即可。”&lt;/p&gt;
&lt;p&gt;作者的经历体现了技术选型中“早期便利 vs. 长期灵活性”的权衡，也反映了 AI 应用开发领域对“抽象与简单”的持续思考。&lt;/p&gt;
&lt;h3 id="2025-年了langchain-还是个无底洞"&gt;&lt;a href="#2025-%e5%b9%b4%e4%ba%86langchain-%e8%bf%98%e6%98%af%e4%b8%aa%e6%97%a0%e5%ba%95%e6%b4%9e" class="header-anchor"&gt;&lt;/a&gt;2025 年了，LangChain 还是个无底洞。
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://www.reddit.com/r/LocalLLaMA/comments/1iudao8/langchain" target="_blank" rel="noopener"
 &gt;https://www.reddit.com/r/LocalLLaMA/comments/1iudao8/langchain&lt;/a&gt;&lt;em&gt;is&lt;/em&gt;still&lt;em&gt;a&lt;/em&gt;rabbit&lt;em&gt;hole&lt;/em&gt;in_2025/?tl=zh-hans&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-23-langchain-shi-yin-tan-hai-shi-ji-shu-zhai/022-d6aace21.png"&gt;&lt;/p&gt;
&lt;h3 id="给研发团队的建议"&gt;&lt;a href="#%e7%bb%99%e7%a0%94%e5%8f%91%e5%9b%a2%e9%98%9f%e7%9a%84%e5%bb%ba%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;给研发团队的建议
&lt;/h3&gt;&lt;p&gt;●“轻 LangChain”：保留少量 LCEL/Runnable 原语（或只用部分解析 / 工具封装），核心链路直接用供应商 SDK 实现，减少抽象层。&lt;/p&gt;
&lt;p&gt;●“换轨到 LangGraph”：涉及复杂状态/长对话/人审/错误恢复的 agent，改用图式运行时（LangGraph / 其他工作流框架）。&lt;/p&gt;
&lt;p&gt;●“专用 RAG 框架 / 自研”：检索、重排、结构化输出走 LlamaIndex / 自研管线&lt;/p&gt;
&lt;p&gt;总之，手写代码是一条自主可控的道路，而梭哈 LangChain 可能会是一条不归路。&lt;/p&gt;</description></item><item><title>AI 编程工具使用有感</title><link>https://xiaobox.github.io/p/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/</link><pubDate>Thu, 26 Jun 2025 08:14:34 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/cover.jpg" alt="Featured image of post AI 编程工具使用有感" /&gt;&lt;p&gt;经过近 2 年的 AI 编程工具使用，积累了一些使用这些工具的经验和心得，本文分享出来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;以下分类纯属个人偏好，无任何客观依据，全是主观感受，仅供参考。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="第一梯队"&gt;&lt;a href="#%e7%ac%ac%e4%b8%80%e6%a2%af%e9%98%9f" class="header-anchor"&gt;&lt;/a&gt;第一梯队
&lt;/h2&gt;&lt;p&gt;Claude Code、Cursor、Augement Code、Windsurf、Warp、Gemini CLI&lt;/p&gt;
&lt;p&gt;第一梯队里的大家应该很熟悉，都是明星产品，我从接触时间的早晚来分别聊一下。&lt;/p&gt;
&lt;h3 id="cursor"&gt;&lt;a href="#cursor" class="header-anchor"&gt;&lt;/a&gt;Cursor
&lt;/h3&gt;&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/001-3275ab0e.png"&gt;&lt;/p&gt;
&lt;p&gt;Cursor 算是老朋友了，一直用。早期最令我兴奋的一款 AI 编程工具产品，还专门写了篇文章尬吹了一下 &lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=MzI3Njk5ODg4OQ==&amp;amp;mid=2247489537&amp;amp;idx=1&amp;amp;sn=147a299e76c9d6147caf097c21fb1bb5&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;Cursor 一个真正让程序员产生危机感的 AI 编程工具&lt;/a&gt;，今天翻回去看，我觉得吹的内容用 Cursor 基本上都能实现了。&lt;/p&gt;
&lt;p&gt;经过多次版本更新，Cursor 的使用模式稳定在了三种&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/002-e6346e53.png"&gt;&lt;/p&gt;
&lt;p&gt;用过 AI 工具的都知道，工具最核心的是底层使用的模型是什么，模型强不强决定着 “输出” 质量高不高，也就决定着代码质量。这跟开发者的切身利益可是息息相关的。&lt;/p&gt;
&lt;p&gt;很多开发者使用 Cursor 最看重的就是它能够使用 Claude 家最能打的模型，过去是 &lt;code&gt;claude-3.5-sonnet&lt;/code&gt; 现在是 &lt;code&gt;claude-4-sonnet&lt;/code&gt; 以及 &lt;code&gt;claude-4-opus&lt;/code&gt; 。这对于非专业开发者可能不够熟悉，大众更熟悉的是 OpenAI 的 4o 或者 Google 家的 gemini，无可厚非，但毋庸置疑的是，上面提到的 claude 家的一系列模型在编程领域就是最强的。不然广大开发者也不会心甘情愿的 “氪金” 来使用它。&lt;/p&gt;
&lt;p&gt;越好的模型越受欢迎，自然价格也水涨船高，像下面这两个模型我一般不开，因为（&lt;code&gt;Max Only&lt;/code&gt;）除了订阅费以外还要单独收费&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/003-0e9b339f.png"&gt;&lt;/p&gt;
&lt;p&gt;除了常规的操作，Cursor 自然也加入了 MCP，你可以添加自定义的 MCP&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/004-b2b95477.png"&gt;&lt;/p&gt;
&lt;p&gt;不过从我的日常开发使用经验上来说，MCP 用的时候不多。Cursor 自己其实也内置了一些 MCP，比如它会读你的本地文件，新建终端并执行 CLI 命令，联网搜索相关问题的答案等。&lt;/p&gt;
&lt;p&gt;Cursor 一直在更新，无论是添加新功能，还是改善老功能，总之肉眼可见的在进步，然而还是有一些常见的使用问题，它比较影响用户体验。比如使用 &lt;code&gt;claude-4-sonnet&lt;/code&gt; 时经常报网络异常，你跟他开始聊得好好的，有时候就突然开始没法响应了，报网络异常，有些时候是真着急，因为你代码改到一半，消耗了那么多 token 和时间，总不能半途而费吧，可 Cursor 就是不给你响应了，等待让人焦虑和上火。这时候我通常会切换到其他模式试一试比如 gemini。gemini 的最大优点是上下文够长，1M 上下文一般一个 Thread 怎么也够用了。但这也有风险，就像你同时请教 2 位专家，一位说着说着停了，你转头问另一位，但关键是 2 个人就有可能有 2 种不同的思路，这时候修改代码就需要你特别注意了，不要被误导，因为第 2 位可能会完全颠覆第 1 位提供的代码和思路。（我已被坑过了 🤣）&lt;/p&gt;
&lt;p&gt;其实这个问题我要反思，用 AI 工具开发，不能真的是 &lt;code&gt;Vibe Coding&lt;/code&gt; ，因为我们是专业的开发人员，不能偷懒，否则容易被坑，得不偿失。**AI 要像 “领航员”、“辅助驾驶” 、“僚机” ，不能够完全托管给它，因为专业的开发人员写的代码不是玩具，也不是仅仅能 run 起来就行的代码。**我们要考虑的问题很多，比如架构、扩展性、易读性、性能、成本、团队情况等等。&lt;/p&gt;
&lt;p&gt;如果你抱着谨慎的态度使用 AI编程工具和你一起编程的话，可能使用最多的就是 &lt;code&gt;TAB&lt;/code&gt; ，而这一点 Cursor 做的相当不错，可以说是很神，你改了一个函数、参数、方法声明、方法实现，按一下 &lt;code&gt;TAB&lt;/code&gt; 它是真的很智能，基本上能够想到你应该做的下一步是什么，这些本来就需要做的，比如重构，让它完美的提醒，这正是使用 Cursor 这种 AI 编程工具的一个非常适合的场景。&lt;/p&gt;
&lt;p&gt;而如果你抱着宽容、放纵的态度使用 Cursor 的话就一定会被 AI 的另一面所伤，比如 “幻觉”，当然伤势情况根据你的宽容程度而定。如果你放手让他大刀阔斧的进行重构，它有可能删除很多文件，新建很多文件，理想的情况是完美的完成了，但前提也一定是你给他做好了任务规划，让他一次只完成一个具体的任务，而不是给一个比较笼统的要求，比如重构一下整个项目。&lt;/p&gt;
&lt;p&gt;还有一种情况是上下文，虽然像 gemini 这种模型具有长上下文，我们在使用时也要脑子里有这根弦，上下文不能够太长，太长很容易产生幻觉和出一些意想不到的问题。我记得有一次我为了解决一个 bug，一直在一个 Thread 中和模型交互，模型最后的解决方案是把我 bug 相关的代码全部删除了，然后跟我说：“我保证，这次一定不会有问题了” 。 🤣 我是真谢了～&lt;/p&gt;
&lt;p&gt;所以，&lt;strong&gt;我们到底应该抱以什么态度来使用 AI 编程工具是个关键的问题&lt;/strong&gt;，我认为要具体问题具体分析，如果你真的是为了写一个 demo 而写代码，真的是能 run 就行，那可以采取比较激进和宽容的态度，放手让AI 实现，没什么大不了的，大不了就从头重写。而如果你写的是公司的生产级代码，那么就需要秉承谨慎和适当放手的策略，全程监督，让 AI 辅助你，而不是完全让他 “自动驾驶”。AI 越来越强大，但人类需要学习，哪怕慢一点，边学边干。否则&amp;hellip;&amp;hellip;(此处省略一万字)&lt;/p&gt;
&lt;h3 id="windsurf"&gt;&lt;a href="#windsurf" class="header-anchor"&gt;&lt;/a&gt;Windsurf
&lt;/h3&gt;&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/005-dd8ac6e8.png"&gt;&lt;/p&gt;
&lt;p&gt;在早期，相对 Cursor,我更喜欢 Windsurf ，原因很简单，同样的底层模型，不知道为什么， Windsurf 给的结果就是更好，更实用、可用。其实发展到现在，从功能上讲它跟 Cursor 差别不大，但从我的使用习惯、使用频率、模型以及软件背后母公司的发展等多方面考虑，最后我还是选择使用 Cursor 作为主力 AI 编程工具。&lt;/p&gt;
&lt;p&gt;后来的事情大家都知道了：“OpenAI 同意以 30 亿美元的价格收购Windsurf”&lt;/p&gt;
&lt;p&gt;后来，Winsurf 发布了自己的新模型 : &lt;code&gt;SWE-1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/006-81675349.png"&gt;&lt;/p&gt;
&lt;p&gt;总之，Winsurf 并不是牛夫人，它是一个很不错的软件，我也表示对它的敬畏和欣赏，Cursor 有的问题它也有，Cursor 没有的问题它不见得没有，只不过是我使用的时间没有那么长而已。&lt;/p&gt;
&lt;p&gt;也许有一天我还会转回使用 Winsurf，但现实就是如此，我不可能同时开那么多订阅，花那么多钱在多个 AI 编程工具上面。&lt;/p&gt;
&lt;h3 id="claude-code"&gt;&lt;a href="#claude-code" class="header-anchor"&gt;&lt;/a&gt;Claude Code
&lt;/h3&gt;&lt;p&gt;就在 Cursor 等一众 AI Coding 工具大杀四方的时候 Claude 低调地推出了它的 Claude Code。起初非常不起眼，我甚至都没有兴趣试用一下，直到后来有很多人用过了以后开始对它大为赞赏这才引起了我的兴趣。&lt;/p&gt;
&lt;p&gt;作为一个看起来有点儿 “土” 的工具，它是以终端命令的形式提供给用户使用的，不是 IDE，没有 GUI 界面，只有命令，你需要在终端使用命令和它交互。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/007-dc598b7e.png"&gt;&lt;/p&gt;
&lt;p&gt;其实作为专业的开发人员，对命令行并不陌生，反而会更亲近，这种形式没有 GUI，效率更高，但相对的是它对非专业人士没有 Cursor、VsCode 这种 IDE 友好。对于我来说，这无所谓，我都能接受。因为我看的是效果、结果、代码质量。&lt;/p&gt;
&lt;p&gt;但另一个问题就是个很大的门槛了，那就是 Claude 的账户问题。无论使用 Cursor 还是 Claude Code，花钱订阅几乎是必须的，但 Claude 家对账号的管控几近变态，动不动账户就被 ban 了，你需要拥有一个 “稳定” 的干净的账号，然后再订阅，其实说难也不难，但处理起来比较麻烦。当然也有使用 API 中转的方式，相对方便，这里就不多说了。&lt;/p&gt;
&lt;p&gt;我在深度体验了 2 天 Claude Code 后明白了为什么大家都想订阅 200每月的服务，因为真的很烧，而 的是不限 token 的，而且服务比较稳定，不像 Cursor 时不时的会抽风。&lt;/p&gt;
&lt;p&gt;我大致同意网上对 Claude Code 的赞美，但我也发现了很多无脑吹的，这和我的体验大相径庭，所以我得谈谈我的感受：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先，Claude Code 内置了许多 tools，而且它对任务的规划比较完整，再加上 tools，这样它对任务的执行就比较完整，注意不是完美，而是完整，不会让一个任务 “缺胳膊少腿”，总是差一点儿。&lt;/li&gt;
&lt;li&gt;完整的任务规划的代价就是烧 token，会用很多的 token，如果你没有订阅 200$ 这种无限量的，那可得省着点儿用。&lt;/li&gt;
&lt;li&gt;会思考，根据上下文、程序的输出日志、执行情况推断任务是否完成，是否重新执行，是否修改任务重新执行等，你看这么多事儿都是要调用模型的，也是要烧 token 的。&lt;/li&gt;
&lt;li&gt;无论哪个模型，仍然有幻觉，我们在其他 AI 工具上的经验可以移植，要谨慎，不要轻信它。&lt;/li&gt;
&lt;li&gt;它看起来很强大，可以思考、规划并自动完成你指定的任务，即便是比较大的任务。但很慢，对于你自己能干的事情，没必要浪费时间让它干，之前我偷懒让它完善一下 .gitignore 文件，它花了好久才搞定，虽然正确，但我干只需要一秒。而它要动用很多工具进行全面的分析，最后得出一个只改一行代码的结论。有点儿坑。&lt;/li&gt;
&lt;li&gt;对代码的管理依赖 git，虽然无可厚非，但确实不如 Cursor方便，鼠标点一下就能 restore 了。这一点儿我不争论，它是个习惯问题，就像不习惯使用 Vim 的虽然也承认 Vim 高效，但就是用不惯。&lt;/li&gt;
&lt;li&gt;用最强的模型+最优的 prompt 自然能产生最好的结果，这是人和 AI 配合的结果，我不知道这个优点能不能算到 Claude Code 的头上，因为对于其他 AI Coding 工具也适用。我不知道能不能算的原因还有一个是我不并知道 Cursor 内部做了什么，Claude Code 内部又做了什么，我只能拿结果比较，事实是 Claude Code 略胜一筹，但却让我有一丝担忧，因为它总让我有种快控制不了它的感觉。（指不定什么时候要出事儿）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;起初，我对 Claude Code 的热情是高涨的，但由于我的 2 个账号接连被 ban，订阅费又这么贵，合计了一下，还是回到 Cursor 了。这并不是说 Claude Code 不好，只不过对于我，这是个选择问题。&lt;/p&gt;
&lt;p&gt;哦，对了，因为不是 IDE，纯命令行，所以如果你用习惯了 &lt;code&gt;TAB&lt;/code&gt; ，Claude Code 可没有哈。使用模式要变。&lt;/p&gt;
&lt;h3 id="gemini-cli"&gt;&lt;a href="#gemini-cli" class="header-anchor"&gt;&lt;/a&gt;Gemini CLI
&lt;/h3&gt;&lt;p&gt;Google 是一家任谁都不能忽视的公司，在科技领域遍布它的身影，自然 AI Coding 工具也少不了它的参与。&lt;/p&gt;
&lt;p&gt;在我写这篇文章的上午 ，google 参战了，发布了 Gemini CLI，它是开源免费的，你用 Google 账号登录，就能直接使用，每天有 1000 次限额，够用了。&lt;/p&gt;
&lt;p&gt;它的产品逻辑和 Claude Code 一样，你可以把它理解成 Claude Code 的平替。它是开源的。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/008-cd7e2036.png"&gt;&lt;/p&gt;
&lt;p&gt;从功能、使用体验、效果等各个角度来看，目前它确实都不如 Claude Code，但它的优势也是那么的明显：免费、gemini 2.5模型上下文够长，量大管饱、大厂背书可信赖、将来生态集成可期&amp;hellip;&lt;/p&gt;
&lt;p&gt;从我在 Cursor 使用 gemini 模型的经验来看，我对 Google , 不，应该是 gemini 是有强烈好感的，它确实强：比我命还长的上下文（1M），强大的推理和思考能力，不输给任何模型的基础能力，你还要什么自行车呢？ 用就好了。&lt;/p&gt;
&lt;h3 id="warp"&gt;&lt;a href="#warp" class="header-anchor"&gt;&lt;/a&gt;Warp
&lt;/h3&gt;&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/009-45d184dd.png"&gt;&lt;/p&gt;
&lt;p&gt;Warp 最初是作为终端工具进入我的视野的，那时候 我还在用 iTerm2，使用了 Warp 以后，被它良好的用户体验和优美的外观吸引。随着它不同的更新，在最近两年加入了 AI 功能，成为了一个智能开发工具。&lt;/p&gt;
&lt;p&gt;由于我经常进行服务器的运维工作，终端工具的使用是非常频繁的，小到执行些基础的运维命令，大到写 shell 、python 脚本 ，进行服务器初始化 、k8s 部署。&lt;/p&gt;
&lt;p&gt;其实相比 Claude Code，Warp 新加的 AI 功能带给我的体验是很自然的。因为在命令行环境，我的输入、输出 Warp 都能捕获到，进而给我具体的建议和任务规划，当然，它背后仍然是大模型提供的能力。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/010-6a447362.png"&gt;&lt;/p&gt;
&lt;p&gt;在我敲命令时，它可以给我提示，当命令执行完成输出结果时，它可以指导我进行下一步的操作，如果我忘了命令该怎么写，它也可以完成命令，或者给出最合理的建议并自动执行。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/011-cc229cf4.png"&gt;&lt;/p&gt;
&lt;p&gt;当然用模型是要花钱的，它有一些免费的额度，用完了就需要付费了。最近它又加入了 “上下文” ，可以将你的代码工程作为上下文给他分析，同时与你一起结伴编程。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/012-a2741553.png"&gt;&lt;/p&gt;
&lt;p&gt;这就和 Claude Code 以及 Gemini CLI 很像了。不过说实话我用 Warp 还是基于命令行的场景，编程一般不会它，还是会用 Cursor。但它确实越来越强了，值得大家的关注。&lt;/p&gt;
&lt;h3 id="augement-code"&gt;&lt;a href="#augement-code" class="header-anchor"&gt;&lt;/a&gt;Augement Code
&lt;/h3&gt;&lt;p&gt;无论 Cursor、Claude Code 如何优秀，都有令人不满的地方，在体验了这么多产品以后，我发现 Augement Code 比较适合我，虽然我还没有正式订阅，但它是目前为止我最满意的。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/013-dc623d29.png"&gt;&lt;/p&gt;
&lt;p&gt;Augement Code 目前并不是一个独立的 IDE，而是一个插件，它可以在 IDEA 以及 VsCode 中安装使用。&lt;/p&gt;
&lt;p&gt;作为一个 AI Coding 工具，它的基础功能和 Cursor 差不多，就不赘述了。下面说说它的特点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;你无法选用模型，从现在知道的资料来看，貌似使用的是 &lt;code&gt;claude-3.5-sonnet&lt;/code&gt; ，但我觉得可能不是，很有可能是更强的。虽然无法选模型，但输出质量很高。不比 Cursor 这种可选模型的差。所以如果是 &lt;code&gt;claude-3.5-sonnet&lt;/code&gt; 就能输出这样的质量，那 Augement Code 团队可真了不起。&lt;/li&gt;
&lt;li&gt;会自动进行一系列的任务规划，并清楚地展示给你看具体细节&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/014-a6e2fe09.png"&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;任务规划完成后，对于没有把握或你没有确认过的事项，更倾向于新建文件，而不是修改你原本的代码。这一点我很受用，因为 Cursor 经常在多轮对话中把代码越改越滥，最后迫不得已我点了 &lt;code&gt;restore checkpoint&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;稳定，很少出网络异常&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不便宜，需要订阅，比 Cursor 贵，每月 50$ 起，而且是限量的（600 次消息）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;目前我还在试用中，从现在的使用情况看，后面很有可能会换用 Augement Code，退订 Cursor。不过我还是有点儿犹豫，因为 Cursor 不限量啊。&lt;/p&gt;
&lt;h2 id="第二梯队"&gt;&lt;a href="#%e7%ac%ac%e4%ba%8c%e6%a2%af%e9%98%9f" class="header-anchor"&gt;&lt;/a&gt;第二梯队
&lt;/h2&gt;&lt;p&gt;Cline、Copilot、firebase&lt;/p&gt;
&lt;p&gt;从第二梯队开始，我在开发上的使用频率依次递减。&lt;/p&gt;
&lt;h3 id="copilot"&gt;&lt;a href="#copilot" class="header-anchor"&gt;&lt;/a&gt;Copilot
&lt;/h3&gt;&lt;p&gt;应该是也不用过多介绍了。Github ，哦不，微软家的。&lt;/p&gt;
&lt;p&gt;最开始是大哥，现在是小老弟了。平时几乎不用，偶尔测试一下，看看效果如何，一点儿都不能打，整体跟 Cursor 那一众差远了，&lt;/p&gt;
&lt;h3 id="firebase"&gt;&lt;a href="#firebase" class="header-anchor"&gt;&lt;/a&gt;firebase
&lt;/h3&gt;&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/015-19bdb3f6.png"&gt;&lt;/p&gt;
&lt;p&gt;也是 Google 家的，但总感觉不是给开发者用的，全 web 的形式，不是 IDE，用起来别扭，但因为模型强大，所以做个前端 demo 什么的效果还不错，真正在开发场景我是不会用的。&lt;/p&gt;
&lt;h3 id="cline"&gt;&lt;a href="#cline" class="header-anchor"&gt;&lt;/a&gt;Cline
&lt;/h3&gt;&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/016-bc045784.png"&gt;&lt;/p&gt;
&lt;p&gt;开源免费，插件形式提供。自己通过 API 配置模型，整体效果还可以，但维护的心智成本略高，用了几天弃了，用回了 Cursor。不是人家不好啊，是我的选择问题。用的人还是很多的，整体成本小，对于用量不大的，你随便买个 API 一接就能使了。&lt;/p&gt;
&lt;h2 id="第三梯队"&gt;&lt;a href="#%e7%ac%ac%e4%b8%89%e6%a2%af%e9%98%9f" class="header-anchor"&gt;&lt;/a&gt;第三梯队
&lt;/h2&gt;&lt;p&gt;Trae、通义灵码、MarsCode、微信开发者工具&lt;/p&gt;
&lt;h3 id="trae"&gt;&lt;a href="#trae" class="header-anchor"&gt;&lt;/a&gt;Trae
&lt;/h3&gt;&lt;p&gt;字节家的，对于它，早期乃至现在的噱头都很足，可以在国内网络环境下使用世界最先进的模型。但是，我真的不知道是什么原因，同样的模型，比如 &lt;code&gt;claude-4-sonnet&lt;/code&gt; Cursor 整体返回的结果就是 OK 的，Trae 就是稀烂。所以我怀疑不是模型的事儿，但又不知道是哪里出的问题。经过多次的尝试效果始终赶不上 Cursor，甚至还不如 Cline,弃了，以后也不会用。&lt;/p&gt;
&lt;p&gt;不过它有它的市场，好好做也许会越来越好吧，谁知道呢？&lt;/p&gt;
&lt;h3 id="通义灵码marscode微信开发者工具"&gt;&lt;a href="#%e9%80%9a%e4%b9%89%e7%81%b5%e7%a0%81marscode%e5%be%ae%e4%bf%a1%e5%bc%80%e5%8f%91%e8%80%85%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;通义灵码、MarsCode、微信开发者工具
&lt;/h3&gt;&lt;p&gt;这些产品我都是早期的使用者，开始都很惊艳，因为早期我也是土包子没见过世面，觉得 AI 工具真的很强大。后来被其他工具征服了以后对这些就没兴趣了。嗯，这些是真正的 “牛夫人”。 如果有条件也不推荐别人用了，有更完善和强大的工具，没必要没苦硬吃。&lt;/p&gt;
&lt;h2 id="第四梯队"&gt;&lt;a href="#%e7%ac%ac%e5%9b%9b%e6%a2%af%e9%98%9f" class="header-anchor"&gt;&lt;/a&gt;第四梯队
&lt;/h2&gt;&lt;p&gt;DeepSeek、ChatGPT、Claude、通义千问、腾讯元宝等&lt;/p&gt;
&lt;p&gt;理论上这些在我这里都不算 AI 编程工具，它们全部都是 文生文的产品。只不过内置了可以预览和编程的工具。但那都仅仅限于代码片段。写个玩具还行，写项目？别闹。&lt;/p&gt;
&lt;p&gt;最近 OpenAI 贼心不死，收了 winsurf 后还要搞编程工具，出了个 codex 集成在 ChatGPT中。说实话 ，玩玩儿还行，有点儿鸡肋。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/017-bf9a9ab7.png"&gt;&lt;/p&gt;
&lt;h2 id="其他"&gt;&lt;a href="#%e5%85%b6%e4%bb%96" class="header-anchor"&gt;&lt;/a&gt;其他
&lt;/h2&gt;&lt;p&gt;v0、bolt、Lovable&lt;/p&gt;
&lt;p&gt;如何让 AI 编程赋能给普罗大众？ 以上这些产品给出了各自不同的答案 。&lt;/p&gt;
&lt;h3 id="v0"&gt;&lt;a href="#v0" class="header-anchor"&gt;&lt;/a&gt;v0
&lt;/h3&gt;&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/018-b1883e95.png"&gt;&lt;/p&gt;
&lt;p&gt;v0 是我使用最多的产品，一般画个架构图，写个页面 Demo，直接聊天就行了，效果也是越来越好。&lt;/p&gt;
&lt;h3 id="bolt"&gt;&lt;a href="#bolt" class="header-anchor"&gt;&lt;/a&gt;bolt
&lt;/h3&gt;&lt;p&gt;bolt 由 Supabase 集成支持，支持上传图片/文件作为提示生成应用原型，适合快速开发应用。支持从设计稿到应用的一键生成。（是这么宣传的，但越是复杂的项目越不可能）&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/019-e9ea52e1.png"&gt;&lt;/p&gt;
&lt;h3 id="lovable"&gt;&lt;a href="#lovable" class="header-anchor"&gt;&lt;/a&gt;Lovable
&lt;/h3&gt;&lt;p&gt;支持通过自然语言生成交互式界面代码，与 v0 类似，但更侧重于低代码与 AI 结合的开发模式，适合非技术人员快速构建应用。尤其偏重于设计师群体。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/020-ffc27caf.png"&gt;&lt;/p&gt;
&lt;p&gt;设计这个领域不止是 Lovable，国人也有产品发布，比如 YouWare。&lt;/p&gt;
&lt;p&gt;YouWare 拥有「代码快速转化与分享」「自然语言生成网站」「一键美化作品」「创意流动与共创」「和谐社区环境」「自主控制作品曝光」和「创作激励体系」七大产品亮点。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-26-ai-bian-cheng-gong-ju-shi-yong-you-gan/021-06fe40dc.png"&gt;&lt;/p&gt;
&lt;p&gt;创始人明超平曾在一加手机担任手机影像产品经理，在字节跳动负责剪映 / Capcut 手机端工具，在月之暗面做过核心产品负责人。&lt;/p&gt;
&lt;p&gt;YouWare 这个产品就是 &lt;strong&gt;帮助普通用户通过 AI Coding 将创意和灵感迅速转化为作品&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="最后"&gt;&lt;a href="#%e6%9c%80%e5%90%8e" class="header-anchor"&gt;&lt;/a&gt;最后
&lt;/h2&gt;&lt;p&gt;我将用一句话总结一下 AI Coding 的未来：&lt;strong&gt;帮助用户（专业的和普通的）通过 AI Coding 将想法利用代码作为媒介转化成产品。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无论 是什么想法&lt;/li&gt;
&lt;li&gt;无论 是什么产品&lt;/li&gt;
&lt;li&gt;无论 是什么用户&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI Coding 未来的想象空间，理论上，是无限的。&lt;/p&gt;</description></item><item><title>从初始化一个现代 python 项目中学习到的东西</title><link>https://xiaobox.github.io/p/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/</link><pubDate>Sun, 27 Apr 2025 06:57:05 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/cover.jpg" alt="Featured image of post 从初始化一个现代 python 项目中学习到的东西" /&gt;&lt;h2 id="uv"&gt;&lt;a href="#uv" class="header-anchor"&gt;&lt;/a&gt;uv
&lt;/h2&gt;&lt;p&gt;我准备用 uv 初始化一个 python 项目&lt;/p&gt;
&lt;h3 id="环境"&gt;&lt;a href="#%e7%8e%af%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;环境
&lt;/h3&gt;&lt;p&gt;我用的是苹果笔记本 MacBookPro ，具体的操作系统及硬件参数如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/001-7b50b558.png"&gt;&lt;/p&gt;
&lt;h3 id="uv-的介绍与安装"&gt;&lt;a href="#uv-%e7%9a%84%e4%bb%8b%e7%bb%8d%e4%b8%8e%e5%ae%89%e8%a3%85" class="header-anchor"&gt;&lt;/a&gt;uv 的介绍与安装
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;uv 是一个使用 Rust 编写的工具，可以用来替代 pip、pipenv、pipx、poetry、virtualenv 等工具的使用，甚至还可以用来管理系统中所安装的 Python 发行版。uv 借鉴了很多现代语言中对于项目依赖的管理方式，项目中对于依赖的管理要远远优于使用 pip 和requirements.txt的方式。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;我之前用过 pip 、pipx 等工具，发现 uv 确实要快不少。具体有多快呢？ github 上有个图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/002-23c27ef6.png"&gt;&lt;/p&gt;
&lt;p&gt;🚀速度比传统 pip 快 10-100倍。&lt;/p&gt;
&lt;p&gt;根据官网的介绍，uv 主要支持以下功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;支持版本锁定的项目依赖管理。&lt;/li&gt;
&lt;li&gt;支持直接运行 Python 脚本。&lt;/li&gt;
&lt;li&gt;支持对系统中安装的 Python 进行管理，支持多版本 Python 共存。&lt;/li&gt;
&lt;li&gt;支持 Python 包的发布和安装。&lt;/li&gt;
&lt;li&gt;支持兼容 pip 的应用接口。&lt;/li&gt;
&lt;li&gt;支持 Cargo 模式的项目工作区管理。&lt;/li&gt;
&lt;li&gt;更优化的全局支持库缓存。&lt;/li&gt;
&lt;li&gt;运行无需 Rust 或者 Python 支持。&lt;/li&gt;
&lt;li&gt;支持 Windows、macOS 和 Linux 系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;uv 对多 python 版本和环境的管理很不错，这样你就可以一个项目指定一个特定的 Python 版本，放心使用，想怎么折腾怎么折腾，不会影响全局。&lt;/p&gt;
&lt;p&gt;最近比较火的 MCP 很多也是用 uv 运行的，因为用 uv 命令可以直接运行 python 脚本。&lt;/p&gt;
&lt;p&gt;uv 的安装非常简单：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# macOS和Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class="p"&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Windows PowerShell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;powershell -ExecutionPolicy ByPass -c &lt;span class="s2"&gt;&amp;#34;irm https://astral.sh/uv/install.ps1 | iex&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="uv-对-python-的环境管理"&gt;&lt;a href="#uv-%e5%af%b9-python-%e7%9a%84%e7%8e%af%e5%a2%83%e7%ae%a1%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;uv 对 Python 的环境管理
&lt;/h3&gt;&lt;p&gt;首先用 uv 管理一下我们本机安装的 Python 环境。即到底安装了几个、哪些版本的 python。&lt;/p&gt;
&lt;p&gt;可以用 &lt;code&gt;uv python list&lt;/code&gt; 查看，像这样：&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/003-cd779d4c.png"&gt;&lt;/p&gt;
&lt;p&gt;可以看到我已经安装了多个版本的 python。 在后面建项目的时候，我选用 3.13 这个版本。当然你也可以根据你的情况下载新的需要使用的版本。这里给出一组相关命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv python install，安装指定版本的 Python。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv python list，列出系统中当前已经安装的 Python 版本。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv python find，查找一个已经安装的 Python 版本。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;uv python pin，固定当前项目使用指定的 Python 版本。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;uv python uninstall，卸载指定版本的 Python。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;比如我要安装 3.12 这个版本，我就可以这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv python install 3.13
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;装好了不想要了，就可以这样卸载掉它：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv python uninstall 3.13 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="uv-进行项目管理"&gt;&lt;a href="#uv-%e8%bf%9b%e8%a1%8c%e9%a1%b9%e7%9b%ae%e7%ae%a1%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;uv 进行项目管理
&lt;/h3&gt;&lt;p&gt;python 的环境有了以后，我们就可以新建项目了，建项目的时候也要用 uv 来进行初始化。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;uv 的项目管理功能更多的借鉴了 Rust 中 Cargo 工具的项目管理理念。但主要区别是 uv 是通过项目目录中的pyproject.toml文件来完成项目管理的。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv init myproject
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;初始化后会生成以下几个文件 ：&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/004-32d38507.png"&gt;&lt;/p&gt;
&lt;p&gt;虽然 uv init myproject 会帮你创建项目目录和 pyproject.toml，但默认 不会自动创建虚拟环境（env），所以我们需要手动创建。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# 手动创建虚拟环境
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv venv --python 3.13
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;# 激活虚拟环境
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;source .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;虚拟环境激活后，项目中会多一个.venv 文件夹。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-04-27-cong-chu-shi-hua-yi-ge-xian-dai-python-xiang-mu-zhong-xue-xi/005-3a39005f.png"&gt;&lt;/p&gt;
&lt;p&gt;接下来我们要自己创建一下源码目录和测试目录：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p src tests
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;到这里工程的相关目录我们就先到此为止，基本上创建完了，然后我们来编辑&lt;/p&gt;
&lt;p&gt;pyproject.toml 配置文件。&lt;/p&gt;
&lt;h3 id="toml-配置文件"&gt;&lt;a href="#toml-%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;toml 配置文件
&lt;/h3&gt;&lt;p&gt;我们先介绍一下 toml 文件，可能有些朋友不怎么了解它，比如搞 java 开发的。&lt;/p&gt;
&lt;p&gt;TOML（Tom&amp;rsquo;s Obvious, Minimal Language）是一种配置文件格式，设计目标是&lt;strong&gt;易读、易写、易于解析&lt;/strong&gt;，非常适合作为程序的配置语言，尤其是在现代的跨平台开发中被广泛采用。&lt;/p&gt;
&lt;p&gt;你看这名字是不是觉得肯定跟 Tom 大哥有关系？&lt;/p&gt;
&lt;p&gt;对，因为 TOML 由 GitHub 联合创始人 Tom Preston-Werner 在 2013 年发起，用以替代 JSON、INI 等配置格式在可读性和灵活性上的不足。&lt;/p&gt;
&lt;p&gt;不过吧，后来这大哥（和她媳妇）不在 GitHub 干了，因为他们的一些不光彩的行为。具体是什么就不多说了，想八卦一下的可以去查查。&lt;/p&gt;
&lt;p&gt;toml 配置文件用途广泛，常用于以下场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用程序运行时配置&lt;/li&gt;
&lt;li&gt;包管理工具（如 Python 的 pyproject.toml、Rust 的 Cargo.toml）&lt;/li&gt;
&lt;li&gt;构建工具配置（如 poetry.toml, uv.toml）&lt;/li&gt;
&lt;li&gt;数据库或服务连接信息等环境参数配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举个例子吧：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;# 数据库配置
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;[database]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;server = &amp;#34;192.168.1.1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;ports = [ 8001, 8001, 8002 ]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;enabled = true
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;# 应用信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;[app]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;name = &amp;#34;MyApp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;version = &amp;#34;1.0.0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;release_date = 2025-04-25T12:00:00Z
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TOML 的特点可以总结为：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;“比 JSON 更适合人读，比 YAML 更适合程序解析。”&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;它已经成为现代软件开发中最流行的配置文件格式之一，特别是在需要 &lt;strong&gt;清晰结构 + 丰富类型 + 可维护性&lt;/strong&gt; 的场景中表现出色。&lt;/p&gt;
&lt;p&gt;常见语言的支持情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python：tomli / toml / pytoml / tomllib（Python 3.11 原生支持）&lt;/li&gt;
&lt;li&gt;Rust：官方包管理工具 Cargo 就使用 TOML 格式的 Cargo.toml&lt;/li&gt;
&lt;li&gt;Go：支持 BurntSushi/toml 库&lt;/li&gt;
&lt;li&gt;Node.js：支持 @iarna/toml 等多个库&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常见用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 包管理：pyproject.toml（PEP 518 标准）&lt;/li&gt;
&lt;li&gt;Rust 项目管理：Cargo.toml&lt;/li&gt;
&lt;li&gt;Web 项目配置：netlify.toml&lt;/li&gt;
&lt;li&gt;DevOps 工具：例如 uv 的配置也是用 toml 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TOML 与其他格式的对比：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;特性&lt;/th&gt;
 &lt;th&gt;TOML&lt;/th&gt;
 &lt;th&gt;JSON&lt;/th&gt;
 &lt;th&gt;YAML&lt;/th&gt;
 &lt;th&gt;INI&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;可读性&lt;/td&gt;
 &lt;td&gt;✅ 高&lt;/td&gt;
 &lt;td&gt;中&lt;/td&gt;
 &lt;td&gt;中高（但复杂）&lt;/td&gt;
 &lt;td&gt;中&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;注释支持&lt;/td&gt;
 &lt;td&gt;✅ 支持&lt;/td&gt;
 &lt;td&gt;❌ 不支持&lt;/td&gt;
 &lt;td&gt;✅ 支持&lt;/td&gt;
 &lt;td&gt;✅ 支持&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;数据类型支持&lt;/td&gt;
 &lt;td&gt;✅ 多&lt;/td&gt;
 &lt;td&gt;✅ 多&lt;/td&gt;
 &lt;td&gt;✅ 多&lt;/td&gt;
 &lt;td&gt;❌ 有限&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;库支持&lt;/td&gt;
 &lt;td&gt;✅ 常见语言皆支持&lt;/td&gt;
 &lt;td&gt;✅ 全面&lt;/td&gt;
 &lt;td&gt;✅ 全面&lt;/td&gt;
 &lt;td&gt;✅ 较好&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;学习曲线&lt;/td&gt;
 &lt;td&gt;✅ 低&lt;/td&gt;
 &lt;td&gt;✅ 低&lt;/td&gt;
 &lt;td&gt;❌ 偏高&lt;/td&gt;
 &lt;td&gt;✅ 极低&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;你看，TOML 作为配置文件感觉很不错对吧。&lt;/p&gt;
&lt;p&gt;我们关于 TOML 的介绍就到此为止，现在来说一下我们这个初始化的新项目中的 pyproject.toml 文件要写成什么样。&lt;/p&gt;
&lt;p&gt;就这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;hatchling&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;hatchling.build&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myproject&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;一个基于Python 3.13.3的项目&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;readme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;README.md&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;requires&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;gt;=3.13&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xiaobox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xiaobox@gmail.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;pytest&amp;gt;=7.4.3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;fastapi&amp;gt;=0.110.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;uvicorn&amp;gt;=0.27.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;httpx&amp;gt;=0.27.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;classifiers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Programming Language :: Python :: 3.13&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;License :: OSI Approved :: MIT License&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Operating System :: OS Independent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myproject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;src.main:main&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;Homepage&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://github.com/yourusername/myproject&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;Bug Tracker&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://github.com/yourusername/myproject/issues&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;black&amp;gt;=23.1.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;isort&amp;gt;=5.12.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;mypy&amp;gt;=1.5.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;testpaths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tests&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;py313&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isort&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;black&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;line_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hatch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;src&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;别小看了这个文件，它可是一个使用了 Hatch 构建工具、遵循 PEP 621 和现代 Python 项目结构规范的项目配置，涵盖了运行依赖、开发依赖、CLI 脚本、格式化工具配置、测试路径和打包目标，非常完整规范。&lt;/p&gt;
&lt;p&gt;所以我们得逐行解释一下这个重要的文件。&lt;/p&gt;
&lt;h3 id="toml-配置文件的逐行解释"&gt;&lt;a href="#toml-%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6%e7%9a%84%e9%80%90%e8%a1%8c%e8%a7%a3%e9%87%8a" class="header-anchor"&gt;&lt;/a&gt;toml 配置文件的逐行解释
&lt;/h3&gt;&lt;p&gt;我们上面的配置文件是一个标准的 Python 项目使用 &lt;code&gt;pyproject.toml&lt;/code&gt; 来管理构建系统、依赖、工具配置的典型示例。下面我们来拆解和解释一下。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;✅ &lt;code&gt;[build-system]&lt;/code&gt;：构建系统配置（PEP 517 标准）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[build-system]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;requires = [&amp;#34;hatchling&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;build-backend = &amp;#34;hatchling.build&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;requires&lt;/code&gt;：构建该项目所需的构建工具，这里是 &lt;code&gt;hatchling&lt;/code&gt;，必须先安装。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;build-backend&lt;/code&gt;：指定用哪个构建后端来执行打包任务，这里是 &lt;code&gt;hatchling.build&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;hatchling 有点儿类似 java 中的 Maven 或 Gradle，都是用来执行自动化构建流程的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maven 是把 java 代码编译、构建成 jar 包，方便管理依赖、分发、版本控制&lt;/li&gt;
&lt;li&gt;hatchling 是把 python 代码构建成 Wheel（.whl 文件）或 Source Distribution（.tar.gz 或 .zip 文件），也是为了做依赖管理、分发和版本控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结来说：&lt;strong&gt;Python 的构建是将代码和依赖打包成 .whl 或 .tar.gz，类似于 Java 打包成 .jar。核心目的是简化分发、确保环境一致性、自动化依赖管理。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;✅ &lt;code&gt;[project]&lt;/code&gt;：项目的核心元信息（PEP 621 标准）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[project]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;name = &amp;#34;myproject&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;项目名称，最终发布到 PyPI 时会用这个名字。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;version = &amp;#34;0.1.0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;当前版本号。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;description = &amp;#34;一个基于Python 3.13.3的项目&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;简短的项目说明。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;readme = &amp;#34;README.md&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;指定项目的 README 文件，将作为 PyPI 上项目首页的介绍内容。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;requires-python = &amp;#34;&amp;gt;=3.13&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;要求的 Python 版本最低为 3.13。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;authors = [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; {name = &amp;#34;xiaobox&amp;#34;, email = &amp;#34;xiaobox@gmail.com&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;作者信息，支持多个，用列表表示。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;dependencies = [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;pytest&amp;gt;=7.4.3&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;fastapi&amp;gt;=0.110.0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;uvicorn&amp;gt;=0.27.0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;httpx&amp;gt;=0.27.0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;项目的运行时依赖库，在安装时会自动安装这些包。这里我加入了 pytest、&lt;strong&gt;fastapi&lt;/strong&gt; 的依赖，因为我想把这个项目作为一个 api 服务提供出去。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;classifiers = [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;Programming Language :: Python :: 3.13&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;License :: OSI Approved :: MIT License&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;Operating System :: OS Independent&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;用于 PyPI 分类（帮助搜索和筛选）。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-projectscripts定义可执行命令如-cli"&gt;&lt;a href="#-projectscripts%e5%ae%9a%e4%b9%89%e5%8f%af%e6%89%a7%e8%a1%8c%e5%91%bd%e4%bb%a4%e5%a6%82-cli" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[project.scripts]&lt;/code&gt;：定义可执行命令（如 CLI）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[project.scripts]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;myproject = &amp;#34;src.main:main&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;安装后运行 &lt;code&gt;myproject&lt;/code&gt; 命令会调用 &lt;code&gt;src/main.py&lt;/code&gt; 中的 &lt;code&gt;main()&lt;/code&gt; 函数。（我们需要提前把之前的 main.py 文件要先移动到 /src 目录下）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-projecturls项目的相关链接非必须"&gt;&lt;a href="#-projecturls%e9%a1%b9%e7%9b%ae%e7%9a%84%e7%9b%b8%e5%85%b3%e9%93%be%e6%8e%a5%e9%9d%9e%e5%bf%85%e9%a1%bb" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[project.urls]&lt;/code&gt;：项目的相关链接（非必须）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[project.urls]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&amp;#34;Homepage&amp;#34; = &amp;#34;https://github.com/yourusername/myproject&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&amp;#34;Bug Tracker&amp;#34; = &amp;#34;https://github.com/yourusername/myproject/issues&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;为项目指定一些有用的链接，如主页、问题反馈页等。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-projectoptional-dependencies可选依赖比如开发环境"&gt;&lt;a href="#-projectoptional-dependencies%e5%8f%af%e9%80%89%e4%be%9d%e8%b5%96%e6%af%94%e5%a6%82%e5%bc%80%e5%8f%91%e7%8e%af%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[project.optional-dependencies]&lt;/code&gt;：可选依赖（比如开发环境）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[project.optional-dependencies]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;dev = [
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;black&amp;gt;=23.1.0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;isort&amp;gt;=5.12.0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &amp;#34;mypy&amp;gt;=1.5.1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们为开发环境安装了三个库：black、isort 和 mypy&lt;/p&gt;
&lt;p&gt;介绍一下这三个工具&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;black：是一个 Python 代码格式化工具。自动把你的 Python 代码排版成统一风格，比如：缩进、换行、空格都按标准格式处理，让你的 Python 代码看起来更整齐、统一，无需自己动手排版。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;isort：是一个 Python 导入（import）语句自动排序工具。自动整理文件顶部的 import 语句，比如按字母顺序排列，分组标准库、第三方库、自定义模块，保持导入部分有序且规范。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mypy：是一个 Python 静态类型检查工具。检查你的代码里的类型注解（type hints）是不是正确，比如函数参数和返回值类型对不对，帮你在写代码时发现类型出错的地方，提前避免 bug。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-toolpytestpytest-配置"&gt;&lt;a href="#-toolpytestpytest-%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[tool.pytest]&lt;/code&gt;：Pytest 配置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;testpaths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tests&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;指定测试用例所在路径，&lt;code&gt;pytest&lt;/code&gt; 会从 &lt;code&gt;tests/&lt;/code&gt; 目录开始查找测试文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-toolblack代码格式化工具-black-的配置"&gt;&lt;a href="#-toolblack%e4%bb%a3%e7%a0%81%e6%a0%bc%e5%bc%8f%e5%8c%96%e5%b7%a5%e5%85%b7-black-%e7%9a%84%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[tool.black]&lt;/code&gt;：代码格式化工具 Black 的配置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;py313&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;设置代码的行最大长度为 88（默认值），目标 Python 版本是 3.13。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-toolisortimport-排序工具-isort-的配置"&gt;&lt;a href="#-toolisortimport-%e6%8e%92%e5%ba%8f%e5%b7%a5%e5%85%b7-isort-%e7%9a%84%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[tool.isort]&lt;/code&gt;：import 排序工具 isort 的配置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isort&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;black&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;line_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;black&lt;/code&gt; 的风格对 import 排序。&lt;/li&gt;
&lt;li&gt;设置行长度为 88，与 black 保持一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-toolhatchbuildtargetswheelhatchling-打包配置"&gt;&lt;a href="#-toolhatchbuildtargetswheelhatchling-%e6%89%93%e5%8c%85%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;✅ &lt;code&gt;[tool.hatch.build.targets.wheel]&lt;/code&gt;：Hatchling 打包配置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hatch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;src&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;指定打包时要包含的代码目录为 &lt;code&gt;src&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;用一句话总结下这个 &lt;code&gt;pyproject.toml&lt;/code&gt; 配置文件 ：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“这是一个使用 Hatch 构建工具、遵循 PEP 621 和现代 Python 项目结构规范的项目配置，涵盖了运行依赖、开发依赖、CLI 脚本、格式化工具配置、测试路径和打包目标，非常完整规范。”&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="安装和更新依赖"&gt;&lt;a href="#%e5%ae%89%e8%a3%85%e5%92%8c%e6%9b%b4%e6%96%b0%e4%be%9d%e8%b5%96" class="header-anchor"&gt;&lt;/a&gt;安装和更新依赖
&lt;/h3&gt;&lt;p&gt;上面这个文件编辑完成后，我们就可以 安装项目和开发依赖了：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip install -e &amp;#34;.[dev]&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果后面你更新了 &lt;code&gt;pyproject.toml&lt;/code&gt; 文件可以执行以下命令来 “手动刷新” 一个依赖库：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv sync --extra dev 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;加入 &lt;code&gt;--extra dev&lt;/code&gt; 参数是因为 &lt;code&gt;uv sync&lt;/code&gt; 默认只安装 [project.dependencies] 中列出的正式依赖。&lt;/p&gt;
&lt;p&gt;不会自动安装 [project.optional-dependencies]（比如 dev 里面的 black、isort、mypy）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;uv sync --extra dev&lt;/code&gt; 的意思是：除了正式依赖，还要把 [project.optional-dependencies.dev] 里的东西也同步上&lt;/p&gt;
&lt;h3 id="uvlock"&gt;&lt;a href="#uvlock" class="header-anchor"&gt;&lt;/a&gt;uv.lock
&lt;/h3&gt;&lt;p&gt;当执行完 &lt;code&gt;uv sync --extra dev&lt;/code&gt; ，安装好依赖好， uv 会在项目根路径生成一个 &lt;code&gt;uv.lock&lt;/code&gt; 文件 。uv.lock 是 锁定依赖版本 的文件。&lt;/p&gt;
&lt;p&gt;它的作用是：把 pyproject.toml 里描述的依赖（比如 &amp;ldquo;fastapi&amp;gt;=0.110.0&amp;rdquo; 这样比较宽松的范围），具体锁定成明确、唯一的版本（比如 &amp;ldquo;fastapi==0.110.1&amp;rdquo;）。&lt;/p&gt;
&lt;p&gt;这样，每次安装时，不管谁来安装（你自己、你的同事、你的服务器），大家安装的依赖版本都是一模一样的，不会因为小版本不同导致奇怪的 bug。&lt;/p&gt;
&lt;p&gt;uv.lock 是自动生成、自动管理的。不需手动编辑。&lt;/p&gt;
&lt;h2 id="其他"&gt;&lt;a href="#%e5%85%b6%e4%bb%96" class="header-anchor"&gt;&lt;/a&gt;其他
&lt;/h2&gt;&lt;p&gt;其他的，如 fastapi 相关的、 打 docker 镜像部署什么的相对本文主题超纲了，就不在本文中过多描述了。&lt;/p&gt;
&lt;h2 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h2&gt;&lt;p&gt;本文我们分享了用 uv 初始化和管理 Python 项目的完整流程。&lt;/p&gt;
&lt;p&gt;从安装 uv 开始，我介绍了它为什么比传统工具（pip、pipx、poetry 等）更快更好用，以及 uv 在多 Python 版本管理、依赖锁定、项目初始化方面带来的便利。&lt;/p&gt;
&lt;p&gt;随后，详细讲了如何用 uv 管理本地 Python 环境、新建项目、创建虚拟环境、编辑 pyproject.toml 配置，并逐步解释了各个配置项的作用&lt;/p&gt;
&lt;p&gt;整体来看，uv 提供了一套现代、规范、高效的 Python 项目管理方案，非常适合用来打基础，后续无论是开发 API、打包 Docker 镜像，还是部署上线，都能有条不紊地进行。&lt;/p&gt;
&lt;p&gt;同时我们通过在项目创建的过程中看到各语言（java、nodejs&amp;hellip;）都相通或类似的工程 “最佳实践”，真是应了那句话：“大道至简，真理趋同”&lt;/p&gt;</description></item></channel></rss>