<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RAG on 小盒子的技术分享</title><link>https://xiaobox.github.io/tags/rag/</link><description>Recent content in RAG on 小盒子的技术分享</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 12 Mar 2026 02:51:44 +0000</lastBuildDate><atom:link href="https://xiaobox.github.io/tags/rag/index.xml" rel="self" type="application/rss+xml"/><item><title>Google 刚刚把多模态检索，从“拼装工程”变成了“基础能力”</title><link>https://xiaobox.github.io/p/2026-03-12-google-gang-gang-ba-duo-mo-tai-jian-suo-cong-pin-zhuang-gong/</link><pubDate>Thu, 12 Mar 2026 02:51:44 +0000</pubDate><guid>https://xiaobox.github.io/p/2026-03-12-google-gang-gang-ba-duo-mo-tai-jian-suo-cong-pin-zhuang-gong/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-12-google-gang-gang-ba-duo-mo-tai-jian-suo-cong-pin-zhuang-gong/cover.jpg" alt="Featured image of post Google 刚刚把多模态检索，从“拼装工程”变成了“基础能力”" /&gt;&lt;p&gt;过去几年，多模态检索一直有一种很别扭的感觉：大家都知道它重要，也都知道它有价值，但真要落地，往往就会迅速滑向一场“拼装工程”。文本一套模型，图片一套模型，音频最好先转写，视频最好先抽帧，PDF 还要单独解析。最后系统看起来像是“能搜”，可背后其实是五六条处理链硬拼在一起，复杂、昂贵，而且很难优雅。&lt;/p&gt;
&lt;p&gt;Google 新发布的 &lt;strong&gt;Gemini Embedding 2&lt;/strong&gt;，真正让人眼前一亮的，不是它又把 embedding 做强了一点，而是它第一次把&lt;strong&gt;文本、图片、音频、视频、PDF拉进了同一个统一向量空间里&lt;/strong&gt;。官方把它定义为 Google &lt;strong&gt;首个原生多模态 embedding 模型&lt;/strong&gt;，目前已经通过 &lt;strong&gt;Gemini API&lt;/strong&gt; 和 &lt;strong&gt;Vertex AI&lt;/strong&gt; 进入 Public Preview。&lt;/p&gt;
&lt;p&gt;这件事听上去像模型更新，实际上更像一次架构层的洗牌。因为从这一刻起，多模态检索终于不再只是“大厂能做、小团队很难做优雅”的高级能力，而开始像一项真正的基础设施：可以被调用，可以被组合，也可以被更低成本地接进你的搜索、RAG、知识库和内容系统里。&lt;/p&gt;
&lt;h2 id="它到底强在哪不只是支持多模态"&gt;&lt;a href="#%e5%ae%83%e5%88%b0%e5%ba%95%e5%bc%ba%e5%9c%a8%e5%93%aa%e4%b8%8d%e5%8f%aa%e6%98%af%e6%94%af%e6%8c%81%e5%a4%9a%e6%a8%a1%e6%80%81" class="header-anchor"&gt;&lt;/a&gt;它到底强在哪，不只是“支持多模态”
&lt;/h2&gt;&lt;p&gt;很多人看到这里，第一反应可能是：&lt;/p&gt;
&lt;p&gt;“支持文本、图片、音频、视频、PDF，这不就是多模态吗？”&lt;/p&gt;
&lt;p&gt;还真不止。&lt;/p&gt;
&lt;p&gt;Gemini Embedding 2 的关键不只是“什么都能输进去”，而是所有模态出来以后能落在同一个 embedding space 里。这意味着什么？意味着你不再一定要为每种媒介维护完全独立的语义体系。文本可以搜图片，图片可以召回 PDF，音频可以关联视频片段，跨模态检索终于不是一层额外的“补丁能力”，而成了模型本身的默认能力。&lt;/p&gt;
&lt;p&gt;这会直接改变系统设计思路。&lt;/p&gt;
&lt;p&gt;以前你更像是在设计“五条平行管线”。&lt;/p&gt;
&lt;p&gt;现在你更像是在设计“一个统一召回底座”。&lt;/p&gt;
&lt;p&gt;注意，我这里说的是“更像”，不是说所有复杂度从此消失。长视频仍然要切片，复杂知识库仍然要做 metadata 设计，高要求场景依然常常需要 rerank。&lt;/p&gt;
&lt;h2 id="最值钱的地方是它终于不再要求你先做翻译官"&gt;&lt;a href="#%e6%9c%80%e5%80%bc%e9%92%b1%e7%9a%84%e5%9c%b0%e6%96%b9%e6%98%af%e5%ae%83%e7%bb%88%e4%ba%8e%e4%b8%8d%e5%86%8d%e8%a6%81%e6%b1%82%e4%bd%a0%e5%85%88%e5%81%9a%e7%bf%bb%e8%af%91%e5%ae%98" class="header-anchor"&gt;&lt;/a&gt;最值钱的地方，是它终于不再要求你先做“翻译官”
&lt;/h2&gt;&lt;p&gt;过去处理非文本内容时，行业里一个非常常见的默认动作是“先降级成文本”。&lt;/p&gt;
&lt;p&gt;●音频？先 Whisper。&lt;/p&gt;
&lt;p&gt;●视频？先抽帧，最好再加字幕。&lt;/p&gt;
&lt;p&gt;●PDF？先 OCR，再抽正文。&lt;/p&gt;
&lt;p&gt;这类方案当然能工作，但本质上是在让系统把所有模态都挤进“文本入口”里。Gemini Embedding 2 做的，是把入口重新打开。它可以&lt;strong&gt;原生摄取音频，不需要中间文本转写&lt;/strong&gt;；视频支持约 2 分钟级别的原生输入；PDF 也可以直接嵌入。&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%b8%80%e4%b8%aa%e7%89%b9%e5%88%ab%e5%ae%b9%e6%98%93%e8%a2%ab%e4%bd%8e%e4%bc%b0%e7%9a%84%e8%83%bd%e5%8a%9b%e5%ae%83%e5%8f%af%e4%bb%a5%e8%a1%a8%e7%a4%ba%e5%ae%9e%e4%bd%93%e4%b8%8d%e5%8f%aa%e6%98%af%e7%b4%a0%e6%9d%90" class="header-anchor"&gt;&lt;/a&gt;一个特别容易被低估的能力：它可以表示“实体”，不只是“素材”
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 还有一个很值得说的亮点：&lt;strong&gt;它支持混合输入。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你在一个 content entry 里传入多个 parts，比如“文字 + 图片”，模型会为这组内容生成一个聚合后的 embedding；如果你在 contents 数组里放多个独立条目，它则会返回多个独立向量。官方文档甚至直接建议：对于像社交媒体帖子这种包含多种媒体内容的复杂对象，可以把多个 embedding 聚合，形成一个 &lt;code&gt;post-level representation&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这件事非常关键。&lt;/p&gt;
&lt;p&gt;因为它把 embedding 的对象，从“原子素材”升级成了“业务实体”。&lt;/p&gt;
&lt;p&gt;一块手表，不只是商品图，也不只是商品描述；&lt;/p&gt;
&lt;p&gt;一条社交帖子，不只是文字，也不只是配图；&lt;/p&gt;
&lt;p&gt;一堂课程，不只是讲义 PDF，也不只是视频和录音。&lt;/p&gt;
&lt;p&gt;过去这些东西往往是拆开建索引、拆开召回、最后在上层硬拼。&lt;/p&gt;
&lt;p&gt;现在你可以在索引层就把它们当成一个“对象”来表示。&lt;/p&gt;
&lt;p&gt;这对于做内容平台、商品搜索、企业知识库、课程检索，影响都非常大。因为从这里开始，RAG 的检索单元不再只能是 text chunk，它可以是一个帖子、一个商品、一段课堂内容，甚至一个带图文说明的复杂知识实体。&lt;/p&gt;
&lt;h2 id="3072-维不是重点重点是你终于可以按成本来调语义密度"&gt;&lt;a href="#3072-%e7%bb%b4%e4%b8%8d%e6%98%af%e9%87%8d%e7%82%b9%e9%87%8d%e7%82%b9%e6%98%af%e4%bd%a0%e7%bb%88%e4%ba%8e%e5%8f%af%e4%bb%a5%e6%8c%89%e6%88%90%e6%9c%ac%e6%9d%a5%e8%b0%83%e8%af%ad%e4%b9%89%e5%af%86%e5%ba%a6" class="header-anchor"&gt;&lt;/a&gt;3072 维不是重点，重点是你终于可以按成本来调“语义密度”
&lt;/h2&gt;&lt;p&gt;做系统的人都知道，维度本身并不是越大越好。更大的维度意味着更高的存储成本、更高的计算开销、更长的检索延迟。Gemini Embedding 2 默认输出 3072 维，但支持用 output_dimensionality 调整维度，官方推荐的常见选择是 768、1536、3072，并说明它支持从 128 到 3072 的灵活输出。这个能力背后用的是 MRL（Matryoshka Representation Learning）&lt;/p&gt;
&lt;p&gt;简单说就是：你可以根据场景，在“效果”和“成本”之间做更细粒度的平衡。&lt;/p&gt;
&lt;p&gt;●如果你是大规模通用检索，1536 维可能就已经很香；&lt;/p&gt;
&lt;p&gt;●如果你追求极致成本和吞吐，768 维会很有吸引力；&lt;/p&gt;
&lt;p&gt;●如果你做的是高价值高精度场景，3072 维会更稳。&lt;/p&gt;
&lt;h2 id="免费吗多少钱"&gt;&lt;a href="#%e5%85%8d%e8%b4%b9%e5%90%97%e5%a4%9a%e5%b0%91%e9%92%b1" class="header-anchor"&gt;&lt;/a&gt;免费吗？多少钱？
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 现在有两条主路径，&lt;strong&gt;想快速试、想低门槛上手，用 Gemini Developer API；想走企业治理、云权限、生产环境，走 Vertex AI。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="第一条是-gemini-developer-api"&gt;&lt;a href="#%e7%ac%ac%e4%b8%80%e6%9d%a1%e6%98%af-gemini-developer-api" class="header-anchor"&gt;&lt;/a&gt;第一条是 Gemini Developer API。
&lt;/h3&gt;&lt;p&gt;这一条更轻，适合开发者快速试。官方价格页明确写了：gemini-embedding-2-preview 当前有 Free Tier，文本、图片、音频、视频输入在免费层里都是 Free of charge。免费层数据 Used to improve our products: Yes；如果切到付费层，这一项会变成 No。付费价格方面：&lt;/p&gt;
&lt;p&gt;●标准模式下文本是 $0.20 / 1M tokens&lt;/p&gt;
&lt;p&gt;●图片约 $0.00012 / 张&lt;/p&gt;
&lt;p&gt;●音频约 $0.00016 / 秒&lt;/p&gt;
&lt;p&gt;●视频约 $0.00079 / 帧；&lt;/p&gt;
&lt;p&gt;如果用 Batch API，价格大约是标准价的 50%。&lt;/p&gt;
&lt;h3 id="第二条是-vertex-ai"&gt;&lt;a href="#%e7%ac%ac%e4%ba%8c%e6%9d%a1%e6%98%af-vertex-ai" class="header-anchor"&gt;&lt;/a&gt;第二条是 Vertex AI。
&lt;/h3&gt;&lt;p&gt;这一条更偏企业与云上生产环境。你需要 Google Cloud 项目、启用 billing、开启 Vertex AI API，并配置认证；而且 AI Studio 的 API key 不能直接用于 Vertex AI。模型页还写明：Gemini Embedding 2 当前支持的是 Standard PayGo，不支持 Provisioned Throughput、Flex PayGo、Priority PayGo 和 Batch Prediction，当前页面列出的区域是 us-central1。Vertex AI 价格页对它的专属条目写的是：&lt;/p&gt;
&lt;p&gt;●文本 $0.2 / 1M tokens&lt;/p&gt;
&lt;p&gt;●图片 $0.00012 / image&lt;/p&gt;
&lt;p&gt;●视频 $0.00079 / frame&lt;/p&gt;
&lt;p&gt;●音频 $0.00016 / sec&lt;/p&gt;
&lt;p&gt;●输出不收费。&lt;/p&gt;
&lt;h2 id="两个很容易踩的坑"&gt;&lt;a href="#%e4%b8%a4%e4%b8%aa%e5%be%88%e5%ae%b9%e6%98%93%e8%b8%a9%e7%9a%84%e5%9d%91" class="header-anchor"&gt;&lt;/a&gt;两个很容易踩的坑
&lt;/h2&gt;&lt;p&gt;第一个坑，&lt;strong&gt;是不要把旧向量直接拿来和新模型混用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;gemini-embedding-001 和 gemini-embedding-2-preview 的 embedding spaces 不兼容。也就是说，如果你准备升级到 Gemini Embedding 2，旧数据不能直接拿来比较，你需要重新做一遍 re-embedding。这对已经有存量索引库的团队来说，是非常现实的迁移成本。&lt;/p&gt;
&lt;p&gt;第二个坑，&lt;strong&gt;是不要把“视频支持时长”写得过于绝对。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;目前官方资料里有三种写法：&lt;/p&gt;
&lt;p&gt;●Google 博客写的是支持最多 120 秒视频；&lt;/p&gt;
&lt;p&gt;●Gemini API 文档写的是视频上限 128 秒；&lt;/p&gt;
&lt;p&gt;●Vertex AI 模型页则更细，写成带音频视频上限 80 秒，不带音频视频上限 120 秒。&lt;/p&gt;
&lt;p&gt;所以总结来说它当前具备 2 分钟级别的视频原生 embedding 能力，更长的视频仍建议切片后索引。&lt;/p&gt;
&lt;h2 id="它不会消灭所有复杂度但它确实改写了默认架构"&gt;&lt;a href="#%e5%ae%83%e4%b8%8d%e4%bc%9a%e6%b6%88%e7%81%ad%e6%89%80%e6%9c%89%e5%a4%8d%e6%9d%82%e5%ba%a6%e4%bd%86%e5%ae%83%e7%a1%ae%e5%ae%9e%e6%94%b9%e5%86%99%e4%ba%86%e9%bb%98%e8%ae%a4%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;它不会消灭所有复杂度，但它确实改写了“默认架构”
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2没有神奇到让多模态检索从此没有工程问题。&lt;/p&gt;
&lt;p&gt;它不会自动帮你解决 metadata、chunking、权限隔离、召回融合、在线延迟、索引更新这些老问题。&lt;/p&gt;
&lt;p&gt;但它确实把过去那种“多模态一定要多套模型、多套索引、多阶段拼装”的默认范式，往前推了一大步。&lt;/p&gt;
&lt;p&gt;更重要的是，这一步不是停留在“论文层面”的。Google 已经给出了官方接入路径，也已经列出 LangChain、LlamaIndex、Haystack、Weaviate、Qdrant、ChromaDB 和 Vertex AI Vector Search 等生态集成方式。也就是说，这不是一个“看上去很厉害但暂时用不起来”的能力，它已经开始变成开发者今天就能碰、今天就能试、今天就能接进系统里的东西。&lt;/p&gt;
&lt;p&gt;所以，Gemini Embedding 2 真正改变的，可能不是“embedding 这个模型又进步了多少”，而是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google 终于把多模态检索，从一项需要大量拼装和妥协的工程活，推进成了一种更统一、更自然、更接近基础设施的能力。&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;如果文本、图片、音频、视频、PDF 真的开始共享一个语义空间，接下来最值得重新思考的问题，也许就不再是：&lt;/p&gt;
&lt;p&gt;“我还能接多少模型？”&lt;/p&gt;
&lt;p&gt;而是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在我的系统里，什么才算一个真正值得被检索的对象？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;是一段文字，&lt;/p&gt;
&lt;p&gt;是一页 PDF，&lt;/p&gt;
&lt;p&gt;是一张图，&lt;/p&gt;
&lt;p&gt;是一条帖子，&lt;/p&gt;
&lt;p&gt;还是一个由图文、声音、视频共同组成的“实体”？&lt;/p&gt;
&lt;p&gt;Gemini Embedding 2 给出的，不只是一个新模型。&lt;/p&gt;
&lt;p&gt;它更像是在提醒所有做 AI 应用的人：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;下一代检索系统要统一的，从来不只是接口，而是我们理解世界的入口。&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>3 毛钱干大事？ 用了几天豆包编程模型，我来扒一扒字节这波操作</title><link>https://xiaobox.github.io/p/2025-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo/</link><pubDate>Mon, 17 Nov 2025 12:58:03 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/cover.jpg" alt="Featured image of post 3 毛钱干大事？ 用了几天豆包编程模型，我来扒一扒字节这波操作" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;测评人： 小盒子（AI 架构仔，Agentic 编程方向，常年被 API 账单搞到头大） 测评时间： 2025 年 11 月 11 日发布后的一周&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;这波价格战，字节是真不想给同行活路了&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;说实话，我当时 &lt;strong&gt;凌晨 1:47&lt;/strong&gt; 在公司改那个傻 X 的 Kubernetes 配置。看到新闻推送，火山引擎出了个 &lt;strong&gt;豆包编程模型 Doubao-Seed-Code&lt;/strong&gt;，说性能 SOTA，但这不是重点。&lt;/p&gt;
&lt;p&gt;重点是价格。它宣称 综合成本能比业界平均水平低 62.7%，直接是 &lt;strong&gt;国内最低价&lt;/strong&gt;。我当时正在用 cc 搭配 k2，心想：都说最低价，质量怎么样呢？k2 测完了其实还是不如原装的 claude，所以 doubao-seed-code 如果真是质量高价格低的话，多一个选择也是蛮不错的。&lt;/p&gt;
&lt;p&gt;以前我们跑一次复杂的 Agentic 任务，特别是涉及多轮 Bug 修复和重构的，Claude Sonnet 4.5 那个账单，每个月看一次疼一次。&lt;/p&gt;
&lt;p&gt;我看官方资料里明晃晃地写着，做一个交互式英语学习网站，用 Doubao-Seed-Code 只需要 &lt;strong&gt;0.34 元左右&lt;/strong&gt;，用 Claude Sonnet 4.5 可是要大概 4 块多。 这差距，可以的～&lt;/p&gt;
&lt;p&gt;它这个 API 定价，输入 1.20 元/百万 Tokens，输出 8.00 元/百万 Tokens（0-32K 区间），配合那个 Cache 技术，还能再降 80% 的成本。我们现在正在做 Agent 自动化项目，以前成本受限，很多地方要做工程优化，要这样的话，感觉忽然就 &lt;strong&gt;经济可行&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/2025-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/001-ae46438e.png"&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-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/002-3fa20132.png"&gt;&lt;/p&gt;
&lt;p&gt;我立马摸鱼时试了下，冲了它那个 &lt;strong&gt;9.9&lt;/strong&gt; 块首月 的 Coding Plan。一杯咖啡钱，买一个号称 SWE-Bench Verified 榜单上 SOTA 的模型（这个榜单是测 Agent 端到端解决问题的能力，很硬核的）。&lt;/p&gt;
&lt;h1 id="兼容-claude-code"&gt;&lt;a href="#%e5%85%bc%e5%ae%b9-claude-code" class="header-anchor"&gt;&lt;/a&gt;兼容 Claude Code
&lt;/h1&gt;&lt;p&gt;感觉最近这都成了编程模型的标配了哈。&lt;/p&gt;
&lt;p&gt;作为 Claude Code 用户，感觉接入不是很丝滑的。Doubao-Seed-Code &lt;strong&gt;原生兼容 Anthropic API&lt;/strong&gt; ，接入方法还是老套路，很简单：&lt;/p&gt;
&lt;h2 id="第一种方式"&gt;&lt;a href="#%e7%ac%ac%e4%b8%80%e7%a7%8d%e6%96%b9%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;第一种方式
&lt;/h2&gt;&lt;p&gt;如果是短期测试，可以直接在终端中配置环境变量，在启动 Claude Code 前输入环境变量&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="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;ark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;beijing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volces&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compatible&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="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ARK&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;&amp;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="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;ANTHROPIC_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;doubao&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;preview&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="第二种方式"&gt;&lt;a href="#%e7%ac%ac%e4%ba%8c%e7%a7%8d%e6%96%b9%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;第二种方式
&lt;/h2&gt;&lt;p&gt;如果是长期使用，可以直接配置文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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;open&lt;/span&gt; &lt;span class="err"&gt;-e&lt;/span&gt; &lt;span class="err"&gt;~/.claude/settings.json&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="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 class="nt"&gt;&amp;#34;api_key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xxxxxxx&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;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;api_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://ark.cn-beijing.volces.com/api/compatible&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="nt"&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doubao-seed-code-preview-latest&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="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;说句提外话，最近这几家搞 code 模型的，就是明着抢 Claude 的客户，但我支持，哈哈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;切换零成本 + 价格低 60%+ 性能 SOTA 确实有点儿心动。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="核心能力体验"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e8%83%bd%e5%8a%9b%e4%bd%93%e9%aa%8c" class="header-anchor"&gt;&lt;/a&gt;核心能力体验
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;长上下文和那个 VLM 才是真杀手锏&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;光便宜和兼容没用，代码写得烂，那也是浪费我时间。&lt;/p&gt;
&lt;p&gt;看了一下上下文，256K，还成，跟 K2 一样，感觉现在没个 256K 都不好拿出手。&lt;/p&gt;
&lt;p&gt;虽然 Claude 4.5 Sonnet 的上下文声称是 1M，但实际上只有 200K，而且还死贵。 256 好，还多 56K，哈哈&lt;/p&gt;
&lt;p&gt;别小看多出来的这点儿。我手头有个遗留项目，Python 写的，几百个文件，那叫一个乱。模型处理 Bug，有时候上下文 Token 一爆，它就变瞎子了，你得手动 RAG 喂它代码，有时候就差那么一两个文件，逼得我重开个 thread，前面都白费劲了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Doubao-Seed-Code 多出来的这 56K，意味着它能把 整个中等规模的项目结构和依赖 都装进 “脑子” 里&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/2025-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/003-9eee4524.png"&gt;&lt;/p&gt;
&lt;p&gt;刚才我让它解决一个跨越十几个文件的逻辑 Bug，以前的模型得来回拉扯五六轮，这次它 &lt;strong&gt;一步到位&lt;/strong&gt; 定位到了问题。而且它不只是修复 Bug，它还会 &lt;strong&gt;优化结构&lt;/strong&gt;，提升代码的可读性和维护性。这才是 Agent 编程，不过客观地讲跟最贵的那位比还是有一定的差距。&lt;/p&gt;
&lt;h1 id="vlm前端仔的末日-还是福音"&gt;&lt;a href="#vlm%e5%89%8d%e7%ab%af%e4%bb%94%e7%9a%84%e6%9c%ab%e6%97%a5-%e8%bf%98%e6%98%af%e7%a6%8f%e9%9f%b3" class="header-anchor"&gt;&lt;/a&gt;VLM：前端仔的末日… 还是福音？
&lt;/h1&gt;&lt;p&gt;这个视觉理解（VLM）能力， &lt;strong&gt;国内首发&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这个功能并不新鲜，但国内首发，算是跟上了。我现在可以直接把 UI 稿截图，或者 手绘草稿 扔给它。然后它能给你生成对应的代码。&lt;/p&gt;
&lt;p&gt;我一开始以为它就是搞了个图转文字，再让 LLM 去生成代码，这种方法信息折损很大。结果 它这个是&lt;strong&gt;原生的 VLM 能力&lt;/strong&gt;，不是靠工具调用。最牛逼的是，它能 &lt;strong&gt;自己完成样式修复和 Bug 修复&lt;/strong&gt;。它生成一个页面，然后拿截图跟你原始的设计稿对比，发现哪里边距不对，哪里颜色溢出了，自己动手改&lt;/p&gt;
&lt;p&gt;我当时试了一个复杂的 Dashboard 界面，只给了一张截图，它生成的 React + Tailwind 代码还原度还是非常高的。前端兄弟估计已经麻木了，据我所知，他们自己也在用 vibe coding 干活，哈哈。&lt;/p&gt;
&lt;h1 id="聊聊技术底裤"&gt;&lt;a href="#%e8%81%8a%e8%81%8a%e6%8a%80%e6%9c%af%e5%ba%95%e8%a3%a4" class="header-anchor"&gt;&lt;/a&gt;聊聊技术底裤
&lt;/h1&gt;&lt;p&gt;Doubao-Seed-Code 的核心是 &lt;strong&gt;Seed-Coder&lt;/strong&gt; 家族，能 SOTA，说明字节在训练上砸了&lt;strong&gt;不少黑科技&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;官方资料里提了一堆很唬人的词儿, 小盒子来翻译翻译：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;“大规模 Agent 强化学习训练系统”&lt;/strong&gt; ：他们好像是搞了一套巨大的 &lt;strong&gt;打怪升级系统&lt;/strong&gt;，专门用来训练代码 Agent。模型不是靠背书（预训练数据）学编程的，它是直接在 &lt;strong&gt;沙盒里&lt;/strong&gt; 跑代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;构建了覆盖 10 万容器镜像的训练数据集”&lt;/strong&gt;：为了让模型见过各种稀奇古怪的运行环境（比如 Python 3.7 + PyTorch 1.9 + CUDA 10.2），他们准备了 10 万个容器&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;“万级并发沙盒 session”&lt;/strong&gt;：几万个容器同时跑。让模型在里面不断试错，错了就 &lt;strong&gt;罚站（接收执行反馈）&lt;/strong&gt;。这样练出来的 Agent，解决问题的鲁棒性才强&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这套机制直接解释了为什么它能在 SWE-Bench Verified 这种需要端到端解决问题的测试里登顶。它不是一个静态的知识库，它是个会 &lt;strong&gt;思考、会动手、会自我修正&lt;/strong&gt; 的开发伙伴&lt;/p&gt;
&lt;p&gt;顺便提一句，这个 Seed-Coder 还有开源版本。开源的 Seed-Coder-8B-Reasoning 有 64K 上下文，虽然不如商业 API 的 256K 那么猛，但对于个人研究也够用了。&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-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/004-1050e617.png"&gt;&lt;/p&gt;
&lt;h1 id="测试"&gt;&lt;a href="#%e6%b5%8b%e8%af%95" class="header-anchor"&gt;&lt;/a&gt;测试
&lt;/h1&gt;&lt;p&gt;这里我做了一个测试，目的是看它能不能真的理解 “Vibe Coding”（用户描述一个抽象的、高层的需求，让 Agent 去实现），特别是设计稿的还原和自我纠错能力&lt;/p&gt;
&lt;p&gt;找一个 UI 稿截图，越复杂越好。&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-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/005-cfa337f6.png"&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-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/006-b0aed37a.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-11-17-3-mao-qian-gan-da-shi-yong-le-ji-tian-dou-bao-bian-cheng-mo-/007-9d9ec23b.png"&gt;&lt;/p&gt;
&lt;h1 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h1&gt;&lt;p&gt;无论最后你是否使用 doubao-seed-code 模型作为你的生产工具，我都推荐你试试，包括 k2 等其他模型，无它，AI 进化的速度很快，先上车！&lt;/p&gt;
&lt;p&gt;单纯就 doubao-seed-code 来说，我觉得也还可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;价格摆在那儿，跑 100 次 Agentic 任务的成本，以前可能只能跑 30 次。&lt;/li&gt;
&lt;li&gt;VLM 是未来：前端开发效率的飞跃。&lt;/li&gt;
&lt;li&gt;256K 上下文：真正能处理企业级复杂重构任务的基础。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Doubao-Seed-Code 这波操作，是想把 AI 编程从 “昂贵的工具” 变成 “水、电、煤” 一样基础设施 。对于追求极致效率和成本控制的团队，值得一试。&lt;/p&gt;</description></item><item><title>怎样才算好文档</title><link>https://xiaobox.github.io/p/2025-10-26-yang-cai-suan-hao-wen-dang/</link><pubDate>Sun, 26 Oct 2025 03:08:25 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-10-26-yang-cai-suan-hao-wen-dang/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-26-yang-cai-suan-hao-wen-dang/cover.jpg" alt="Featured image of post 怎样才算好文档" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;优秀文档的核心原则 —— 来自 OpenAI 团队 Cookbook&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h1 id="写文档是一种同理心的体现"&gt;&lt;a href="#%e5%86%99%e6%96%87%e6%a1%a3%e6%98%af%e4%b8%80%e7%a7%8d%e5%90%8c%e7%90%86%e5%bf%83%e7%9a%84%e4%bd%93%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;写文档是一种同理心的体现
&lt;/h1&gt;&lt;p&gt;文档的核心目标是将有用信息高效注入读者的头脑中，避免读者在信息海洋中迷失。优秀文档不是长篇大论，而是通过结构化、清晰和共情的设计，帮助读者快速解决问题。&lt;/p&gt;
&lt;h1 id="让文档易于浏览"&gt;&lt;a href="#%e8%ae%a9%e6%96%87%e6%a1%a3%e6%98%93%e4%ba%8e%e6%b5%8f%e8%a7%88" class="header-anchor"&gt;&lt;/a&gt;让文档易于浏览
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;读者很少从头到尾线性阅读文档，他们更倾向于跳跃式浏览，寻找直接解决问题的部分。因此，文档应像一张高效的 “信息地图”，降低搜索成本，提高成功率。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;●&lt;strong&gt;使用描述性标题&lt;/strong&gt;：标题应是信息完整的句子，而非抽象名词。例如，用 “流式处理将首 token 响应时间缩短 50%” 代替 “结果”，让读者无需深入阅读即可获知要点。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;添加目录&lt;/strong&gt;：目录如哈希表般加速定位，同时提供文档整体线索，帮助读者判断是否值得阅读。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;保持段落简短&lt;/strong&gt;：短段落易于扫描；关键点可独立成一句单句段落，避免被长文淹没。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;以独立主题句开头&lt;/strong&gt;：段落和节的首句应自成一体，不依赖前文。例如，“向量数据库可加速嵌入搜索” 优于 “基于此，让我们讨论更快的方法”，便于跳读者快速理解。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;主题词置于句首&lt;/strong&gt;：如 “向量数据库加速嵌入搜索” 比 “嵌入搜索可由向量数据库加速” 更高效，因为读者只需读前两词即可把握主题。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;要点前置&lt;/strong&gt;：将最重要的信息置于文档或节的顶部，避免司马式渐进式展开，先结果后过程。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;多用 bullet 列表和表格&lt;/strong&gt;：这些格式天然支持扫描，提高可读性。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;加粗关键文本&lt;/strong&gt;：大胆突出重要内容，帮助读者快速锁定。&lt;/p&gt;
&lt;p&gt;这些技巧的核心是“&lt;strong&gt;读者优先”：设计时假设读者时间有限、注意力分散。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="2-写出高质量文本"&gt;&lt;a href="#2-%e5%86%99%e5%87%ba%e9%ab%98%e8%b4%a8%e9%87%8f%e6%96%87%e6%9c%ac" class="header-anchor"&gt;&lt;/a&gt;2. 写出高质量文本
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;糟糕的文风会消耗读者的认知资源，导致疲劳。优秀文档应追求简洁、流畅，减少解析负担。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;●&lt;strong&gt;句子简洁&lt;/strong&gt;：拆分长句、去除副词和冗余词，使用祈使语气（如写作书籍建议）。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;确保无歧义解析&lt;/strong&gt;：避免词性模糊的句子。例如，“用句子标题节”（Title sections with sentences）易混淆词性；改为 “将节标题写成句子”（Write section titles as sentences）更易解析，即使稍长。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;避免左分支句子&lt;/strong&gt;：这类句子要求读者短期记忆过多，如 “你需要面粉、鸡蛋、牛奶、黄油和少许盐来做煎饼”。改为右分支：“做煎饼需要面粉、鸡蛋、牛奶、黄油和少许盐”，更符合大脑处理习惯（类似于深度优先搜索）。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;少用指示代词&lt;/strong&gt;：如 “this” 跨句使用易造成回溯负担。改为具体名词：“基于消息格式，让我们讨论函数调用” 优于 “基于此讨论”。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;保持一致性&lt;/strong&gt;：统一标题大小写、标点（如尾随逗号）和命名规范（如 Cookbook 中的下划线 + 句首小写），避免读者分心。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;不假设读者心态&lt;/strong&gt;：避免 “你现在可能想了解函数调用” 这类推测；改为 “To call a function, &amp;hellip;”，保持中立。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;写作原则源于认知科学：减少大脑负载，让内容自然流动。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="3-广泛有益于读者"&gt;&lt;a href="#3-%e5%b9%bf%e6%b3%9b%e6%9c%89%e7%9b%8a%e4%ba%8e%e8%af%bb%e8%80%85" class="header-anchor"&gt;&lt;/a&gt;3. 广泛有益于读者
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;文档用户背景多样（从新手到专家、多语言使用者），优秀文档应包容性强，覆盖潜在痛点，而非仅针对 “理想读者”。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;●&lt;strong&gt;用简单语言&lt;/strong&gt;：比预期更简化解释（但不低估）。考虑非母语者和术语生疏者，优先清晰而非炫技。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;避免缩写&lt;/strong&gt;：全写出，如 “instruction following” 而非 “IF”；“retrieval-augmented generation”（或 “搜索 - 询问流程”）而非 “RAG”。专家成本低，新手收益高。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;预解常见问题&lt;/strong&gt;：即使 95% 读者知晓 Python 包安装，也值得说明 —— 专家可略过，新手避免卡壳。记住，跨语言专家（如 JavaScript 开发者）可能 Python 是新手。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;选用具体准确术语&lt;/strong&gt;：避开行话，如用 “input” 代替 “prompt”，“max token limit” 代替 “context limit”，更自明且贴合实际。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;代码示例通用自洽&lt;/strong&gt;：最小化依赖，避免额外库或跨页引用，确保可直接复制运行。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;优先高价值主题&lt;/strong&gt;：聚焦常见问题（如 token 计数），而非罕见场景（如表情符号数据库优化）。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;避免不良习惯&lt;/strong&gt;：如 API 密钥勿硬编码示例。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;以广义开场引入主题&lt;/strong&gt;：如解释推荐系统时，先提及 YouTube、Amazon 等应用场景，增强读者安全感。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这些建议体现共情：文档是为 “所有人” 服务的工具，过多假设会疏离部分用户。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="4-必要时打破规则"&gt;&lt;a href="#4-%e5%bf%85%e8%a6%81%e6%97%b6%e6%89%93%e7%a0%b4%e8%a7%84%e5%88%99" class="header-anchor"&gt;&lt;/a&gt;4. 必要时打破规则
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;这些是指导而非铁律。文档写作是移情练习：代入读者视角，选择最有帮助的方式。最终，灵活应用才能适应具体情境。&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>给 AI 一双 “慧眼”：深度评测 7 款主流 AI 搜索引擎（Tavily, SerpApi, Exa.ai 等）</title><link>https://xiaobox.github.io/p/2025-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/</link><pubDate>Sat, 25 Oct 2025 03:35:29 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/cover.jpg" alt="Featured image of post 给 AI 一双 “慧眼”：深度评测 7 款主流 AI 搜索引擎（Tavily, SerpApi, Exa.ai 等）" /&gt;&lt;h1 id="给-ai-用的搜索引擎"&gt;&lt;a href="#%e7%bb%99-ai-%e7%94%a8%e7%9a%84%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e" class="header-anchor"&gt;&lt;/a&gt;给 AI 用的搜索引擎
&lt;/h1&gt;&lt;p&gt;“给 AI 用的搜索引擎” 是一个专门为软件程序（尤其是人工智能模型）设计的接口，让它们能够以编程方式请求、接收和理解来自网络的信息。&lt;/p&gt;
&lt;h2 id="为什么-ai-需要这样的搜索引擎"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88-ai-%e9%9c%80%e8%a6%81%e8%bf%99%e6%a0%b7%e7%9a%84%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e" class="header-anchor"&gt;&lt;/a&gt;为什么 AI 需要这样的搜索引擎？
&lt;/h2&gt;&lt;p&gt;大型语言模型（如 GPT、Gemini 等）本身非常强大，但它们存在一些固有局限。搜索引擎是克服这些局限性的关键工具。&lt;/p&gt;
&lt;p&gt;1.&lt;strong&gt;克服 “知识截止日期”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;问题&lt;/strong&gt;：AI 模型的知识不是实时的。它的知识被 “冻结” 在它训练数据截止的那个时间点。例如，一个在 2023 年训练的模型不知道 2024 年发生的新闻。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;解决方案&lt;/strong&gt;：当被问及一个新事件时，AI 可以使用搜索引擎 API 查询最新的新闻和信息，然后根据这些实时信息来生成答案。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;例子&lt;/strong&gt;：你问 AI：“昨天的股市收盘价是多少？” AI 无法直接回答，但它可以调用一个金融搜索引擎 API，获取数据后再告诉你。&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;提高事实准确性，减少 “幻觉”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;问题&lt;/strong&gt;：AI 有时会 “一本正经地胡说八道”，即编造一些看似合理但实际上是错误的信息，这被称为 “幻觉” (Hallucination)。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;解决方案&lt;/strong&gt;：在回答需要精确事实的问题时，AI 可以先通过搜索引擎进行事实核查。它将搜索到的可靠来源（如维基百科、官方新闻稿）作为其回答的基础，而不是凭空捏造。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;例子&lt;/strong&gt;：你问 AI：“X 公司的 CEO 是谁？” AI 不会直接猜测，而是会先搜索 “X company CEO”，找到官方信息后再给出准确答案。&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;提供信息来源和可信度&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;○通过搜索引擎，AI 不仅能给出答案，还能提供它获取信息的来源链接。这大大增强了答案的可信度，也允许用户自行验证。证许多现代的 AI 问答产品（如 Perplexity AI, Google&amp;rsquo;s Gemini）都会在回答下方附上参考链接。&lt;/p&gt;
&lt;p&gt;4.&lt;strong&gt;执行需要实时数据的复杂任务&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;问题&lt;/strong&gt;：许多现实世界的任务依赖于动态变化的信息。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;解决方案&lt;/strong&gt;：AI 代理 (AI Agent) 可以利用搜索引擎来完成任务。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;例子&lt;/strong&gt;：一个 “旅行规划 AI” 需要查询实时的航班价格、酒店空房情况、目的地天气预报等。它会通过调用多个不同的搜索服务 API 来收集所有这些信息，然后为你制定一个完整的旅行计划。&lt;/p&gt;
&lt;p&gt;“给 AI 用的搜索引擎” 本质上是将互联网从一个为人类视觉设计的、非结构化的信息海洋，转变成一个为机器准备的、结构化的、可查询的知识库。它赋予了 AI 模型一双能 “看到” 并 “理解” 当前世界的眼睛，使其能够突破自身训练数据的限制，变得更加准确、实时、可信和强大。&lt;/p&gt;
&lt;h2 id="流程示意"&gt;&lt;a href="#%e6%b5%81%e7%a8%8b%e7%a4%ba%e6%84%8f" class="header-anchor"&gt;&lt;/a&gt;流程示意
&lt;/h2&gt;&lt;p&gt;以下为一个 AI 应用 Action 的示意图：&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-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/001-1b6f98b8.png"&gt;&lt;/p&gt;
&lt;h1 id="供应商"&gt;&lt;a href="#%e4%be%9b%e5%ba%94%e5%95%86" class="header-anchor"&gt;&lt;/a&gt;供应商
&lt;/h1&gt;&lt;p&gt;提供 web search 能力的供应商有很多，我们选择了几家知名和流行的厂商作为选型参考：&lt;/p&gt;
&lt;p&gt;●Tavily :https://www.tavily.com/&lt;/p&gt;
&lt;p&gt;●SerpApi:https://serpapi.com/&lt;/p&gt;
&lt;p&gt;●Serper API:https://serper.dev/&lt;/p&gt;
&lt;p&gt;●Exa.ai:https://exa.ai/&lt;/p&gt;
&lt;p&gt;●Ollama Web Search:https://docs.ollama.com/capabilities/web-search&lt;/p&gt;
&lt;p&gt;●Jina.ai DeepSearch:https://jina.ai/deepsearch/&lt;/p&gt;
&lt;p&gt;●Brave Search:https://brave.com/search/api/&lt;/p&gt;
&lt;h2 id="tavily"&gt;&lt;a href="#tavily" class="header-anchor"&gt;&lt;/a&gt;Tavily
&lt;/h2&gt;&lt;p&gt;Tavily 是一个面向 LLM 与 AI 智能体的 “Web 接入层”—— 提供实时网络搜索与内容提取的 API，常用于 RAG（检索增强生成）和各类智能体工作流，目标是把 “上网检索→抓取→清洗→结构化” 的繁琐流程封装成简单、可控的接口。&lt;/p&gt;
&lt;h3 id="核心-api"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;●Search：发送查询；可调搜索深度、时间范围、域名白/黑名单等，返回已清理的相关片段与链接，并可选生成简短回答/返回图片结果。&lt;/p&gt;
&lt;p&gt;●Extract：按给定 URL 抽取网页全文（可选 Markdown 或纯文本，也可返回图片），便于直接供模型使用。&lt;/p&gt;
&lt;p&gt;●Crawl：图式并行爬取整站（带内置抽取与智能发现），适合做站点级信息收集。&lt;/p&gt;
&lt;p&gt;●Map（Beta）：生成站点地图/URL 列表，可设置深度、广度及路径/域名过滤。&lt;/p&gt;
&lt;h3 id="适用场景与优势"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;●给 RAG、聊天助手、数据富集等提供&lt;strong&gt;实时、可追溯&lt;/strong&gt;的外部信息；返回结果强调&lt;strong&gt;带来源引用&lt;/strong&gt;与&lt;strong&gt;面向 LLM 的片段&lt;/strong&gt;，以降低幻觉并提升可审计性&lt;/p&gt;
&lt;p&gt;●官方定位是 “&lt;strong&gt;为智能体提供上网能力的基础层&lt;/strong&gt;”，强调速度、稳定性与与开发者 / 智能体工作流的适配。&lt;/p&gt;
&lt;h3 id="生态与集成"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;提供官方 &lt;strong&gt;Python/JavaScript SDK&lt;/strong&gt; 与在线 Playground；并与 &lt;strong&gt;LangChain、LlamaIndex&lt;/strong&gt; 等框架集成，便于直接接入现有 Agent / RAG 管道。&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Tavily Search API - 超简洁版
&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="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; 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;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; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;tavily&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TavilyClient&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="n"&gt;load_dotenv&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&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;# 创建客户端&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TavilyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;TAVILY_API_KEY&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;# 搜索&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&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&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="c1"&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&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;h3 id="价格与配额"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d" 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-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/002-b3b618ef.png"&gt;&lt;/p&gt;
&lt;h2 id="serpapi"&gt;&lt;a href="#serpapi" class="header-anchor"&gt;&lt;/a&gt;SerpApi
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;SerpApi 是一个付费的第三方 API 服务，它能让你实时地抓取并解析来自 Google、Bing、Baidu 等多个主流搜索引擎的搜索结果页面（SERP），并以结构化的 JSON 格式返回给你。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你可以把它理解成一个 “超级加强版” 的、非官方的搜索引擎 API。它解决的核心问题是：&lt;strong&gt;官方的 Google API 返回的结果有限且不完整，而自己去抓取（Scrape）Google 又极其困难&lt;/strong&gt;。 SerpApi 就是填补这个鸿沟的商业解决方案。&lt;/p&gt;
&lt;p&gt;可以看到它的 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-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/003-816f7b88.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SerpApi&lt;/strong&gt; 和 &lt;strong&gt;Tavily AI&lt;/strong&gt; 都是服务于 AI 应用的搜索 API，但它们在&lt;strong&gt;哲学、目标和返回内容&lt;/strong&gt;上有着根本性的不同。用一个简单的比喻来开始：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;SerpApi&lt;/strong&gt; 像是给了你的 AI &lt;strong&gt;一整箱乐高积木的原始零件&lt;/strong&gt;。它提供了关于搜索结果页面的所有原始、详细、未经处理的数据。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Tavily AI&lt;/strong&gt; 像是给了你的 AI &lt;strong&gt;一个根据说明书预先拼好了大半的乐高模型&lt;/strong&gt;。它为你完成了搜索、筛选、阅读和总结的步骤，直接提供给 AI 一个接近最终答案的、简洁的信息包。&lt;/p&gt;
&lt;h3 id="核心-api-1"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api-1" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;SerpApi 的核心是一个简单而强大的 REST API，其本质是 “&lt;strong&gt;搜索结果页面即服务” (SERP as a Service)&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;工作机制&lt;/strong&gt;: 你通过一个标准的 GET 请求，向 SerpApi 的端点（Endpoint）发送查询，它会返回一个结构化的 JSON 对象，该对象完整地描述了真实搜索引擎的结果页面。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;关键参数&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○api_key: (必需) 用于账户认证的密钥。&lt;/p&gt;
&lt;p&gt;○engine: (必需) 指定要查询的搜索引擎。这是其强大功能的体现，例如 google, Maps, google_jobs, bing, baidu, duckduckgo, youtube, amazon 等。&lt;/p&gt;
&lt;p&gt;○q: (必需) 你要搜索的关键词。&lt;/p&gt;
&lt;p&gt;○location: (可选, 但非常重要) 模拟搜索的地理位置。你可以传递一个具体的城市名、国家，甚至精确的地理坐标，来获取高度本地化的结果。例如，你可以轻松模拟一出来自东京涩谷的搜索请求。&lt;/p&gt;
&lt;p&gt;○gl &amp;amp; hl: 分别指定搜索的国家（geolocation）和语言（host language），例如 gl=jp 和 hl=ja 来获取日本的日语结果。&lt;/p&gt;
&lt;p&gt;○start, num: 用于翻页，控制搜索结果的偏移量和数量。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心产出&lt;/strong&gt;: API 的输出是其最核心的价值 —— &lt;strong&gt;一个经过深度解析的、结构化的 JSON&lt;/strong&gt;。这个 JSON 不仅包含自然搜索结果（蓝链），还精确地解析了页面上几乎所有的动态元素，包括：&lt;/p&gt;
&lt;p&gt;○广告 (Ads)&lt;/p&gt;
&lt;p&gt;○知识图谱 (Knowledge Graph)&lt;/p&gt;
&lt;p&gt;○本地包 / 地图包 (Local Pack)&lt;/p&gt;
&lt;p&gt;○相关问题 (People Also Ask)&lt;/p&gt;
&lt;p&gt;○购物结果 (Shopping Results)&lt;/p&gt;
&lt;p&gt;○图片和视频轮播 (Carousels)&lt;/p&gt;
&lt;h3 id="适用场景与优势-1"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf-1" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;SerpApi 的价值在于它为需要高质量、真实搜索引擎数据的用户解决了最棘手的技术难题。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;适用场景&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;SEO / SEM 行业&lt;/strong&gt;: 监控关键词排名、跟踪竞争对手的广告投放策略、分析 SERP 页面特性。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;市场研究与商业智能&lt;/strong&gt;: 聚合来自 Google Shopping 或 Amazon 的商品价格、分析特定行业的市场趋势、监控品牌在网络上的提及。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;AI 与大语言模型 (LLM)&lt;/strong&gt;: 作为 AI Agent 的 “眼睛”，为其提供高质量、实时的外部世界信息源，用于需要完整页面上下文的 RAG（检索增强生成）系统或事实核查。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;本地化服务&lt;/strong&gt;: 验证本地商家的地图排名、聚合特定区域的服务信息。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心优势&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;数据的完整性与真实性&lt;/strong&gt;: 最大的优势。它提供的是真实用户所见的完整页面镜像，而非官方 API 提供的阉割版数据。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;规避所有抓取障碍&lt;/strong&gt;: 用户无需担心 IP 封锁、代理管理、浏览器指纹以及最令人头疼的 CAPTCHA（人机验证）。SerpApi 在后端完全处理了这些问题。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;强大的本地化和定制能力&lt;/strong&gt;: location 参数功能强大，可以实现全球任意地点的精准模拟搜索。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;广泛的平台支持&lt;/strong&gt;: 一个 API 接口即可访问全球几十个主流的搜索引擎和电商平台。&lt;/p&gt;
&lt;h3 id="生态与集成-1"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90-1" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;SerpApi 非常注重开发者体验，已经建立了一个成熟的生态系统，使其能够轻松地集成到现有工作流中。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;官方编程语言库&lt;/strong&gt;: 提供了对主流语言的官方支持，包括 Python, Node.js, Ruby, Java, PHP, Go, C# 等。这使得开发者可以在几分钟内就开始调用 API，而无需手动构建 HTTP 请求。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;与 AI 框架的深度集成&lt;/strong&gt;: 在当前的 AI 浪潮中，SerpApi 已成为标准工具之一。它被深度集成到 &lt;strong&gt;LangChain&lt;/strong&gt; 和 &lt;strong&gt;LlamaIndex&lt;/strong&gt; 等主流 AI 开发框架中，通常作为一个开箱即用的 Tool 或 Wrapper 存在，方便 AI Agent 直接调用。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;无代码 / 低代码平台集成&lt;/strong&gt;: 支持 Zapier, Make (原 Integromat) 等自动化平台，让非程序员也能利用其强大的数据抓取能力来构建自动化流程。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;完善的文档与工具&lt;/strong&gt;: 提供了交互式的 API 文档（Playground），用户可以在网页上直接测试各种参数组合，并实时查看返回的 JSON 结果，极大地降低了学习和调试成本。&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;SerpApi Search API - 超简洁版
&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="s2"&gt;Google 搜索引擎爬取 API
&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="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; 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;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; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;serpapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GoogleSearch&lt;/span&gt; &lt;span class="c1"&gt;# type: ignore[import-untyped]&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;load_dotenv&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;# 创建搜索参数&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;params&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;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&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;api_key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SERPAPI_API_KEY&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;num&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&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;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;# 执行搜索&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;search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoogleSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&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="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_dict&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&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;# 打印结果&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔍 搜索结果: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\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;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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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&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;# 显示有机搜索结果&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="n"&gt;organic_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&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;organic_results&amp;#34;&lt;/span&gt;&lt;span class="p"&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;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;organic_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;【&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;】 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;无标题&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;🔗 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;33&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;📝 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;snippet&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;无描述&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;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="nb"&gt;print&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&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;✅ 共找到 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;organic_results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="价格与配额-1"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d-1" 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-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/004-0f944cb6.png"&gt;&lt;/p&gt;
&lt;h2 id="serper"&gt;&lt;a href="#serper" class="header-anchor"&gt;&lt;/a&gt;Serper
&lt;/h2&gt;&lt;p&gt;Serper.dev 在搜索引擎 API 市场中扮演了一个非常独特的、具有破坏性的角色。你可以将 Serper.dev 理解为一个&lt;strong&gt;主打极致速度和极具竞争力的低廉价格&lt;/strong&gt;的挑战者。它专注于做好一件事 —— 提供 Google 搜索结果 —— &lt;strong&gt;并力求比任何竞争对手都更快、更便宜&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Serper.dev 的存在就是为了解决 SerpApi 等传统服务存在的两个痛点：&lt;strong&gt;响应慢和价格贵&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;1.&lt;strong&gt;速度 (Speed)&lt;/strong&gt;: Serper.dev 的首要卖点是其极低的延迟。它通过自建的、高度优化的反向代理和缓存系统，能够在极短时间内返回 Google 的搜索结果。对于需要实时交互的应用（例如，与用户对话的 AI 聊天机器人），这种低延迟是至关重要的。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;成本效益 (Cost-Effectiveness)&lt;/strong&gt;: 这是它最大的颠覆之处。Serper.dev 的定价策略非常激进，其单位搜索成本远低于 SerpApi。它提供了一个极其慷慨的免费套餐，并且付费套餐的价格也很有吸引力，这使得它对个人开发者、初创公司和需要大规模搜索但预算有限的项目极具诱惑力。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;实测下来，Serper确实是最快的。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="核心-api-2"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api-2" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;API 类型&lt;/strong&gt;: 同样是简单易用的 REST API。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;端点&lt;/strong&gt;: 主要提供 /search 端点用于网页搜索，以及 /images 等用于图片搜索的特定端点。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;关键参数&lt;/strong&gt;: 与 SerpApi 非常相似，包括 q (查询), gl (国家), hl (语言), location (地理位置) 等，使其易于上手和迁移。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心产出&lt;/strong&gt;: 返回与 SerpApi 类似、结构清晰的 JSON 对象，其中包含了 Google SERP 的主要元素，如自然结果、广告、知识图谱、相关问题等。&lt;/p&gt;
&lt;h3 id="适用场景与优势-2"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf-2" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;适用场景&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;实时 AI 对话应用&lt;/strong&gt;: 当 AI 需要在对话中快速查找信息时，Serper 的低延迟可以避免让用户感到明显的等待。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;大规模数据采集&lt;/strong&gt;: 当项目需要百万级别的搜索量时，Serper 的低成本优势会变得极为显著。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;初创公司和独立开发者&lt;/strong&gt;: 慷慨的免费套餐和低廉的付费门槛，使其成为验证想法（MVP）和开发早期产品的理想选择。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;任何以 Google 搜索为主要信息源且对成本和速度敏感的应用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心优势&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;快&lt;/strong&gt;: 无与伦比的响应速度。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;省钱&lt;/strong&gt;: 极低的单位搜索成本和慷慨的免费额度。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;简单&lt;/strong&gt;: API 设计直观，专注于核心功能，没有过多复杂选项。&lt;/p&gt;
&lt;h3 id="生态与集成-2"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90-2" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;与 AI 框架的集成&lt;/strong&gt;: Serper.dev 同样是 &lt;strong&gt;LangChain&lt;/strong&gt; 和 &lt;strong&gt;LlamaIndex&lt;/strong&gt; 生态系统中的一等公民。它作为一个标准的 Tool 或 Wrapper 被广泛支持，许多教程和项目都因其性价比而推荐使用它。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;编程语言支持&lt;/strong&gt;: 虽然可能没有像 SerpApi 那样提供十几种语言的官方库，但由于其 API 简单，通过任何支持 HTTP 请求的语言（如 Python, Node.js）进行集成都非常容易。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;社区认知度&lt;/strong&gt;: 在 AI 开发者社区中，Serper.dev 因其出色的性价比而广为人知，并经常被推荐为 SerpApi 的首选替代品。&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Serper.dev Search API - 超简洁版
&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="s2"&gt;更快更便宜的 Google 搜索 API
&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="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; 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;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; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt; &lt;span class="c1"&gt;# type: ignore[import-untyped]&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;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;load_dotenv&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;# API 配置&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;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SERPER_API_KEY&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;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://google.serper.dev/search&amp;#34;&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="c1"&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&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;API_URL&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;headers&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;X-API-KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json&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="n"&gt;json&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;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;num&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&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&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&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;# 打印结果&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔍 搜索结果: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\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;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="s2"&gt;&amp;#34;=&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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&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;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&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;organic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]),&lt;/span&gt; &lt;span class="mi"&gt;1&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;【&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;】 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;无标题&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;🔗 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;33&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;📝 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;snippet&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;无描述&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;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="nb"&gt;print&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&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;✅ 共找到 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&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="s1"&gt;&amp;#39;organic&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]))&lt;/span&gt;&lt;span class="si"&gt;}&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="价格与配额-2"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d-2" class="header-anchor"&gt;&lt;/a&gt;价格与配额
&lt;/h3&gt;&lt;p&gt;这是 Serper.dev 最闪亮的标签。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;免费套餐&lt;/strong&gt;: 提供每月 2,500 次的免费搜索，足以满足大多数个人项目和小型应用的开发与测试需求。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;付费模式&lt;/strong&gt;: 订阅制。其付费套餐的性价比极高，例如，每月支付少量费用（例如 10 美元）就可以获得数万次的搜索量，这个数量在 SerpApi 上可能需要花费高出数倍甚至一个数量级的费用。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;定价哲学&lt;/strong&gt;: 薄利多销。通过低价吸引大量用户，尤其是在 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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/005-13824e3a.png"&gt;&lt;/p&gt;
&lt;h3 id="exaai"&gt;&lt;a href="#exaai" class="header-anchor"&gt;&lt;/a&gt;Exa.ai
&lt;/h3&gt;&lt;p&gt;如果我们说 SerpApi / Serper 是对传统关键词搜索引擎的 “API 化”，Tavily 是为 AI “优化答案”，那么 &lt;strong&gt;Exa.ai (其前身为 Metaphor) 则是一种完全不同类型的搜索引擎&lt;/strong&gt;。它不是一个传统的 “关键词搜索引擎” 的 API 封装，而是一个&lt;strong&gt;为 AI 和大型语言模型 (LLM) 从头构建的 “神经搜索引擎” 或 “概念搜索引擎”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心理念：搜索 “概念”，而非 “关键词”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Exa.ai 最根本的不同在于它的&lt;strong&gt;搜索方式&lt;/strong&gt;。它不依赖于你输入精确的关键词，而是让你用&lt;strong&gt;自然语言描述你想要找的 “那种” 内容&lt;/strong&gt;。Exa 的底层是一个大型的 Transformer 模型，它被训练来理解网页内容之间的关系和 “意义”，而不是仅仅索引它们的文字。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;举个例子来理解这种差异&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;传统关键词搜索 (SerpApi/Serper/Tavily)&lt;/strong&gt;: 你想找一些关于日本小众旅行地的深度文章，你可能会输入关键词：&amp;ldquo;日本 深度游 博客&amp;rdquo; 或 &amp;ldquo;Japan hidden gems travel blog&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;○返回的结果会是那些&lt;strong&gt;包含了这些关键词&lt;/strong&gt;的页面，质量良莠不齐。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Exa.ai 概念搜索&lt;/strong&gt;: 你可以直接告诉它你的&lt;strong&gt;意图&lt;/strong&gt;: &amp;ldquo;请给我找一些关于日本旅行的、写得像诗一样优美的个人博客，内容要侧重于当地文化体验，而不是热门旅游景点。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;○Exa 会理解 “诗一样优美”、“侧重文化体验”、“非热门景点” 这些&lt;strong&gt;抽象概念&lt;/strong&gt;，然后返回那些在&lt;strong&gt;内容和风格上&lt;/strong&gt;与你的描述相匹配的链接，即使这些页面中根本没有出现你用到的描述词。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exa.ai 不是用来替代 Google 搜索的，而是为需要进行深度研究、发现和内容探索的 AI 系统提供了一种全新的、更强大的工具&lt;/strong&gt;。如果说 SerpApi / Serper 是给了 AI 一张 “地图”，Tavily 是给了 AI 一个 “向导”，那么 &lt;strong&gt;Exa.ai 则是给了 AI 一个拥有直觉和品味的 “图书管理员” 或 “研究伙伴”&lt;/strong&gt;。它开启了让 AI 从 “信息检索者” 向 “知识发现者” 转变的可能性。&lt;/p&gt;
&lt;h3 id="核心-api-3"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api-3" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;Exa 的 API 设计完全体现了其 “概念驱动” 的哲学，主要有三个强大的端点：&lt;/p&gt;
&lt;p&gt;1./search: 核心的搜索功能。接收一个自然语言描述作为查询，返回一个按相关性排序的链接列表。&lt;/p&gt;
&lt;p&gt;2./findSimilar: 极具特色的功能。你给它一个 URL，它会返回一串内容和风格上都与这个 URL “&lt;strong&gt;相似&lt;/strong&gt;” 或 “&lt;strong&gt;同类&lt;/strong&gt;” 的其他链接。这对于构建推荐引擎或进行深度研究非常强大。&lt;/p&gt;
&lt;p&gt;3./contents: 检索和内容提取功能。你给它一个或多个搜索结果的 ID，它能直接返回这些页面的&lt;strong&gt;干净、去除了广告和无关元素的文本内容&lt;/strong&gt;，可以直接作为上下文喂给 LLM。这相当于集成了搜索和内容抓取两步。&lt;/p&gt;
&lt;h3 id="适用场景与优势-3"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf-3" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;适用场景&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;高级 AI 研究代理 (Agent)&lt;/strong&gt;: 构建能够进行深度、开放式研究的 AI 代理，而不仅仅是查找孤立的事实。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;内容发现与推荐&lt;/strong&gt;: 帮助用户发现他们可能喜欢但难以用关键词描述的新博客、文章或资源。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;高质量 RAG&lt;/strong&gt;: 为 RAG 系统寻找特定领域、特定风格或特定深度的高质量信息源，以提升生成内容的质量。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;个人知识管理&lt;/strong&gt;: 根据一篇你喜欢的文章，发现更多类似的高质量内容来拓展你的知识边界。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心优势&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;超越关键词的理解力&lt;/strong&gt;: 能够理解抽象的意图和概念，找到 “隐藏的宝藏”。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;发现高质量内容&lt;/strong&gt;: 其模型倾向于发现更高质量、更独特的内容，而不是被 SEO 优化的普通页面。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;独特的 “相似性” 搜索&lt;/strong&gt;: /findSimilar 功能是独一无二的，开辟了新的应用可能性。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;端到端的内容获取&lt;/strong&gt;: /contents API 将搜索和内容提取无缝衔接，极大简化了 RAG 流程。&lt;/p&gt;
&lt;h3 id="生态与集成-3"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90-3" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;Exa.ai 在 AI 开发者社区中，尤其是在那些探索 Agentic AI 和高级 RAG 的前沿开发者中，声名鹊起。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;AI 框架&lt;/strong&gt;: 它是 &lt;strong&gt;LangChain&lt;/strong&gt; 和 &lt;strong&gt;LlamaIndex&lt;/strong&gt; 的官方集成工具，被认为是构建复杂研究型 Agent 的首选工具之一。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;社区定位&lt;/strong&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Exa.ai Search API - 超简洁版
&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="s2"&gt;专为 AI 设计的语义搜索引擎
&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="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; 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;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; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;exa_py&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Exa&lt;/span&gt; &lt;span class="c1"&gt;# type: ignore&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;load_dotenv&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;# 创建客户端&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Exa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;EXA_API_KEY&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&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;# 搜索&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search_and_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&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;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;# 打印结果&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔍 搜索结果: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\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="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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;【&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;】 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&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;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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;🔗 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&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;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&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;snippet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&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&lt;/span&gt;&lt;span class="s2"&gt;&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;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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;📝 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;snippet&lt;/span&gt;&lt;span class="si"&gt;}&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;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="nb"&gt;print&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&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;✅ 共找到 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="价格与配额-3"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d-3" class="header-anchor"&gt;&lt;/a&gt;价格与配额
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;定价模型&lt;/strong&gt;: 采用基于用量的定价模式。通常会有一个免费的开发者额度，用于测试和小型项目。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;计费方式&lt;/strong&gt;: 它的计费可能比其他服务稍复杂，因为它有不同的 API 端点。通常，一次 /search 或 /findSimilar 调用会消耗一定数量的 “API 单元”，而一次 /contents 调用（因为它涉及实际的网页抓取和解析）会消耗更多的 “API 单元”。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;成本考量&lt;/strong&gt;: 相对于 Serper 这样的低成本关键词搜索，Exa 的单次查询成本更高。它的价值不在于便宜，而在于它能做到其他搜索引擎做不到的事情。&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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/006-f5c4ac08.png"&gt;&lt;/p&gt;
&lt;h2 id="ollama-web-search"&gt;&lt;a href="#ollama-web-search" class="header-anchor"&gt;&lt;/a&gt;Ollama Web Search
&lt;/h2&gt;&lt;p&gt;Ollama 公司官方直接提供了一个云端 Web 搜索 API 服务。个人用户完全免费&lt;/p&gt;
&lt;h3 id="核心-api-4"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api-4" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;服务类型&lt;/strong&gt;: 一个由 Ollama 公司直接运营和维护的&lt;strong&gt;托管式 (Managed) REST API。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心功能&lt;/strong&gt;: 接收用户的自然语言查询，访问互联网，并返回相关的搜索结果。Ollama 在后端处理了所有的复杂性，包括选择搜索引擎、处理反爬虫、解析结果等。对用户来说，它是一个单一、可靠的入口。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;简易性&lt;/strong&gt;: API 的设计极致简约，如您的代码所示，只有一个端点、一种认证方式和一个核心参数，几乎没有学习成本。&lt;/p&gt;
&lt;h3 id="适用场景与优势-4"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf-4" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;适用场景&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;快速原型开发&lt;/strong&gt;: 开发者可以立刻为他们的应用添加联网搜索功能，而无需注册和配置多个服务。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;Ollama 生态内的应用&lt;/strong&gt;: 与在本地运行的 Ollama 模型无缝集成，是官方推荐的、最简单的联网方式。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;任何需要简单、免费搜索功能的项目&lt;/strong&gt;: 由于其易用性和免费特性，它适用于各种轻量级的 AI 聊天、RAG 应用或自动化脚本。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心优势&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;极致简化 (Extreme Simplicity): 这是其最大的优势&lt;/strong&gt;。开发者不再需要 “Ollama + 第三方搜索 API” 的组合，只需要一个 Ollama 账户和 API 密钥，即可搞定一切。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;免费或极低成本&lt;/strong&gt;: 根据您的信息，免费提供这一点使其在成本上无与伦比。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;无缝的生态集成&lt;/strong&gt;: 作为官方服务，它能保证与 Ollama 的其他产品（无论是本地运行的开源工具还是未来可能推出的云端服务）达到最完美的兼容性。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;单一供应商&lt;/strong&gt;: 无需管理多个供应商的账户、API 密钥和账单，降低了管理复杂性。&lt;/p&gt;
&lt;h3 id="生态与集成-4"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90-4" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;核心定位&lt;/strong&gt;: 它是 &lt;strong&gt;Ollama 自身生态系统&lt;/strong&gt;的官方、原生搜索解决方案。它的主要目标是服务于使用 Ollama 运行模型的广大开发者。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;通用性&lt;/strong&gt;: 尽管它与 Ollama 生态紧密相连，但从您的代码可以看出，它是一个标准的 REST API，可以被&lt;strong&gt;任何应用程序、任何编程语言&lt;/strong&gt;独立调用，完全不依赖于本地的 Ollama 运行环境。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;未来潜力&lt;/strong&gt;: 这种模式为 Ollama 未来的发展铺平了道路，例如推出官方托管的 LLM 推理服务，并与此搜索服务打包，提供一站式的 “模型 + 搜索” 解决方案。&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Ollama Web Search - 超简洁版
&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="s2"&gt;文档: https://docs.ollama.com/capabilities/web-search
&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="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; 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;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; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&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;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;load_dotenv&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;# API 配置&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;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OLLAMA_API_KEY&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://ollama.com/api/web_search&amp;#34;&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="c1"&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&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;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&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;Authorization&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;json&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;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&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&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="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 class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&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;h3 id="价格与配额-4"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d-4" class="header-anchor"&gt;&lt;/a&gt;价格与配额
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;当前模式&lt;/strong&gt;: 根据您的信息和代码示例，该服务目前是&lt;strong&gt;免费提供&lt;/strong&gt;的。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;可能的未来&lt;/strong&gt;: 行业内常见的模式是提供一个非常慷慨的&lt;strong&gt;免费层级（Free Tier）&lt;/strong&gt;，足以满足绝大多数个人开发者和小型项目的需求。对于超出免费额度的大规模商业应用，未来可能会推出付费的&lt;strong&gt;专业版套餐（Pro Tier）&lt;/strong&gt;，提供更高的请求速率限制、更大的请求量和更强的技术支持。&lt;/p&gt;
&lt;h2 id="jina-ai--deepsearch"&gt;&lt;a href="#jina-ai--deepsearch" class="header-anchor"&gt;&lt;/a&gt;Jina AI DeepSearch
&lt;/h2&gt;&lt;p&gt;Jina AI 是一家专注于神经搜索（Neural Search）和多模态 AI 的公司，他们的 DeepSearch 服务是其核心产品之一。DeepSearch 与我们之前讨论的 SerpApi、Serper、Tavily，甚至 Exa.ai 都有所不同，它更侧重于&lt;strong&gt;语义理解和基于向量嵌入（Embeddings）的内容搜索&lt;/strong&gt;，而不是简单地抓取关键词或提供预设的答案摘要。&lt;/p&gt;
&lt;p&gt;可以将 DeepSearch 理解为一个&lt;strong&gt;允许你构建和查询自己的语义搜索引擎的平台&lt;/strong&gt;。它不仅仅是帮你 “搜索 Google”，更是帮你 “理解和搜索你自己的数据，以及整个网络上与你概念相关的数据”。&lt;/p&gt;
&lt;p&gt;Jina AI 的 DeepSearch 代表了搜索引擎的&lt;strong&gt;未来方向之一&lt;/strong&gt;：从基于字符串匹配的 “关键词搜索” 转向基于&lt;strong&gt;语义理解和概念匹配的 “神经搜索”&lt;/strong&gt;。它对于需要构建能够真正 “理解” 用户意图并发现深层相关内容的 AI 应用来说，是一个强大而高级的工具。如果你的项目需要超越传统搜索的语义能力，尤其是在处理非结构化数据、进行深度内容发现和构建智能 RAG 系统时，DeepSearch 是一个非常值得考虑的选择。&lt;/p&gt;
&lt;h3 id="核心-api-5"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api-5" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;Jina AI DeepSearch 的核心是一个强大的神经搜索 API，其能力基于向量嵌入和语义匹配。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心理念&lt;/strong&gt;: 它不依赖于关键词匹配，而是通过将文本、图像、视频等各种模态的数据转化为&lt;strong&gt;高维向量（Embeddings）&lt;/strong&gt;。当用户发起查询时，查询本身也被转化为向量，然后在大规模的向量数据库中进行&lt;strong&gt;语义相似性匹配&lt;/strong&gt;，找到概念上最相关的内容。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;主要功能&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;语义搜索&lt;/strong&gt;: 用户可以用自然语言描述其意图或提供一个内容片段（文本、URL），DeepSearch 会返回语义上最相关的内容，即使这些内容不包含任何关键词。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;多模态搜索&lt;/strong&gt;: 能够处理和搜索不同类型的数据，理论上包括文本、图片、音频、视频等（尽管其网页搜索功能主要集中在文本和图片上）。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;自定义数据集索引&lt;/strong&gt;: 用户可以将自己的数据（例如公司的文档库、产品目录、内部知识库）上传并索引到 DeepSearch 中，构建一个完全语义化的内部搜索引擎。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;网页抓取与索引&lt;/strong&gt;: DeepSearch 提供了抓取网页并将其内容向量化的能力。这意味着你可以用它来构建一个基于语义的、针对特定网站或整个网络的索引。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;上下文增强&lt;/strong&gt;: 返回的不仅仅是链接，通常还会包含抓取到的、与查询相关的页面文本片段，非常适合作为 LLM 的上下文。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;产出&lt;/strong&gt;: API 会返回一个包含相关结果的列表，每个结果通常包括：原始 URL、页面标题、抓取到的相关文本片段，以及一个表示语义相关性的得分。&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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/007-dcb8988c.png"&gt;&lt;/p&gt;
&lt;h3 id="适用场景与优势-5"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf-5" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;DeepSearch 的优势在于其深度语义理解能力，使其在传统关键词搜索力不从心的地方大放异彩。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;适用场景&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;高级 RAG 系统&lt;/strong&gt;: 为 LLM 提供高度相关的、语义化的上下文。当 LLM 需要的不是 “包含这些关键词的页面”，而是 “概念上与此主题最接近的深度分析” 时，DeepSearch 就能发挥作用。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;内部知识库搜索&lt;/strong&gt;: 企业可以利用它构建一个能够理解员工自然语言提问、并提供最相关内部文档的搜索引擎。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;内容推荐与发现&lt;/strong&gt;: 基于用户阅读过的内容（URL 或文本），通过语义相似性发现更多高质量、风格或主题相似的内容。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;创新型搜索引擎&lt;/strong&gt;: 构建更智能、更具洞察力的搜索引擎，例如根据产品描述找到最相似的产品，或根据图片找到相关描述的文本。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;开放域问答&lt;/strong&gt;: 提供超越关键词匹配的、更智能的答案来源。&lt;/p&gt;
&lt;p&gt;●核心优势:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;语义理解&lt;/strong&gt;: 最核心的优势。它理解查询和内容背后的 “意义”，而非表面的词语。这避免了 “关键词陷阱” 和同义词问题。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;高质量的相关性&lt;/strong&gt;: 能够发现传统搜索难以找到的、但在概念上高度相关的内容。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;多模态潜力&lt;/strong&gt;: 为未来处理更复杂的多模态信息奠定基础。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;高度可定制&lt;/strong&gt;: 允许用户索引自己的数据，构建定制化的神经搜索体验。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;解决 “搜索长尾” 问题&lt;/strong&gt;: 对于非常具体、小众、难以用关键词描述的查询，其语义匹配能力更强。&lt;/p&gt;
&lt;h3 id="生态与集成-5"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90-5" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;Jina AI 在开源社区和 AI 框架中都有很强的存在感，DeepSearch 也受益于此。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Jina 生态系统&lt;/strong&gt;: Jina AI 提供了包括 Jina Core (构建神经搜索应用的框架)、DocArray (用于处理多模态数据的库) 等一系列工具。DeepSearch 是这个生态中的一个商业化服务。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;与 LLM 框架集成&lt;/strong&gt;: 作为先进的搜索解决方案，DeepSearch 也被集成到 &lt;strong&gt;LangChain&lt;/strong&gt; 和 &lt;strong&gt;LlamaIndex&lt;/strong&gt; 等主流的 AI 框架中，作为 Retriever（检索器）或 Tool（工具）使用。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;开发者工具&lt;/strong&gt;: Jina AI 提供了易于使用的客户端库和详细的文档，方便开发者快速集成其 API。&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Jina AI DeepSearch API - 超简洁版
&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="s2"&gt;AI 驱动的深度搜索引擎
&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="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; 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;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; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt; &lt;span class="c1"&gt;# type: ignore[import-untyped]&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;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;load_dotenv&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;# API 配置&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;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;JINA_API_KEY&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;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://s.jina.ai/&amp;#34;&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="c1"&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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;headers&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;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&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;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json&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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_URL&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&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;# 打印结果&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔍 搜索结果: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\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;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="s2"&gt;&amp;#34;=&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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&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="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&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;data&amp;#34;&lt;/span&gt;&lt;span class="p"&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;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&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 class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;【&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;】 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;无标题&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;33&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;🔗 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;34&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="n"&gt;result&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;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;content&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;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;description&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="n"&gt;snippet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&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&lt;/span&gt;&lt;span class="s2"&gt;&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;37&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;📝 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;snippet&lt;/span&gt;&lt;span class="si"&gt;}&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;38&lt;/span&gt;&lt;span class="cl"&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;&lt;/span&gt;&lt;span class="se"&gt;\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="s2"&gt;&amp;#34;=&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;40&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;✅ 共找到 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="价格与配额-5"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d-5" class="header-anchor"&gt;&lt;/a&gt;价格与配额
&lt;/h3&gt;&lt;p&gt;相较于关键词抓取服务（如 Serper），或者纯粹的答案摘要服务（如 Tavily），由于其底层的向量嵌入和语义匹配计算成本较高，DeepSearch 的单次查询或数据处理成本可能相对更高。但其提供的是更高的价值和更深层次的语义理解。&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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/008-34f71a81.png"&gt;&lt;/p&gt;
&lt;h2 id="brave-search"&gt;&lt;a href="#brave-search" class="header-anchor"&gt;&lt;/a&gt;Brave Search
&lt;/h2&gt;&lt;p&gt;Brave Search 代表了搜索引擎领域中一股独特而强大的力量：&lt;strong&gt;真正的独立性&lt;/strong&gt;。与我们之前讨论的许多依赖于 Google 或 Bing 数据的服务不同，Brave 从头构建了&lt;strong&gt;自己独立的网络索引&lt;/strong&gt;，这使其在市场上独树一帜。&lt;/p&gt;
&lt;p&gt;Brave Search 的诞生源于对 Google 和 Bing 在搜索领域双头垄断的担忧。其核心使命是提供一个不依赖于大型科技公司、注重隐私、并能提供无偏见结果的替代品。它的 API 让你能够以编程方式访问这个独特的、独立的索引。&lt;/p&gt;
&lt;h3 id="核心-api-6"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83-api-6" class="header-anchor"&gt;&lt;/a&gt;核心 API
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://api-dashboard.search.brave.com/app/documentation/web-search/get-started" target="_blank" rel="noopener"
 &gt;https://api-dashboard.search.brave.com/app/documentation/web-search/get-started&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;独立索引 (Independent Index): 这是它最核心、最与众不同的特点&lt;/strong&gt;。当你调用 Brave Search API 时，你查询的是 Brave 自己爬虫和算法构建的数据库，而不是 Google 或 Bing 的 “二手数据”。这意味着你能得到一套可能完全不同的、未经主流引擎过滤的结果。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Goggles 功能&lt;/strong&gt;: 这是一个非常独特的创新功能，也通过 API 提供。Goggles 允许用户创建或使用自定义的 “规则集” 来重新排序搜索结果。例如，你可以应用一个 “反科技巨头” 的 Goggle，它会自动降低大型科技公司网站的排名；或者应用一个 “学术优先” 的 Goggle，来优先显示学术论文和研究。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;多类型搜索&lt;/strong&gt;: API 支持多种搜索类型，包括网页搜索 (web)、新闻搜索 (news)、视频搜索 (videos) 等。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;简洁的 API 设计&lt;/strong&gt;: API 的端点和参数设计得非常直观，包括 q (查询), country, search_lang 等标准参数，易于开发者上手。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心产出&lt;/strong&gt;: 返回一个干净的、结构化的 JSON 对象，其中包含了各种类型的搜索结果，以及丰富的元数据。&lt;/p&gt;
&lt;h3 id="适用场景与优势-6"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af%e4%b8%8e%e4%bc%98%e5%8a%bf-6" class="header-anchor"&gt;&lt;/a&gt;适用场景与优势
&lt;/h3&gt;&lt;p&gt;选择 Brave Search API 通常是基于对其核心理念的认同，以及对其独特优势的需求。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;适用场景&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;注重隐私的应用&lt;/strong&gt;: 对于不想将用户数据和查询历史发送给 Google 或 Bing 的应用来说，Brave 是理想选择。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;需要 “第二意见” 的工具&lt;/strong&gt;: 在研究、分析或事实核查应用中，可以同时调用 Brave API 和其他主流 API，为用户提供一个对比视角，打破 “信息茧房”。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;构建新型 AI Agent&lt;/strong&gt;: 为 AI 代理提供一个非主流、可能更少偏见的信源，以获得更多样化的观点和信息。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;新闻聚合与分析&lt;/strong&gt;: 利用其独立的新闻索引来发现可能被主流引擎忽略的报道。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;核心优势&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;真正的独立性&lt;/strong&gt;: 结果不受 Google 或 Bing 排名算法的影响，提供了真正的多样性。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;隐私保护&lt;/strong&gt;: 继承了 Brave 浏览器对用户隐私的承诺，API 调用不会被用于用户画像分析。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;无偏见的结果&lt;/strong&gt;: Brave 声称其排名算法旨在提供最相关、最公正的结果，减少商业化和 SEO 的过度影响。&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;创新的 Goggles 功能&lt;/strong&gt;: 提供了前所未有的结果定制能力，让开发者可以根据特定需求对结果进行重新排序。&lt;/p&gt;
&lt;h3 id="生态与集成-6"&gt;&lt;a href="#%e7%94%9f%e6%80%81%e4%b8%8e%e9%9b%86%e6%88%90-6" class="header-anchor"&gt;&lt;/a&gt;生态与集成
&lt;/h3&gt;&lt;p&gt;作为一个现代化的 API 服务，Brave Search 非常注重开发者生态。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;AI 框架集成&lt;/strong&gt;: 它被迅速地集成到了 &lt;strong&gt;LangChain&lt;/strong&gt; 和 &lt;strong&gt;LlamaIndex&lt;/strong&gt; 等主流 AI 开发框架中。开发者可以非常轻松地将其作为一个 Tool 或 Retriever 添加到自己的 AI 应用中，这极大地推动了它在 AI 社区的普及。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;易于使用&lt;/strong&gt;: 作为一个标准的 REST API，它可以被任何编程语言轻松调用。官方文档清晰，API 控制台 (api-dashboard) 直观易用。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;社区支持&lt;/strong&gt;: 围绕 Brave 的隐私和独立理念，已经形成了一个强大的开发者和用户社区。&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-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="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; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Brave Search API - 超简洁版
&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="s2"&gt;独立索引的隐私优先搜索引擎 API
&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="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; 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;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; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt; &lt;span class="c1"&gt;# type: ignore[import-untyped]&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;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&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;load_dotenv&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;# API 配置&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;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;BRAVE_API_KEY&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;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://api.search.brave.com/res/v1/web/search&amp;#34;&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;API_KEY&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="s2"&gt;&amp;#34;❌ 错误：请设置 BRAVE_API_KEY 环境变量&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;提示：在 .env 文件中添加：BRAVE_API_KEY=your_key_here&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="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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="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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&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;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;headers&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;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json&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="s2"&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;gzip&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 class="s2"&gt;&amp;#34;X-Subscription-Token&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&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 class="n"&gt;params&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;q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&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&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;try&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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="n"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&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;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raise_for_status&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&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="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;❌ 请求错误: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&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;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ifhasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;响应: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&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;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔍 搜索结果: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\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;42&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;43&lt;/span&gt;&lt;span class="cl"&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;web_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&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;web&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&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;results&amp;#34;&lt;/span&gt;&lt;span class="p"&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;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;web_results&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 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&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;API 响应: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="si"&gt;}&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;48&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;49&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;web_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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;50&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;【&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;】 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;无标题&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;51&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;🔗 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="s1"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;52&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="n"&gt;result&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;description&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;53&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;description&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;54&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 移除 HTML 标签&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="n"&gt;clean_desc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;strong&amp;gt;&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;/strong&amp;gt;&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;56&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;snippet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clean_desc&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&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&lt;/span&gt;&lt;span class="s2"&gt;&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;57&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;📝 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;snippet&lt;/span&gt;&lt;span class="si"&gt;}&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;58&lt;/span&gt;&lt;span class="cl"&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="nb"&gt;print&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&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;60&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;✅ 共找到 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;web_results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="价格与配额-6"&gt;&lt;a href="#%e4%bb%b7%e6%a0%bc%e4%b8%8e%e9%85%8d%e9%a2%9d-6" class="header-anchor"&gt;&lt;/a&gt;价格与配额
&lt;/h3&gt;&lt;p&gt;Brave Search API 的定价模型旨在吸引从个人开发者到大型企业的各类用户，具有很强的竞争力。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;免费套餐 (Free Plan)&lt;/strong&gt;: 提供一个非常慷慨的免费层级，通常&lt;strong&gt;每月提供多达 2,000 次的免费查询&lt;/strong&gt;。这足以满足绝大多数个人项目、开发测试和小型应用的需求。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;付费套餐 (Paid Plans)&lt;/strong&gt;: 对于需要更高查询量的用户，提供了多个付费订阅套餐。&lt;/p&gt;
&lt;p&gt;○付费套餐的起步价非常亲民（例如，每月几美元即可获得数万次查询）。&lt;/p&gt;
&lt;p&gt;○其单位查询成本在整个行业中都非常有竞争力，使其成为 SerpApi 等高端服务的低成本、高质量替代品。&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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/009-76380a46.png"&gt;&lt;/p&gt;
&lt;h2 id="其他厂家"&gt;&lt;a href="#%e5%85%b6%e4%bb%96%e5%8e%82%e5%ae%b6" class="header-anchor"&gt;&lt;/a&gt;其他厂家
&lt;/h2&gt;&lt;p&gt;还有一些其它的厂商也提供类似服务，比如国内的：&lt;/p&gt;
&lt;p&gt;●https://open.bochaai.com/&lt;/p&gt;
&lt;p&gt;●https://aisearch.anspire.cn/&lt;/p&gt;
&lt;h1 id="选型建议"&gt;&lt;a href="#%e9%80%89%e5%9e%8b%e5%bb%ba%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;选型建议
&lt;/h1&gt;&lt;p&gt;我们快速回顾一下各个供应商的核心定位：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Tavily&lt;/strong&gt;: 专为 AI Agent 和 RAG 设计的 “答案层” API，强调对搜索结果的清洗、总结和整合，直接输出对 LLM 友好的内容&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;SerpApi&lt;/strong&gt;: 功能最全面的 “数据层” API，精确抓取并解析 Google、Bing、Baidu 等几十个平台的完整 SERP（搜索结果页面），数据极其丰富&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Serper&lt;/strong&gt;: SerpApi 的挑战者，主打&lt;strong&gt;极致的速度和极低的价格&lt;/strong&gt;，专注于提供 Google 搜索结果&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Exa.ai&lt;/strong&gt;: “概念搜索引擎”，使用自然语言描述进行搜索，能理解抽象意图，擅长内容发现和深度研究，而非简单的关键词匹配&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Ollama Web Search&lt;/strong&gt;: Ollama 官方提供的免费云端 API 服务，极致简化，与 Ollama 生态无缝集成&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Jina.ai DeepSearch&lt;/strong&gt;: 强大的 “神经搜索引擎”，基于向量嵌入进行语义搜索，支持自定义数据索引和多模&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;Brave Search&lt;/strong&gt;: 建立在&lt;strong&gt;独立网络索引&lt;/strong&gt;之上的搜索引擎，主打隐私保护和不受主流引擎影响的 “第二意见” 结果&lt;/p&gt;
&lt;h2 id="综合对比与分析"&gt;&lt;a href="#%e7%bb%bc%e5%90%88%e5%af%b9%e6%af%94%e4%b8%8e%e5%88%86%e6%9e%90" class="header-anchor"&gt;&lt;/a&gt;综合对比与分析
&lt;/h2&gt;&lt;p&gt;我们将从响应速度、成本、功能、易用性和适用场景五个维度进行详细对比。&lt;/p&gt;
&lt;h3 id="响应速度"&gt;&lt;a href="#%e5%93%8d%e5%ba%94%e9%80%9f%e5%ba%a6" class="header-anchor"&gt;&lt;/a&gt;响应速度
&lt;/h3&gt;&lt;p&gt;经过本地实测，响应速度上 Brave Search 和 SerpApi 是伯仲之间&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;🏆 响应速度排名（从快到慢）
&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;🥇 1. SerpApi 627ms
&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;🥈 2. Brave Search 662ms
&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;🥉 3. Tavily 976ms
&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; 4. Serper.dev 1.35s
&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; 5. Exa.ai 2.29s
&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; 6. Jina AI 4.66s
&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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="成本"&gt;&lt;a href="#%e6%88%90%e6%9c%ac" class="header-anchor"&gt;&lt;/a&gt;成本
&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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/010-46c987b4.png"&gt;&lt;/p&gt;
&lt;p&gt;成本排序（&lt;strong&gt;从低到高&lt;/strong&gt;）：&lt;/p&gt;
&lt;p&gt;Ollama &amp;gt; Serper &amp;gt; Brave &amp;gt; Tavily &amp;gt; Exa.ai &amp;gt; Jina.ai &amp;gt; SerpApi&lt;/p&gt;
&lt;h3 id="功能"&gt;&lt;a href="#%e5%8a%9f%e8%83%bd" 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-10-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/011-807a9603.png"&gt;&lt;/p&gt;
&lt;h3 id="易用性"&gt;&lt;a href="#%e6%98%93%e7%94%a8%e6%80%a7" class="header-anchor"&gt;&lt;/a&gt;易用性
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;最简单&lt;/strong&gt;: &lt;strong&gt;Ollama Web Search&lt;/strong&gt;。官方原生，一个 API Key 解决所有问题，无需任何第三方配置 。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;非常简单&lt;/strong&gt;: &lt;strong&gt;Serper, Brave, Tavily&lt;/strong&gt;。都是标准的 REST API，API 设计直观简洁，且都深度集成了 LangChain 等 AI&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;中等&lt;/strong&gt;: &lt;strong&gt;SerpApi&lt;/strong&gt;。功能非常多，参数复杂，但因为有完善的文档、工具和多语言库，集成也相对顺畅&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;较复杂 / 需理解新概念&lt;/strong&gt;: &lt;strong&gt;Exa.ai, Jina.ai&lt;/strong&gt;。它们引入了新的搜索范式（概念搜索、神经搜索），需要开发者改变传统的 “关键词思维” 才能发挥其最大价值&lt;/p&gt;
&lt;h3 id="适用场景"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;适用场景
&lt;/h3&gt;&lt;p&gt;●&lt;strong&gt;需要最高性价比、大规模获取 Google 结果&lt;/strong&gt;: &lt;strong&gt;Serper&lt;/strong&gt; 是不二之选&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;快速原型、个人项目或 Ollama 生态内应用&lt;/strong&gt;: &lt;strong&gt;Ollama Web Search&lt;/strong&gt; 的免费和简易性使其成为首选&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;注重隐私、需要独立 / 差异化结果源&lt;/strong&gt;: &lt;strong&gt;Brave Search&lt;/strong&gt; 是最佳选择。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;构建高质量 RAG 或 AI Agent: Tavily&lt;/strong&gt; 经过优化的输出能显著提升效果和效率，是此场景的理想选择&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;需要完整、真实的 SERP 数据用于 SEO 或市场分析: SerpApi&lt;/strong&gt; 的数据完整性和多平台支持无可替代。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;需要进行深度研究、内容发现或构建推荐系统: Exa.ai&lt;/strong&gt; 的概念搜索和相似性搜索能力是独一无二的&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;需要构建企业内部的语义知识库或进行高级语义搜索: Jina.ai&lt;/strong&gt; 的自定义索引和神经搜索能力最为强大&lt;/p&gt;
&lt;h2 id="选型建议-1"&gt;&lt;a href="#%e9%80%89%e5%9e%8b%e5%bb%ba%e8%ae%ae-1" class="header-anchor"&gt;&lt;/a&gt;选型建议
&lt;/h2&gt;&lt;p&gt;综合以上分析，以下是针对不同需求的选型建议：&lt;/p&gt;
&lt;p&gt;1.&lt;strong&gt;个人开发者 / 初创公司 / 预算极度敏感项目&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;首选：Ollama Web Search&lt;/strong&gt;。完全免费且极致简单，没有任何理由不优先考虑它&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;备选：Serper 或 Brave Search&lt;/strong&gt;。当 Ollama 不可用或需要更高查询量时，这两者提供了业内最慷慨的免费额度和最低的付费门槛&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;构建标准 RAG 或 AI Agent 应用&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;首选：Tavily&lt;/strong&gt;。它专为此场景设计，能直接提供清洗和总结后的高质量上下文，有效降低幻觉，节省你自己处理数据的成本和 LLM 的 Token 消耗&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;备选：Serper&lt;/strong&gt;。如果你的 RAG 流程需要自己控制总结逻辑，且对成本和速度要求很高，可以使用 Serper 作为快速的数据获取层&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;专业的 SEO / 市场分析 / 需要多平台数据的企业级应用&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;唯一选择：SerpAp&lt;/strong&gt;i。尽管价格昂贵，但其数据的完整性、真实性以及对全球几十个搜索引擎和电商平台的支持是其他所有服务都无法比拟的&lt;/p&gt;
&lt;p&gt;4.&lt;strong&gt;探索前沿 AI 应用 / 需要进行深度内容发现和研究&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;首选：Exa.ai&lt;/strong&gt;。如果你需要 AI 去 “发现” 而不是 “查找”，或者需要基于一篇好文章找到更多同类内容，Exa 的概念搜索和相似性搜索能力是你的不二之选&lt;/p&gt;
&lt;p&gt;○&lt;strong&gt;备选：Jina.ai DeepSearch&lt;/strong&gt;。如果你不仅要搜索网络，还想构建一个能理解内部文档的、强大的语义知识库，Jina 提供了更完整的平台级解决方案&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-25-gei-ai-yi-shuang-hui-yan-shen-du-ping-ce-7-kuan-zhu-liu-ai-s/012-2f3410b6.png"&gt;&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>不止于工具：PromptPilot如何将AI开发从“手工作坊”推向“工业时代”？</title><link>https://xiaobox.github.io/p/2025-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/</link><pubDate>Sun, 03 Aug 2025 10:09:58 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/cover.jpg" alt="Featured image of post 不止于工具：PromptPilot如何将AI开发从“手工作坊”推向“工业时代”？" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;在AI应用的最后一公里，我们面临一个深刻的悖论：我们拥有了前所未有强大的大模型“引擎”，却常常在如何精确“驾驶”它这件事上捉襟见肘。我们真正缺的，或许不是更强的模型，而是更准的“缰绳”。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="概览"&gt;&lt;a href="#%e6%a6%82%e8%a7%88" class="header-anchor"&gt;&lt;/a&gt;概览
&lt;/h2&gt;&lt;p&gt;最近，火山引擎开了一场发布会，端出了两道“硬菜”：一个是性能更强的豆包大模型1.6，另一个则是我们今天要深挖的主角——PromptPilot。&lt;/p&gt;
&lt;p&gt;这篇文章会把这两件事给你一次性讲明白。读完本文，你会清晰地了解到：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为何要关注豆包1.6： 首先，我们会快速过一遍豆包大模型1.6的升级亮点，并列出它在中文处理、成本、长文本等方面的几个硬核优势，让你明白为何它值得被选入你的生产环境。&lt;/li&gt;
&lt;li&gt;主角PromptPilot如何解决痛点： 接着，我们会深入本文真正的主角——PromptPilot。带你从头到尾走一遍它的全流程，看它到底是如何通过“生成→调试→评测→优化”的闭环，将写提示词这件“玄学”彻底工程化的。&lt;/li&gt;
&lt;li&gt;横向对比： 把它放到市场中，与谷歌、微软等大厂的同类产品做对比，看清它的真实水平和独特价值到底在哪。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="豆包大模型-16"&gt;&lt;a href="#%e8%b1%86%e5%8c%85%e5%a4%a7%e6%a8%a1%e5%9e%8b-16" class="header-anchor"&gt;&lt;/a&gt;豆包大模型 1.6
&lt;/h2&gt;&lt;p&gt;豆包大模型升级了。2025 年 6 月 11 日在火山引擎 FORCE 原动力大会上正式发布豆包大模型 1.6 版本&lt;/p&gt;
&lt;p&gt;从原来的 1.5 到现在的 1.6，间隔仅有 140 天（豆包大模型 1.5 版本于 2025 年 1 月 22 日正式发布）。4 个多月出新版本，算得上是很快了。我想团队内部遇到的困难、挑战一定不少，在这些困难下，工程师们交出的结果却一点儿不差，令人尊重。&lt;/p&gt;
&lt;p&gt;现在你可以通过 &lt;a class="link" href="https://www.volcengine.com/experience/ark?model=doubao-seed-1-6-flash-250715" target="_blank" rel="noopener"
 &gt;https://www.volcengine.com/experience/ark?model=doubao-seed-1-6-flash-250715&lt;/a&gt; 来体验 1.6 版本的模型，会送 50 万 token。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/001-a356184e.png"&gt;&lt;/p&gt;
&lt;p&gt;大概介绍一下 1.6 模型，主要有以下两个子模型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Doubao-Seed-1.6-thinking｜250715：模型思考能力大幅强化， 对比 Doubao-1.5-thinking-pro，在 Coding、Math、 逻辑推理等基础能力上进一步提升， 支持视觉理解。 支持 256k 上下文窗口，输出长度支持最大 16k tokens。&lt;/li&gt;
&lt;li&gt;Doubao-Seed-1.6-flash｜250715： 推理速度极致的多模态深度思考模型，TPOT 仅需 10ms； 同时支持文本和视觉理解，文本理解能力超过上一代 lite，纯文本能力大幅提升近 10%。支持 256k 上下文窗口，输出长度支持最大 16k tokens。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从我个人的使用体验上看，1.6 比 1.5 强了很多。据悉，在众多权威评测集上，豆包大模型 1.6 的得分均位居国际第一梯队。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/002-ce42d4ee.png"&gt;&lt;/p&gt;
&lt;p&gt;可能很多人有这样一个问题：&lt;strong&gt;有那么多模型，我为什么要选择豆包？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;嗯，确实，市面上众多模型，开源的也好，闭源的也罢，除了国民级别的豆包 APP，好像豆包大模型的存在感不太高。然而实际上可能只是你不知道，我来列举一些，你可能真的想在生产应用中使用豆包大模型的原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;中文准确度必须顶尖（教育、政务、法律），比如在 2025 年高考数学新高考卷实测拿到 144/150，中文复杂推理居国内榜首&lt;/li&gt;
&lt;li&gt;国内首个 256 K token 对话模型，单条上下文 &amp;gt; 128 K（长合同、源代码库、历史聊天）&lt;/li&gt;
&lt;li&gt;成本：0–32 K 输入只要 ¥0.8/百万 token，综合成本是上一代模型的 1/3&lt;/li&gt;
&lt;li&gt;能够“看图说话”或读视频（电商质检、巡检、短视频客服）：60 项公开多模态基准 38 项第一&lt;/li&gt;
&lt;li&gt;通过中国网信办算法备案：豆包已完成“网信算备 110108823483901230031”备案，可直接商用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;心动吗？ 如果你要做一个 AI 应用，我想以上每一项都对你的模型选型很重要。&lt;/p&gt;
&lt;h2 id="promptpilot"&gt;&lt;a href="#promptpilot" class="header-anchor"&gt;&lt;/a&gt;PromptPilot
&lt;/h2&gt;&lt;p&gt;随着豆包大模型 1.6 更新的，还有今天的主角 &lt;code&gt;PromptPilot&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;众所周知，Prompt（提示词）作为大模型的核心输入指令，直接影响模型的理解准确性和输出质量。优质的 Prompt 能显著提升大语言模型处理复杂任务的能力，如逻辑推理、步骤分解等。&lt;/p&gt;
&lt;p&gt;作为 AI 应用的资深玩家，写提示词几乎成了每天必须要做的事情，我不但使用 AI 工具，还开发 AI 产品。就拿最近做的一个 RAG 项目来说，在整个 RAG pipeline 中，有一个很重要的环节就是 “响应生成”。顾名思义，就是通过 prompt 驱动 LLM 生成结果。其实 prompt engineering（提示词工程） 在整个 AI 应用中的性价比是极高的，要知道对整个技术工程进行优化的成本其实是相当大的，而且往往有时候投入产出不成正比，但 prompt engineering 不一样，一个好的提示词返回的结果质量可能比一个差的提示词强 10 倍，这在我们研发团队内部是有共识的。&lt;/p&gt;
&lt;p&gt;prompt engineering 看起来是叫“提示词工程”，但在实践中，它缺少传统工程的严谨范式，它不像其他可工程化的技术那样有明确的流程和标准，甚至与传统‘技术’的关联也显得不那么紧密。写提示词不用懂技术，不用会编程，语文和表达力好就够用了。&lt;/p&gt;
&lt;p&gt;然而这正是这个问题的症结所在，没法工程化，写提示词不成了管理的玄学了吗？系统、应用可不能由着你的性子玩儿“抽卡”啊，技术上一定要落地，一定要明确才行。但整个 AI 生态上，大家都在忙于开发模型，忙于开发基于模型的应用，或者大家觉得写提示词太简单？ 总之并没有很好地把写提示词这个问题工程化地解决好，对于 prompt engineering ，从我的经验看，至少有以下几个痛点：&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;li&gt;经常变更，写了新版忘了旧版，版本和生命周期全靠手动维护&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;随着我们项目开发的深入，以上这些问题我们也使用了一些办法，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;利用提示词模板固定提示词，将变量提出，前期手动管理提示词和提示词模板的版本与生命周期，后期开发系统功能来管理。&lt;/li&gt;
&lt;li&gt;与客户一起编写 Q/A 手册，一来为了将问题和标准回答定义清晰，二来为了验收做准备。研发团队基于 Q/A 可以有的放矢地对整个工程以及提示词进行优化。&lt;/li&gt;
&lt;li&gt;虽然客户不一定懂 prompt engineering，但知道什么是满意的结果什么是不满意的结果，通过点头 Yes 摇头 No 的方式来逐步固定提示词的衡量标准&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实从项目和工程的角度，诸如以上的办法我们还有一些，但作为一个开发者，这些办法一点儿“技术的味道” 都没有，它很别扭，不是说我们要为了技术而技术，而是技术是确定性的，可落地的，有保障的东西，没有工程来管理这个事儿，总让我不踏实。整个 prompt engineering 的过程可以说一点儿都不丝滑。里面有很多人工、手动、流程和制度的东西，太原始了，啥呀这是，什么时代了，一定有更好的解决办法才对。所以我一直在找，幸运的是我没找太久就看到了 &lt;code&gt;PromptPilot&lt;/code&gt; ，只一眼，我就知道，就是它了，它能解决我的问题！&lt;/p&gt;
&lt;h3 id="promptpilot-简介"&gt;&lt;a href="#promptpilot-%e7%ae%80%e4%bb%8b" class="header-anchor"&gt;&lt;/a&gt;PromptPilot 简介
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;火山引擎出品的 &lt;code&gt;PromptPilot&lt;/code&gt; 提供全流程智能优化，涵盖生成、调优、评估和管理全阶段。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;我引入了官方文档的一句话，我想这句话就够了，一句话就解决了我之前所说的几乎所有痛点。&lt;/p&gt;
&lt;p&gt;目前可以通过两个入口使用（&lt;strong&gt;限时免费 90 天&lt;/strong&gt; 2025.06.11-2025.09.11）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;独立站：https://promptpilot.volcengine.com/home&lt;/li&gt;
&lt;li&gt;火山方舟：https://console.volcengine.com/ark/region:ark+cn-beijing/autope/startup?&lt;/li&gt;
&lt;/ul&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/003-33005111.png"&gt;&lt;/p&gt;
&lt;p&gt;下面我分别说一下它是怎么解决我的痛点的。&lt;/p&gt;
&lt;h3 id="从生成一个-prompt-开始"&gt;&lt;a href="#%e4%bb%8e%e7%94%9f%e6%88%90%e4%b8%80%e4%b8%aa-prompt-%e5%bc%80%e5%a7%8b" class="header-anchor"&gt;&lt;/a&gt;从生成一个 prompt 开始
&lt;/h3&gt;&lt;p&gt;我经常看到一些刚接触 AI 大模型的伙伴，在起初面对大模型时手足无措，不知道应该怎么写 prompt ，实际上我开始也不太清楚要怎么写，但好在我经常写文章，还有一些经验，至少我能把事儿说明白，大模型给我的反馈也还不错，我把我的这种方法称为 &lt;strong&gt;“白描”&lt;/strong&gt;。然而并不是所有的事情都可以通过“白描” 来解决，有时候你用对了一个专业词汇就能够提升 90% 的效果，而正常情况下我们不太可能对所有领域的专业知识都精通，所以用不对词汇，写不好提示词几乎成了常态。&lt;/p&gt;
&lt;p&gt;于是我们好像很崇拜那些把提示词写的很好的人，纷纷效仿、分享、学习提示词，比如李继刚，他写的提示词用到了编程语言 Lisp 的一些特点。Lisp? 别说外行了，就是专业的程序员也很少有会的了。&lt;/p&gt;
&lt;p&gt;那我们怎么办呢？ 就像你明明来到了装有宝藏的房间大门前，却说不出打开门的咒语，一个劲儿地在那儿：“阿巴阿巴” ，像个傻子一样。&lt;/p&gt;
&lt;p&gt;promptpilot 给了我答案，那就是 ：&lt;strong&gt;“用魔法打败魔法，最终实现 prompt 袪魅”&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/2025-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/004-ee5959c4.png"&gt;&lt;/p&gt;
&lt;p&gt;这里我输入了一行自己写的 prompt： “判断舆论的内容对出行行业的影响”，点击 “生成 prompt” 就会在右边自己生成一个结构化的 prompt:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&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;舆论内容：
&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;public_opinion&lt;/span&gt;&lt;span class="p"&gt;&amp;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;{{PUBLIC_OPINION}}
&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;public_opinion&lt;/span&gt;&lt;span class="p"&gt;&amp;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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;1. 仔细阅读整个舆论内容，明确其核心观点和主要信息。
&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;2. 思考出行行业的各个方面，如交通方式、市场需求、企业运营、政策法规等。
&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;3. 分析舆论内容可能对出行行业的这些方面产生的直接或间接影响。
&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;4. 考虑舆论的传播范围、影响力和受众反应，以及这些因素如何放大或缩小对出行行业的影响。
&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;5. 形成初步判断，并再次检查，确保没有遗漏重要细节。
&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;思考&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;标签中详细分析舆论对出行行业的影响，考虑其可能涉及的各个方面。然后在&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;判断&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;标签中给出明确的影响判断结果，如“积极影响”“消极影响”“无明显影响”等。最后，在&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;解释&lt;/span&gt;&lt;span class="p"&gt;&amp;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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;思考&lt;/span&gt;&lt;span class="p"&gt;&amp;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&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="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;思考&lt;/span&gt;&lt;span class="p"&gt;&amp;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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;判断&lt;/span&gt;&lt;span class="p"&gt;&amp;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&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;判断&lt;/span&gt;&lt;span class="p"&gt;&amp;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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;解释&lt;/span&gt;&lt;span class="p"&gt;&amp;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="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;解释&lt;/span&gt;&lt;span class="p"&gt;&amp;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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;promptpilot 不但生成了结构化的 prompt，还自动提取出了变量 &lt;code&gt;{{PUBLIC_OPINION}}&lt;/code&gt;。此外在现有结构化 prompt 的基础上还可以点击功能按钮持续优化。&lt;/p&gt;
&lt;p&gt;这个功能总结来说就是：&lt;strong&gt;“简单描述你的需求，一键生成结构化的 prompt，输入你的修改意见，即刻智能改写。也可以框选局部文字，精准调整每个细节，帮你初步获得一个不错的 prompt”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不知道是不是我的错觉，因为最近一直在 vibe coding，所以用着用着 promptpilot 总感觉他们产品的很多功能可能就是 AI 写的，哈哈。&lt;/p&gt;
&lt;p&gt;我们稍微想一想这个功能的实现原理。我给他一段自己写的 prompt，他给我一段丰富的结构化的 prompt，还能继续优化，这一看就是用提示词让 AI 对我的提示词进行了重写啊。 这不就是 “用魔法打败魔法” 吗？所以对 prompt 袪魅吧朋友们，也没啥难的，但我一直对 AI 是有警觉的，我的意思是工具你可以用，好的工具更可以用，你完全可以放心大胆的使用 promptpilot，但请你看一看这个名字里有个 &lt;strong&gt;pilot&lt;/strong&gt;，领航员。看过拉力赛车吧，坐主驾旁边念路书的那哥们，很重要，但是没他人家主驾也能开车。《飞驰人生 2》中张驰在最终的比赛时，能不靠路书心不慌、面对使坏的对手大胆碰撞超车，赢得比赛的胜利,靠的是自己的经验和能力。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/005-95d20dd9.png"&gt;&lt;/p&gt;
&lt;p&gt;promptpilot 或任何 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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/006-bc4602c2.png"&gt;&lt;/p&gt;
&lt;h3 id="调试-prompt"&gt;&lt;a href="#%e8%b0%83%e8%af%95-prompt" class="header-anchor"&gt;&lt;/a&gt;调试 prompt
&lt;/h3&gt;&lt;p&gt;写好了 prompt 以后，我们还需要调试，点击“验证 prompt&amp;quot; , 进入调试界面：&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/007-0a7321c5.png"&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/008-edcf7ed5.png"&gt;&lt;/p&gt;
&lt;p&gt;进入到调试页面后，我们可以设置变量、继续改写与优化 prompt、选择不同的大语言模型，并生成模型回答，总之就是不断调试并查看 prompt 的最终生成效果如何。&lt;/p&gt;
&lt;p&gt;在你不断优化 prompt 的过程中无需关心版本的问题，系统会自动记录并管理提示词版本，你可以放心回退：&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/009-f9ca6756.png"&gt;&lt;/p&gt;
&lt;h3 id="评测"&gt;&lt;a href="#%e8%af%84%e6%b5%8b" class="header-anchor"&gt;&lt;/a&gt;评测
&lt;/h3&gt;&lt;p&gt;在完成调试后，接下来就该进行评测了。&lt;/p&gt;
&lt;p&gt;评测的目的是：&lt;strong&gt;在不同数据情况下验证 prompt 的效果如何，用各种 case 来检验 prompt 写的有没有问题，进而有针对性的进行优化。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;了解了目的，我想下一步你一定猜到了，那就是准备评测数据。&lt;/p&gt;
&lt;p&gt;哎呀，准备数据，这就有点儿烦人了，但没关系，promptpilot 帮你做了一个“AI 生成变量” 功能，之前生成的 prompt 不是已经自动帮我们提取出了变量了吗？ 在此基础上，它还可以再帮我们生成变量的数据，这评测数据不就有了吗？&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/010-d83c3d5d.png"&gt;&lt;/p&gt;
&lt;p&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/011-cf72d1db.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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/012-6231bebb.png"&gt;&lt;/p&gt;
&lt;p&gt;评分甚至可以让 AI 自动评，评分规则也可以自己写或让 AI 帮你写。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/013-77217d97.png"&gt;&lt;/p&gt;
&lt;p&gt;可能你注意到了有一列是 “理想回答”，我个人认为这一列非常重要，所谓定标准，就是要告诉人家什么是好的，一个问题问出去，如果你自己都不知道什么是好的答案，那 AI 其实也无能为力，它还没有那么聪明。这一点可能对于大部分 C 端用户不太好接受，因为就像你没有使用苹果手机前你是不知道你想要一个 iPhone 的，长期以来你被创造出来的需求所满足，习惯了，你觉得别人告诉你喜欢什么很正常，你自己不知道也很正常。&lt;/p&gt;
&lt;p&gt;对，是很正常，那是因为场景不同。在面对不同客户，不同需求，不同场景下，我们的解决方案也不同。对于 C 端场景可能真的就是那样，商家可以创造需求，创造价值。但对于 B 端客户是需要解决问题、满足需求，不要乱创造你以为的价值。&lt;/p&gt;
&lt;p&gt;在 B 端场景下，需求必须是明确的，解决的问题是清晰的，问题的答案是满意还是不满意也一定得是确定的。这是项目落地的必要条件！&lt;/p&gt;
&lt;p&gt;就像考试的试题有标准答案一样，当有了标准答案，自然就有清晰的方向和路径来解题了。所以 “理想回答” 这一列的重要性不言而喻。无论对于评分还是后续的智能优化都有极大的帮助，原因很简单，目标有了，剩下的就是如何达到目标的事儿了。&lt;/p&gt;
&lt;h3 id="智能优化"&gt;&lt;a href="#%e6%99%ba%e8%83%bd%e4%bc%98%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;智能优化
&lt;/h3&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/014-ea07c359.png"&gt;&lt;/p&gt;
&lt;p&gt;大模型将对 Prompt 进行优化（模型回答和评分齐全的数据会用于智能优化），优化完成后你 将获得：1.AI 智能优化后的 Prompt；2. 使用新 Prompt 生成的回答与评分&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/015-dde0c2ab.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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/016-7a062f5a.png"&gt;&lt;/p&gt;
&lt;p&gt;这一步其实还是对我最初的 prompt 进行优化，只不过因为有了更多的评测数据以及评分作为依据，优化方向更为明确，那么优化结果也一定更切合实际。&lt;/p&gt;
&lt;h3 id="视觉理解"&gt;&lt;a href="#%e8%a7%86%e8%a7%89%e7%90%86%e8%a7%a3" class="header-anchor"&gt;&lt;/a&gt;视觉理解
&lt;/h3&gt;&lt;p&gt;因为 prompt 是文本，promptpilot 最终生成、优化的也一定是 prompt 文本。也就是说输出是定死了的，就是“文本”，但输入可是多样的，除了文本的理解，promptpilot 还支持视觉理解。别误会，目前只支持图片。&lt;/p&gt;
&lt;p&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;“为了安全生产，你需要根据生产车间的图片，判断生产车间是否存在违规操作设备和未佩戴安全帽的情况，需要给出违规类别。”
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/017-a42fdace.png"&gt;&lt;/p&gt;
&lt;p&gt;我看了下右边生成的 prompt 觉得变量名太长，于是我想改一下，把变量名改成 &lt;code&gt;image_url&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/018-fe1d27d0.png"&gt;&lt;/p&gt;
&lt;p&gt;改写生成后的 prompt 是这样：&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;
&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;- 生产车间图片：{{image_url}}
&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;1. **`是否存在违规操作设备`**: （字符串，&amp;#34;是&amp;#34;/&amp;#34;否&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; - **判定**: 图像中是否存在工人违规操作设备的情况？
&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; - &amp;#34;是&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; - &amp;#34;否&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; - **违规类别**: 若判定为“是”，违规类别标记为“违规操作设备”。
&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;2. **`是否存在未佩戴安全帽`**: （字符串，&amp;#34;是&amp;#34;/&amp;#34;否&amp;#34;)
&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; - &amp;#34;是&amp;#34;: 至少有一人未佩戴安全帽。
&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; - &amp;#34;否&amp;#34;: 所有人都佩戴了安全帽，或者图像中无人。
&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&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;请按照以下 JSON 格式输出你的判断结果。所有字段的值必须是字符串 “是” 或 “否”，违规类别若存在多个以逗号分隔，若不存在违规则标记为“无”。
&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; &amp;#34;是否存在违规操作设备&amp;#34;: &amp;#34;是&amp;#34;,
&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; &amp;#34;是否存在未佩戴安全帽&amp;#34;: &amp;#34;否&amp;#34;,
&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; &amp;#34;违规类别&amp;#34;: &amp;#34;违规操作设备&amp;#34;
&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接着我们开始调试这个视觉理解的 prompt：新建一个内容理解任务，点击加号&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/019-1f5bd5bd.png"&gt;&lt;/p&gt;
&lt;p&gt;复制之前改写好的完整 prompt 到调试 prompt 栏里面&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/020-5dc1cb27.png"&gt;&lt;/p&gt;
&lt;p&gt;上传一个图片数据，这里采用 url 上传，并点击确定&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;https://img0.baidu.com/it/u=1094762033,1331895175&amp;amp;fm=253&amp;amp;fmt=auto&amp;amp;app=138&amp;amp;f=JPEG?w=500&amp;amp;h=561
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/021-1939cf50.png"&gt;&lt;/p&gt;
&lt;p&gt;选择 target model，即：推理模型，多模态选择带 thinking 的模型&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/022-8991229e.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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/023-93c40e1a.png"&gt;&lt;/p&gt;
&lt;p&gt;获取理想回答：平台对同一个 case，提供了不同模型回答的结果给用户参考，用户可以自由选定好的答案，并基于选定的答案进行反馈拿到理想回答。 这里作为示例，取模型回答 2 的结果，并点击应用。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/024-aa13ecd8.png"&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/025-28ea38ed.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;思考过程简洁一点
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/026-dd6cf3e7.png"&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/027-a919af39.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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/028-85569aff.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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/029-65e23efc.png"&gt;&lt;/p&gt;
&lt;p&gt;然后就可以按照前文一步一步地进行 prompt 调优、打分、智能优化并生成优化报告了。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/030-8521df33.png"&gt;&lt;/p&gt;
&lt;p&gt;你看，总之，图片它也是能够理解的，甚至还有更复杂的任务也可以（不过还处于 beta 状态），比如在一个复杂场景下检查人数：&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/031-a5d619a8.png"&gt;&lt;/p&gt;
&lt;h3 id="promptpilot-使用流程"&gt;&lt;a href="#promptpilot-%e4%bd%bf%e7%94%a8%e6%b5%81%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;promptpilot 使用流程
&lt;/h3&gt;&lt;p&gt;前文写的内容有点儿多，这里我们总结一下 promptpilot 的使用流程，我们从官方文档中找个图来说明一下&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/032-926a6334.png"&gt;&lt;/p&gt;
&lt;p&gt;初看可能有点儿复杂，但只要你真正用几回 promptpilot 再看这个图就会感觉无比的清晰了。&lt;/p&gt;
&lt;p&gt;我们通过视频再快速回顾一下 promptpilot 的核心功能&lt;/p&gt;
&lt;p&gt;已关注&lt;/p&gt;
&lt;p&gt;Follow&lt;/p&gt;
&lt;p&gt;Replay Share Like&lt;/p&gt;
&lt;p&gt;Close&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;观看更多&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更多&lt;/p&gt;
&lt;p&gt;&lt;em&gt;退出全屏&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;切换到竖屏全屏**退出全屏&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;小盒子的技术分享已关注&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Share Video&lt;/p&gt;
&lt;p&gt;，时长01:35&lt;/p&gt;
&lt;p&gt;0/0&lt;/p&gt;
&lt;p&gt;00:00/01:35&lt;/p&gt;
&lt;p&gt;切换到横屏模式&lt;/p&gt;
&lt;p&gt;继续播放&lt;/p&gt;
&lt;p&gt;进度条，百分之0&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;Play&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;00:00&lt;/p&gt;
&lt;p&gt;/&lt;/p&gt;
&lt;p&gt;01:35&lt;/p&gt;
&lt;p&gt;01:35&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;倍速&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;全屏&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;倍速播放中&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;0.5倍&lt;/a&gt; &lt;a class="link" href="javascript:;" &gt;0.75倍&lt;/a&gt; &lt;a class="link" href="javascript:;" &gt;1.0倍&lt;/a&gt; &lt;a class="link" href="javascript:;" &gt;1.5倍&lt;/a&gt; &lt;a class="link" href="javascript:;" &gt;2.0倍&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;超清&lt;/a&gt; &lt;a class="link" href="javascript:;" &gt;流畅&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Your browser does not support video tags&lt;/p&gt;
&lt;p&gt;继续观看&lt;/p&gt;
&lt;p&gt;不止于工具：PromptPilot如何将AI开发从“手工作坊”推向“工业时代”？&lt;/p&gt;
&lt;p&gt;观看更多&lt;/p&gt;
&lt;p&gt;转载&lt;/p&gt;
&lt;p&gt;,&lt;/p&gt;
&lt;p&gt;不止于工具：PromptPilot如何将AI开发从“手工作坊”推向“工业时代”？&lt;/p&gt;
&lt;p&gt;小盒子的技术分享已关注&lt;/p&gt;
&lt;p&gt;Share点赞Wow&lt;/p&gt;
&lt;p&gt;Added to Top Stories&lt;a class="link" href="javascript:;" &gt;Enter comment&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="javascript:;" &gt;Video Details&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="提示词工程产品对比"&gt;&lt;a href="#%e6%8f%90%e7%a4%ba%e8%af%8d%e5%b7%a5%e7%a8%8b%e4%ba%a7%e5%93%81%e5%af%b9%e6%af%94" class="header-anchor"&gt;&lt;/a&gt;提示词工程产品对比
&lt;/h2&gt;&lt;h3 id="横向对比"&gt;&lt;a href="#%e6%a8%aa%e5%90%91%e5%af%b9%e6%af%94" class="header-anchor"&gt;&lt;/a&gt;横向对比
&lt;/h3&gt;&lt;p&gt;其实还有其他的主流的提示词工程解决方案，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Azure Prompt Flow（微软）&lt;/li&gt;
&lt;li&gt;Vertex AI Studio（谷歌）&lt;/li&gt;
&lt;li&gt;Amazon Bedrock Prompt Playground（亚马逊）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;篇幅限制，我就不一一介绍了，这里简单介绍一下 Vertex AI Studio，通过对比，你会对 PromptPilot 的水平有更深刻地了解。&lt;/p&gt;
&lt;p&gt;Google 家的 Vertex AI studio 提供了一个直观界面，让你能够以低代码或甚至无代码的环境来构建 GenAI 应用，你能通过 Prompt, 连接后台，最后反馈结果。&lt;/p&gt;
&lt;p&gt;关于提示词工程部分，它的核心功能有：零次提示（Zero-shot prompting）、单次提示（One-shot prompting）和少量提示（Few-shot prompting）。&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;然后就没有然后了，对，就这些，界面很 google 很简单。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/033-31959af9.png"&gt;&lt;/p&gt;
&lt;p&gt;我看了一下 Azure Prompt Flow 和 Amazon Bedrock Prompt Playground 感觉产品逻辑和 Vertex AI studio 差不多。&lt;/p&gt;
&lt;p&gt;你可能已经发现，与 PromptPilot 相比，谷歌、微软、亚马逊这三大云服务商在提示词工程上的产品功能显得相对单薄。这主要是因为它们的产品方向和侧重点有所不同： &lt;strong&gt;三大云把 Prompt 工程塞进整条 LLM DevOps 流水线，它们把 Prompt 当作 LLM 应用流水线里的一环，仅提供“写＋测”或“写＋存＋跑”，深度要靠开发者自己拼接脚本或流水线。 而 PromptPilot 把“提示词”当作核心产品做了纵深。把 “提示词” 的 写 → 调 → 测 → 版本管理 等全部动作做了深耕。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因此，当你的主要痛点就是“写好提示词”而非“布好全链路”，PromptPilot 会显得顺手；而当项目需要管部署、监控、成本、接第三方工具时，Prompt Flow 等全栈 IDE 的价值就会凸显出来。&lt;/p&gt;
&lt;p&gt;而类似三大云厂商做的那种 LLM 流水线产品可以在&lt;strong&gt;火山引擎&lt;/strong&gt;上找到，在 AI 时代，阿里云、腾讯云、火山引擎是我比较喜欢的国内云厂商三巨头。之前也用过华为云，它的市场占有率也很高，但可能客户群体和技术方向的问题，在 AI 时代，它的声音并不多。&lt;/p&gt;
&lt;h3 id="纵向对比"&gt;&lt;a href="#%e7%ba%b5%e5%90%91%e5%af%b9%e6%af%94" class="header-anchor"&gt;&lt;/a&gt;纵向对比
&lt;/h3&gt;&lt;p&gt;从深耕提示词工程的角度来说，PromptPilot 身上也有不少优秀产品的影子，比如：promptlayer、Prompt Optimizer 。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/034-54d01c66.png"&gt;&lt;/p&gt;
&lt;p&gt;有这么多优秀的产品，足以见得提示词工程的需求在一段时间内还是存在的，需要被满足。但对比多家产品，我觉得 PromptPilot 目前做的是最好的，没有之一。&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;PromptPilot 的最大价值在于通过 自动“写+测+改” 把写 Prompt 这件“小事” 完全工程化产品化，让使用者几乎零门槛的使用，无论对于开发者还是小白都非常友好，我猜测将来甚至可以直接集成到企业级 AI 开发流水线中。&lt;/p&gt;
&lt;p&gt;另外不得不提一下的是，豆包大模型是商业模型，那么火山引擎作为一个云平台一定会引导用户用自家的大模型，所以构建“护城河” 这个事儿是一个常规操作，很正常。目前除了自家的豆包大模型，promptpilot 也支持 DeepSeek 等其他模型。&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-08-03-bu-zhi-yu-gong-ju-promptpilot-ru-he-jiang-ai-kai-fa-cong-sho/035-73e6c471.png"&gt;&lt;/p&gt;
&lt;p&gt;我相信未来在模型使用上，火山的策略不会那么激进，而会采用融合、共赢，权重优先的方式，长期允许多模型共存，但一定会在自家模型的推广和销售上大做文章。&lt;/p&gt;
&lt;p&gt;最后，我想说，在 AI 领域，未来一定会有越来越多的新产品出现，而所有这些产品都像是一个时代的注脚，你需要明白的是，时代不同了，AI应用开发正在从“炼丹师”式的个人英雄主义，走向体系化的工业生产阶段。在这个过程要解决的问题和相应的机会会很多，但只有真正务实地的解决问题的团队才能够赢得未来，因为他们行动深刻表达了四个字：&lt;strong&gt;“价值创造”&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>AI圈的新宠：Context Engineering</title><link>https://xiaobox.github.io/p/2025-07-22-ai-quan-de-xin-chong-context-engineering/</link><pubDate>Tue, 22 Jul 2025 03:32:03 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-07-22-ai-quan-de-xin-chong-context-engineering/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-07-22-ai-quan-de-xin-chong-context-engineering/cover.jpg" alt="Featured image of post AI圈的新宠：Context Engineering" /&gt;&lt;p&gt;AI 的发展真是 “日新月异” ，新概念也是满天飞。去年还在折腾 “提示工程”（Prompt Engineering），今年就整出了 “&lt;strong&gt;上下文工程&lt;/strong&gt;”（Context Engineering）&lt;/p&gt;
&lt;p&gt;最近看到 大佬们像 Andrej Karpathy、Harrison Chase 都在热议这个词。&lt;/p&gt;
&lt;p&gt;Manus 这篇文章《AI 智能体的上下文工程：构建 Manus 的经验教训》 更是对于做 Agent 的同行很有借鉴意义。&lt;/p&gt;
&lt;h2 id="context-engineering到底是个啥"&gt;&lt;a href="#context-engineering%e5%88%b0%e5%ba%95%e6%98%af%e4%b8%aa%e5%95%a5" class="header-anchor"&gt;&lt;/a&gt;Context Engineering，到底是个啥？
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;想象一下你正在和一个姑娘约会，你只了解了姑娘的基本信息，于是你绞尽脑汁地想话题，想和姑娘接下来聊点儿什么，但你的知识储备、记忆力也一般，于是你买了个 AI 眼镜，但这玩意就像某度一样，问什么答什么，其他没问的一概不知，而且有时候还 “胡说八道”，于是你给姑娘带来了像机器人一样的约会体验，然后就没有然后了。&amp;hellip;..&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;不得不说你是一个有“上进心”的人，觉得不能再给双方如此糟糕的体验了，为了自己的终身大事于是你决定要升级装备，你发现 AI 眼镜有 Plus 版本，你决定再给它一次机会。 下单-约会-实战开始！&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;这一次，你按照 “指南” 提前给设备塞了点儿 “备忘录”——比如你们最近的聊天记录、姑娘的相关资料、甚至工具怎么用。于是你根据姑娘和你的共同喜好，组织了好多双方感兴趣的话题，成功引起了姑娘的兴趣，再深入了解下去发现你们有更多共同的兴趣和朋友，甚至精神层面也有共鸣，你们探讨了最近看的书，三观，以及处世哲学，然后时间不早了，你根据姑娘和你的综合情况在 AI 的帮助下快速选定了一家餐厅，邀请姑娘共进午餐，姑娘欣然接受。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;可以说这次约会是成功的，AI 眼镜秒变 神助攻！&lt;/p&gt;
&lt;p&gt;这就是 Context Engineering 的本质：&lt;strong&gt;不是简单扔个问题给 AI，而是精心准备一堆“上下文”，让 AI 知道该怎么思考、怎么行动。简单说，它管着 AI“看到”的所有东西：系统提示、聊天历史、从数据库扒出来的数据、工具说明，甚至长期记忆。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Context Engineering 看起来 比 “提示工程” 靠谱多了&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“提示工程听起来就像日常聊天里随便问问，但工业级 AI 应用里，Context Engineering 才是艺术加科学——怎么塞对信息进上下文窗口，让 AI 一步步干活。”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;而且现在时机成熟了，因为 AI 模型的“记忆窗口”从几千字扩到百万字了（像 GPT-4o 或 gemini-2.5），光靠一个完美提示不够用，得动态管理上下文，避免 AI“迷路”或胡说八道&lt;/p&gt;
&lt;h2 id="老梗翻新"&gt;&lt;a href="#%e8%80%81%e6%a2%97%e7%bf%bb%e6%96%b0" class="header-anchor"&gt;&lt;/a&gt;老梗翻新？
&lt;/h2&gt;&lt;p&gt;老实说，初看起来 Context Engineering 多少有点儿新瓶装旧酒的意思，但细看起来确实有新意。&lt;/p&gt;
&lt;p&gt;AI 从简单聊天工具进化到“代理”（agent），这些代理得处理复杂任务，比如帮你分析法律文件、写代码或管客户支持。单纯的提示工程像扔个球给 AI，Context Engineering 则是建个球场、定规则、备道具。&lt;/p&gt;
&lt;p&gt;实际上 agent 开发者早就在干这活儿了，提炼出个概念来能吸引更多人注意，推动工具开发。哈哈，炒作的效果。&lt;/p&gt;
&lt;p&gt;所以也有人吐槽：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“Context Engineering 不就等于语义搜索吗？很多人忘了老排名机制的重要性，非得追新潮。”&lt;/li&gt;
&lt;li&gt;“dumping 数据进 AI 就算工程了？”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;我发现 coder 这个群体嘴有时候是真臭啊，哈哈。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;不过说的也没毛病，Context Engineering 就是整合了检索增强生成（RAG）、内存管理这些老技术，早期的 RAG 系统就已经在玩儿上下文检索了。所以，它不是从天而降的革命，而是对现有实践的升级包装。&lt;/p&gt;
&lt;p&gt;我们做个表格来对比一下 Prompt Engineering 和 Context Engineering&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-07-22-ai-quan-de-xin-chong-context-engineering/001-c511c1f3.png"&gt;&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;总之呢，AI 越来越复杂，得从“艺术”转向“工程”。但如果你只是随便玩玩 AI，不用纠结——它更适合开发者或企业。&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;ul&gt;
&lt;li&gt;manus 的文章： &lt;a class="link" href="https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus" target="_blank" rel="noopener"
 &gt;https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Rag chunk 之：Excel 文档解析</title><link>https://xiaobox.github.io/p/2025-06-06-rag-chunk-zhi-excel-wen-dang-jie-xi/</link><pubDate>Fri, 06 Jun 2025 01:39:11 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-06-06-rag-chunk-zhi-excel-wen-dang-jie-xi/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-06-rag-chunk-zhi-excel-wen-dang-jie-xi/cover.jpg" alt="Featured image of post Rag chunk 之：Excel 文档解析" /&gt;&lt;h2 id="前言"&gt;&lt;a href="#%e5%89%8d%e8%a8%80" class="header-anchor"&gt;&lt;/a&gt;前言
&lt;/h2&gt;&lt;p&gt;处理 Excel 文件时会遇到一些独特的挑战。与典型的结构化格式不同，由于合并单元格、多个表头、嵌入式图表和非传统的布局（这些布局主要设计用于人阅读而非机器解析）等元素，这些文件在数据提取和处理方面存在障碍。&lt;/p&gt;
&lt;p&gt;在处理 Excel 时可能会遇到各种 Excel 文件格式，从现代的 .xlsx 到旧版的.xls 或宏启用版的 .xlsm 文件，每种格式都需要不同的解析方法和库。跨工作表或单个工作表内的数据不一致进一步使过程复杂化。非标准文件通常缺乏统一性，呈现不同的列顺序、不一致的日期格式或列内混合的数据类型，需要强大的错误处理和数据验证机制。&lt;/p&gt;
&lt;p&gt;合并单元格对解析算法来说尤其成问题，因为它们可以跨越多行或多列，使数据关联变得复杂。必须编写程序逻辑来准确处理这些合并区域。隐藏的行、列或工作表增加了另一层复杂性，需要彻底检查整个工作簿以确保完整的数据提取。&lt;/p&gt;
&lt;p&gt;为应对这些挑战，必须开发稳健、灵活的解析解决方案。这通常涉及结合多种方法，例如使用专门的 Excel 解析库、为特定文件结构实现自定义逻辑，以及采用机器学习技术对半结构化数据进行模式识别。&lt;/p&gt;
&lt;h2 id="预处理"&gt;&lt;a href="#%e9%a2%84%e5%a4%84%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;预处理
&lt;/h2&gt;&lt;p&gt;在分块前处理合并单元格、复杂公式和非表格数据。这些属于预处理。&lt;/p&gt;
&lt;h3 id="合并单元格问题"&gt;&lt;a href="#%e5%90%88%e5%b9%b6%e5%8d%95%e5%85%83%e6%a0%bc%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;合并单元格问题
&lt;/h3&gt;&lt;p&gt;在对 Excel 进行分块之前，必须先把「合并单元格导致的信息缺失」消除，否则嵌入时会出现 NaN 或空字符串，严重影响检索召回。&lt;/p&gt;
&lt;h3 id="为什么要先处理合并单元格"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e5%85%88%e5%a4%84%e7%90%86%e5%90%88%e5%b9%b6%e5%8d%95%e5%85%83%e6%a0%bc" class="header-anchor"&gt;&lt;/a&gt;为什么要先处理合并单元格？
&lt;/h3&gt;&lt;p&gt;我们以一个 “功能清单.xlsx” 为例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读取时只保留左上角值：无论 openpyxl 还是 pandas.read_excel，合并区域内除左上角外其余格值会被置空 。&lt;/li&gt;
&lt;li&gt;行级分块会丢字段：合并了“模块名称”或“子系统”的行，在转换成文本时会缺列，导致检索无法定位 。&lt;/li&gt;
&lt;li&gt;RAG 检索依赖元数据：若模块名丢失，metadata_filter 将失效，回答准确率显著下降（内部测试下降 15–25 pp）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="解决方案"&gt;&lt;a href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;解决方案
&lt;/h3&gt;&lt;p&gt;思路：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;利用 ws.merged_cells.ranges 拿到所有合并区域&lt;/li&gt;
&lt;li&gt;读取左上角值，遍历填充到区域内每个单元格。&lt;/li&gt;
&lt;li&gt;调用 ws.unmerge_cells() 取消合并，再保存临时文件供 pandas / Unstructured 后续处理。&lt;/li&gt;
&lt;/ol&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;openpyxl&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_workbook&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;explode_merged_cells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_in&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;path_out&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&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;wb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_workbook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_in&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;worksheets&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merged_cells&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ranges&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; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unmerge_cells&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;rng&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; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tl_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_row&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_col&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="c1"&gt;# 左上角 Cell&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_row&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&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;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_col&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&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;ws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tl_cell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&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;wb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_out&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;核心 API 参考：unmerge_cells() 、merged_cells&lt;/p&gt;
&lt;h2 id="chunking-策略"&gt;&lt;a href="#chunking-%e7%ad%96%e7%95%a5" class="header-anchor"&gt;&lt;/a&gt;Chunking 策略
&lt;/h2&gt;&lt;p&gt;我手头有一些《功能清单》 和 《工时评估表》 就以这些文件为例，讨论一下具体的 chunking 策略，具体来说，是使用 &lt;strong&gt;两级分块&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="什么是两级分块"&gt;&lt;a href="#%e4%bb%80%e4%b9%88%e6%98%af%e4%b8%a4%e7%ba%a7%e5%88%86%e5%9d%97" class="header-anchor"&gt;&lt;/a&gt;什么是“两级分块”？
&lt;/h3&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-06-rag-chunk-zhi-excel-wen-dang-jie-xi/001-a923c989.png"&gt;&lt;/p&gt;
&lt;p&gt;Azure 官方指南将这种把大块再拆子块的做法称作“层次化 chunking/hierarchical chunking”，可与 Auto-Merging Retrieval 等检索算法天然配合&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能清单与工时评估表本质是一条条功能点记录；行级粒度最能保持“一问就能命中一行”的高精检索。&lt;/li&gt;
&lt;li&gt;单纯行级又易丢失上下文，例如“所属子系统”；用业务模块字段先聚合可在召回时带来更丰富的背景。&lt;/li&gt;
&lt;li&gt;如果某模块非常大，使用递归切分（递归字符或 token 限长）可以在不破坏结构的情况下继续拆分。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体来说是：模块 → 行 先聚后拆，更适合 Excel 表中已有明确模块列、需要用向量库分区或 metadata 过滤的系统&lt;/p&gt;
&lt;p&gt;处理流程上务必：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先处理合并单元格&lt;/li&gt;
&lt;li&gt;行文本带列名&lt;/li&gt;
&lt;li&gt;metadata 保留 module 字段，以便精准过滤与 Auto-Merging 聚合。 而元数据的处理（模块、行号、sheet 名），决定了查询过滤与答案上下文的可控性。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="详细说明"&gt;&lt;a href="#%e8%af%a6%e7%bb%86%e8%af%b4%e6%98%8e" class="header-anchor"&gt;&lt;/a&gt;详细说明
&lt;/h2&gt;&lt;p&gt;两级分块中的 父和子，具体来说是：“摘要型父块 + 行级子块”&lt;/p&gt;
&lt;h3 id="父块"&gt;&lt;a href="#%e7%88%b6%e5%9d%97" class="header-anchor"&gt;&lt;/a&gt;父块
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;父块的存在价值在于提供业务背景 + 索引锚点。比如 “模块 A：支付结算；记录 426 行” 。&lt;/li&gt;
&lt;li&gt;父块采用“header + 小块”策略&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;为什么父块可只包含结构信息？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;父块不包含子行信息，因为子块检索命中后，通过父 ID 回溯获得模块级上下文，提高回答完整度。&lt;/li&gt;
&lt;li&gt;在层次化 (hierarchical) 分块体系里，“父块 (parent document)” 的核心职责是让检索器知道一批子块属于哪 个业务语境，而不是存放子块的全文内容。&lt;/li&gt;
&lt;li&gt;通常父块只保存模块级背景（例如模块名、描述、记录数等），不再内嵌每一行子块的具体文本；这样既保上下文，又避免重复嵌入&lt;/li&gt;
&lt;/ul&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&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;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&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.docstore.document&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Document&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.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;functions_flat.xlsx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;openpyxl&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&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="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 class="n"&gt;parent_docs&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;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;模块名称: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;总记录数: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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="n"&gt;metadata&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;module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;parent&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sub&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groupby&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;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="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;row_docs&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iterrows&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;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;**&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;**: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&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;row_docs&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;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;md&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;metadata&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;module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;模块&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;child&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&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;# ➌ 可选：对子块再递归切分，确保 &amp;lt;2048 chars&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;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&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;child_chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row_docs&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;ParentDocumentRetriever 在检索时会先命中 child_chunks，随后自动用父 ID 把对应模块摘要拼回上下文。如需“关键列拼接”模式，只需把 row[[&amp;lsquo;ID&amp;rsquo;,&amp;lsquo;Name&amp;rsquo;]] 等字段 join 到父块内容。&lt;/p&gt;
&lt;h3 id="子块"&gt;&lt;a href="#%e5%ad%90%e5%9d%97" class="header-anchor"&gt;&lt;/a&gt;子块
&lt;/h3&gt;&lt;p&gt;在“模块 → 行”层次化分块里，子块（child chunk）就是把 Excel 中“一行业务记录”转成能让向量检索与 LLM 都看得懂的最小语义单元。它既要携带行内全部有效信息，又不能冗余到超出模型窗口。&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-06-rag-chunk-zhi-excel-wen-dang-jie-xi/002-53406af0.png"&gt;&lt;/p&gt;
&lt;p&gt;子块典型 Markdown／JSON 结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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="err"&gt;模块:&lt;/span&gt; &lt;span class="err"&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="err"&gt;**功能ID**:&lt;/span&gt; &lt;span class="err"&gt;PAY&lt;/span&gt;&lt;span class="mi"&gt;-001&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="err"&gt;**功能名称**:&lt;/span&gt; &lt;span class="err"&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 class="err"&gt;**功能类型**:&lt;/span&gt; &lt;span class="err"&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="err"&gt;**COSMIC&lt;/span&gt; &lt;span class="err"&gt;FP**:&lt;/span&gt; &lt;span class="mi"&gt;6&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="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="nt"&gt;&amp;#34;module&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; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;功能ID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PAY-001&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="nt"&gt;&amp;#34;功能名称&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;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;功能类型&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="nt"&gt;&amp;#34;COSMIC_FP&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&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;/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-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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&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.docstore.document&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Document&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.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;functions_flat.xlsx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;openpyxl&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&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;child_docs&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iterrows&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;module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&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="c1"&gt;# —— 1) 行→Markdown&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;**&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;**: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&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="c1"&gt;# —— 2) 写入 Document&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;child_docs&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&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;Document&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;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;# 模块: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="si"&gt;}&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;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadata&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="s2"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;module&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;row_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Excel 行号（含表头补1）&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;sheet&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&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&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 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&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;# 3) 控制长度，避免超窗口&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;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&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 class="n"&gt;child_chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child_docs&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;h3 id="标题行"&gt;&lt;a href="#%e6%a0%87%e9%a2%98%e8%a1%8c" class="header-anchor"&gt;&lt;/a&gt;标题行
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;行级子块一定写列名-值对&lt;/li&gt;
&lt;li&gt;父块按需保存一次表头或仅存摘要&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="父子块生成策略"&gt;&lt;a href="#%e7%88%b6%e5%ad%90%e5%9d%97%e7%94%9f%e6%88%90%e7%ad%96%e7%95%a5" class="header-anchor"&gt;&lt;/a&gt;父子块生成策略
&lt;/h3&gt;&lt;p&gt;在 Excel → 向量库的 RAG 管道里，最省事、也最被 LangChain/LlamaIndex/Haystack 等工具链推荐的做法，就是 “&lt;strong&gt;在同一遍遍历中同时生成父块和子块，并用 module 或 parent_id 把两者关联起来&lt;/strong&gt;”。这样既避免二次扫描，又保证所有子块天生带着正确的父信息，检索器便能先召回精确的行级子块，再顺着指针把对应的模块级父块自动补进上下文，实现“精召回 + 背景补全”的最佳组合。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一遍循环生成父子块的核心流程&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;步骤 0：展开合并单元格 用 openpyxl 的 unmerge_cells 把合并区域拆开，再把左上角值填满整块；或用 pandas.ffill() 向下补齐。这样每行都能拿到正确的 模块 字段&lt;/p&gt;
&lt;p&gt;步骤 1：遍历行 → 同时产出父块与子块&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&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.docstore.document&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Document&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.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;functions_flat.xlsx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;openpyxl&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;ffill&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;parent_seen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&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;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 控长:contentReference[oaicite:7]{index=7}&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iterrows&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;mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&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="c1"&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;notin&lt;/span&gt; &lt;span class="n"&gt;parent_seen&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;parent_seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Document&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="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;模块: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="si"&gt;}&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;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadata&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;module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;parent&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="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="n"&gt;parents&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;parent_seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mod&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&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;**&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;**: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;# ② 行→Markdown，保留列名&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;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Document&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;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;body&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;metadata&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;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod&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;parent_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent_seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="c1"&gt;# 或直接存 module&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="s2"&gt;&amp;#34;row&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&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="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&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;children&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;child&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;父块 只存简短摘要（如模块名、记录数），避免重复嵌入。&lt;/li&gt;
&lt;li&gt;子块 带齐列名-值对、行号及父引用，保证可追溯。社区经验贴也强调“列名+值”比裸值更利于语义检索&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;步骤 2：写入向量库 只向量化 子块，将 module 作为 partition key 或 metadata。父块可放旁路索引，或与子块一同存但不做向量化。&lt;/p&gt;
&lt;p&gt;步骤 3：检索时自动拼接 用 LangChain ParentDocumentRetriever、LlamaIndex AutoMergingRetriever 或 Haystack Auto-Merging Retriever：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先做向量检索拿到 k 个子块；&lt;/li&gt;
&lt;li&gt;按 parent_id/module 查父块；&lt;/li&gt;
&lt;li&gt;拼 “父摘要 + 命中子块(±近邻)” 送入 LLM。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="检索流程"&gt;&lt;a href="#%e6%a3%80%e7%b4%a2%e6%b5%81%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;检索流程
&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-06-rag-chunk-zhi-excel-wen-dang-jie-xi/003-b232c26a.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;过滤：查询时先用 filter={&amp;ldquo;module&amp;rdquo;: &amp;lt;候选模块&amp;gt;} 做向量库精搜；Milvus 文档示例说明 filtered search 会先裁剪候选集再做 ANN，比全库检索快 2-4×&lt;/li&gt;
&lt;li&gt;Auto-Merging：若一次命中同模块多行，LlamaIndex/Haystack 会把这些行和父摘要合并，避免窗口碎片化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="注意事项"&gt;&lt;a href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9" class="header-anchor"&gt;&lt;/a&gt;注意事项
&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-06-rag-chunk-zhi-excel-wen-dang-jie-xi/004-cf4ee85b.png"&gt;&lt;/p&gt;
&lt;h2 id="其他-chunking-策略"&gt;&lt;a href="#%e5%85%b6%e4%bb%96-chunking-%e7%ad%96%e7%95%a5" class="header-anchor"&gt;&lt;/a&gt;其他 chunking 策略
&lt;/h2&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;h2 id="用于-excel-分块的工具和库"&gt;&lt;a href="#%e7%94%a8%e4%ba%8e-excel-%e5%88%86%e5%9d%97%e7%9a%84%e5%b7%a5%e5%85%b7%e5%92%8c%e5%ba%93" class="header-anchor"&gt;&lt;/a&gt;用于 Excel 分块的工具和库
&lt;/h2&gt;&lt;h3 id="pandas"&gt;&lt;a href="#pandas" class="header-anchor"&gt;&lt;/a&gt;pandas
&lt;/h3&gt;&lt;p&gt;Python 的 pandas 库是许多 Excel 处理任务的核心，为读取 Excel 文件提供了强大的分块支持。 read_excel() 函数的 chunksize 参数允许进行内存高效、固定大小的分块&lt;/p&gt;
&lt;h3 id="openpyxl"&gt;&lt;a href="#openpyxl" class="header-anchor"&gt;&lt;/a&gt;openpyxl
&lt;/h3&gt;&lt;p&gt;对于更复杂的 Excel 结构，openpyxl 库提供了对 Excel 文件解析的粒度控制，使其适用于基于内容的分块方法，能够有效处理合并单元格、公式和其他非标准元素。&lt;/p&gt;
&lt;h3 id="xlrd"&gt;&lt;a href="#xlrd" class="header-anchor"&gt;&lt;/a&gt;xlrd
&lt;/h3&gt;&lt;p&gt;xlrd 库虽然主要针对较旧的.xls 格式，但对于遗留系统仍然具有相关性，并提供快速解析功能，在混合分块方法中，当速度至关重要时，这些功能非常有用。&lt;/p&gt;</description></item><item><title>RAG 系统文本切分：从固定长度到智能检索的六种方法解析</title><link>https://xiaobox.github.io/p/2025-06-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/</link><pubDate>Mon, 02 Jun 2025 03:18:54 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-06-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/cover.jpg" alt="Featured image of post RAG 系统文本切分：从固定长度到智能检索的六种方法解析" /&gt;&lt;h2 id="一固定大小切分fixed-size-chunking"&gt;&lt;a href="#%e4%b8%80%e5%9b%ba%e5%ae%9a%e5%a4%a7%e5%b0%8f%e5%88%87%e5%88%86fixed-size-chunking" class="header-anchor"&gt;&lt;/a&gt;一、固定大小切分（Fixed-size chunking）
&lt;/h2&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-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/001-616ec950.png"&gt;&lt;/p&gt;
&lt;h3 id="优势"&gt;&lt;a href="#%e4%bc%98%e5%8a%bf" class="header-anchor"&gt;&lt;/a&gt;优势
&lt;/h3&gt;&lt;p&gt;顾名思义且容易实现。由于直接分割可能会破坏语义流程，建议在两个连续的片段之间保持一些重叠。&lt;/p&gt;
&lt;h3 id="劣势"&gt;&lt;a href="#%e5%8a%a3%e5%8a%bf" class="header-anchor"&gt;&lt;/a&gt;劣势
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;破坏语义结构&lt;/strong&gt;：固定大小切分可能在句子或段落中间进行切分，导致语义信息被割裂，影响模型对文本的理解。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文信息丢失&lt;/strong&gt;：由于切分不考虑文本的语义边界，相关信息可能被分散到不同的块中，导致模型在处理时缺乏必要的上下文支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺乏灵活性&lt;/strong&gt;：固定大小切分无法适应不同文本结构的变化，对于结构复杂或格式不一致的文档，可能导致切分效果不佳。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;影响检索效果&lt;/strong&gt;：在基于检索的生成任务中，固定大小切分可能导致相关信息被分散，降低检索的准确性和生成结果的质量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;处理长文本的挑战&lt;/strong&gt;：对于包含长句子的文本，固定大小切分可能无法完整保留句子信息，影响模型的理解和处理能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点较多，不建议在大多数真实生产场景中使用。&lt;/p&gt;
&lt;h2 id="二语义切分semantic-chunking"&gt;&lt;a href="#%e4%ba%8c%e8%af%ad%e4%b9%89%e5%88%87%e5%88%86semantic-chunking" class="header-anchor"&gt;&lt;/a&gt;二、语义切分（Semantic chunking）
&lt;/h2&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-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/002-d1ec0d7a.png"&gt;&lt;/p&gt;
&lt;h3 id="原理概述"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%a6%82%e8%bf%b0" class="header-anchor"&gt;&lt;/a&gt;原理概述
&lt;/h3&gt;&lt;p&gt;语义分块的核心思想是通过计算相邻句子的嵌入向量之间的相似度，识别语义上的断点，从而将文本划分为语义连贯的块。具体步骤包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;句子分割：将文本按标点符号（如句号、问号等）分割成句子。&lt;/li&gt;
&lt;li&gt;嵌入计算：使用嵌入模型（如 OpenAI Embedding）计算每个句子的向量表示。&lt;/li&gt;
&lt;li&gt;相似度计算：计算相邻句子之间的语义相似度。&lt;/li&gt;
&lt;li&gt;断点识别：当相邻句子的相似度低于设定阈值时，认为存在语义断点，进行分块。&lt;/li&gt;
&lt;li&gt;块生成：将相似度高的句子合并为一个语义块。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这种方法旨在确保每个块内部的语义连贯性，从而提高检索和生成的准确性。&lt;/p&gt;
&lt;h3 id="优势-1"&gt;&lt;a href="#%e4%bc%98%e5%8a%bf-1" class="header-anchor"&gt;&lt;/a&gt;优势
&lt;/h3&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;h3 id="劣势-1"&gt;&lt;a href="#%e5%8a%a3%e5%8a%bf-1" class="header-anchor"&gt;&lt;/a&gt;劣势
&lt;/h3&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;语义分块在保持文本语义完整性方面具有优势，适用于对语义连贯性要求高的任务，如复杂问答系统。然而，其高计算成本和实现复杂度使其在资源受限或对处理速度要求高的场景中不太适用。相比之下，递归切分方法实现简单、处理速度快，适用于结构清晰的自然语言文本。因此，选择合适的分块策略应根据具体任务需求、数据类型和可用资源综合考虑。&lt;/p&gt;
&lt;h2 id="三基于文档结构的切片-document-structure-based-chunking"&gt;&lt;a href="#%e4%b8%89%e5%9f%ba%e4%ba%8e%e6%96%87%e6%a1%a3%e7%bb%93%e6%9e%84%e7%9a%84%e5%88%87%e7%89%87-document-structure-based-chunking" class="header-anchor"&gt;&lt;/a&gt;三、基于文档结构的切片 （Document structure-based chunking）
&lt;/h2&gt;&lt;p&gt;文档结构化分块（Document Structure-Based Chunking）是一种利用文档自身结构进行内容切分的策略。其核心思想是根据文档的自然组织形式（如标题、段落、章节、函数等）进行分块，以保留语义完整性和上下文连贯性，从而提升检索和生成的效果。&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-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/003-fc37014c.png"&gt;&lt;/p&gt;
&lt;p&gt;“Document structure-based chunking”（基于文档结构的切分）不是按固定长度或句子切，而是“按逻辑块”划分内容，常见于 Word、PDF、HTML 等格式的企业文档处理中，尤其适合处理说明书、规约、设计文档的场景。&lt;/p&gt;
&lt;h3 id="原理概述-1"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%a6%82%e8%bf%b0-1" class="header-anchor"&gt;&lt;/a&gt;原理概述
&lt;/h3&gt;&lt;p&gt;文档结构化分块的基本原理是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;结构感知：识别文档中的结构元素（如 Markdown 的标题、HTML 的标签、代码中的函数或类等），并以这些元素作为分块的边界。&lt;/li&gt;
&lt;li&gt;语义完整：确保每个分块在语义上是完整的，避免将相关内容拆分到不同的块中。&lt;/li&gt;
&lt;li&gt;上下文保留：通过保留文档的结构信息，维护内容之间的逻辑关系，增强模型对上下文的理解。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例如：在处理包含 Markdown 格式的文档时，可以使用 LangChain 提供的 MarkdownHeaderTextSplitter 类，根据标题层级（如 #、##、###）进行分块，从而保留文档的层次结构。&lt;/p&gt;
&lt;h3 id="原理解析"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e8%a7%a3%e6%9e%90" class="header-anchor"&gt;&lt;/a&gt;原理解析
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1. 结构识别&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从文档中提取结构元素，包括但不限于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标题层级（如 H1/H2/H3、1.、1.1、1.1.2）&lt;/li&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;这些结构在不同文档格式中的表现形式不同，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Word：段落样式 + Outline Level&lt;/li&gt;
&lt;li&gt;PDF：字体大小、粗细、缩进等视觉特征&lt;/li&gt;
&lt;li&gt;HTML：DOM 节点层级&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. 结构驱动的切分逻辑&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;常见策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;按 每一个小节（如 1.1、1.2.1）作为一个 chunk，或多个小节合并为一个 chunk&lt;/li&gt;
&lt;li&gt;同一标题下的所有段落视为一个逻辑块&lt;/li&gt;
&lt;li&gt;若小节内容过多，则再结合递归切分或 token 限制切分&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关键不是按“多少 token”切，而是“从属于哪个结构单元”切。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 结构标签保留（可选）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;切分后的 chunk 还可保留其结构标识，如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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&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="nt"&gt;&amp;#34;chunk&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;本系统支持 7 层安全防护措施……&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="nt"&gt;&amp;#34;section&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.3 安全架构设计&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 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;ul&gt;
&lt;li&gt;检索时进行 rerank&lt;/li&gt;
&lt;li&gt;LLM 回答时增强上下文定位感（结构提示）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举个例子:&lt;/p&gt;
&lt;p&gt;给定这样一段 Word 文档内容：&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;1. 系统概述
&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;2. 功能模块
&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; 2.1 用户管理
&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; 2.2 设备管理
&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Structure-based Chunking 结果可能是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chunk 1: 1. 系统概述 介绍系统的设计目标与背景。&lt;/li&gt;
&lt;li&gt;Chunk 2: 2.1 用户管理 包括登录、注册、权限分配等功能。&lt;/li&gt;
&lt;li&gt;Chunk 3: 2.2 设备管理 支持设备的接入、控制与监控。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;docx2python 示例：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;示例目录：&lt;/p&gt;
&lt;p&gt;我们将把 Word 文档解析成如下结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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&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="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="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;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; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;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; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="nt"&gt;&amp;#34;content&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&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&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 class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1.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;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1.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;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&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="nt"&gt;&amp;#34;content&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&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="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="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#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;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#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;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="nt"&gt;&amp;#34;content&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&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="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;完整代码：解析 Word 文档结构和正文内容&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;docx2python&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;docx2python&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;re&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;import&lt;/span&gt; &lt;span class="nn"&gt;json&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_level_and_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&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&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; 从标题行中提取编号和层级（例：1.2.3 → level 3）
&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; &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; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;^(\d+(\.\d+)*)(\s+|$)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&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&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;if&lt;/span&gt; &lt;span class="k"&gt;match&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;id_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id_str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&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="mi"&gt;1&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;id_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&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;returnNone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_docx_structure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docx_path&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&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;doc_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;docx2python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docx_path&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc_result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&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="n"&gt;parsed_chunks&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="n"&gt;current_chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;body&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;para_group&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;section&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;para_group&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="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&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&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;ifnot&lt;/span&gt; &lt;span class="n"&gt;text&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="k"&gt;continue&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;# 如果段落以编号开头，视为新段落标题&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;id_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_level_and_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;id_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;33&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;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_chunk&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="n"&gt;parsed_chunks&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;current_chunk&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&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;current_chunk&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;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id_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;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&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;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;level&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="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;&amp;#34;&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 class="p"&gt;}&lt;/span&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="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;44&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;45&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_chunk&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 class="n"&gt;current_chunk&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="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&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="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;48&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;49&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;current_chunk&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;50&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&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;51&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;title&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;52&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&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;53&lt;/span&gt;&lt;span class="cl"&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="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&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="p"&gt;}&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&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_chunk&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;57&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed_chunks&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;current_chunk&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;58&lt;/span&gt;&lt;span class="cl"&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;parsed_chunks&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&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 class="c1"&gt;# 示例使用&lt;/span&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="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_docx_structure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;example.docx&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;63&lt;/span&gt;&lt;span class="cl"&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;# 美观打印输出&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="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;chunks&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;66&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;=== &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&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;67&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="s2"&gt;&amp;#34;content&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;68&lt;/span&gt;&lt;span class="cl"&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;# 可选：保存为 JSON&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 class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;parsed_chunks.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&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;71&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&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;ul&gt;
&lt;li&gt;Markdown 文档：使用 MarkdownHeaderTextSplitter，根据标题层级进行分块。&lt;/li&gt;
&lt;li&gt;HTML 文档：使用 HTMLHeaderTextSplitter，根据 HTML 标签（如 &lt;code&gt;&amp;lt;h1&amp;gt;、&amp;lt;h2&amp;gt;&lt;/code&gt;）进行分块。&lt;/li&gt;
&lt;li&gt;代码文件：使用 PythonCodeTextSplitter 等工具，根据函数或类的定义进行分块。&lt;/li&gt;
&lt;li&gt;表格数据：将表格内容格式化为模型易于理解的形式（如 HTML 的 &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; 标签、CSV 格式等），以保留表格的结构信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些工具通常会在分块的同时添加元数据（如标题、层级信息等），以便在后续的检索和生成过程中提供更丰富的上下文。&lt;/p&gt;
&lt;h3 id="优势与适用场景"&gt;&lt;a href="#%e4%bc%98%e5%8a%bf%e4%b8%8e%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;优势与适用场景
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;优势&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;&lt;strong&gt;适用场景：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;结构清晰的文档，如技术文档、API 文档、法律文本等。&lt;/li&gt;
&lt;li&gt;需要保留文档层次结构的应用，如知识库问答系统、文档摘要生成等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;注意事项:&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;文档结构化分块是一种有效的分块策略，特别适用于结构清晰、层次分明的文档。在实际应用中，可以结合其他分块方法（如递归分块、语义分块）进行混合使用，以获得更好的效果。&lt;/p&gt;
&lt;h2 id="四递归切分recursive-splitting"&gt;&lt;a href="#%e5%9b%9b%e9%80%92%e5%bd%92%e5%88%87%e5%88%86recursive-splitting" class="header-anchor"&gt;&lt;/a&gt;四、递归切分（Recursive Splitting）
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;实际上 递归切分（Recursive Splitting） 也是 固定大小文本切块&lt;/p&gt;

 &lt;/blockquote&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-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/004-0a7325ac.png"&gt;&lt;/p&gt;
&lt;p&gt;在 RAG（Retrieval-Augmented Generation）系统中，递归切分（Recursive Splitting）是一种常用的文本分块策略，旨在将长文本有效地划分为适合处理的小块（chunk），以便后续的嵌入、检索和生成任务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;工具：&lt;code&gt;RecursiveCharacterTextSplitter&lt;/code&gt; (LangChain)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;参数建议：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;chunk_size=512 （适合多数 Embedding 模型）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;chunk_overlap=128 （平衡上下文连贯性与冗余）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;separators=&lt;code&gt;[&amp;quot;\n\n&amp;quot;, &amp;quot;\n&amp;quot;, &amp;quot;。&amp;quot;, &amp;quot;？&amp;quot;, &amp;quot;！&amp;quot;, &amp;quot;；&amp;quot;, &amp;quot;...&amp;quot;]&lt;/code&gt;（中文场景优化分隔符）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优势：先按大结构（标题）切，再按段落/句子细化，避免硬切关键信息。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="原理概述-2"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%a6%82%e8%bf%b0-2" class="header-anchor"&gt;&lt;/a&gt;原理概述
&lt;/h3&gt;&lt;p&gt;递归切分的核心思想是使用一组预定义的分隔符（如段落符、句号、空格等）按层次递归地将文本拆分成更小的块，直到每个块的长度满足设定的要求。&lt;/p&gt;
&lt;p&gt;具体步骤如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初步切分：使用第一个分隔符（例如换行符 \n）对文本进行初步切分。&lt;/li&gt;
&lt;li&gt;检查块大小：对于每个切分得到的块，判断其长度是否超过设定的最大块大小（chunk_size）。&lt;/li&gt;
&lt;li&gt;递归处理：如果某个块的长度仍然超过 chunk_size，则使用下一个分隔符（例如句号 。）对该块进行进一步切分。&lt;/li&gt;
&lt;li&gt;继续递归：重复上述过程，依次使用预定义的分隔符列表中的下一个分隔符，直到所有块的长度都不超过 chunk_size，或者无法再进行切分。&lt;/li&gt;
&lt;li&gt;合并块（可选）：在某些实现中，如果相邻的文本块合并后长度不超过 chunk_size，则可以将它们合并，以确保块的长度尽可能接近 chunk_size，同时保留上下文完整性。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这种方法的优点在于它能够尽量保留文本的语义结构，例如段落和句子边界，从而在保持上下文连贯性的同时，生成大小合适的文本块。&lt;/p&gt;
&lt;h3 id="示例langchain"&gt;&lt;a href="#%e7%a4%ba%e4%be%8blangchain" class="header-anchor"&gt;&lt;/a&gt;示例（LangChain）：
&lt;/h3&gt;&lt;p&gt;LangChain 提供了 RecursiveCharacterTextSplitter 类来实现递归切分。以下是一个使用示例：&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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;text_splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&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 class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&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;length_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;len&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;separators&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;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&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; &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; 7&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; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;text&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="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 class="n"&gt;texts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_documents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;text&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;texts&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&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;ul&gt;
&lt;li&gt;chunk_size=200：设置每个文本块的最大长度为 200 个字符&lt;/li&gt;
&lt;li&gt;chunk_overlap=50：设置相邻文本块之间的重叠长度为 50 个字符，以保留上下文&lt;/li&gt;
&lt;li&gt;separators=&lt;code&gt;[&amp;quot;\n&amp;quot;, &amp;quot;。&amp;quot;, &amp;quot; &amp;quot;, &amp;quot;&amp;quot;]&lt;/code&gt;：定义了分隔符的优先级顺序，依次为换行符、句号、空格和空字符串。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种方式确保了文本在切分时尽量保持语义的完整性和上下文的连贯性。&lt;/p&gt;
&lt;h3 id="优势-2"&gt;&lt;a href="#%e4%bc%98%e5%8a%bf-2" class="header-anchor"&gt;&lt;/a&gt;优势
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;保持语义结构：递归切分优先使用自然语言中的分隔符（如段落、句子等）进行切分，有助于保留文本的语义结构，减少信息碎片化的风险。&lt;/li&gt;
&lt;li&gt;灵活的分块大小：通过递归使用不同的分隔符，能够根据文本的实际结构动态调整分块大小，适应不同长度和结构的文本。&lt;/li&gt;
&lt;li&gt;适用于多种文本格式：递归切分方法适用于多种文本格式，包括自然语言文本、Markdown、HTML 等，能够处理结构复杂或层次分明的文档。&lt;/li&gt;
&lt;li&gt;减少上下文割裂：通过在相邻文本块之间引入重叠部分（chunk_overlap），有助于保留上下文信息，提高模型对文本的理解能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="适用场景"&gt;&lt;a href="#%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;适用场景
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;自然语言文本：如新闻文章、博客、书籍等，文本结构清晰，适合使用递归切分方法。&lt;/li&gt;
&lt;li&gt;结构化文档：如 Markdown、HTML 等，具有明确的结构层次，递归切分能够有效地保留其结构信息。&lt;/li&gt;
&lt;li&gt;需要保持语义完整性的任务：如问答系统、摘要生成等，对文本的语义连贯性要求较高，适合使用递归切分。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="劣势-2"&gt;&lt;a href="#%e5%8a%a3%e5%8a%bf-2" class="header-anchor"&gt;&lt;/a&gt;劣势
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;处理速度较慢：递归切分需要多次遍历文本，尤其是在处理大型文档时，可能导致处理速度较慢。&lt;/li&gt;
&lt;li&gt;块大小不一致：由于依赖于自然语言的分隔符，生成的文本块大小可能不一致，这可能影响后续的处理效果。&lt;/li&gt;
&lt;li&gt;计算资源消耗大：多次递归切分和合并操作可能导致较高的计算资源消耗，尤其是在大规模数据处理时。&lt;/li&gt;
&lt;li&gt;对文档结构依赖强：递归切分依赖于文档的结构清晰度，对于结构不明确或格式混乱的文档，效果可能不佳。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="不适用场景"&gt;&lt;a href="#%e4%b8%8d%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;不适用场景
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;结构化数据（如 Excel 表格）：Excel 表格中的数据通常以行和列的形式组织，递归切分无法有效保留其结构和语义信息。&lt;/li&gt;
&lt;li&gt;代码或标记语言文档：对于包含代码块或标记语言（如 HTML、Markdown）的文档，递归切分可能会破坏其语法结构，影响后续处理。&lt;/li&gt;
&lt;li&gt;多语言或混合语言文档：在处理包含多种语言的文档时，递归切分可能无法正确识别和处理不同语言的分隔符，导致切分效果不佳。&lt;/li&gt;
&lt;li&gt;对块大小有严格要求的应用：某些应用对输入块的大小有严格限制，递归切分生成的不一致块大小可能不满足这些要求。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五句子窗口检索sentence-window-retrieval"&gt;&lt;a href="#%e4%ba%94%e5%8f%a5%e5%ad%90%e7%aa%97%e5%8f%a3%e6%a3%80%e7%b4%a2sentence-window-retrieval" class="header-anchor"&gt;&lt;/a&gt;五、句子窗口检索（Sentence-Window Retrieval）
&lt;/h2&gt;&lt;p&gt;准确地讲，Sentence-Window Retrieval（检索期再扩窗）不是切片方式，而是 检索策略 —— 先以“单句 chunks”建索引，命中后再把 前后 N 句 拼回去给 LLM。&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-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/005-3ae4c7fd.png"&gt;&lt;/p&gt;
&lt;h2 id="原理概述-3"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%a6%82%e8%bf%b0-3" class="header-anchor"&gt;&lt;/a&gt;原理概述
&lt;/h2&gt;&lt;p&gt;传统的 RAG 系统通常将文档按固定长度或段落进行切分，并对每个块进行向量化处理。然而，这种方法可能导致语义相关的信息被切割，影响检索效果。&lt;/p&gt;
&lt;p&gt;句子窗口检索通过以下步骤优化这一过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;按句子切分文档：将文档按句子进行切分，每个句子作为一个最小的检索单元。&lt;/li&gt;
&lt;li&gt;构建句子窗口：对于每个句子，记录其前后若干个句子，形成一个“窗口”。这个窗口包含了目标句子及其上下文信息。&lt;/li&gt;
&lt;li&gt;向量化处理：仅对目标句子进行向量化处理，而将其窗口信息作为元数据存储。&lt;/li&gt;
&lt;li&gt;检索与生成：在检索阶段，根据用户查询与句子向量的相似度，找到最相关的句子，并将其对应的窗口信息提供给语言模型，以生成更准确的答案。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这种方法结合了细粒度的检索和丰富的上下文信息，提升了检索的精确度和生成的质量。&lt;/p&gt;
&lt;h3 id="示例llamaindex"&gt;&lt;a href="#%e7%a4%ba%e4%be%8bllamaindex" class="header-anchor"&gt;&lt;/a&gt;示例（LlamaIndex）
&lt;/h3&gt;&lt;p&gt;在 LlamaIndex 中，可以通过 SentenceWindowNodeParser 实现句子窗口检索： from llama_index.node_parser import SentenceWindowNodeParser&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;node_parser = SentenceWindowNodeParser.from_defaults(
&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; window_size=3,
&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; window_metadata_key=&amp;#34;window&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; original_text_metadata_key=&amp;#34;original_text&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;window_size=3：表示窗口包含目标句子前后各 3 个句子，共 7 个句子。&lt;/li&gt;
&lt;li&gt;window_metadata_key 和 original_text_metadata_key：用于在元数据中标识窗口内容和原始句子&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在检索阶段，可以使用 MetadataReplacementPostProcessor 将检索到的句子替换为其对应的窗口内容，提供给语言模型进行生成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LlamaIndex 的 SentenceWindowRetriever 实践显示，对长段落文档回答的 F1 明显提升。&lt;/li&gt;
&lt;li&gt;常用窗口：中心句 ± 3 句；别忘了把原句位置做 metadata，方便精确引用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="优势-3"&gt;&lt;a href="#%e4%bc%98%e5%8a%bf-3" class="header-anchor"&gt;&lt;/a&gt;优势
&lt;/h3&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;适用于需要高精度检索和丰富上下文支持的场景，如问答系统、文档摘要等。&lt;/p&gt;
&lt;h3 id="注意事项"&gt;&lt;a href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9" class="header-anchor"&gt;&lt;/a&gt;注意事项
&lt;/h3&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;h2 id="六自动合并检索auto-merging-retrieval"&gt;&lt;a href="#%e5%85%ad%e8%87%aa%e5%8a%a8%e5%90%88%e5%b9%b6%e6%a3%80%e7%b4%a2auto-merging-retrieval" class="header-anchor"&gt;&lt;/a&gt;六、自动合并检索（Auto-merging retrieval）
&lt;/h2&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-02-rag-xi-tong-wen-ben-qie-fen-cong-gu-ding-chang-du-dao-zhi-ne/006-5a44e69b.png"&gt;&lt;/p&gt;
&lt;p&gt;Auto-merging Retrieval（自动合并检索）本质上是一种检索策略，而非单纯的 chunk（文本切分）方法。要实现这一策略，确实需要配合特定的 chunk 策略，尤其是层次化的 chunking（Hierarchical Chunking）。&lt;/p&gt;
&lt;p&gt;我们前文说的 “Document structure-based chunking”（基于文档结构的切分）就属于“Hierarchical Chunking”（层次化切分）策略的一种。&lt;/p&gt;
&lt;h3 id="原理概述-4"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%a6%82%e8%bf%b0-4" class="header-anchor"&gt;&lt;/a&gt;原理概述
&lt;/h3&gt;&lt;p&gt;自动合并检索的核心思想是将文档划分为多个层次的块（chunk），形成父子关系的树状结构。在检索过程中，如果多个相关的子块属于同一个父块，系统会自动将这些子块合并为其父块，从而提供更完整的上下文信息给大语言模型（LLM）&lt;/p&gt;
&lt;h3 id="实现步骤"&gt;&lt;a href="#%e5%ae%9e%e7%8e%b0%e6%ad%a5%e9%aa%a4" class="header-anchor"&gt;&lt;/a&gt;实现步骤
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;文档层次化拆分：使用如 LlamaIndex 的 HierarchicalNodeParser 或 Haystack 的 HierarchicalDocumentSplitter，将文档按预设的块大小（如 2048、512、128）递归拆分，构建出多层级的节点结构。&lt;/li&gt;
&lt;li&gt;索引构建：将最小的叶子节点（最小块）进行向量化，并存入向量数据库中，供后续检索使用。&lt;/li&gt;
&lt;li&gt;检索与合并：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;在用户查询时，系统首先检索与查询最相关的叶子节点。&lt;/li&gt;
&lt;li&gt;如果检索到的叶子节点中，有多个属于同一个父节点，并且超过设定的阈值（例如，超过该父节点子节点数量的50%），则系统会自动将这些子节点合并为其父节点，作为最终的检索结果返回&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="优势-4"&gt;&lt;a href="#%e4%bc%98%e5%8a%bf-4" class="header-anchor"&gt;&lt;/a&gt;优势
&lt;/h3&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;h3 id="注意事项-1"&gt;&lt;a href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9-1" class="header-anchor"&gt;&lt;/a&gt;注意事项
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;合理设置层次结构：根据文档的结构和内容，选择合适的 chunk 大小和层数，避免层次过多或过少影响检索效果。&lt;/li&gt;
&lt;li&gt;调整合并阈值：根据具体应用场景，设置合适的合并阈值，确保在需要时合并相关子块，同时避免引入不相关的信息。&lt;/li&gt;
&lt;li&gt;利用元数据管理父子关系：在构建层次结构时，确保每个子块都包含其父节点的引用信息，以便在检索时能够正确合并。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="document-structure-based-chunking-结合-auto-merging-retrieval"&gt;&lt;a href="#document-structure-based-chunking-%e7%bb%93%e5%90%88-auto-merging-retrieval" class="header-anchor"&gt;&lt;/a&gt;Document structure-based chunking 结合 Auto-merging Retrieval
&lt;/h3&gt;&lt;p&gt;要将“基于文档结构的切分”（Document Structure-Based Chunking）与“自动合并检索”（Auto-merging Retrieval）结合应用于 RAG（Retrieval-Augmented Generation）系统，可以按照以下步骤进行开发：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1 基于文档结构的层次化切分&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;目标：利用文档的结构信息（如标题、段落、列表等）进行多层次的切分，构建父子关系的树状结构。&lt;/p&gt;
&lt;p&gt;实现方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用工具：可以使用如 LlamaIndex 的 HierarchicalNodeParser 或 Haystack 的 HierarchicalDocumentSplitter。这些工具允许根据文档结构进行层次化切分。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置参数：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;block_sizes：定义每一层的最大块大小，例如 {2048, 512, 128} 表示父块最大为 2048 个单位，子块最大为 512 个单位，叶子节点为 128 个单位。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;split_by：指定按何种单位进行切分，如按词（&amp;ldquo;word&amp;rdquo;）或句子（&amp;ldquo;sentence&amp;rdquo;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;构建层次结构：通过上述工具和参数设置，将文档切分为多个层次的块，形成父子关系的树状结构。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2 构建向量索引与文档存储&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;目标：将最小的叶子节点进行向量化，并存入向量数据库中，同时保留父节点的信息以供后续合并使用。 实现方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;向量化叶子节点：使用如 OpenAI 的 text-embedding-3-small 或 SentenceTransformers 等模型，对叶子节点进行向量化。&lt;/li&gt;
&lt;li&gt;存储向量：将向量化后的叶子节点存入向量数据库中，如 FAISS、Pinecone、Weaviate 等。&lt;/li&gt;
&lt;li&gt;保留父子关系：在存储过程中，保留每个叶子节点与其父节点之间的关系信息，以便在检索时进行合并。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3 配置自动合并检索器&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;目标：在检索过程中，根据设定的阈值自动将相关的子块合并为其父块，提供更完整的上下文信息。 实现方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用工具：可以使用如 Haystack 的 AutoMergingRetriever 或 LlamaIndex 的 AutoMergingRetriever。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置参数：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;threshold：设定合并的阈值，例如 0.5 表示当超过 50% 的子块被检索到时，合并为父块。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;document_store：指定包含父节点的文档存储。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&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;统计被检索到的叶子节点中，属于同一父节点的数量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果某个父节点下的被检索到的子节点数量超过设定的阈值，则将这些子节点合并为其父节点，作为最终的检索结果返回。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;在构建基于大语言模型（LLM）的检索增强生成（RAG）系统时，文本分块策略的选择对系统性能和生成质量具有决定性影响。本文深入探讨了六种主流的文本分块方法，分别是：固定大小切分、语义切分、基于文档结构的切分、递归切分、句子窗口检索和自动合并检索。以下是对这些方法的综合比较与应用建议：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 固定大小切分（Fixed-size Chunking）&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;&lt;strong&gt;2. 语义切分（Semantic Chunking）&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;&lt;strong&gt;3. 基于文档结构的切分（Document Structure-based Chunking）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优势：保留文档的层次结构，增强上下文理解，提高检索效果。&lt;/li&gt;
&lt;li&gt;劣势：对文档结构依赖强，块大小可能不均，需结合其他策略优化。&lt;/li&gt;
&lt;li&gt;应用建议：适用于结构清晰的文档，如技术文档、API文档、法律文本等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. 递归切分（Recursive Splitting）&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;&lt;strong&gt;5. 句子窗口检索（Sentence-Window Retrieval）&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;&lt;strong&gt;6. 自动合并检索（Auto-merging Retrieval）&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;在实际应用中，选择合适的文本分块策略应根据具体任务需求、数据类型和可用资源综合考虑。对于结构清晰的文档，建议优先采用基于文档结构的切分方法，并结合递归切分优化块大小；对于对语义连贯性要求高的任务，可采用语义切分方法；对于需要高精度检索和丰富上下文支持的场景，可采用句子窗口检索或自动合并检索策略。此外，根据实际情况以上 chunk 策略不必拘泥于任何一种，&lt;strong&gt;可以混合使用&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>Milvus 向量数据库快速入门（人话版）</title><link>https://xiaobox.github.io/p/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/</link><pubDate>Sun, 01 Jun 2025 04:03:27 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/cover.jpg" alt="Featured image of post Milvus 向量数据库快速入门（人话版）" /&gt;&lt;h2 id="milvus-到底是干嘛的"&gt;&lt;a href="#milvus-%e5%88%b0%e5%ba%95%e6%98%af%e5%b9%b2%e5%98%9b%e7%9a%84" class="header-anchor"&gt;&lt;/a&gt;Milvus 到底是干嘛的？
&lt;/h2&gt;&lt;p&gt;它是“给向量找对象”的超高速数据库——存向量、比相似、返回前 K 名。&lt;/p&gt;
&lt;p&gt;Milvus 就是给「向量」找对象的数据库——它能帮你把一堆高维向量存好、管好、飞快地按“相似度”把最像的几条挑出来。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;和普通数据库比，Milvus天生会“模糊配对”，不是 exact match 而是“谁更像”。&lt;/li&gt;
&lt;li&gt;内核走的是“先分桶/建图，再局部暴力”，所以大规模也能搜得飞快。&lt;/li&gt;
&lt;li&gt;2.x 版本把「数据落盘」「分布式容灾」都外包给 RocksDB + MinIO + etcd——省了你很多心。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="先认几个关键词"&gt;&lt;a href="#%e5%85%88%e8%ae%a4%e5%87%a0%e4%b8%aa%e5%85%b3%e9%94%ae%e8%af%8d" class="header-anchor"&gt;&lt;/a&gt;先认几个关键词
&lt;/h2&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-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/001-c2fdff5a.png"&gt;&lt;/p&gt;
&lt;h2 id="部署使用"&gt;&lt;a href="#%e9%83%a8%e7%bd%b2%e4%bd%bf%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;部署使用
&lt;/h2&gt;&lt;p&gt;五步跑通「单机体验」+ 三步升级「小集群」&lt;/p&gt;
&lt;h3 id="单机-5-步"&gt;&lt;a href="#%e5%8d%95%e6%9c%ba-5-%e6%ad%a5" class="header-anchor"&gt;&lt;/a&gt;单机 5 步
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;拉镜像 docker run milvusdb/milvus:v2.4.3&lt;/li&gt;
&lt;li&gt;建楼 create_collection()——确定字段维度、主键、向量字段。&lt;/li&gt;
&lt;li&gt;搬人 insert() → flush()。&lt;/li&gt;
&lt;li&gt;装电梯 create_index()；小数据直接 FLAT，大数据先 IVF，再视情况换 HNSW。&lt;/li&gt;
&lt;li&gt;开门找人 load() → search()/query()；用完可 release().&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="变成-3-节点小集群"&gt;&lt;a href="#%e5%8f%98%e6%88%90-3-%e8%8a%82%e7%82%b9%e5%b0%8f%e9%9b%86%e7%be%a4" class="header-anchor"&gt;&lt;/a&gt;变成 3 节点小集群
&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-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/002-c0911d8c.png"&gt;&lt;/p&gt;
&lt;h2 id="最常用的-5-步操作"&gt;&lt;a href="#%e6%9c%80%e5%b8%b8%e7%94%a8%e7%9a%84-5-%e6%ad%a5%e6%93%8d%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;最常用的 5 步操作
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;建楼：create collection，把字段都定义好&lt;/li&gt;
&lt;li&gt;搬人：insert，把向量和元信息塞进去；记得 flush() 真正落盘&lt;/li&gt;
&lt;li&gt;装电梯：create index，选对索引类型，未来搜索才快&lt;/li&gt;
&lt;li&gt;请保安开门：load，没 load 就像门锁着，啥也搜不到&lt;/li&gt;
&lt;li&gt;找人：search（可加条件 expr），或者只按字段 query&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="索引怎么挑"&gt;&lt;a href="#%e7%b4%a2%e5%bc%95%e6%80%8e%e4%b9%88%e6%8c%91" class="header-anchor"&gt;&lt;/a&gt;索引怎么挑？
&lt;/h2&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-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/003-0a75133a.png"&gt;&lt;/p&gt;
&lt;h2 id="索引调优口诀"&gt;&lt;a href="#%e7%b4%a2%e5%bc%95%e8%b0%83%e4%bc%98%e5%8f%a3%e8%af%80" class="header-anchor"&gt;&lt;/a&gt;索引调优口诀
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;小样本先 FLAT 做 baseline——它慢但最准，方便肉眼看 Recall。&lt;/li&gt;
&lt;li&gt;百 万级优先 IVF_FLAT：调 nlist=√N 起步；提高 nprobe 越准越慢。&lt;/li&gt;
&lt;li&gt;千万级冲 HNSW：关键参 M (边数) 和 efConstruction (建图宽度)，调高两倍能大幅增 Recall。&lt;/li&gt;
&lt;li&gt;超高并发记得“机＋内存”一起扩——索引放内存，多副本才分摊 QPS。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="别踩这些坑-"&gt;&lt;a href="#%e5%88%ab%e8%b8%a9%e8%bf%99%e4%ba%9b%e5%9d%91-" class="header-anchor"&gt;&lt;/a&gt;别踩这些坑 💡
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;向量维度要统一：128 就全 128，别混着来。&lt;/li&gt;
&lt;li&gt;插完别忘 flush：不 flush 就像东西放购物车没结账，搜索不到。&lt;/li&gt;
&lt;li&gt;没 load 就搜索：会报错，先 load()。&lt;/li&gt;
&lt;li&gt;内存不够全加载：用 Partition，分批 load()。&lt;/li&gt;
&lt;li&gt;精度不满意：调 nprobe（IVF）或换 HNSW 试试。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="十大踩坑--急救方案"&gt;&lt;a href="#%e5%8d%81%e5%a4%a7%e8%b8%a9%e5%9d%91--%e6%80%a5%e6%95%91%e6%96%b9%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;十大踩坑 + 急救方案
&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-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/004-d5e81d65.png"&gt;&lt;/p&gt;
&lt;h2 id="再进阶一点点"&gt;&lt;a href="#%e5%86%8d%e8%bf%9b%e9%98%b6%e4%b8%80%e7%82%b9%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;再进阶一点点
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Hybrid Search：边比向量相似度，边过滤价格 &amp;lt; 500 这种条件，SQL 味道更浓。&lt;/li&gt;
&lt;li&gt;一致性模式：默认够用；真要跨机房强一致性就选 Strong。&lt;/li&gt;
&lt;li&gt;持久化：Milvus 本身用 RocksDB ＋ MinIO 存数据，你不用操心怎么落盘。&lt;/li&gt;
&lt;li&gt;与 RAG 的关系：大模型把文本→向量，Milvus 负责“最近邻检索”，再把查到的文档喂回模型。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="跟其它工具怎么配"&gt;&lt;a href="#%e8%b7%9f%e5%85%b6%e5%ae%83%e5%b7%a5%e5%85%b7%e6%80%8e%e4%b9%88%e9%85%8d" class="header-anchor"&gt;&lt;/a&gt;跟其它工具怎么配？
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;LangChain / LlamaIndex：把 Milvus VectorStore 接进去即可，RAG 极速上线。&lt;/li&gt;
&lt;li&gt;Spark / Flink：批量离线写入 Milvus；确保分批 1 万条以内避免 RPC 超时。&lt;/li&gt;
&lt;li&gt;Airflow：定时 ETL → Embedding → Milvus；flush、compact 都能写成 task。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="到底需要多大机器粗算公式"&gt;&lt;a href="#%e5%88%b0%e5%ba%95%e9%9c%80%e8%a6%81%e5%a4%9a%e5%a4%a7%e6%9c%ba%e5%99%a8%e7%b2%97%e7%ae%97%e5%85%ac%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;“到底需要多大机器？”——粗算公式
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;内存 ≈ （向量维度 × 4 bytes × 向量条数 × 1.4 倍索引系数）﹢ 元数据大小&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例：1 亿条 768 维 → 768×4×1e8×1.4 ≈ 430 GB（得至少 512 GB 机器，或分区加载）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;硬盘 ≈ 内存 × 1.2（索引 + RocksDB + 日志）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;512G 内存看起来有点儿夸张，所以如果内存吃紧，可以参考以下方法进行优化：&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-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/005-35ceb743.png"&gt;&lt;/p&gt;
&lt;h2 id="python-端到端-demo-含增删改查"&gt;&lt;a href="#python-%e7%ab%af%e5%88%b0%e7%ab%af-demo-%e5%90%ab%e5%a2%9e%e5%88%a0%e6%94%b9%e6%9f%a5" class="header-anchor"&gt;&lt;/a&gt;Python 端到端 Demo （含增删改查）
&lt;/h2&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pymilvus&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;utility&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CollectionSchema&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;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&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;connections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;19530&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; 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. 建楼（如果已存在就删掉重建）&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;utility&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;utility&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;demo&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&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;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CollectionSchema&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;FieldSchema&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 class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INT64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is_primary&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 class="n"&gt;auto_id&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;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&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;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;price&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&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="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;emb&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FLOAT_VECTOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&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="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;col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema&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. 插 10 条数据&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;titles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;商品&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;vecs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tolist&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;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vecs&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&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;# 3. 建 IVF 索引 &amp;amp; 加载&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;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;emb&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;index_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;IVF_FLAT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;metric_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;L2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nlist&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;64&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;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&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="c1"&gt;# 4. 搜索 + 过滤价格 &amp;lt; 50&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="n"&gt;qv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tolist&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="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;emb&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;metric_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;L2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nprobe&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;price &amp;lt; 50&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="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;([(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entity&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="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="p"&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;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="c1"&gt;# 5. 删除一条，再查&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;del_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&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;id&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;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id in [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;del_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&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;</description></item></channel></rss>