<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>算法 on 小盒子的技术分享</title><link>https://xiaobox.github.io/tags/%E7%AE%97%E6%B3%95/</link><description>Recent content in 算法 on 小盒子的技术分享</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 13 Apr 2026 23:00:00 +0000</lastBuildDate><atom:link href="https://xiaobox.github.io/tags/%E7%AE%97%E6%B3%95/index.xml" rel="self" type="application/rss+xml"/><item><title>为什么 .tar.gz 要两个后缀</title><link>https://xiaobox.github.io/p/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/</link><pubDate>Mon, 13 Apr 2026 23:00:00 +0000</pubDate><guid>https://xiaobox.github.io/p/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/cover.jpg" alt="Featured image of post 为什么 .tar.gz 要两个后缀" /&gt;&lt;p&gt;前两天我在重新编译一版 nginx。&lt;/p&gt;
&lt;p&gt;流程基本闭着眼睛都能走。&lt;code&gt;wget&lt;/code&gt; 拉下来一个 &lt;code&gt;nginx-1.27.4.tar.gz&lt;/code&gt;，&lt;code&gt;tar -xzvf&lt;/code&gt; 解开，进目录，&lt;code&gt;./configure&lt;/code&gt;，&lt;code&gt;make&lt;/code&gt;，&lt;code&gt;make install&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;敲完 tar 那条命令的一瞬间，我突然愣了一下。&lt;/p&gt;
&lt;p&gt;这个 &lt;code&gt;.tar.gz&lt;/code&gt;，两个后缀。&lt;/p&gt;
&lt;p&gt;我用了大概十几年，从来没认真想过为什么要两个。&lt;/p&gt;
&lt;p&gt;顺着这事我又想起来，我这双手对 tar 的记忆完全是肌肉记忆，&lt;code&gt;xzvf&lt;/code&gt; 这四个字母该按什么顺序，大脑是不参与的，手指自己会动。正因为是肌肉记忆，我还踩过一个经典坑，偶尔下载到没有顶层目录的 tar 包，照样一梭子解下去，几十个文件啪一下全炸到当前目录，瞬间把工作目录变成垃圾场。&lt;/p&gt;
&lt;p&gt;那种时候我一边 &lt;code&gt;ls | xargs rm&lt;/code&gt; 一边告诉自己下次一定先 &lt;code&gt;mkdir&lt;/code&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;code&gt;.tar.gz&lt;/code&gt;。这两个后缀到底是什么关系，为什么非得拆成两个。&lt;/p&gt;
&lt;p&gt;我带着这个疑问查了一圈，发现这事比我想象的有趣得多。它不是什么历史包袱，也不是约定俗成的命名习惯，它是两个时代两个工具掰着手指头拼出来的一个结果。&lt;/p&gt;
&lt;p&gt;先说 tar。&lt;/p&gt;
&lt;p&gt;tar 这个命令，最早出现在 1979 年 1 月的 Unix Version 7 里，AT&amp;amp;T 贝尔实验室做的。名字也没什么加密的缩写，就是 Tape ARchive。翻译过来，磁带归档。字面意思。&lt;/p&gt;
&lt;p&gt;你可以想象一下 1979 年。那会儿大家备份数据靠的是磁带，就是老电影里那种两个圆盘转啊转的大盘子，数据一圈一圈顺序刻在带子上。你不能跳着读，也不能中间插一段，只能从头到尾一次性过。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/001-c4cd4c83.png"&gt;&lt;/p&gt;
&lt;p&gt;tar 这个工具的出生使命，就是为了给磁带服务的。&lt;/p&gt;
&lt;p&gt;所以它做的事情特别简单，就一个动作，把一堆小文件按顺序拼成一条长长的字节流，好让磁带机一口气写下去。&lt;/p&gt;
&lt;p&gt;注意，我说的是「拼成一条流」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tar 压根就不压缩。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你拿 tar 把一个 100MB 的目录打成一个包，出来的文件还是 100MB，一个字节都没省。它只是把这些东西排成一列而已，没做别的事情。&lt;/p&gt;
&lt;p&gt;tar 文件内部的最小单位是 512 字节一块，这个数字也不是随便选的。它就是 Unix V7 文件系统磁盘扇区的大小。1979 年的一个选择，刻在所有 tar 文件的基因里，一直刻到今天。 所以 tar 管的事情，就到「拼」为止。&lt;/p&gt;
&lt;p&gt;那压缩呢？&lt;/p&gt;
&lt;p&gt;tar 不管。&lt;/p&gt;
&lt;p&gt;这事儿一直到 1992 年才有人接手。&lt;/p&gt;
&lt;p&gt;那一年，两个叫 Jean-loup Gailly 和 Mark Adler 的人做了一个东西叫 gzip。Gailly 写压缩，Adler 写解压，1992 年 10 月 31 号，gzip 0.1 正式发布。&lt;/p&gt;
&lt;p&gt;这里有个背景值得一提。在 gzip 之前，Unix 自带的压缩工具叫 compress，用的是 LZW 算法。但 LZW 被 Unisys 和 IBM 捏在手里，九十年代初开始到处收钱，开源圈被整得很紧张。gzip 就是被逼出来的替代品，用的是另一个叫 DEFLATE 的算法，完美绕开了专利地雷。&lt;/p&gt;
&lt;p&gt;这段往事本身就够写一篇文章的，但今天我们只关心一个点。&lt;/p&gt;
&lt;p&gt;gzip 做的事也特别简单，就一个动作，把一条字节流压缩成一条更短的字节流。&lt;/p&gt;
&lt;p&gt;你注意到了吗？gzip 也很轴。它只认「一条流」。你不能拿 gzip 去压一个目录，它不认识目录这回事。给它一个文件，它就吐一个压缩后的文件，给它一条流，它就吐一条压缩后的流。别的事它一概不管。&lt;/p&gt;
&lt;p&gt;tar 只打包不压缩，gzip 只压缩不打包。&lt;/p&gt;
&lt;p&gt;两个工具，谁都不会干对方的活。&lt;/p&gt;
&lt;p&gt;那怎么办？&lt;/p&gt;
&lt;p&gt;中间用一根 Unix 管道粘起来。&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;tar cf - mydir | gzip &amp;gt; mydir.tar.gz
&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/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/002-1c3931bc.png"&gt;&lt;/p&gt;
&lt;p&gt;这条命令左边 tar 把 &lt;code&gt;mydir&lt;/code&gt; 打成一条流，用 &lt;code&gt;-&lt;/code&gt; 表示「别写文件，直接吐到标准输出」。中间一个 &lt;code&gt;|&lt;/code&gt;，把这条流接到 gzip 的嘴边。右边 gzip 啃完这条流，吐出一条压缩过的流，重定向到 &lt;code&gt;mydir.tar.gz&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;一个 &lt;code&gt;|&lt;/code&gt; 符号，两个工具，一条流水线。&lt;/p&gt;
&lt;p&gt;你看到的那个 &lt;code&gt;.tar.gz&lt;/code&gt;，就是这条流水线走完之后自然掉下来的结果。它的后缀之所以是两个，是因为这个文件真的经历了两道工序。第一道叫 tar，第二道叫 gz。后缀诚实地告诉你它是谁。&lt;/p&gt;
&lt;p&gt;这里顺便说一句 tar 后来的 &lt;code&gt;-z&lt;/code&gt; 参数。&lt;/p&gt;
&lt;p&gt;GNU tar 的作者们觉得每次写管道太烦，加了一个 &lt;code&gt;z&lt;/code&gt; 参数，告诉 tar，你要压缩的时候帮我顺手调一下 gzip。这就是为什么我们今天敲 &lt;code&gt;tar -xzvf&lt;/code&gt; 这个 &lt;code&gt;z&lt;/code&gt;。但你要知道，&lt;strong&gt;是 tar 在「替你调 gzip」，不是 tar 自己会压缩。四十五年过去了，tar 本体始终没长出压缩这项能力。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个决定非常 Unix，非常硬核。&lt;/p&gt;
&lt;p&gt;有意思的是，几乎就在 tar 过着自己小日子的同一年代，大洋对岸的 DOS/Windows 世界走了完全不同的一条路。&lt;/p&gt;
&lt;p&gt;1989 年，美国程序员 Phil Katz 在 DOS 上搞出 PKZIP，顺手发明了 &lt;code&gt;.zip&lt;/code&gt; 格式。zip 跟 tar + gzip 的哲学几乎是正相反的，一个工具同时做两件事，既打包又压缩，一把梭到底。&lt;/p&gt;
&lt;p&gt;四年之后的 1993 年，另一个年轻人进场了。俄罗斯程序员 Eugene Roshal 发布命令行 RAR，1995 年又推出图形界面版 WinRAR。RAR 是 Roshal Archive 的缩写，字面意思就是「Roshal 的归档」，一个用作者自己名字命名的格式，主打比 zip 更高的压缩率。&lt;/p&gt;
&lt;p&gt;WinRAR 这个软件顺便还成了互联网历史上最著名的「永恒试用版」。它写着 40 天试用期，但过期后不会拦你，只会弹一个很客气的提示让你买 license，你关掉它接着用，下次再弹。这个 40 天续命了二十多年，全球无数人用了一辈子没付过钱，它也不生气。这事本身已经成了一个互联网梗。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/003-12bd445d.png"&gt;&lt;/p&gt;
&lt;p&gt;这一路跟 Unix 那边的区别非常明显，一个软件管到底，打包压缩全包在一个 exe 里。后来 1999 年俄罗斯人 Igor Pavlov 又搞了开源的 7-Zip，自带一个 &lt;code&gt;.7z&lt;/code&gt; 格式，压缩率再往上提一截。1996 年 Julian Seward 做的 bzip2、2009 年 Lasse Collin 做的 xz 也都先后加入了这个江湖，压缩格式的主要玩家基本就是这些人了。&lt;/p&gt;
&lt;p&gt;但你注意到一个很好玩的分化没有。&lt;/p&gt;
&lt;p&gt;bzip2 和 xz 这两个后来的家伙，在 Unix 世界里叫什么？&lt;code&gt;.tar.bz2&lt;/code&gt; 和 &lt;code&gt;.tar.xz&lt;/code&gt;。tar 先把文件拼成流，bzip2 或者 xz 接着压。&lt;strong&gt;换压缩工具可以，换哲学不行。Unix 那边认死一件事，打包和压缩必须是两件事，永远是两件事。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Windows 那边正相反，出了更强的算法，就把旧软件整个换掉，一个 exe 管到底。&lt;/p&gt;
&lt;p&gt;这已经不只是格式之争了，是两个世界对「一个工具应该长成什么样」的根本分歧。&lt;/p&gt;
&lt;p&gt;为什么 Unix 那边坚持要拆？&lt;/p&gt;
&lt;p&gt;这就得搬出 Doug McIlroy 了。&lt;/p&gt;
&lt;p&gt;1978 年，贝尔实验室的 McIlroy 在 Bell System Technical Journal 上写了一段后来被反复引用的话，核心就三句。&lt;/p&gt;

 &lt;blockquote&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;/blockquote&gt;
&lt;p&gt;这就是后来被叫作 Unix 哲学的那一段。&lt;/p&gt;
&lt;p&gt;但这段话最有意思的一点，不在文字本身。在于说这话的人是谁。&lt;/p&gt;
&lt;p&gt;Doug McIlroy 不光是写这段话的人，他同时还是 Unix 管道 &lt;code&gt;|&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/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/004-470ec597.png"&gt;&lt;/p&gt;
&lt;p&gt;你品一下这个巧合。&lt;/p&gt;
&lt;p&gt;他说「让程序互相协作」的时候，他心里想的不是什么抽象的合作，他想的就是管道。一个程序的输出，通过一根 &lt;code&gt;|&lt;/code&gt;，无缝流进下一个程序的嘴里。小工具、单一职责、用管道粘起来，组合出任意复杂的流水线。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.tar.gz&lt;/code&gt; 就是这段话最直白的产物。&lt;/p&gt;
&lt;p&gt;tar 是第一个只做一件事的小工具，gzip 是第二个只做一件事的小工具，中间那根 &lt;code&gt;|&lt;/code&gt; 是 McIlroy 本人发明的管道。你每打一个 &lt;code&gt;.tar.gz&lt;/code&gt; 文件，都是在重演一遍 1978 年那段话。&lt;/p&gt;
&lt;p&gt;这就是为什么我说它是活化石。&lt;/p&gt;
&lt;p&gt;化石这个词听起来像是死掉的东西，但 &lt;code&gt;.tar.gz&lt;/code&gt; 不是。你今天去 GitHub 上随便点一个 C 项目的 release，下载下来的几乎永远是 &lt;code&gt;.tar.gz&lt;/code&gt;，不是 &lt;code&gt;.zip&lt;/code&gt;。Linux 内核、nginx、curl、redis，全都是。它不是因为惯性才活着，它是因为那套哲学在今天依然被认为是对的才活着。&lt;/p&gt;
&lt;p&gt;所以回到开头那个问题。&lt;/p&gt;
&lt;p&gt;为什么 &lt;code&gt;.tar.gz&lt;/code&gt; 要两个后缀？&lt;/p&gt;
&lt;p&gt;因为它不是一个文件，是两个工具排成的一条流水线，每个后缀对应一个工位。你看到的是这条流水线吐出来的结果。&lt;/p&gt;
&lt;p&gt;下次你再敲 &lt;code&gt;tar -xzvf some-thing.tar.gz&lt;/code&gt; 的时候，可以稍微多看两眼那个 &lt;code&gt;z&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;那个 &lt;code&gt;z&lt;/code&gt; 不是 tar 在解压。&lt;/p&gt;
&lt;p&gt;那是 tar 在回头喊一声 gzip，过来搭把手。&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/2026-04-13-wei-shen-me-tar-gz-yao-liang-ge-hou-zhui/005-6c5fb0a0.png"&gt;&lt;/p&gt;</description></item><item><title>拒绝内卷！为什么我们应该抵制用 LeetCode 考查真实的工程师？</title><link>https://xiaobox.github.io/p/2026-03-04-ju-jue-nei-juan-wei-shen-me-wo-men-ying-gai-di-zhi-yong-leet/</link><pubDate>Wed, 04 Mar 2026 08:41:32 +0000</pubDate><guid>https://xiaobox.github.io/p/2026-03-04-ju-jue-nei-juan-wei-shen-me-wo-men-ying-gai-di-zhi-yong-leet/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-04-ju-jue-nei-juan-wei-shen-me-wo-men-ying-gai-di-zhi-yong-leet/cover.jpg" alt="Featured image of post 拒绝内卷！为什么我们应该抵制用 LeetCode 考查真实的工程师？" /&gt;&lt;h1 id="拒绝内卷为什么我们应该抵制用-leetcode-考查真实的工程师"&gt;&lt;a href="#%e6%8b%92%e7%bb%9d%e5%86%85%e5%8d%b7%e4%b8%ba%e4%bb%80%e4%b9%88%e6%88%91%e4%bb%ac%e5%ba%94%e8%af%a5%e6%8a%b5%e5%88%b6%e7%94%a8-leetcode-%e8%80%83%e6%9f%a5%e7%9c%9f%e5%ae%9e%e7%9a%84%e5%b7%a5%e7%a8%8b%e5%b8%88" class="header-anchor"&gt;&lt;/a&gt;拒绝内卷！为什么我们应该抵制用 LeetCode 考查真实的工程师？
&lt;/h1&gt;&lt;p&gt;如果你要招募一位主刀医生，你会让他当场默写《人体解剖学》的第一章吗？如果你要找一位米其林大厨，你会蒙住他的眼睛，让他比赛在一分钟内切出多少根标准厚度的土豆丝吗？&lt;/p&gt;
&lt;p&gt;显然不会。但在如今的软件工程招聘中，我们却在做着同样荒谬的事情：让那些在复杂的业务泥潭中摸爬滚打、主导过千万级并发系统、熟练操纵复杂云原生架构的资深工程师，站在白板前，徒手写出一个“翻转二叉树”或者“接雨水”的最佳时间复杂度解法。&lt;/p&gt;
&lt;p&gt;不知从何时起，“刷 LeetCode”已经从一种思维训练，演变成了一场病态的军备竞赛。是时候戳破这个泡沫了：&lt;strong&gt;LeetCode 根本选拔不出优秀的软件工程师，它正在毁掉我们的行业生态。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="一-真实的工程世界从来不是一道闭卷考试"&gt;&lt;a href="#%e4%b8%80-%e7%9c%9f%e5%ae%9e%e7%9a%84%e5%b7%a5%e7%a8%8b%e4%b8%96%e7%95%8c%e4%bb%8e%e6%9d%a5%e4%b8%8d%e6%98%af%e4%b8%80%e9%81%93%e9%97%ad%e5%8d%b7%e8%80%83%e8%af%95" class="header-anchor"&gt;&lt;/a&gt;一、 真实的工程世界，从来不是一道“闭卷考试”
&lt;/h3&gt;&lt;p&gt;让我们先来看看，一个现代软件工程师的真实一天是怎样度过的。&lt;/p&gt;
&lt;p&gt;你可能会花一整个上午，在一堆没有注释的“屎山”代码中追踪一个诡异的内存泄漏问题；你可能会在下午和产品经理反复拉扯，确定一个新功能在微服务架构下的 API 边界；你可能会在排查为什么 Kubernetes 集群里的 HPA（水平Pod自动扩缩容）没有按预期触发，或者研究 Istio 网关的流量路由策略。&lt;/p&gt;
&lt;p&gt;如果你身处最前沿的 AI 领域，你可能正在评估是用 LangGraph 还是 AutoGen 来构建多 Agent 协同流，或者在调试大模型 API 的 Top-p 采样参数，试图让生成的回答既准确又具有随机性。甚至，在业余时间，你可能在设计一款解决自己痛点的小工具——比如一个用来清理、分类和管理繁杂书签的浏览器插件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这些工作有一个共同点：它们都是极其复杂的、高度依赖上下文的、开放性的问题。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;而在真实的工作环境中，我们解决这些问题依靠的是什么？&lt;/p&gt;
&lt;p&gt;1.&lt;strong&gt;查阅文档与搜索能力：&lt;/strong&gt; 我们有 Google、有官方文档、有开源社区，甚至现在还有 AI 助手。&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;调试与试错能力：&lt;/strong&gt; 我们通过打日志、单步调试、看监控指标来定位问题。&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;架构视野与经验直觉：&lt;/strong&gt; 我们知道什么时候该用单例模式，什么时候该用工厂方法；我们知道在高并发下如何设计缓存策略，如何保证数据一致性。&lt;/p&gt;
&lt;p&gt;4.&lt;strong&gt;沟通与协作：&lt;/strong&gt; 我们需要阅读别人的代码，也需要让别人看懂我们的设计。&lt;/p&gt;
&lt;p&gt;反观 LeetCode 面试，它创造了一个极其不真实的&lt;strong&gt;无菌实验室环境&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;●题目边界清晰，输入输出明确。&lt;/p&gt;
&lt;p&gt;●只有单一的“最优解”（通常是时间复杂度和空间复杂度的极限）。&lt;/p&gt;
&lt;p&gt;●不允许查阅文档，甚至不允许使用趁手的 IDE（有时只能在网页的纯文本框里写代码）。&lt;/p&gt;
&lt;p&gt;●偏离日常使用的技术栈（你可能用 Python 写了十几年业务，却要用 C++ 的思维去考虑指针和内存管理）。&lt;/p&gt;
&lt;p&gt;这就像是要求一个现代战争中的王牌飞行员，在面试时去比拼谁的射箭准头更好。它考察的不是“解决问题的能力”，而是“在极其受限条件下的默写能力”。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="二-刷题面试正在惩罚真正有经验的老兵"&gt;&lt;a href="#%e4%ba%8c-%e5%88%b7%e9%a2%98%e9%9d%a2%e8%af%95%e6%ad%a3%e5%9c%a8%e6%83%a9%e7%bd%9a%e7%9c%9f%e6%ad%a3%e6%9c%89%e7%bb%8f%e9%aa%8c%e7%9a%84%e8%80%81%e5%85%b5" class="header-anchor"&gt;&lt;/a&gt;二、 刷题面试，正在惩罚真正有经验的“老兵”
&lt;/h3&gt;&lt;p&gt;在软件开发领域，经验是一笔巨大的财富。一个拥有 10 年、15 年工作经验的研发架构师，他最大的价值并不在于写代码的速度有多快，而在于他&lt;strong&gt;踩过足够多的坑&lt;/strong&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;然而，当这位资深架构师带着一身的实战本领走进面试房间时，等待他的却是一道“动态规划（DP）”的 Hard 题。&lt;/p&gt;
&lt;p&gt;这是一种极大的资源浪费。一个能在生产环境中稳稳掌控全局、能设计出高可用 AI 基础设施、能带领团队攻坚克难的资深人才，仅仅因为最近几个月忙于项目交付、或者忙于应对生活中的变故（比如寻找新机会、照顾家庭），没有抽出几百个小时去死记硬背算法题库，就被无情地贴上“技术不过关”的标签淘汰出局。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这种现象导致了一个极其荒谬的倒挂：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;那些刚刚毕业、没有写过一行生产环境代码、不懂得什么是持续集成、不知道如何进行线上排障的学生，只要花三个月把 LeetCode 刷个滚瓜烂熟，就能在面试中大杀四方；而那些真正在一线扛过枪、打过仗，能够解决复杂工程灾难的老兵，却在白板前因为忘记了一个状态转移方程而涨红了脸。&lt;/p&gt;
&lt;p&gt;企业以为自己招到了“绝顶聪明”的天才，结果新人一入职，面对极其复杂的微服务依赖和一团乱麻的业务逻辑，立刻束手无策。因为真实的业务系统里，没有人会为你准备好整洁的 &lt;code&gt;ListNode&lt;/code&gt; 或者 &lt;code&gt;TreeNode&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="三-算法题面试的本质一场低效的智商服从性测试"&gt;&lt;a href="#%e4%b8%89-%e7%ae%97%e6%b3%95%e9%a2%98%e9%9d%a2%e8%af%95%e7%9a%84%e6%9c%ac%e8%b4%a8%e4%b8%80%e5%9c%ba%e4%bd%8e%e6%95%88%e7%9a%84%e6%99%ba%e5%95%86%e6%9c%8d%e4%bb%8e%e6%80%a7%e6%b5%8b%e8%af%95" class="header-anchor"&gt;&lt;/a&gt;三、 算法题面试的本质：一场低效的“智商服从性测试”
&lt;/h3&gt;&lt;p&gt;为什么即便怨声载道，这么多公司依然痴迷于 LeetCode 面试？很多面试官会辩解说：“算法题能考察候选人的聪明程度和逻辑思维。”&lt;/p&gt;
&lt;p&gt;这其实是一个伪命题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 算法题早就不测智商了，它只测“准备度”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在互联网早期，用算法题面试确实能筛选出一些思维敏捷的人，因为那时没有题库。但现在，LeetCode 已经有上千道题，“面经”满天飞。面试不仅变成了开卷考试的闭卷化，更变成了一门应试产业。能解出 Hard 题，往往不意味着你绝顶聪明，只意味着你刷到过原题，或者你花了大把时间去背诵套路。这充其量是一场“服从性测试”——看候选人愿不愿意为了这份工作去吃毫无意义的苦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 忽视了工程中最关键的“可维护性”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在 LeetCode 的评价体系里，“代码跑得快”是唯一的真理。哪怕你的代码里全是 &lt;code&gt;i&lt;/code&gt;, &lt;code&gt;j&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt;, &lt;code&gt;dp&lt;/code&gt;, &lt;code&gt;res&lt;/code&gt; 这种毫无语义的变量名，哪怕你的逻辑晦涩难懂如天书，只要能 AC（Accepted），你就是赢家。&lt;/p&gt;
&lt;p&gt;但在实际工程中，这种代码是灾难。好的工程师写出的代码是给人看的，其次才是给机器执行的。如果你的代码在生产环境中出了 Bug，同事半夜被叫醒排查，看到满屏追求极致技巧却毫无注释的“炫技代码”，他大概率会在心里把你骂上一万遍。LeetCode 培养出的“做题家”思维，与团队协作所需的工程素养往往是背道而驰的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 面试官的“安全牌”与偷懒。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;其实，很多面试官也根本不知道该怎么面试。对他们来说，从题库里随机抽一道题扔给候选人，是最省事、最没有风险的做法。如果你没写出来，那是你不行，面试官不需要承担招错人的责任。这种做法掩盖了面试官自身架构视野和识人能力的匮乏。要深入了解一个人的项目经验、技术深度和系统设计能力，需要面试官投入极大的精力和极高的技术水平去进行深度的技术探讨，而“考一道题”则轻易地把压力全抛给了候选人。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="四-如何打破僵局回归工程本质的面试方法"&gt;&lt;a href="#%e5%9b%9b-%e5%a6%82%e4%bd%95%e6%89%93%e7%a0%b4%e5%83%b5%e5%b1%80%e5%9b%9e%e5%bd%92%e5%b7%a5%e7%a8%8b%e6%9c%ac%e8%b4%a8%e7%9a%84%e9%9d%a2%e8%af%95%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;四、 如何打破僵局：回归工程本质的面试方法
&lt;/h3&gt;&lt;p&gt;批判之后，我们需要建设。如果不考 LeetCode，我们该怎么筛选优秀的软件工程师？真正的面试，应该是一场对日常工作的高度模拟。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 结对编程 (Pair Programming)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不要让候选人在白板上写代码，给他一台配置好 IDE 的电脑。面试官准备一个真实但简化过的业务小项目，或者直接在公司的一个开源代码分支上，两人结对协作。&lt;/p&gt;
&lt;p&gt;●“我们现在有一个 Python 的服务端，用 FastAPI 写的，现在需要增加一个中间件来做简单的限流，你打算怎么做？”&lt;/p&gt;
&lt;p&gt;●允许候选人查阅文档，允许使用 Google。&lt;/p&gt;
&lt;p&gt;●观察他的编码习惯、他对框架的熟悉程度、他如何拆解问题，以及更重要的——他如何与你沟通和协作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 代码审查 (Code Review)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;给候选人一段存在各种“坑”的代码（可以是以前团队写出的真实烂代码，隐去敏感信息）。这段代码可能存在并发竞争、内存泄漏、或者设计模式的滥用。&lt;/p&gt;
&lt;p&gt;让候选人进行 Code Review。优秀的工程师能立刻嗅出代码中的“坏味道”，并提出合理的重构建议。这比让他默写快速排序要有效得多。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 深度系统设计与项目复盘&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;抛弃那些假大空的“如何设计一个推特”的八股文。让候选人深度讲解他简历中最自豪的一个项目。&lt;/p&gt;
&lt;p&gt;●“你在简历中提到主导了容器化改造，能画一下当时的 Kubernetes 架构图吗？”&lt;/p&gt;
&lt;p&gt;●“在使用 Ingress 和服务网格（比如 APISIX 或 Istio）时，你们遇到了什么性能瓶颈？是如何排查的？”&lt;/p&gt;
&lt;p&gt;●“你提到在做 AI 相关的研发，在整合底层大模型接口时，你们是如何处理长上下文带来的延迟问题和 token 消耗的？”&lt;/p&gt;
&lt;p&gt;通过深度的追问，直到触及他的知识边界。真正的行家，在谈论自己亲手一砖一瓦建起来的系统时，眼里是有光的，细节是经得起推敲的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 聊聊他创造的“小玩意儿”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个真正的工程师，往往是对技术充满热情的创造者。与其问算法，不如问问他平时都在折腾什么。如果他告诉你，他因为受不了浏览器书签太乱，正在自己设计开发一个管理书签的插件；或者他为了解某种新技术栈，自己搭了一个爬虫和数据展示网站。请让他展示一下！这种对痛点的敏锐察觉和动手解决问题的能力，是任何算法题都无法衡量出的核心特质。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="五-结语放过工程师也放过企业自己"&gt;&lt;a href="#%e4%ba%94-%e7%bb%93%e8%af%ad%e6%94%be%e8%bf%87%e5%b7%a5%e7%a8%8b%e5%b8%88%e4%b9%9f%e6%94%be%e8%bf%87%e4%bc%81%e4%b8%9a%e8%87%aa%e5%b7%b1" class="header-anchor"&gt;&lt;/a&gt;五、 结语：放过工程师，也放过企业自己
&lt;/h3&gt;&lt;p&gt;技术招聘走到今天“无算法不面试”的地步，是整个行业的悲哀。它消耗了工程师们原本可以用来学习新框架、钻研底层原理、甚至陪伴家人的宝贵精力；它也让企业错失了大量踏实肯干、经验丰富的实战派人才。&lt;/p&gt;
&lt;p&gt;编程，是一门结合了逻辑、工程、设计甚至艺术的创造性活动。它不该被简化为一场机械的背诵比赛。&lt;/p&gt;
&lt;p&gt;作为面试官，下次当你准备掏出一道 LeetCode Hard 题时，不妨停下来问问自己：“这道题，真的能帮我找到那个能和我并肩作战、一起扛住双十一流量洪峰、一起在深夜排查诡异 Bug 的可靠队友吗？”&lt;/p&gt;
&lt;p&gt;如果不能，请放下那道该死的算法题，和候选人像真正的工程师一样，聊聊真实的架构，看看真实的代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把时间还给工程，把尊严还给工程师。&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>全程0人工写代码！干掉低级码农的不是大模型</title><link>https://xiaobox.github.io/p/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/</link><pubDate>Tue, 24 Feb 2026 03:46:39 +0000</pubDate><guid>https://xiaobox.github.io/p/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/cover.jpg" alt="Featured image of post 全程0人工写代码！干掉低级码农的不是大模型" /&gt;&lt;h1 id="全程0人工写代码干掉低级码农的不是大模型"&gt;&lt;a href="#%e5%85%a8%e7%a8%8b0%e4%ba%ba%e5%b7%a5%e5%86%99%e4%bb%a3%e7%a0%81%e5%b9%b2%e6%8e%89%e4%bd%8e%e7%ba%a7%e7%a0%81%e5%86%9c%e7%9a%84%e4%b8%8d%e6%98%af%e5%a4%a7%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;全程0人工写代码！干掉低级码农的不是大模型
&lt;/h1&gt;&lt;p&gt;在当前全行业的 AI 辅助编程浪潮中，大多数工具仍停留在“交互式伴游”阶段，而支付巨头 Stripe 却打造了一套完全无人值守的端到端代码智能体——“小黄人”（Minions）&lt;/p&gt;
&lt;p&gt;小黄人是一个独立打工的“数字员工”。目前的惊人数据是：在 Stripe 内部，&lt;strong&gt;每周有超过 1300 个由小黄人完全生成的 Pull Requests（合并请求）被成功合并。这些代码在最终阶段会经过人类审查，但其中不包含任何人类编写的代码。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更具挑战的是，Stripe 的代码库高达数亿行，主要使用较冷门的带有 Sorbet 类型的 Ruby 语言，且包含大量 LLM 根本没见过的大型内部自研库。此外，这些代码每年要处理超过 1 万亿美元的支付量，合规与容错要求极高。&lt;/p&gt;
&lt;p&gt;Stripe 是如何让 LLM 驾驭如此庞大且复杂的企业级代码库的？核心答案在于极其强大的定制化工程脚手架。&lt;/p&gt;
&lt;p&gt;以下是小黄人能高效运转的四大核心技术拆解。&lt;/p&gt;
&lt;h3 id="1-极致标准化的预热沙盒devboxes"&gt;&lt;a href="#1-%e6%9e%81%e8%87%b4%e6%a0%87%e5%87%86%e5%8c%96%e7%9a%84%e9%a2%84%e7%83%ad%e6%b2%99%e7%9b%92devboxes" class="header-anchor"&gt;&lt;/a&gt;1 极致标准化的预热沙盒（Devboxes）
&lt;/h3&gt;&lt;p&gt;要让全自动 Agent 大规模并行工作，绝不能让它们跑在开发者杂乱的本地笔记本上。Stripe 的解法是直接复用为人类工程师打造的云端开发机（Devboxes）。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;10 秒极速“热启动”&lt;/strong&gt;：这些 Devbox 是 AWS EC2 实例。Stripe 预先配置并预热了一个资源池，里面已经克隆好了巨大的 Git 仓库，预热了 Bazel 构建缓存和类型检查缓存，甚至启动了持续运行的代码生成服务。因此，只要 10 秒钟，小黄人就能拿到一台随时可以运行测试和修改代码的机器。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;免弹窗的完全提权&lt;/strong&gt;：为了让小黄人在后台静默运行，它需要无缝执行各种 Shell 命令。因为 Devbox 运行在与生产资源和外部互联网隔离的 QA 环境中，爆炸半径被严格限制，所以系统敢于跳过人类权限确认弹窗，给予小黄人完整的执行自由。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;解决并发冲突&lt;/strong&gt;：如果用本地环境，并发运行多个 Agent 需要处理复杂的 git worktrees（这在 Stripe 的庞大代码库中无法扩展）。而在云端，工程师可以轻易地同时为 6 个不同的任务启动 6 个分配了独立 Devbox 的小黄人，实现物理级别的完美隔离&lt;/p&gt;
&lt;h3 id="2--蓝图编排blueprints将大模型装进确定性的盒子里"&gt;&lt;a href="#2--%e8%93%9d%e5%9b%be%e7%bc%96%e6%8e%92blueprints%e5%b0%86%e5%a4%a7%e6%a8%a1%e5%9e%8b%e8%a3%85%e8%bf%9b%e7%a1%ae%e5%ae%9a%e6%80%a7%e7%9a%84%e7%9b%92%e5%ad%90%e9%87%8c" class="header-anchor"&gt;&lt;/a&gt;2 “蓝图”编排（Blueprints）：将大模型装进确定性的盒子里
&lt;/h3&gt;&lt;p&gt;常规的 Agent 往往采用开放的循环机制，任由 LLM 自己决定下一步调什么工具，这极易导致出错和浪费 Token。 Stripe 创造性地引入了**“蓝图”（Blueprints）**状态机机制。蓝图将整个工作流视为一张图，将 LLM 的创造力与确定性的系统代码交织在一起：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;确定性节点 vs Agent 节点&lt;/strong&gt;：在蓝图中，像“实现具体任务”或“修复 CI 失败”是让 LLM 自由发挥的 Agent 节点；但是，像“运行配置好的 Linter”或“推送 Git 变更”则是完全不调用 LLM 的纯代码确定性节点。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;底线兜底&lt;/strong&gt;：这意味着小黄人无法绕过代码格式化等硬性规范。把大模型“关进受控的盒子里”，不仅极大地节省了 Token，还从系统层面提高了整体可靠性。各团队甚至可以编写自定义的蓝图，来处理复杂的、LLM 辅助的代码库迁移任务&lt;/p&gt;
&lt;h3 id="3-极其克制的上下文投喂规则文件与-toolshed"&gt;&lt;a href="#3-%e6%9e%81%e5%85%b6%e5%85%8b%e5%88%b6%e7%9a%84%e4%b8%8a%e4%b8%8b%e6%96%87%e6%8a%95%e5%96%82%e8%a7%84%e5%88%99%e6%96%87%e4%bb%b6%e4%b8%8e-toolshed" class="header-anchor"&gt;&lt;/a&gt;3 极其克制的上下文投喂：规则文件与 Toolshed
&lt;/h3&gt;&lt;p&gt;面对上亿行代码，如果把所有全局规则都塞给大模型，上下文窗口瞬间就会被撑爆。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;按目录生效的局部规则&lt;/strong&gt;：Stripe 几乎只使用作用于特定子目录或文件模式的规则文件。他们巧妙地复用了人类工程师为 Cursor 编写的规则格式。这样，工程师在日常开发中沉淀的最佳实践，小黄人（以及 Claude Code）在遍历文件系统时就能直接动态读取并学习。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;MCP 工具棚（Toolshed）&lt;/strong&gt;：小黄人通过模型上下文协议（MCP）获取网络信息（工单、文档、代码搜索等）。Stripe 建立了一个包含近 500 个内部与 SaaS 工具的中央服务器 Toolshed。但为了防止 Agent 分心，系统每次只会为小黄人精心挑选一个“小巧而高度相关”&lt;/p&gt;
&lt;h3 id="4-反馈左移shifting-feedback-left极速纠错循环"&gt;&lt;a href="#4-%e5%8f%8d%e9%a6%88%e5%b7%a6%e7%a7%bbshifting-feedback-left%e6%9e%81%e9%80%9f%e7%ba%a0%e9%94%99%e5%be%aa%e7%8e%af" class="header-anchor"&gt;&lt;/a&gt;4 反馈左移（Shifting Feedback Left）：极速纠错循环
&lt;/h3&gt;&lt;p&gt;无人值守 Agent 成功的关键在于能否实现自我闭环修正。Stripe 为其构建了多层极速反馈循环：&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;5 秒内的本地验证&lt;/strong&gt;：在小黄人把代码推送到 CI 之前，Devbox 上的后台守护进程会通过启发式算法自动运行相关的 Linter 和类型检查。这个本地节点耗时不到 5 秒，让小黄人在本地极速完成语法纠错。&lt;/p&gt;
&lt;p&gt;●&lt;strong&gt;克制的 CI 测试轮数&lt;/strong&gt;：Stripe 的 CI 拥有超过 300 万个测试用例。推送到 CI 后，系统会运行相关测试，并自动应用已有的修复脚本（Autofixes）。如果还有未修复的错误，报错会发回给小黄人。但为了平衡算力成本、时间与边际收益，小黄人最多只被允许进行 1 到 2 次的 CI 循环试错。之后无论成败，都会将其移交给人类处理，防止其陷入昂贵的死循环&lt;/p&gt;
&lt;h2 id="给我的启示"&gt;&lt;a href="#%e7%bb%99%e6%88%91%e7%9a%84%e5%90%af%e7%a4%ba" class="header-anchor"&gt;&lt;/a&gt;给我的启示
&lt;/h2&gt;&lt;p&gt;基于 Stripe 公开的这些技术细节，我得出了以下几点关于 AI 研发提效的深刻感悟：&lt;/p&gt;
&lt;p&gt;1.“&lt;strong&gt;对人类工程师有益的基础设施，对 LLM 同样有益&lt;/strong&gt;” 这是 Stripe 整个小黄人项目最核心的哲学。Stripe 并没有为了做 AI Agent 去凭空造一套新基建，而是直接将 AI 接入了他们多年打磨的 Devbox 环境、Pre-push hooks 和自动化测试管线中。这给所有企业的启示是：AI Agent 的天花板，取决于你现有工程基础设施的底座。 如果你的人类工程师本地环境经常崩溃、缺乏单测覆盖率、文档陈旧，那么大模型也一样会在这些泥坑里寸步难行。过去在人类开发者体验（Developer Productivity）上的每一分投资，都会在 AI 时代转化为巨大的复利回报。&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;放弃追求纯粹的“全能 Agent”&lt;/strong&gt;，用“蓝图”管控不确定性 目前业界过度迷恋让一个 Agent 自主解决所有问题。但 Stripe 的蓝图（Blueprints）设计极其务实：能用一行 Bash 脚本或 Linter 稳定解决的问题（如代码格式化、Git 提交流程），就绝对不让 LLM 消耗 Token 去“推理”。在企业级生产环境中，**混合架构（确定性代码逻辑 + 局部受控的 LLM 节点）**才是保证系统高可靠性（SLA）的唯一出路。&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;工程师的日常工作流正在被重塑&lt;/strong&gt; ，在 Stripe，触发小黄人的方式极度符合人体工程学：工程师可以直接在 Slack 的讨论线程里@小黄人，或者在内部的“CI 间歇性失败（Flaky test）”工单中点击一个按钮启动它。我们可以预见，未来的高级工程师将越来越像一个“包工头”：他们在值班（On-call）时并行启动几十个小黄人去处理琐碎的 Bug，自己则专注于审查 PR、设计架构，以及维护和编写能够指导小黄人的局部规则（Cursor rules）。工程师不再逐行敲击代码，而是定义意图并管理基础设施。&lt;/p&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-02-24-quan-cheng-0-ren-gong-xie-dai-ma-gan-diao-di-ji-ma-nong-de-b/001-a01d1a80.png"&gt;&lt;/p&gt;
&lt;h2 id="参考"&gt;&lt;a href="#%e5%8f%82%e8%80%83" class="header-anchor"&gt;&lt;/a&gt;参考
&lt;/h2&gt;&lt;p&gt;●https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents&lt;/p&gt;
&lt;p&gt;●https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2&lt;/p&gt;</description></item><item><title>AI 模型推理平台架构设计与实践</title><link>https://xiaobox.github.io/p/2025-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/</link><pubDate>Sun, 30 Nov 2025 04:11:10 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/cover.jpg" alt="Featured image of post AI 模型推理平台架构设计与实践" /&gt;&lt;h1 id="一背景"&gt;&lt;a href="#%e4%b8%80%e8%83%8c%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;一、背景
&lt;/h1&gt;&lt;h2 id="为什么要搞推理平台"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e6%90%9e%e6%8e%a8%e7%90%86%e5%b9%b3%e5%8f%b0" class="header-anchor"&gt;&lt;/a&gt;为什么要搞推理平台
&lt;/h2&gt;&lt;p&gt;从实用的角度讲，搞推理平台的目的就是为了给部署、运行、维护模型打造一个良好的 “环境”。&lt;/p&gt;
&lt;h2 id="为什么要自己部署运行维护模型呢-全部用-api-不行吗"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e8%87%aa%e5%b7%b1%e9%83%a8%e7%bd%b2%e8%bf%90%e8%a1%8c%e7%bb%b4%e6%8a%a4%e6%a8%a1%e5%9e%8b%e5%91%a2-%e5%85%a8%e9%83%a8%e7%94%a8-api-%e4%b8%8d%e8%a1%8c%e5%90%97" class="header-anchor"&gt;&lt;/a&gt;为什么要自己部署、运行、维护模型呢？ 全部用 API 不行吗？
&lt;/h2&gt;&lt;p&gt;这个问题涉及到&lt;strong&gt;模型的功能分化&lt;/strong&gt;。简单来讲，传统的 LLM 基座模型是很强，类似全能型选手，但在企业落地场景下并不完全适用。企业需要的是 ROI 极高的方案，企业场景下会考虑并发、延迟、成本等非常具体的指标。所以用满足单一场景且成本极低的小模型 + 基座大模型是比较务实的选择。&lt;/p&gt;
&lt;h2 id="一定要有-gpu-显卡资源吗"&gt;&lt;a href="#%e4%b8%80%e5%ae%9a%e8%a6%81%e6%9c%89-gpu-%e6%98%be%e5%8d%a1%e8%b5%84%e6%ba%90%e5%90%97" class="header-anchor"&gt;&lt;/a&gt;一定要有 GPU （显卡资源）吗？
&lt;/h2&gt;&lt;p&gt;不一定，有些模型在 CPU 也跑的很好。 比如 all-MiniLM-L6-v2，但绝大多数模型是需要 GPU 的。&lt;/p&gt;
&lt;h1 id="二资源规划与集群架构"&gt;&lt;a href="#%e4%ba%8c%e8%b5%84%e6%ba%90%e8%a7%84%e5%88%92%e4%b8%8e%e9%9b%86%e7%be%a4%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;二、资源规划与集群架构
&lt;/h1&gt;&lt;p&gt;我们假设你的生产环境是如下图所示的 K8S 集群环境&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/001-35230c44.png"&gt;&lt;/p&gt;
&lt;h2 id="不止-k8s"&gt;&lt;a href="#%e4%b8%8d%e6%ad%a2-k8s" class="header-anchor"&gt;&lt;/a&gt;不止 k8s
&lt;/h2&gt;&lt;p&gt;对于一个 “&lt;strong&gt;模型在线推理平台（Serving 平台）&lt;/strong&gt;”，光靠 k8s 是不够的。&lt;/p&gt;
&lt;p&gt;如果光有 k8s 我们会遇到以下几个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;资源利用率极低，成本高昂&lt;/strong&gt;：Kubernetes 的原生调度单位是 Pod。它不理解 “模型” 这个概念，也不知道如何在一张 GPU 上高效地运行多个模型。那就意味着一个模型会独占一张 GPU 卡。中小模型的计算量不大，大部分时间里，这个 Pod 和 GPU 都是空闲的。当模型数量增加时（例如 10 个或 50 个模型），成本会呈线性增长，变得非常昂贵。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运维复杂度极高&lt;/strong&gt;：原生 Kubernetes 缺少一个更高层次的抽象来描述 “模型服务” 这个场景，必须手动组合多个底层资源来完成一个任务（手动编写和维护一套复杂的 Kubernetes YAML 文件（Deployment, Service, HorizontalPodAutoscaler 等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺乏标准化的模型服务能力&lt;/strong&gt;：这些都是应用层的逻辑，原生的 Kubernetes 并不直接提供这些开箱即用的功能&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;如何进行 A / B 测试或金丝雀发布（Canary Rollouts）来平滑升级模型？&lt;/li&gt;
&lt;li&gt;如何处理模型的预处理和后处理逻辑？&lt;/li&gt;
&lt;li&gt;如何监控模型的 QPS、延迟、成功率等指标？ &lt;strong&gt;可观测性不足（难以按 “模型维度” 看指标）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;流量高峰时如何自动扩容，没有流量时如何缩容以节省成本？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kserve"&gt;&lt;a href="#kserve" class="header-anchor"&gt;&lt;/a&gt;KServe
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;Standardized Distributed Generative and Predictive AI Inference Platform for Scalable, Multi-Framework Deployment on Kubernetes&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;为了解决上述问题，社区催生了专门针对 Kubernetes 的模型服务平台，KServe 就是其中的佼佼者。&lt;strong&gt;它通过引入一个名为 InferenceService 的自定义资源（CRD）来解决这些问题。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解决资源利用率问题&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;模型复用&lt;/strong&gt; (Multi-Model Serving)：KServe 可以与 NVIDIA Triton Inference Server 或 TorchServe 等高性能推理服务器集成。这些服务器支持在 &lt;strong&gt;单个 Pod 和单个 GPU 上加载和运行多个模型&lt;/strong&gt;。当请求进来时，由推理服务器动态地将计算任务分配给 GPU。这样，多个中小模型就可以共享一张 GPU，极大提高资源利用率。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动缩容至零&lt;/strong&gt; (Scale to Zero)：当一个模型在一段时间内没有收到任何请求时，KServe 可以自动将该模型的 Pod 缩减到 0。当新的请求到来时，它又能快速拉起一个新的 Pod 来提供服务。这对于流量不稳定的中小模型来说，是巨大的成本节省。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解决运维复杂度问题&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;单一抽象&lt;/strong&gt; (InferenceService)：不再需要编写 Deployment, Service 等一大堆 YAML。只需要定义一个 InferenceService 对象，在里面声明用的是什么框架（TensorFlow, PyTorch, Triton 等）以及模型的存储路径（如 S3）。KServe 会自动创建和管理所有底层的 Kubernetes 资源。这极大地简化了运维工作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解决标准化服务能力问题&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开箱即用的高级部署&lt;/strong&gt;：在 InferenceService 的配置中，只需修改几行代码，就可以轻松实现金丝雀发布。例如，您可以指定将 10% 的流量发送到新模型，90% 的流量发送到旧模型，验证通过后再全量切换。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求日志、监控指标&lt;/strong&gt;：KServe 自动提供了标准化的接口和可观测性指标，方便接入 Prometheus、Grafana 等监控系统。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;推理图谱&lt;/strong&gt; (Inference Graph)：对于需要多个模型串联（例如预处理 -&amp;gt; 模型 A -&amp;gt; 后处理 -&amp;gt; 模型 B）的复杂场景，KServe 也提供了标准化的解决方案。&lt;/p&gt;
&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-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/002-febeb6af.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对于 “在 Kubernetes 上部署多个中小模型” 这个场景， KServe 是目前最好、最主流的开源解决方案之一。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直接采用 KServe 将会极大降低成本、简化管理、并提升部署的稳定性和灵活性，让我们可以更专注于模型算法本身，而不是底层的基础设施。&lt;/p&gt;
&lt;h3 id="kserve-架构"&gt;&lt;a href="#kserve-%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;KServe 架构
&lt;/h3&gt;&lt;p&gt;KServe 架构概览：&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/003-de90c2f0.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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/004-3db13bc5.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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/005-af8372cf.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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/006-dd47cccc.png"&gt;&lt;/p&gt;
&lt;p&gt;模型 runtime 支持：&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/007-d3f9de7c.png"&gt;&lt;/p&gt;
&lt;h3 id="vllm-和-triton"&gt;&lt;a href="#vllm-%e5%92%8c-triton" class="header-anchor"&gt;&lt;/a&gt;vLLM 和 Triton
&lt;/h3&gt;&lt;p&gt;从 KServe 的运行体系图中可以看到在推理层面，大致有两种最流行的软件，一个是 vLLM，一个是 Triton&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;vLLM&lt;/strong&gt; 是 LLM 专用推理引擎（只跑 Transformer，极快但单一）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Triton&lt;/strong&gt; 通用推理平台（CV/NLP/LLM/推荐都能跑，全能但略重）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 KServe 里，两者的选择就是： “要极速跑 LLM，还是要一车拉所有模型” 。在实践中，KServe 是一个统一平台，可以支持我们按需选引擎，&lt;strong&gt;所以不用 all in 其中任何一种，比较灵活、方便。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="三部署思路"&gt;&lt;a href="#%e4%b8%89%e9%83%a8%e7%bd%b2%e6%80%9d%e8%b7%af" class="header-anchor"&gt;&lt;/a&gt;三、部署思路
&lt;/h1&gt;&lt;h2 id="架构"&gt;&lt;a href="#%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;架构
&lt;/h2&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/008-4c464ba2.png"&gt;&lt;/p&gt;
&lt;p&gt;这里我们需要解释几个问题&lt;/p&gt;
&lt;h3 id="1-整体链路是谁在做自动扩缩容"&gt;&lt;a href="#1-%e6%95%b4%e4%bd%93%e9%93%be%e8%b7%af%e6%98%af%e8%b0%81%e5%9c%a8%e5%81%9a%e8%87%aa%e5%8a%a8%e6%89%a9%e7%bc%a9%e5%ae%b9" class="header-anchor"&gt;&lt;/a&gt;1. 整体链路是谁在做自动扩缩容？
&lt;/h3&gt;&lt;p&gt;在 KServe + Knative 模式 下，职责大致是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;KServe&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写 InferenceService CRD（YAML）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;KServe Controller 把它翻译成一个 Knative Service（和一些 K8s 资源）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;同时通过 annotations / 字段把我们希望的 autoscaling 配置写进去&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Knative Serving&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个 Revision&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个对应的 Deployment（里面的 Pod 跑模型容器）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个自动伸缩器：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要么是 KPA（Knative Pod Autoscaler）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要么是一个真正的 Kubernetes HPA（如果配置了 autoscaling.knative.dev/class: hpa.autoscaling.knative.dev）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;接管 Knative Service，创建：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Istio&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;负责入口网关、路由、mTLS 等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把请求导入到 Knative 的 activator / queue-proxy 上&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;为 Knative 提供 HTTP 请求 metrics（QPS、并发等）&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;Knative 的 KPA 或 HPA，再通过 Deployment 控制最终 Pod 数量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;KServe 只是 “声明模型 + 帮我们写好 Knative 配置”，并不直接操作 replicas&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-enable-scale-to-zero-true--的含义是什么"&gt;&lt;a href="#2-enable-scale-to-zero-true--%e7%9a%84%e5%90%ab%e4%b9%89%e6%98%af%e4%bb%80%e4%b9%88" class="header-anchor"&gt;&lt;/a&gt;2. enable-scale-to-zero: &amp;ldquo;true&amp;rdquo; 的含义是什么？
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# 文件： knative-config.yaml
&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;enable-scale-to-zero: &amp;#34;true&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 Knative 的 config（比如 config-autoscaler）里，表示 允许某个 Knative Service 被 KPA 缩到 0 个 Pod。 再配合 InferenceService / Knative Service 上的配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若没有设置 minScale / minReplicas，默认允许从 0 → N&lt;/li&gt;
&lt;li&gt;若在 InferenceService 里（或 annotations）配了 minReplicas: 1 或 autoscaling.knative.dev/minScale: &amp;ldquo;1&amp;rdquo;，则不会缩到 0，而是至少保留 1 个 Pod（即 1 块 GPU 一直常驻）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;缩到 0 的流程大致是：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一段时间内没有请求（由 Knative 的 autoscaler 统计）&lt;/li&gt;
&lt;li&gt;KPA 认为可以缩减，就把 Deployment 的 replicas 降到 0&lt;/li&gt;
&lt;li&gt;Pod 把 GPU 释放掉；节点上的 GPU 就空闲了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;从 0 唤醒：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;有新请求到达 Istio 网关 → 被路由到 Knative 的 Activator&lt;/li&gt;
&lt;li&gt;Activator 缓冲请求，并通知 autoscaler&lt;/li&gt;
&lt;li&gt;autoscaler 把 Deployment 从 0 扩到 1（或更多）个 Pod&lt;/li&gt;
&lt;li&gt;Pod 启动，模型加载进 GPU，处理缓存的请求（这就是冷启动）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="3-单模型-多-pod-如何占多机多卡"&gt;&lt;a href="#3-%e5%8d%95%e6%a8%a1%e5%9e%8b-%e5%a4%9a-pod-%e5%a6%82%e4%bd%95%e5%8d%a0%e5%a4%9a%e6%9c%ba%e5%a4%9a%e5%8d%a1" class="header-anchor"&gt;&lt;/a&gt;3. 单模型 多 Pod ，如何占多机多卡？
&lt;/h3&gt;&lt;p&gt;把上面的流程套到 GPU 上看就是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 每个推理 Pod 的容器请求&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&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="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2. K8s 调度时确保：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每个 Pod 分配到一个有空闲 GPU 的节点&lt;/li&gt;
&lt;li&gt;默认 nvidia.com / gpu 是「不可共享资源」，所以 1 Pod 独占 1 块卡&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3. 当 autoscaler 决定从 1 Pod 扩到 N Pod 时：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;K8s 再调度 N-1 个新的 Pod 到其他 GPU 节点&lt;/li&gt;
&lt;li&gt;最终你就是：同一个模型，多 Pod，分布在多台单卡机器上&lt;/li&gt;
&lt;li&gt;Istio / Knative 负责把请求均衡到这些 Pod 上&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. 当流量变小&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;autoscaler 把 replicas 从 N 缩回 1，甚至缩到 0&lt;/li&gt;
&lt;li&gt;对应地释放掉一部分 / 全部节点上的 GPU&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;/ul&gt;
&lt;ol&gt;
&lt;li&gt;单模型 + 单 Pod = 占用一台单卡机&lt;/li&gt;
&lt;li&gt;单模型 + 多 Pod = 水平扩展到多台单卡机，多卡并行处理请求&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;多 Pod 的自动扩缩容流程：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;决策逻辑在 Knative（KPA 或 HPA）这层&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;KServe 只是根据 InferenceService 的 spec &amp;amp; annotations 帮我们创建出合适的 Knative Service / autoscaler 配置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Istio 不做扩缩容决策，只负责网关和路由，同时为 Knative 提供 metrics / 流量通路&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;enable-scale-to-zero: &amp;ldquo;true&amp;rdquo; 是 Knative 的全局开关，允许在 InferenceService 里配置成真正可缩到 0 的无流量模型服务。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="面临的问题"&gt;&lt;a href="#%e9%9d%a2%e4%b8%b4%e7%9a%84%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;面临的问题
&lt;/h2&gt;&lt;p&gt;整个架构从水平扩容的角度讲是没有太大的问题，但当我们把视角切换到机器内部，看 pod 内部的情况，是有问题的，比如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个显卡 48G 显存，一个小模型可能只需要 10G 显示，但它独占了一张显示，这会造成资源的浪费&lt;/li&gt;
&lt;li&gt;当我只有一两个模型需要部署时候问题不大。浪费也不大，但如果我有多个小模型（单卡能放下）都需要同时部署，如果不仔细计算显卡的使用率，那么有可能造成大量的资源浪费。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="解决办法"&gt;&lt;a href="#%e8%a7%a3%e5%86%b3%e5%8a%9e%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;解决办法
&lt;/h3&gt;&lt;p&gt;对一个 LLM 来说，显存大致分三块：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;模型权重（weights）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运行时开销&lt;/strong&gt;（activations / 临时 buffer 等）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;KV Cache&lt;/strong&gt;（连续 batching 的关键，vLLM 会尽可能把剩余显存拿来做这个）VLLM Docs&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;vLLM 通过 &amp;ndash;gpu-memory-utilization 控制 “自己能用的显存占比”（默认 0.9），在这个额度内， 剩下的空间基本都会拿去做 KV Cache，以提升吞吐和并发。&lt;/p&gt;
&lt;p&gt;所以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果我们看到 “模型只占 10G”，&lt;strong&gt;很可能只是在低并发、短上下文下的一瞬间观感；&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;一旦并发、上下文长度、请求峰值上去，KV Cache 会吃掉大量显存，这时候那 “剩余的 30+ G” 就会逐步被用起来。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果在&lt;strong&gt;业务高峰期&lt;/strong&gt;，这几个指标都比较高（比如显存长期 &amp;gt;70%，KV cache 使用率也不低），那 “单模型独占一张卡” 并不浪费，而是在换 &lt;strong&gt;性能 &amp;amp; 稳定性&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;ol&gt;
&lt;li&gt;&lt;strong&gt;业务层合并：能不用多模型就别用多模型&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;能用 一个 “能力足够强” 的主模型 + Prompt / LoRA 搞定，就不要真部署 N 个完全独立的小模型。&lt;/li&gt;
&lt;li&gt;多数 “业务小模型” 的差异，其实是 “提示词 + 风格 + LoRA” 的区别，不一定非要上不同 base model。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;把单模型的吞吐吃满&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;利用 vLLM 的连续 batching，提高并发、适当增加最大上下文、控制 QPS，让 GPU 真正跑到比较高的利用率。&lt;/li&gt;
&lt;li&gt;我们已经有完整的 Prometheus / Grafana 看板方案，可以直接看 QPS、Token 吞吐、GPU Util、KV Cache 占用来调优。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;实在必须多模型同卡，再考虑 “共享 GPU” 技术&lt;/strong&gt;（下面会拆开说）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="共享-gpu-技术"&gt;&lt;a href="#%e5%85%b1%e4%ba%ab-gpu-%e6%8a%80%e6%9c%af" class="header-anchor"&gt;&lt;/a&gt;共享 GPU 技术
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Time-Slicing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;NVIDIA GPU Operator / k8s-device-plugin 提供的 Time-Slicing，本质是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;把一张物理 GPU 虚拟成多个 “replica” 资源&lt;/strong&gt;，Pod 申请 nvidia.com / gpu: 1 时，拿到的是其中一个 replica；&lt;/li&gt;
&lt;li&gt;底层靠 时间片轮转 在同一张卡上跑多个 Pod。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关键点（也是坑点）是：&lt;strong&gt;Time-Slicing 只切算力，不切显存，显存是共享的，没有隔离&lt;/strong&gt;。NVIDIA Docs 这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果多个 Pod 加起来申请 / 实际占用的显存 &amp;gt; 实际物理显存，就有概率 OOM；&lt;/li&gt;
&lt;li&gt;即使不 OOM，Page Fault / 内存碎片也会让延迟非常不稳定。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而 vLLM 非常依赖稳定且持续的显存做 KV Cache，Time-Slicing 没有显存隔离，很容易被别的 Pod 挤爆显存导致 OOM，所以&lt;strong&gt;不适合 vLLM&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MIG（Multi-Instance GPU）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MIG 的特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;真正把 &lt;strong&gt;一张 GPU 切成多个硬件隔离的 “小卡”&lt;/strong&gt;，每块有独立的显存、高带宽内存、缓存和计算核心&lt;/li&gt;
&lt;li&gt;适合需要 &lt;strong&gt;延迟可预测、多租户隔离&lt;/strong&gt; 的 LLM 推理场景&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但 MIG 只在 A100 / H100 / A30 等特定卡上存在，普通云上 L4、L40、T4、V100 这类要么不支持，要么支持非常有限。对于我们来说，&lt;strong&gt;也不适用&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ModelMesh&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;KServe 其实就内置了两种 “模型平台形态”：&lt;strong&gt;1. Single-Model Serving（单模型平台）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每个服务只跑一个模型；&lt;/li&gt;
&lt;li&gt;LLM / 大模型几乎都是走这一条（包括 vLLM Runtime）。&lt;strong&gt;2. Multi-Model Serving（基于 ModelMesh 的多模型平台）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;同一个模型服务器里可以放多模型，按需加载/卸载，适合一堆小模型共享有限卡的场景（比如 SKLearn/ONNX/OpenVINO 那些）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ModelMesh 适合「很多模型 + 访问稀疏」的场景，ModelMesh 的设计目标是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;管理 大量模型（&lt;strong&gt;几十、几百甚至更多&lt;/strong&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;很多模型 QPS 很低，没必要长时间常驻显存 / 内存&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过「按需加载 + LRU 驱逐」来平衡：&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;p&gt;另外，社区对 ModelMesh 的定位也比较明确：更偏向 “可伸缩多模型平台”，现在要把 LLM Runtime（特别是 vLLM）硬往 ModelMesh 里塞，是有一定探索和集成成本的，而且生态也还在演进中 &lt;a class="link" href="https://github.com/kserve/kserve/issues/4299" target="_blank" rel="noopener"
 &gt;https://github.com/kserve/kserve/issues/4299&lt;/a&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/009-719449fc.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果我们前期的目标只是「十个以内」的小模型，希望高利用率、简单稳定，所以可以先不用 ModelMesh，真正到模型数爆炸、并且很多模型很冷时，再考虑 ModelMesh 会更合适。尤其是当前的重点是 “先把核心 LLM 跑稳定 &amp;amp; 可观测 &amp;amp; 易扩容”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Triton + vLLM + 多模型同 Pod / 同 GPU&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以上方案都不太合适，于是我把目光投向了 Triton&lt;/p&gt;
&lt;p&gt;NVIDIA Triton 的能力是比较强的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;支持在同一台机器上&lt;strong&gt;多个模型 / 多个模型实例并行执行&lt;/strong&gt;，由 Triton 负责调度；NVIDIA Docs&lt;/li&gt;
&lt;li&gt;支持多种后端（TensorRT-LLM、PyTorch、ONNXRuntime、Python backend 等）；&lt;/li&gt;
&lt;li&gt;现在还有 &lt;strong&gt;官方的 vLLM backend&lt;/strong&gt;，可以在 Triton 里用 vLLM 做 LLM 推理。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从 GPU 视角看，Triton 做的事类似于：&lt;strong&gt;“一个进程负责管理很多模型，来了请求就把对应的 op 丢给 GPU，GPU 再在硬件层面做调度并发。” 但是：Triton 也不会神奇地帮我们 “切显存”—— 多个模型的权重 + KV Cache 依然是往同一个物理显存里塞。Triton 提供的是 “共享一块显存的多模型协调器”，不是 “把显存分成几块小卡” 的硬隔离器。&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/010-068205ed.png"&gt;&lt;/p&gt;
&lt;p&gt;因此：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Triton 不能像 MIG 一样说：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;“模型 A 只能用 16G，模型 B 只能用 8G，互相绝不会越界”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它顶多是：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过配置 + 调度让你 “尽量别把自己搞到 OOM”；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;但如果你把几个模型配置得都很激进，合起来 &amp;gt; 物理显存，照样可能 OOM，仅仅是更 “有迹可循”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;结合我们的实际情况，综合考虑，Triton 可以有以下几种组合姿势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Triton 只负责传统模型（embedding、CV、语音等），LLM 仍由独立 vLLM 服务跑&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;这时候 “一卡多模型” 主要是非 LLM 模型之间的事，LLM 是单卡独占或少量共享；&lt;/li&gt;
&lt;li&gt;对现在的 “私有化大模型平台” 来说，这是最现实、也最可控的一种搭配。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;Triton + vLLM backend，把 LLM 也塞进 Triton 的统一服务里&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;本质上还是 “一张卡一个 vLLM 引擎”，只是对外通过 Triton 统一暴露接口而已；&lt;/li&gt;
&lt;li&gt;多模型同卡时，显存依然一起抢；如果你试图放多个 LLM（哪怕是 7B SLM），很快就会撞上显存天花板，需要极其克制的 &amp;ndash;gpu-memory-utilization 和并发控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;Triton 内部多 LLM + 非 LLM 模型混合&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;这种组合在理论上可行，工程上可做，但对资源规划、监控、故障排查的要求会非常高；&lt;/li&gt;
&lt;li&gt;对现在来说，属于 “下一阶段再考虑” 的东西&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;综上，目前我们利用 Triton 采用第一种方式：负责传统模型（embedding、CV、语音等），LLM 仍由独立 vLLM 服务跑&lt;/strong&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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/011-66896efb.png"&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;上图是从 KServe 视角看的，如果从 k8s 视角，不同的 pod 还会有多副本扩容的情况。但每个 pod 都是独占 GPU。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Triton 多模型（非 LLM）分组方案&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;整体思路：&lt;strong&gt;1 GPU 1 Triton，多模型共用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在现有架构下，最自然的做法是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;每块 GPU 起一个 Triton Pod（由一个 InferenceService 管）&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这个 Triton Pod 里面的 &lt;strong&gt;model repository 里放多个非 LLM 模型&lt;/strong&gt;：embedding / rerank / CV / ASR…&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;KServe 只是负责：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;帮我们起 kserve-tritonserver 这个 runtime&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把远端（S3/MinIO/PVC）上的 Triton model repository 挂到 /models（或 /mnt/models）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;暴露统一的 HTTP / gRPC 入口（/v2/models//infer）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Triton 本身就是为「一台机上多个模型、多个实例并发」设计的：多个模型、多个实例可以在同一块卡上并发执行，通过 instance_group、dynamic_batching 来调度和吃满卡资源。NVIDIA Docs&lt;/p&gt;
&lt;p&gt;建议&lt;strong&gt;按业务域 + 性能特性分组&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一组：文本向量 + rerank（text-embedder / text-reranker）&lt;/li&gt;
&lt;li&gt;一组：CV / OCR / ASR（图像 &amp;amp; 语音） 这样：&lt;/li&gt;
&lt;li&gt;同一组内模型的 batch 维度、输入大小比较接近，Triton 的 dynamic batching 比较好调；&lt;/li&gt;
&lt;li&gt;资源隔离更清晰：文本这组爆了不会影响语音那组。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是一套完整配置样例（可以先从「所有非 LLM 都放一个组」开始，后面再拆分）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分组示例&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Triton 模型仓库（model repository）结构示例，Triton 要求的模型仓库布局类似这样：&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; s3://your-bucket/triton-nonllm-repo/
&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;├── text-embedding-e5-small/
&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;│ ├── config.pbtxt
&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/
&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;│ └── model.onnx
&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;├── text-rerank-msmarco/
&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;│ ├── config.pbtxt
&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;│ └── 1/
&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;│ └── model.onnx
&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;├── vision-cls-resnet50/
&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;│ ├── config.pbtxt
&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;│ └── 1/
&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;│ └── model.onnx
&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;├── asr-conformer/
&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;│ ├── config.pbtxt
&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;│ └── 1/
&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;│ └── model.onnx
&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;└── search-pipeline/
&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; ├── config.pbtxt # 可选：Triton ensemble，把 embedder + reranker 串起来
&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; └── 1/
&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; └── model.graphdef / model.py / ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只要 storageUri 指向这个目录，Triton 就会把子目录当成多个模型一起加载。&lt;/p&gt;
&lt;p&gt;单个模型的 config.pbtxt 示例（带分组 / 实例配置），以一个 ONNX embedding 模型 为例： 路径：text-embedding-e5-small/config.pbtxt&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;name: &amp;#34;text-embedding-e5-small&amp;#34;
&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;platform: &amp;#34;onnxruntime_onnx&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;max_batch_size: 128 # 这里根据你的 embedding 模型实际情况调
&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;input [
&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; name: &amp;#34;input_ids&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; data_type: TYPE_INT64
&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; dims: [ -1 ] # 序列长度，-1 表示动态
&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;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; name: &amp;#34;attention_mask&amp;#34;
&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; data_type: TYPE_INT64
&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; dims: [ -1 ]
&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&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;output [
&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; name: &amp;#34;embedding&amp;#34;
&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; data_type: TYPE_FP32
&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; dims: [ 768 ] # 或者你的模型真实向量维度
&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&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;# 关键：在同一块 GPU 上开多实例，提高吞吐
&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;instance_group [
&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; kind: KIND_GPU
&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; count: 2 # 这块卡上起两个实例，看显存情况调 1/2/3
&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&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;# 关键：Dynamic Batching，让 Triton 自动拼 batch
&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;dynamic_batching {
&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; preferred_batch_size: [ 8, 16, 32, 64 ]
&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; max_queue_delay_microseconds: 2000 # 2ms 内尽量攒一波请求
&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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同理，你可以为其他模型写各自的 config.pbtxt。分组思路：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对 &lt;strong&gt;高 QPS 的模型&lt;/strong&gt;（比如 text embedding）可以把 max_batch_size 和 preferred_batch_size 设得大些，多起几个 instance_group；&lt;/li&gt;
&lt;li&gt;对 &lt;strong&gt;低 QPS 但重模型&lt;/strong&gt;（ASR、复杂 CV）就用 max_batch_size 小一点，甚至单实例。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果有完整的 pipeline（比如「embedding → rerank」），可以用 Triton 的 ensemble 在 search-pipeline/config.pbtxt 里把两个模型串起来，一次请求走一条 DAG，减少网络往返。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KServe InferenceService YAML 示例（kserve-tritonserver）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;KServe 自带 kserve-tritonserver 这个 ClusterServingRuntime，支持 TensorFlow / ONNX / PyTorch / TensorRT 模型。可以这样起一个「非 LLM 小模型专用」的 Triton 服务：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serving.kserve.io/v1beta1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;InferenceService&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;triton-nonllm-text&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Knative 自动扩缩容（按并发）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/metric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;concurrency&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;10&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 每 Pod 目标并发&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/minScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/maxScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;5&amp;#34;&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;predictor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ✅ 新 schema：通过 model.runtime 显式指定使用 kserve-tritonserver&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;modelFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 这里写实际模型格式（比如 onnx / pytorch），只要包含在 kserve-tritonserver 支持列表中即可&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Triton 仓库里可以混放多种 backend，KServe 不会限制这一层&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;onnx&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-tritonserver&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 指向刚才那个包含多个模型的 Triton 模型仓库&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3://your-bucket/triton-nonllm-repo&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runtimeVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;24.03-py3&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 按你集群里安装的 kserve-tritonserver 版本改&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 如需 gRPC（性能更好），参考官方示例暴露 9000 端口:contentReference[oaicite:6]{index=6}&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;h2c&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9000&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;32Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu-pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 按你集群里标的 label 改，确保调度到有 GPU 的节点&lt;/span&gt;&lt;span class="w"&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="w"&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;ol&gt;
&lt;li&gt;&lt;strong&gt;多模型是 Triton 内部概念&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;KServe 看到的只是「一个 InferenceService + 一个 Triton Pod」。&lt;/li&gt;
&lt;li&gt;Triton 会根据 storageUri 下的目录加载多个模型。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;请求路径&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;走 KServe / Istio / Knative 的网关时：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTTP：POST http:///v2/models//infer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gRPC：grpc://:/InferenceServer/ModelInfer（按 Triton V2 协议）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;就是每个子目录名：text-embedding-e5-small / vision-cls-resnet50 / asr-conformer…&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;简单 Checklist：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;准备 Triton 模型仓库&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;在 MinIO / S3 / PVC 上建好 triton-*-repo 目录；&lt;/li&gt;
&lt;li&gt;把 embedding、rerank、CV、ASR 模型按 Triton 要求拆目录 + 写 config.pbtxt。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;确认集群里有 kserve-tritonserver 的 ClusterServingRuntime&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;kubectl get clusterservingruntime | grep triton&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;应用上面那个 InferenceService YAML&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;改好 storageUri、runtimeVersion、nodeSelector；&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;&lt;strong&gt;通过 /v2/models//infer 分别打 smoke test&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;文本 embedding / rerank / CV / ASR 各来几条请求；&lt;/li&gt;
&lt;li&gt;对比 Triton metrics（/metrics）和 DCGM，看 GPU 利用率 &amp;amp; 显存占用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="请求流--监控流两条主链路"&gt;&lt;a href="#%e8%af%b7%e6%b1%82%e6%b5%81--%e7%9b%91%e6%8e%a7%e6%b5%81%e4%b8%a4%e6%9d%a1%e4%b8%bb%e9%93%be%e8%b7%af" class="header-anchor"&gt;&lt;/a&gt;请求流 &amp;amp; 监控流（两条主链路）
&lt;/h2&gt;&lt;h3 id="推理请求链路从客户端到-vllm"&gt;&lt;a href="#%e6%8e%a8%e7%90%86%e8%af%b7%e6%b1%82%e9%93%be%e8%b7%af%e4%bb%8e%e5%ae%a2%e6%88%b7%e7%ab%af%e5%88%b0-vllm" class="header-anchor"&gt;&lt;/a&gt;推理请求链路（从客户端到 vLLM）
&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-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/012-7abde61a.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KServe 把 InferenceService 抽象出来，底层仍然是 Knative Service + Istio VirtualService 这些资源；Istio ServiceMesh 文档里也有 “给 InferenceService 打 sidecar 做安全 / 流量治理” 的说明。&lt;/li&gt;
&lt;li&gt;vLLM 服务端会在 /metrics 上暴露自身的 Prometheus 指标，例如 vllm:prompt_tokens_total、vllm:generation_tokens_total、vllm:e2e_request_latency_seconds 等，用来统计 QPS、Token 数量和端到端延迟。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="监控链路业务--gpu"&gt;&lt;a href="#%e7%9b%91%e6%8e%a7%e9%93%be%e8%b7%af%e4%b8%9a%e5%8a%a1--gpu" class="header-anchor"&gt;&lt;/a&gt;监控链路（业务 + GPU）
&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-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/013-b187c0ff.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NVIDIA 官方文档明确建议：在 Kubernetes 中监控 GPU 时，使用 DCGM Exporter → Prometheus → Grafana 这一条链路。&lt;/li&gt;
&lt;li&gt;我们现在的设计就是把这一套和 vLLM 的业务 metrics 汇总到同一个 kube-prometheus-stack 里 —— 这也是很多实践里推荐的做法，用 Prometheus Operator 的 ServiceMonitor 去发现所有 exporter 与应用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 K8s 里做 GPU 监控，典型链路是：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;GPU 节点 → GPU Operator → DCGM Exporter → Prometheus → Grafana&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPU Operator&lt;/strong&gt;：在 GPU 节点上自动装好驱动、Container Toolkit、Device Plugin、DCGM / Exporter 等一整套 GPU 栈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DCGM Exporter&lt;/strong&gt;：基于 NVIDIA DCGM，把 GPU 的利用率、显存、温度、功耗等指标以 Prometheus /metrics 的形式暴露出来。&lt;/li&gt;
&lt;li&gt;NVIDIA 官方推荐：在 K8s 集群里采集 GPU Telemetry，就用 DCGM Exporter + Prometheus + Grafana 这一套。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU Operator 默认就会启用 DCGM Exporter 来采集 GPU metrics&lt;/strong&gt;（可以通过 Helm values 里的 dcgmExporter.enabled 开关）。&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-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/014-041efd3a.png"&gt;&lt;/p&gt;
&lt;p&gt;所以，我们只需要：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 Kubekey 装好的 K8s 集群中安装 GPU Operator（包含 DCGM Exporter）。&lt;/li&gt;
&lt;li&gt;在公司统一 Prometheus 上加一个 scrape job（或者在集群里用 ServiceMonitor），把这些 /metrics 抓过去即可&lt;/li&gt;
&lt;/ol&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;GPU Operator 是一个管理者，DCGM Exporter 是它管理的一个组件。 你只和管理者（Operator）打交道，它会帮你搞定一切。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h1 id="四环境搭建步骤"&gt;&lt;a href="#%e5%9b%9b%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba%e6%ad%a5%e9%aa%a4" class="header-anchor"&gt;&lt;/a&gt;四、环境搭建步骤
&lt;/h1&gt;&lt;h2 id="需要安装的软件版本及顺序"&gt;&lt;a href="#%e9%9c%80%e8%a6%81%e5%ae%89%e8%a3%85%e7%9a%84%e8%bd%af%e4%bb%b6%e7%89%88%e6%9c%ac%e5%8f%8a%e9%a1%ba%e5%ba%8f" 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-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/015-14833749.png"&gt;&lt;/p&gt;
&lt;h2 id="安装步骤-sop"&gt;&lt;a href="#%e5%ae%89%e8%a3%85%e6%ad%a5%e9%aa%a4-sop" class="header-anchor"&gt;&lt;/a&gt;安装步骤 SOP
&lt;/h2&gt;&lt;h3 id="第-0-步准备工作"&gt;&lt;a href="#%e7%ac%ac-0-%e6%ad%a5%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;第 0 步：准备工作
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# 添加所有需要的 Helm 仓库
&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;helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
&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;helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
&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;helm repo add jetstack https://charts.jetstack.io
&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;helm repo add istio https://istio-release.storage.googleapis.com/charts
&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;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-1-步安装-nvidia-gpu-operator-v2491"&gt;&lt;a href="#%e7%ac%ac-1-%e6%ad%a5%e5%ae%89%e8%a3%85-nvidia-gpu-operator-v2491" class="header-anchor"&gt;&lt;/a&gt;第 1 步：安装 NVIDIA GPU Operator (v24.9.1)
&lt;/h3&gt;&lt;p&gt;目的：启用 GPU 驱动，并配置 CDI (Container Device Interface) 以兼容 K8s 1.30。&lt;/p&gt;
&lt;p&gt;以下命令是在 GPU 驱动都安装好的前提下执行&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="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="n"&gt;nvidia&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;operator&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="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespace&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="n"&gt;v24&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;9.1&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;false&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;cdi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;cdi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证：等待 kubectl get pods -n gpu-operator 全绿。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果出错，那么：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个命令显式指定了版本，并且强制告诉 Operator 你的 Containerd 配置文件在哪里，避免出现之前的 FailedCreatePodSandBox 错误。&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="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="n"&gt;nvidia&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;operator&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="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespace&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="n"&gt;v24&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;9.1&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;false&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTAINERD_CONFIG&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&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;value&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containerd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toml&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&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 class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTAINERD_SOCKET&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;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&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 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;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containerd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containerd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&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;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&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 class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTAINERD_RUNTIME_CLASS&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&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 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;nvidia&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;cdi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&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="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;cdi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-2-步安装-kube-prometheus-stack-v6190"&gt;&lt;a href="#%e7%ac%ac-2-%e6%ad%a5%e5%ae%89%e8%a3%85-kube-prometheus-stack-v6190" class="header-anchor"&gt;&lt;/a&gt;第 2 步：安装 Kube-Prometheus-Stack (v61.9.0)
&lt;/h3&gt;&lt;p&gt;目的：基础监控。必须修正配置，否则 KServe 的 ServiceMonitor 会被忽略。&lt;/p&gt;
&lt;p&gt;准备 values-kube-prometheus-stack.yaml&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# values-kube-prometheus-stack.yaml&lt;/span&gt;&lt;span class="w"&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="w"&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;prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheusSpec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 允许抓取所有 namespace 下的 ServiceMonitor / PodMonitor&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceMonitorNamespaceSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podMonitorNamespaceSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 不再强制使用 Helm 的 release label 做筛选&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# （默认是 true，会要求 ServiceMonitor 带 release=&amp;lt;helm release&amp;gt; 这样的 label）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceMonitorSelectorNilUsesHelmValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podMonitorSelectorNilUsesHelmValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 空 selector = 不按 label 过滤，看到就抓&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceMonitorSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podMonitorSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 可选：Prometheus 数据保留时间&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;15d&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 暴露 Prometheus 的方式（开发环境方便直接 NodePort）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30090&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 访问地址：任一节点IP:30090 &lt;/span&gt;&lt;span class="w"&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="w"&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="nt"&gt;grafana&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Grafana 用 NodePort 方便先调试；生产看你们自己安全策略&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30080&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 可不填，让 kube 随机分配&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 管理员密码（不写一般是 prom-operator，也可以明确写死）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;adminPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prom-operator&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这套配置的核心就是：Prometheus 不再只认「带 release=kube-prometheus-stack 的 ServiceMonitor」，而是「所有 namespace 下的 ServiceMonitor 都抓」，这样 GPU Operator 自动创建的 ServiceMonitor 也不会漏掉。&lt;/p&gt;
&lt;p&gt;安装 kube-prometheus-stack&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;helm install monitoring prometheus-community/kube-prometheus-stack \
&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; -n monitoring --create-namespace \
&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; --version 61.9.0 \
&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; -f values-kube-prometheus-stack.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;打开 &lt;strong&gt;GPU Operator 的 监控组件（ServiceMonitor）&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;#解释：
&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;#--reuse-values: 保留之前设置的 cdi.enabled=true 等参数。
&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;#--set dcgmExporter.serviceMonitor.enabled=true: 这才是核心，告诉 Operator 创建监控对象。
&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;helm upgrade gpu-operator nvidia/gpu-operator \
&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; -n gpu-operator \
&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; --reuse-values \
&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; --set dcgmExporter.serviceMonitor.enabled=true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-3-步安装-cert-manager-v1153"&gt;&lt;a href="#%e7%ac%ac-3-%e6%ad%a5%e5%ae%89%e8%a3%85-cert-manager-v1153" class="header-anchor"&gt;&lt;/a&gt;第 3 步：安装 Cert-Manager (v1.15.3)
&lt;/h3&gt;&lt;p&gt;目的：为 KServe 和 Knative 的 Webhook 签发自签名证书。&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;helm install cert-manager jetstack/cert-manager \
&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; -n cert-manager --create-namespace \
&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; --version v1.15.3 \
&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; --set crds.enabled=true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证：等待 kubectl get pods -n cert-manager 全绿。&lt;/p&gt;
&lt;h3 id="第-4-步安装-istio-v1226"&gt;&lt;a href="#%e7%ac%ac-4-%e6%ad%a5%e5%ae%89%e8%a3%85-istio-v1226" class="header-anchor"&gt;&lt;/a&gt;第 4 步：安装 Istio (v1.22.6)
&lt;/h3&gt;&lt;p&gt;目的：流量网关。严格按照 Base -&amp;gt; Istiod -&amp;gt; Gateway 的顺序安装。&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. 安装 Base CRD
&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;helm install istio-base istio/base -n istio-system --create-namespace --version 1.22.6
&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;# 2. 安装 Istiod 控制平面
&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;helm install istiod istio/istiod -n istio-system --version 1.22.6 --wait
&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;# 3. 安装 Ingress Gateway (数据平面)
&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;helm install istio-ingressgateway istio/gateway -n istio-system --version 1.22.6
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-5-步安装-knative-serving--net-istio-v1151"&gt;&lt;a href="#%e7%ac%ac-5-%e6%ad%a5%e5%ae%89%e8%a3%85-knative-serving--net-istio-v1151" class="header-anchor"&gt;&lt;/a&gt;第 5 步：安装 Knative Serving &amp;amp; Net-Istio (v1.15.1)
&lt;/h3&gt;&lt;p&gt;目的：实现 Serverless 扩缩容能力。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 安装 CRDs&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;kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.15.2/serving-crds.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 安装 Serving Core&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;kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.15.2/serving-core.yaml
&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;# 3. 安装 Net-Istio (网络适配器)&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;kubectl apply -f https://github.com/knative-extensions/net-istio/releases/download/knative-v1.15.1/net-istio.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证：kubectl get pods -n knative-serving，确保 net-istio-controller 和 activator 状态为 Running。&lt;/p&gt;
&lt;h3 id="第-6-步安装-kserve-v0141"&gt;&lt;a href="#%e7%ac%ac-6-%e6%ad%a5%e5%ae%89%e8%a3%85-kserve-v0141" class="header-anchor"&gt;&lt;/a&gt;第 6 步：安装 KServe (v0.14.1)
&lt;/h3&gt;&lt;p&gt;目的：核心推理平台。 注意这里使用的是 v0.14.1。&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;# 安装 KServe CRDs
&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;helm install kserve-crd oci://ghcr.io/kserve/charts/kserve-crd \
&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; --version v0.14.1 \
&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; -n kserve --create-namespace
&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;# 安装 KServe Controller
&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;helm install kserve oci://ghcr.io/kserve/charts/kserve \
&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; --version v0.14.1 \
&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; -n kserve 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行完上述两条命令后，检查 KServe 的系统组件： kubectl get pods -n kserve&lt;/p&gt;
&lt;h3 id="第-7-步配置-vllm-runtime-关键"&gt;&lt;a href="#%e7%ac%ac-7-%e6%ad%a5%e9%85%8d%e7%bd%ae-vllm-runtime-%e5%85%b3%e9%94%ae" class="header-anchor"&gt;&lt;/a&gt;第 7 步：配置 vLLM Runtime (关键)
&lt;/h3&gt;&lt;p&gt;KServe 默认只有简单的 CPU 模型支持。为了运行公司级 LLM 服务，必须添加支持 GPU 的 Runtime。&lt;/p&gt;
&lt;p&gt;保存以下内容为 vllm-runtime.yaml 并执行 kubectl apply -f vllm-runtime.yaml：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serving.kserve.io/v1alpha1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterServingRuntime&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-vllm&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.kserve.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;8080&amp;#39;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.kserve.io/path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/metrics&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;supportedModelFormats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vllm&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoSelect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-container&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vllm/vllm-openai:latest&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 建议生产环境锁定具体 image sha256&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;python3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-m&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;vllm.entrypoints.openai.api_server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;port=8080&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;model=/mnt/models&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;gpu-memory-utilization=0.9&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PORT&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8080&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;32Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-8-步为-gpu-调度开启-knative-的-nodeselector--tolerations"&gt;&lt;a href="#%e7%ac%ac-8-%e6%ad%a5%e4%b8%ba-gpu-%e8%b0%83%e5%ba%a6%e5%bc%80%e5%90%af-knative-%e7%9a%84-nodeselector--tolerations" class="header-anchor"&gt;&lt;/a&gt;第 8 步：为 GPU 调度开启 Knative 的 nodeSelector / tolerations
&lt;/h3&gt;&lt;p&gt;Knative 默认禁止你在 Knative Service 的 Pod 里写 nodeSelector / tolerations，KServe 官方教程在使用 GPU 时也会做这一步 patch。&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch configmap/config-features &lt;span class="se"&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; --namespace knative-serving &lt;span class="se"&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; --type merge &lt;span class="se"&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; --patch &lt;span class="s1"&gt;&amp;#39;{&amp;#34;data&amp;#34;:{&amp;#34;kubernetes.podspec-nodeselector&amp;#34;:&amp;#34;enabled&amp;#34;, &amp;#34;kubernetes.podspec-tolerations&amp;#34;:&amp;#34;enabled&amp;#34;}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;重启 Webhook：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete pod -n knative-serving -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;webhook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-9-步istio-sidecar-注入策略避免影响-gpu-operator-和监控"&gt;&lt;a href="#%e7%ac%ac-9-%e6%ad%a5istio-sidecar-%e6%b3%a8%e5%85%a5%e7%ad%96%e7%95%a5%e9%81%bf%e5%85%8d%e5%bd%b1%e5%93%8d-gpu-operator-%e5%92%8c%e7%9b%91%e6%8e%a7" class="header-anchor"&gt;&lt;/a&gt;第 9 步：Istio Sidecar 注入策略（避免影响 GPU Operator 和监控）
&lt;/h3&gt;&lt;p&gt;默认 Istio 只对打了 istio-injection=enabled 标签的 namespace 注入 sidecar。确保「不需要注入」的 namespace 没有 label&lt;/p&gt;
&lt;p&gt;保护基础设施 (防止 Sidecar 导致 Job 不退出)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 明确禁止 GPU Operator 注入 (防止 Validator/Driver 安装卡死)&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;kubectl label namespace gpu-operator istio-injection&lt;span class="o"&gt;=&lt;/span&gt;disabled --overwrite
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 明确禁止 监控 注入 (减少开销)&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;kubectl label namespace monitoring istio-injection&lt;span class="o"&gt;=&lt;/span&gt;disabled --overwrite
&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;# 3. 明确禁止 kube-system 注入 (安全底线)&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;kubectl label namespace kube-system istio-injection&lt;span class="o"&gt;=&lt;/span&gt;disabled --overwrite
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;保护控制平面 (防止 Webhook 超时)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl label namespace knative-serving istio-injection&lt;span class="o"&gt;=&lt;/span&gt;disabled --overwrite 
&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;kubectl label namespace kserve istio-injection&lt;span class="o"&gt;=&lt;/span&gt;disabled --overwrite
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;启用业务空间 (让模型享受 Service Mesh 能力)，业务命名空间 “必须” 注入 ✅&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 创建你的业务空间 (如果你还没创建)&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;kubectl create namespace model-serving
&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="c1"&gt;# 2. 启用注入 (关键一步)&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;kubectl label namespace model-serving istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled --overwrite
&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;GPU Operator、DCGM Exporter、Prometheus 不会被 sidecar 干扰&lt;/li&gt;
&lt;li&gt;模型推理流量全部走 Istio + Knative 控制的入口&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="第-10-步安装-minio可选"&gt;&lt;a href="#%e7%ac%ac-10-%e6%ad%a5%e5%ae%89%e8%a3%85-minio%e5%8f%af%e9%80%89" class="header-anchor"&gt;&lt;/a&gt;第 10 步：安装 MinIO（可选）
&lt;/h3&gt;&lt;p&gt;添加所有依赖 Helm 仓库&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;# 添加MinIO、Loki官方仓库
&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;helm repo add minio https://helm.min.io/
&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;helm repo add grafana https://grafana.github.io/helm-charts
&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;# 更新所有仓库（确保获取最新Chart版本）
&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;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;MinIO 部署 —— 部署 2 节点分布式 MinIO（Loki 后端存储） MinIO 配置为 2 副本分布式，适配当前 2 节点，同时预留未来扩容参数，升级时仅需修改副本数即可。&lt;/p&gt;
&lt;p&gt;编写 MinIO 配置文件 minio-distributed-values.yaml&lt;/p&gt;
&lt;p&gt;关键标注：文件内 replicas 和 numberOfNodes 为扩容核心参数，未来扩容需同步修改为 3+ 等节点数。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 核心：启用分布式模式（2节点适配，未来扩容改replicas/numberOfNodes）&lt;/span&gt;&lt;span class="w"&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;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;distributed&lt;/span&gt;&lt;span class="w"&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;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&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;numberOfNodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 镜像配置（你原单节点的成功版本）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;quay.io/minio/minio&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RELEASE.2023-07-07T07-13-57Z&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pullPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;IfNotPresent&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 访问密钥（完全沿用你的配置，Loki对接需一致）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;rootUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;U4DwltABIX8p20aONyoY &lt;/span&gt;&lt;span class="w"&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="nt"&gt;rootPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;9YZInPYCqXwerS0NE6PDGrxo9g0l4akt2fs0IJNm &lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 持久化存储配置（你的成功配置，保障数据持久化）&lt;/span&gt;&lt;span class="w"&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;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 使用集群默认存储类&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi &lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/export&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 服务配置（集群内访问，无需暴露外网）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterIP&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# S3兼容接口端口（Loki对接用）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;consoleService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterIP&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9001&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 管理控制台端口（可选）&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 默认Bucket（Loki日志存储专用，自动创建，无需手动操作）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;defaultBucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki-chunks &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Loki配置需与该Bucket名一致&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;read-write&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;purge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 卸载MinIO时保留数据&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 资源限制（适配测试环境，低资源占用）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;100m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;512Mi&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1Gi&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 健康检查（分布式启动稍慢，微调延迟避免探针失败）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;livenessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;90&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;periodSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&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="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;periodSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&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="w"&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 class="c"&gt;# 跨节点调度策略（强制2个副本分布在不同节点，保障高可用）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAntiAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;labelSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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 class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;minio&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topologyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 安全配置（确保权限足够）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 监控集成（默认关闭，若需对接Prometheus可改为true）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceMonitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装分布式 MinIO&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;helm install minio minio/minio \
&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; -n monitoring \
&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; --version 5.4.0 \
&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; -f minio-distributed-values.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证 MinIO 部署（2 节点核心检查）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看MinIO Pod状态（2个副本均为Running，分布在不同节点）&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;kubectl get pods -n monitoring -o wide &lt;span class="p"&gt;|&lt;/span&gt; grep minio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看MinIO Service（地址固定，扩容后不变）&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;kubectl get svc -n monitoring &lt;span class="p"&gt;|&lt;/span&gt; grep minio
&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;# 验证桶创建成功&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;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -n monitoring minio-0 -- mc ls minio
&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;# 预期输出：[2024-xx-xx xx:xx:xx UTC] DIR loki-data&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;Loki 的 ConfigMap 中指定了两个桶：chunks（存储日志块）、ruler（存储规则），先在 MinIO 中手动创建这两个桶（避免 Loki 首次写入时因桶不存在报错）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 进入minio-0 Pod，创建chunks和ruler桶&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;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -it minio-0 -n monitoring -- /bin/sh -c &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;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; /usr/local/bin/mc alias set minio http://localhost:9000 U4DwltABIX8p20aONyoY 9YZInPYCqXwerS0NE6PDGrxo9g0l4akt2fs0IJNm --api S3v4 &amp;amp;&amp;amp;
&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; /usr/local/bin/mc mb minio/chunks --ignore-existing &amp;amp;&amp;amp;
&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; /usr/local/bin/mc mb minio/ruler --ignore-existing &amp;amp;&amp;amp;
&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; echo &amp;#39;✅ Loki所需的chunks和ruler桶创建成功&amp;#39; &amp;amp;&amp;amp;
&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; /usr/local/bin/mc ls minio # 验证桶是否存在
&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;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第-11-步安装-loki-和-promtail"&gt;&lt;a href="#%e7%ac%ac-11-%e6%ad%a5%e5%ae%89%e8%a3%85-loki-%e5%92%8c-promtail" class="header-anchor"&gt;&lt;/a&gt;第 11 步：安装 Loki 和 Promtail
&lt;/h3&gt;&lt;p&gt;编写 Loki 配置文件（loki-values.yaml）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;autoscaling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxReplicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minReplicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetCPUUtilizationPercentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;70&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetMemoryUtilizationPercentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&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="nt"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 可选新增：就绪探针（解决之前Pod卡死问题，不影响原有配置）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeoutSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&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;canary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="nt"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="nt"&gt;grafanaAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2.9.2&lt;/span&gt;&lt;span class="w"&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="nt"&gt;loki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention_period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;720h&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;schemaConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;24h&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;index_&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;object_store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v11&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;boltdb-shipper&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;U4DwltABIX8p20aONyoY&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucketnames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chunks &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 匹配MinIO已创建的chunks桶&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio:9000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 保留你原有简写地址，不改动&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;9YZInPYCqXwerS0NE6PDGrxo9g0l4akt2fs0IJNm&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3forcepathstyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# MinIO必需的核心配置&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3&lt;/span&gt;&lt;span class="w"&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="nt"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 可选新增：就绪探针（解决之前Pod卡死问题，不影响原有配置）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeoutSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&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="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1000m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;300m&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;768Mi&lt;/span&gt;&lt;span class="w"&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="nt"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;20Gi&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 可选新增：就绪探针（解决之前Pod卡死问题，不影响原有配置）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeoutSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;部署 Loki&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;# 部署Loki
&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;helm install loki grafana/loki -n monitoring \
&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; -f loki-values.yaml \
&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; --version 5.36.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Loki ConfigMap:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&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;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config.yaml&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;|2&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;common&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;compactor_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;loki-backend&amp;#39;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path_prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/loki&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replication_factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucketnames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chunks&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 新增：MinIO集群内服务地址&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio.monitoring.svc.cluster.local:9000&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 新增：MinIO的Access Key&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;U4DwltABIX8p20aONyoY&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 新增：MinIO的Secret Key&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;9YZInPYCqXwerS0NE6PDGrxo9g0l4akt2fs0IJNm&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 修正：MinIO未开启HTTPS，改为true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 修正：MinIO必须开启路径风格，改为true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3forcepathstyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;frontend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scheduler_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;query-scheduler-discovery.monitoring.svc.cluster.local.:9095&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;frontend_worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scheduler_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;query-scheduler-discovery.monitoring.svc.cluster.local.:9095&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;index_gateway&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ring&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enforce_metric_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;max_cache_freshness_per_query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;reject_old_samples&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;reject_old_samples_max_age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;168h&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention_period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;720h&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;split_queries_by_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;15m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memberlist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;join_members&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;loki-memberlist&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;query_range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;align_queries_with_step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucketnames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ruler&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 新增：MinIO集群内服务地址&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio.monitoring.svc.cluster.local:9000&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 新增：MinIO的Access Key&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;U4DwltABIX8p20aONyoY&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 新增：MinIO的Secret Key&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;9YZInPYCqXwerS0NE6PDGrxo9g0l4akt2fs0IJNm&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 修正：MinIO未开启HTTPS，改为true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 修正：MinIO必须开启路径风格，改为true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3forcepathstyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runtime_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/loki/runtime-config/runtime-config.yaml&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;schema_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;24h&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;index_&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;object_store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v11&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;boltdb-shipper&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;grpc_listen_port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9095&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;http_listen_port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3100&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hedging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;250ms&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;max_per_second&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;up_to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&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="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&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="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;meta.helm.sh/release-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki&lt;/span&gt;&lt;span class="w"&gt;
&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;meta.helm.sh/release-namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;monitoring&lt;/span&gt;&lt;span class="w"&gt;
&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;creationTimestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2025-11-24T08:14:03Z&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/instance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/managed-by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Helm&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2.9.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;helm.sh/chart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki-5.36.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;monitoring&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resourceVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8228076&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;103b336c-fcb1-4516-85d8-76d45ca6c79d&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证 Loki 部署&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看Loki核心组件（read/write/backend均需Running）&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;kubectl get pods -n monitoring &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s2"&gt;&amp;#34;loki-read|loki-write|loki-backend&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&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="c1"&gt;# loki-backend-0 2/2 Running 0 5m&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="c1"&gt;# loki-read-546cd5b67c-dsb84 1/1 Running 0 5m&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="c1"&gt;# loki-write-0 1/1 Running 0 5m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;部署 Promtail（日志采集代理）&lt;/p&gt;
&lt;p&gt;编写 Promtail 配置文件（promtail-values.yaml）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 对接Loki的write服务（集群内服务名解析）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://loki-write:3100/loki/api/v1/push&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 日志采集规则（采集K8s Pod日志）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scrape_configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;job_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes-pods&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 基于Pod自动发现&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;relabel_configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 添加命名空间标签&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;__meta_kubernetes_pod_namespace]&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;namespace&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 添加Pod名称标签&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;__meta_kubernetes_pod_name]&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 添加容器名称标签&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;__meta_kubernetes_pod_container_name]&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;container&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 过滤掉无需采集的系统组件（可选，按需调整）&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;__meta_kubernetes_pod_namespace]&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;kube-system|istio-system&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;drop&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 部署模式：DaemonSet（每个节点1个副本）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;daemonset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extraArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;max-open-files=1000000 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 增加文件打开限制&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 健康检查配置&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeoutSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 权限配置（解决日志目录读取权限问题）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 以root用户运行&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;DAC_READ_SEARCH &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 增加目录读取权限&lt;/span&gt;&lt;span class="w"&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="w"&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="c"&gt;# 资源配置（低资源占用）&lt;/span&gt;&lt;span class="w"&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="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;50m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;64Mi&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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 class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;200m&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;256Mi&lt;/span&gt;&lt;span class="w"&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="w"&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 class="c"&gt;# 禁用非必需组件&lt;/span&gt;&lt;span class="w"&gt;
&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="nt"&gt;serviceMonitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&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 class="nt"&gt;prometheusRule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;部署 Promtail&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;# 部署Promtail
&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;helm install promtail grafana/promtail -n monitoring \
&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; -f promtail-values.yaml \
&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; --version 5.36.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证 Promtail 部署&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看Promtail Pod（每个节点1个副本，均需Running）&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;kubectl get pods -n monitoring &lt;span class="p"&gt;|&lt;/span&gt; grep promtail
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看Promtail日志（确认无报错，有日志推送记录）&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="nv"&gt;PROMTAIL_POD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pods -n monitoring -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;promtail -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&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;kubectl logs -n monitoring &lt;span class="nv"&gt;$PROMTAIL_POD&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s2"&gt;&amp;#34;Successfully sent batch&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="c1"&gt;# 示例输出：level=info ts=xxx caller=client.go:347 msg=&amp;#34;Successfully sent batch&amp;#34;&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="#%e6%9c%80%e7%bb%88%e9%aa%8c%e8%af%81" class="header-anchor"&gt;&lt;/a&gt;最终验证
&lt;/h2&gt;&lt;h3 id="验证-gpu-operator--gpu-metrics-是否正常"&gt;&lt;a href="#%e9%aa%8c%e8%af%81-gpu-operator--gpu-metrics-%e6%98%af%e5%90%a6%e6%ad%a3%e5%b8%b8" class="header-anchor"&gt;&lt;/a&gt;验证 GPU Operator &amp;amp; GPU metrics 是否正常
&lt;/h3&gt;&lt;p&gt;看 GPU Operator 相关 Pod：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n gpu-operator get pods
&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;kubectl -n gpu-operator get ds
&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;驱动 DaemonSet&lt;/li&gt;
&lt;li&gt;Device Plugin DaemonSet&lt;/li&gt;
&lt;li&gt;nvidia-dcgm-exporter 或类似名字的 DaemonSet&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;找到 DCGM Exporter 暴露出来的 Service：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n gpu-operator get svc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;里面一般会有一个和 dcgm-exporter 类似名字的 Service，对应端口 9400（Prometheus 默认端口）。&lt;/p&gt;
&lt;p&gt;本地 port-forward 看看 /metrics：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 换成你查到的 dcgm exporter 服务名&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;kubectl -n gpu-operator port-forward svc/nvidia-dcgm-exporter 9400:9400
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 打开一个新终端：&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;curl http://127.0.0.1:9400/metrics &lt;span class="p"&gt;|&lt;/span&gt; head
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;应该能看到类似：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# HELP DCGM_FI_DEV_SM_CLOCK SM clock frequency (in MHz).
&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;# TYPE DCGM_FI_DEV_SM_CLOCK gauge
&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;DCGM_FI_DEV_SM_CLOCK{gpu=&amp;#34;0&amp;#34;,UUID=&amp;#34;GPU-xxxx&amp;#34;} 139
&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;说明 GPU 指标已经通过 DCGM Exporter 暴露出来了。&lt;/p&gt;
&lt;h3 id="轻量级测试"&gt;&lt;a href="#%e8%bd%bb%e9%87%8f%e7%ba%a7%e6%b5%8b%e8%af%95" class="header-anchor"&gt;&lt;/a&gt;轻量级测试
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 运行 GPU 测试 (显式申请 1 个 GPU)&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;sudo kubectl run test-gpu-real &lt;span class="se"&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; -n model-serving &lt;span class="se"&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; --image&lt;span class="o"&gt;=&lt;/span&gt;vllm/vllm-openai:latest &lt;span class="se"&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; --restart&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&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; --overrides&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;: {&amp;#34;annotations&amp;#34;: {&amp;#34;sidecar.istio.io/inject&amp;#34;: &amp;#34;false&amp;#34;}}, &amp;#34;spec&amp;#34;: {&amp;#34;containers&amp;#34;: [{&amp;#34;name&amp;#34;: &amp;#34;test-gpu-real&amp;#34;, &amp;#34;image&amp;#34;: &amp;#34;vllm/vllm-openai:latest&amp;#34;, &amp;#34;command&amp;#34;: [&amp;#34;nvidia-smi&amp;#34;], &amp;#34;resources&amp;#34;: {&amp;#34;limits&amp;#34;: {&amp;#34;nvidia.com/gpu&amp;#34;: &amp;#34;1&amp;#34;}}}]}}&amp;#39;&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;kubectl logs test-gpu-real -n model-serving
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="完整测试triton--vllm"&gt;&lt;a href="#%e5%ae%8c%e6%95%b4%e6%b5%8b%e8%af%95triton--vllm" class="header-anchor"&gt;&lt;/a&gt;完整测试（triton + vllm）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;有关 Namespace&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;注意 InferenceService 的 namespace 是：model-serving&lt;/p&gt;
&lt;p&gt;为什么必须是 model-serving？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Istio 注入生效：我们之前只给 model-serving 命名空间打了 istio-injection=enabled 标签。只有部署在这个命名空间下的 Pod，才会自动拥有 Istio Sidecar（负责流量路由、Metrics 等）。&lt;/li&gt;
&lt;li&gt;资源隔离：将业务模型与系统组件（如 gpu-operator, knative-serving）分开，是生产环境的最佳实践。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;举例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serving.kserve.io/v1beta1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;InferenceService&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;qwen-7b-chat &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 你的服务名称&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;model-serving &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 👈 这里必须写 model-serving&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;predictor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;modelFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vllm &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 对应 ClusterServingRuntime 的名字&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-vllm &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 如果你有自定义 Runtime，这里指定名字&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pvc://model-pvc/qwen-7b&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 或者 &amp;#34;s3://...&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 👈 申请 1 张显卡&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;即使 YAML 里写了 namespace，习惯上在 apply 时显式指定一下也是个好习惯（双重保险）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f isvc-llm.yaml -n model-serving
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;五、完整调用链路&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/016-0a588075.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-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/017-0e4fb1a7.png"&gt;&lt;/p&gt;
&lt;h1 id="六基于-argo-的-ci--cd"&gt;&lt;a href="#%e5%85%ad%e5%9f%ba%e4%ba%8e-argo-%e7%9a%84-ci--cd" class="header-anchor"&gt;&lt;/a&gt;六、基于 Argo 的 CI / CD
&lt;/h1&gt;&lt;p&gt;GitHub: &lt;a class="link" href="https://github.com/argoproj/argo-cd" target="_blank" rel="noopener"
 &gt;https://github.com/argoproj/argo-cd&lt;/a&gt; 官网：https://argoproj.github.io/&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;Argo = 一套专门给 Kubernetes 用的开源工具家族，用来做 CI / CD、工作流编排、GitOps 部署、灰度发布、事件驱动等，是 CNCF 下面的毕业项目&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Argo 不是一个单一软件，而是一个 “工具矩阵”，主要包括四个子项目：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Argo Workflows&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes 原生的 工作流 / 任务编排引擎&lt;/li&gt;
&lt;li&gt;用 CRD（自定义资源）定义 Workflow，每个步骤跑在 Pod 里，非常适合 CI 流水线、数据处理、ML 训练等批处理任务&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Argo CD&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;一个 GitOps 风格的持续交付工具&lt;/li&gt;
&lt;li&gt;通过对比 Git 仓库里的 “期望状态” 和 K8s 集群中的 “实际状态”，自动同步和回滚应用，常用来管理大规模集群配置&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Argo Rollouts&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;替代原生 Deployment 的 CRD&lt;/li&gt;
&lt;li&gt;支持 蓝绿发布、金丝雀发布，可以接入网关、监控指标做渐进式发布和自动回滚&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Argo Events&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;做 事件驱动 自动化&lt;/li&gt;
&lt;li&gt;支持各种事件源（Webhook、Kafka、S3 等），触发 Argo Workflows 或其他 K8s 资源，实现 event-driven CI / CD 或自动化任务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话：Argo = “围绕 Kubernetes 打造的一整套自动化 / GitOps / 发布 / 事件工具链”。&lt;/p&gt;
&lt;h2 id="argo-跟-kubernetes-是什么关系"&gt;&lt;a href="#argo-%e8%b7%9f-kubernetes-%e6%98%af%e4%bb%80%e4%b9%88%e5%85%b3%e7%b3%bb" class="header-anchor"&gt;&lt;/a&gt;Argo 跟 Kubernetes 是什么关系？
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;Kubernetes 提供 “集群和基础设施”，Argo 提供 “在这个集群上自动化地干活的工具”。Argo 是 Kubernetes 最主流的 GitOps / Workflow 方案之一&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;CNCF 官方介绍中就把 Argo 定义为 “Kubernetes-native tools to run workflows, manage clusters, and do GitOps right”&lt;/p&gt;
&lt;p&gt;运行环境层面：完全依赖 K8s&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Argo 的所有组件（Controller、UI 等）都是以 Deployment / Pod 的形式部署在 Kubernetes 集群中。&lt;/li&gt;
&lt;li&gt;Argo 的核心对象（Workflow、Rollout、EventSource、Application 等）都是 Kubernetes CRD。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;职责分工：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes 负责：调度 Pod、管理节点、网络、存储、基础监控。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Argo 负责：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把一堆任务编排成 “工作流” 并在 K8s 上跑（Workflows）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把 Git 仓库里的 YAML 自动同步到集群（CD &amp;amp; GitOps）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把发布过程做成可观测、可灰度控制的 rollouts（Rollouts）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把外部事件变成触发器（Events）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="部署层级"&gt;&lt;a href="#%e9%83%a8%e7%bd%b2%e5%b1%82%e7%ba%a7" class="header-anchor"&gt;&lt;/a&gt;部署层级
&lt;/h2&gt;&lt;p&gt;所有文件都应该放到 git 让 Argo 负责吗？&lt;/p&gt;
&lt;p&gt;不是的，这涉及到 “部署层级” 的问题。在云原生的 GitOps 实践中，我们将部署分为了两个截然不同的层级：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;层级一：平台基础设施层&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;包含组件：Istio, Knative Serving, KServe, Cert-Manager, Nvidia Device Plugin 等。&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;管理者：平台运维工程师 / SRE。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部署方式：通常使用 Helm Chart 或 Operator。&lt;/p&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;p&gt;包含组件：InferenceService (模型), gateway (网关), ConfigMap (业务配置)。&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;管理者：算法工程师 / MLOps 工程师。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部署方式：YAML 文件 (InferenceService)。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;所以目前来看，层级二的内容要以放到 git 中由 argo 管理 CD。层级一的也可以放到 git 中，但手动运维。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="实践"&gt;&lt;a href="#%e5%ae%9e%e8%b7%b5" class="header-anchor"&gt;&lt;/a&gt;实践
&lt;/h2&gt;&lt;p&gt;Jenkins 本身是可以做全套的 CI + CD 的，但从我们推理服务部署这件事上来讲，CD (持续部署) 并不适合用 Jenkins，而适合用 Argo。Jenkins 在我们的这个场景下可以继续做它擅长的 CI (持续集成)，但想了想，没必要那么麻烦，全部用 Argo 结合 Git 就完全能搞定，而且很方便，不适合用 jenkins 再增加运维复杂度了。&lt;/p&gt;
&lt;p&gt;ArgoCD 是云原生时代的王者（GitOps 流）&lt;/p&gt;
&lt;h3 id="实操-for-triton预演"&gt;&lt;a href="#%e5%ae%9e%e6%93%8d-for-triton%e9%a2%84%e6%bc%94" class="header-anchor"&gt;&lt;/a&gt;实操 for Triton（预演）
&lt;/h3&gt;&lt;p&gt;假设：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git 仓库地址：git@github.com:your-name/ai-ops.git&lt;/li&gt;
&lt;li&gt;S3 Bucket：my-ai-models&lt;/li&gt;
&lt;li&gt;EKS 命名空间：ai-serving&lt;/li&gt;
&lt;li&gt;自定义 Docker 镜像 &amp;ndash;&amp;gt; 镜像仓库&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第一阶段：基础设施与权限准备 (一次性工作)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这部分工作通常不需要经常变动，主要是为了打通 K8s 和 S3 的权限，以及准备 Git 仓库。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建 Namespace (如果还没建)&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create namespace ai-serving
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;配置 S3 访问凭证 (Secrets) 注意：敏感信息不要直接上传到 Git。 我们先用 kubectl 手动创建 Secret（或者使用 ExternalSecrets / SealedSecrets 等高级方案，但现在先用简单直接的方式）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;准备一个 s3-secret.yaml 在你本地（ 不要提交到 Git）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-s3-secret&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serving.kserve.io/s3-endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;s3.amazonaws.com&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# AWS S3&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serving.kserve.io/s3-region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;us-east-1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 你的 Region&lt;/span&gt;&lt;span class="w"&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Opaque&lt;/span&gt;&lt;span class="w"&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;stringData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你的AK&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你的SK&amp;#34;&lt;/span&gt;&lt;span class="w"&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f s3-secret.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;准备 Git 仓库目录结构&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在你的 ai-ops Git 仓库中，创建一个专门存放 ASR 部署文件的目录，例如 apps/asr-service/overlays/prod (如果是 Kustomize 结构) 或者直接 manifests/asr-service。&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;manifests/asr-service/
&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;├── service-account.yaml # 关联 Secret 的账号配置
&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;└── inference-service.yaml # 核心模型服务配置
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;编写 manifests/asr-service/service-account.yaml 并提交到 Git：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sa-s3-access&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving&lt;/span&gt;&lt;span class="w"&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;secrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-s3-secret&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 引用刚才手动创建的 Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第二阶段：模型工件准备 (模型上线 / 更新时操作)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个阶段是 “搬运工” 工作，把模型传上去，让 KServe 有东西可拉。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;本地整理 Triton 结构&lt;/li&gt;
&lt;/ol&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;simple-asr/
&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;├── config.pbtxt
&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;└── 1/
&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; └── model.onnx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;上传到 S3&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;使用 AWS CLI 或手动上传。&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;# 假设上传到 bucket 的 triton-repo 目录下
&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;aws s3 cp --recursive simple-asr/ s3://my-ai-models/triton-repo/simple-asr/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证： 确保 s3://my-ai-models/triton-repo/simple-asr/config.pbtxt 存在。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三阶段：Argo CD 配置与部署 (GitOps 核心)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是让 Argo CD 接管部署的关键步骤。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;编写 InferenceService 配置文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 Git 仓库的 manifests/asr-service/inference-service.yaml 中写入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serving.kserve.io/v1beta1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;InferenceService&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;asr-service&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 稍微改动这个字段可以触发 Argo 重新同步和 Pod 重启，常用于强制重新拉取模型&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serving.kserve.io/model-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;v1-20231121&amp;#34;&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;predictor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sa-s3-access&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;modelFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;onnx&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-tritonserver&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3://my-ai-models/triton-repo/simple-asr&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;提交代码到 Git：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git add .
&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;git commit -m &lt;span class="s2"&gt;&amp;#34;Add ASR inference service&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;创建 Argo CD Application&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你需要告诉 Argo CD：“去监控我的 Git 仓库，把东西部署到 EKS 里”。&lt;/p&gt;
&lt;p&gt;你可以通过 Argo CD 的 Web UI 点击 &amp;ldquo;New App&amp;rdquo; 创建，或者写一个 YAML 文件（推荐 YAML 方式，这叫 App-of-Apps 模式）。&lt;/p&gt;
&lt;p&gt;创建一个文件 asr-argocd-app.yaml (手动 apply 这个文件)：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argoproj.io/v1alpha1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Application&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;asr-serving-app&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argocd&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repoURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://github.com/your-name/ai-ops.git&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 你的 Git 地址&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetRevision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HEAD&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manifests/asr-service &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 你的 YAML 所在目录&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://kubernetes.default.svc&amp;#39;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 开启自动同步和自愈&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;syncPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;automated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prune&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Git 里删了文件，K8s 里也删掉&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selfHeal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 手动改了 K8s 配置，Argo 会强制改回来&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;syncOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;CreateNamespace=true&lt;/span&gt;&lt;span class="w"&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f asr-argocd-app.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第四阶段：验证与观察&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一旦应用了上面的 Application YAML，奇迹就开始了：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;观察 Argo CD UI：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;你会看到 asr-serving-app 变成 Processing 状态。&lt;/li&gt;
&lt;li&gt;它会画出一棵树：Application -&amp;gt; InferenceService -&amp;gt; Knative Configuration -&amp;gt; Revision -&amp;gt; Deployment -&amp;gt; Pod。&lt;/li&gt;
&lt;li&gt;确保所有图标变绿（Healthy 和 Synced）。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;观察 Pod 状态 (命令行)：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -n ai-serving
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你会看到类似 asr-service-predictor-00001-deployment-xxx 的 Pod。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果是 Init:0 / 1：正在运行 storage-initializer 下载 S3 模型。&lt;/li&gt;
&lt;li&gt;如果是 Running：模型下载完毕，Triton 启动成功&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;日常开发流程&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这套系统搭建好后，以后的日常工作流就是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;算法同学：训练新模型 -&amp;gt; 导出 ONNX -&amp;gt; 上传覆盖 S3 上的 model.onnx。&lt;/li&gt;
&lt;li&gt;运维 / 算法同学：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;修改 Git 里的 inference-service.yaml。&lt;/li&gt;
&lt;li&gt;比如修改 annotations 里的 version: &amp;ldquo;v2&amp;rdquo; 或者修改资源配额。&lt;/li&gt;
&lt;li&gt;git push。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Argo CD：自动检测到 Git 变化 -&amp;gt; 更新 K8s 资源 -&amp;gt; Knative 滚动更新 -&amp;gt; 新 Pod 拉取新模型 -&amp;gt; 流量平滑切换。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这就是最标准的 GitOps 模型部署流程。&lt;/p&gt;
&lt;h3 id="实操-for-vllm预演"&gt;&lt;a href="#%e5%ae%9e%e6%93%8d-for-vllm%e9%a2%84%e6%bc%94" class="header-anchor"&gt;&lt;/a&gt;实操 for vLLM（预演）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一阶段：基础设施准备 (一次性工作)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因为 KServe 可能不知道怎么启动 vLLM，我们需要先在集群里注册一个 “说明书”，告诉 KServe：“当我说用 vllm 时，请拉取这个镜像并运行这个命令”。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建 vLLM 的 ClusterServingRuntime&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;将以下内容保存为 vllm-runtime.yaml 并 kubectl apply -f（或者放入 ArgoCD 管理的基础设施 Git 仓库中）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serving.kserve.io/v1alpha1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterServingRuntime&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-vllm&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.kserve.io/path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/metrics&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.kserve.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8000&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-container&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vllm/vllm-openai:latest &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 使用 vLLM 官方镜像&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;python3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-m&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;vllm.entrypoints.openai.api_server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 这里的 args 是默认值，会被 InferenceService 里的 args 覆盖或追加&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;port=8080&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;model=/mnt/models&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;served-model-name=default&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;trust-remote-code&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HF_HOME&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/tmp/hf&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;32Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;“&lt;/p&gt;
&lt;p&gt;注意：vLLM 默认监听 8000，但 KServe 容器通常要求监听 8080，所以我们在 args 里强制指定 &amp;ndash;port = 8080。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第二阶段：模型上传 (S3)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;vLLM 不需要 Triton 那种 1 / model.onnx 的结构。它只需要标准的 HuggingFace 模型文件夹。&lt;/p&gt;
&lt;p&gt;假设你要部署 Qwen2-7B：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;本地准备&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你需要把 HuggingFace 上的文件下载下来，目录结构大概长这样：&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;Qwen2-7B/
&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;├── config.json
&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;├── tokenizer.json
&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;├── model-00001-of-00004.safetensors
&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;└── model.safetensors.index.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;上传 S3&lt;/li&gt;
&lt;/ol&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;aws s3 cp --recursive Qwen2-7B/ s3://my-ai-models/llm/Qwen2-7B/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第三阶段：Argo CD 部署配置 (GitOps)&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 Git 仓库中（manifests/llm-service/），编写 inference-service.yaml。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这里有几个关键点需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;runtime: 指定刚才创建的 kserve-vllm。&lt;/li&gt;
&lt;li&gt;storageUri: 指向 S3 文件夹。KServe 会把这里面的所有文件下载到 Pod 的 /mnt/models 目录下。&lt;/li&gt;
&lt;li&gt;args: 我们需要覆盖启动参数，告诉 vLLM 模型就在 /mnt/models。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serving.kserve.io/v1beta1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;InferenceService&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;qwen-llm&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# LLM 启动很慢（加载权重需要时间），必须调大健康检查超时时间，否则会被 K8s 杀掉&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serving.knative.dev/progressDeadline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;20m&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 自动扩缩容配置 (LLM通常基于并发或请求数)&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;5&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/minScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 建议 LLM 至少保留1个，因为冷启动太慢了&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaling.knative.dev/maxScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span class="w"&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="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;predictor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sa-s3-access&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 别忘了 S3 权限账号&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;modelFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pytorch &lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kserve-vllm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 对应 ClusterServingRuntime 的名字&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# KServe 会把这个 S3 路径下的内容下载到容器的 /mnt/models&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3://my-ai-models/llm/Qwen2-7B&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 核心参数配置&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;model=/mnt/models &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 必填：指向下载好的模型路径&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;served-model-name=qwen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 服务名称，API调用时用到&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;gpu-memory-utilization=0.9&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 显存占用率&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;max-model-len=4096 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 上下文长度，防止 OOM&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;dtype=float16 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 或 bfloat16&lt;/span&gt;&lt;span class="w"&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="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;32Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 必须有 GPU&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;16&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;64Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;A100&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 建议指定节点类型&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;提交到 Git，Argo CD 检测到后会自动同步。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;创建 Argo CD Application&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你可以通过 Argo CD 的 Web UI 点击 &amp;ldquo;New App&amp;rdquo; 创建，或者写一个 YAML 文件（推荐 YAML 方式，这叫 App-of-Apps 模式）。&lt;/p&gt;
&lt;p&gt;创建一个文件 llm-argocd-app.yaml (手动 apply 这个文件)：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argoproj.io/v1alpha1&lt;/span&gt;&lt;span class="w"&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;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Application&lt;/span&gt;&lt;span class="w"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;llm-serving-app &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 应用名称，要在 Argo 面板上显示的&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argocd &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ArgoCD 安装的命名空间&lt;/span&gt;&lt;span class="w"&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;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repoURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://github.com/your-name/ai-ops.git&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 你的 Git 仓库&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetRevision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HEAD&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manifests/llm-service &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ✅ 关键点：指向存放 vLLM InferenceService 的目录&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://kubernetes.default.svc&amp;#39;&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ai-serving &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 部署的目标命名空间&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 启用自动同步，Git 变了 K8s 自动变&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;syncPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;automated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prune&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Git 里删了，K8s 也删&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selfHeal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# K8s 里被改了，强制还原回 Git 的状态&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;syncOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;CreateNamespace=true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 如果 ai-serving 命名空间不存在，自动创建&lt;/span&gt;&lt;span class="w"&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f llm-argocd-app.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第四阶段：部署后的验证与调用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;vLLM 启动成功后，它提供的是 OpenAI Compatible API。这意味着你可以直接用 OpenAI 的 SDK 或者 curl 来调用，这比 Triton 的 gRPC 接口对开发者更友好。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;验证 Pod 状态&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -n ai-serving
&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="c1"&gt;# 等待状态变为 Running (可能需要几分钟下载模型和加载权重)&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;kubectl logs -f &amp;lt;pod-name&amp;gt; -c kserve-container -n ai-serving
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 看到日志显示 &amp;#34;Uvicorn running on http://0.0.0.0:8080&amp;#34; 即成功&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;调用测试 (在集群内部或通过 Ingress)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;获取服务的 URL&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get isvc qwen-llm -n ai-serving
&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="c1"&gt;# 假设 URL 是 http://qwen-llm.ai-serving.svc.cluster.local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;发送请求（完全兼容 OpenAI 格式）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;curl http://qwen-llm.ai-serving.svc.cluster.local/v1/chat/completions &lt;span class="se"&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; -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="se"&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; -d &lt;span class="s1"&gt;&amp;#39;{
&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="s1"&gt; &amp;#34;model&amp;#34;: &amp;#34;qwen&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 class="s1"&gt; &amp;#34;messages&amp;#34;: [
&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="s1"&gt; {&amp;#34;role&amp;#34;: &amp;#34;system&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;You are a helpful assistant.&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="s1"&gt; {&amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&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; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&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="s1"&gt; &amp;#34;max_tokens&amp;#34;: 100
&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="s1"&gt; }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;vLLM 流程的关键 Checklist&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ClusterServingRuntime: 你的集群里如果没有 kserve-vllm 定义，第一步就会报错，必须先加这个 CRD。&lt;/li&gt;
&lt;li&gt;Timeouts: LLM 动辄 20GB+，下载 + 加载显存需要很久。一定要在 annotations 里设置 progressDeadline 为 20m 或更长，否则 Knative 会以为部署失败并回滚。&lt;/li&gt;
&lt;li&gt;Arguments: 必须通过 args 显式指定 &amp;ndash;model=/mnt/models，因为这是 KServe storageUri 下载的目标路径。&lt;/li&gt;
&lt;li&gt;Resources: 显存和内存给够，否则 vLLM 会报 OOM（Out Of Memory）并 CrashLoopBackOff。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这套流程结合 ArgoCD 后，以后更新 LLM 版本（比如从 Qwen2 换到 Qwen2.5），你只需要：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;上传新模型到 S3 的新目录。&lt;/li&gt;
&lt;li&gt;修改 Git 里的 storageUri。&lt;/li&gt;
&lt;li&gt;ArgoCD 自动同步，Knative 会等待新 Pod 里的 vLLM 完全加载好权重后，才切断旧 Pod 的流量。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="七如何衡量平台是否成功"&gt;&lt;a href="#%e4%b8%83%e5%a6%82%e4%bd%95%e8%a1%a1%e9%87%8f%e5%b9%b3%e5%8f%b0%e6%98%af%e5%90%a6%e6%88%90%e5%8a%9f" class="header-anchor"&gt;&lt;/a&gt;七、如何衡量平台是否成功？
&lt;/h1&gt;&lt;p&gt;一个优秀的模型服务平台，其核心指标应该覆盖 性能、成本、稳定性 几个维度。&lt;/p&gt;
&lt;h2 id="维度一性能与延迟-performance--latency---我们的服务快不快"&gt;&lt;a href="#%e7%bb%b4%e5%ba%a6%e4%b8%80%e6%80%a7%e8%83%bd%e4%b8%8e%e5%bb%b6%e8%bf%9f-performance--latency---%e6%88%91%e4%bb%ac%e7%9a%84%e6%9c%8d%e5%8a%a1%e5%bf%ab%e4%b8%8d%e5%bf%ab" class="header-anchor"&gt;&lt;/a&gt;维度一：性能与延迟 (Performance &amp;amp; Latency) - “我们的服务快不快？”
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;端到端延迟 (End-to-End Latency) - P95 / P99&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 从业务应用发出 API 请求，到收到完整响应的总时间。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是衡量用户体验的黄金标准。我们通常关注 P95（95% 的请求都快于此值）和 P99，因为平均值会掩盖那些最慢的、最影响用户的请求。&lt;/li&gt;
&lt;li&gt;如何衡量？ 从 Istio Gateway 或 Prometheus 中间件获取。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;首 Token 时间 (Time to First Token - TTFT) - (LLM 专属)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 对于生成式模型，从发出请求到收到第一个有意义的 token 所需的时间。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是衡量 LLM 服务 “感知响应速度” 的最关键指标。一个低 TTFT 的模型会让用户感觉 “反应很快”，即使生成全文总时间较长。&lt;/li&gt;
&lt;li&gt;如何衡量？ 需要在客户端或 Transformer 中进行定制化测量&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;每输出 Token 时间 (Time Per Output Token - TPOT) - (LLM 专属)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 生成每个后续 token 的平均时间。它是 (总时间 - TTFT) / (总 token 数 - 1)。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是衡量 LLM “生成速度” 的核心指标。一个低的 TPOT 意味着模型的 “吐字” 速度很快，用户体验流畅。&lt;/li&gt;
&lt;li&gt;如何衡量？ 客户端或 Transformer 中计算。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;吞吐量 (Throughput)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 单位时间内平台能成功处理的请求数。通常用 RPS (Requests Per Second) 或 QPS (Queries Per Second) 表示。&lt;/li&gt;
&lt;li&gt;对于 LLM，一个更有意义的指标可能是 输出 Tokens/秒 (Output Tokens/Second)，因为它综合了并发处理能力和生成速度。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是衡量平台容量和处理能力的上限。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="维度二成本与效率-cost--efficiency---我们的钱花得值不值"&gt;&lt;a href="#%e7%bb%b4%e5%ba%a6%e4%ba%8c%e6%88%90%e6%9c%ac%e4%b8%8e%e6%95%88%e7%8e%87-cost--efficiency---%e6%88%91%e4%bb%ac%e7%9a%84%e9%92%b1%e8%8a%b1%e5%be%97%e5%80%bc%e4%b8%8d%e5%80%bc" class="header-anchor"&gt;&lt;/a&gt;维度二：成本与效率 (Cost &amp;amp; Efficiency) - “我们的钱花得值不值？”
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;GPU 利用率 (GPU Utilization - Compute)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ GPU 计算核心在单位时间内的繁忙程度百分比。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是衡量 “GPU 是否在干活” 的首要指标。一个持续低于 20% 的利用率可能意味着巨大的资源浪费。&lt;/li&gt;
&lt;li&gt;如何衡量？ 通过 NVIDIA DCGM Exporter 在 Prometheus 中采集。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;GPU 显存利用率 (GPU Memory Utilization)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ GPU 显存被占用的百分比。&lt;/li&gt;
&lt;li&gt;为什么重要？ 很多模型（尤其是 LLM）可能计算量不大，但会占用海量显存。高显存占用会限制单卡能部署的模型数量。这是成本优化的另一个关键。&lt;/li&gt;
&lt;li&gt;如何衡量？ 通过 NVIDIA DCGM Exporter 采集。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;闲置实例数 / 缩容至零频率 (Scale-to-Zero Metrics)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 平台上有多少模型服务实例处于 0 副本状态，以及它们进入和退出 0 副本状态的频率。&lt;/li&gt;
&lt;li&gt;为什么重要？ 直接体现了 KServe + Knative Serverless 架构带来的成本节省效果。&lt;/li&gt;
&lt;li&gt;如何衡量？ 从 Knative 的监控指标中获取。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;冷启动延迟 (Cold Start Latency)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 当一个服务从 0 副本状态接收到第一个请求时，从开始拉起 Pod 到成功响应请求的总时间。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是 Serverless 模式为了节省成本而付出的性能代价。你需要监控并优化它，确保它在可接受的范围内。&lt;/li&gt;
&lt;li&gt;如何衡量？ 结合 Knative 指标和应用日志进行分析。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="维度三稳定性与可用性-stability--availability--我们的服务稳不稳"&gt;&lt;a href="#%e7%bb%b4%e5%ba%a6%e4%b8%89%e7%a8%b3%e5%ae%9a%e6%80%a7%e4%b8%8e%e5%8f%af%e7%94%a8%e6%80%a7-stability--availability--%e6%88%91%e4%bb%ac%e7%9a%84%e6%9c%8d%e5%8a%a1%e7%a8%b3%e4%b8%8d%e7%a8%b3" class="header-anchor"&gt;&lt;/a&gt;维度三：稳定性与可用性 (Stability &amp;amp; Availability)- “我们的服务稳不稳？”
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;服务可用性 (Availability)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 在规定时间内，服务能够正常响应的请求比例。通常目标是 99.9% 或 99.99%。&lt;/li&gt;
&lt;li&gt;为什么重要？ 这是衡量服务可靠性的最终标准。&lt;/li&gt;
&lt;li&gt;如何衡量？ (成功请求数 / 总请求数) * 100%。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;错误率 (Error Rate)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 返回 5xx（服务器错误）状态码的请求比例。&lt;/li&gt;
&lt;li&gt;为什么重要？ 错误率的飙升是服务出现严重问题的最直接信号。需要设置告警。&lt;/li&gt;
&lt;li&gt;如何衡量？ 从 Istio Gateway 或 Prometheus 中间件获取。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Pod 重启次数 (Pod Restart Count)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;是什么？ 模型服务 Pod 的重启次数。&lt;/li&gt;
&lt;li&gt;为什么重要？ 频繁的重启（特别是 CrashLoopBackOff 状态）表明代码存在 Bug、内存溢出（OOM Killed）或配置错误。&lt;/li&gt;
&lt;li&gt;如何衡量？ 从 Kubernetes API 直接获取。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;短期看，最重要的指标有这几个：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端到端延迟 (End-to-End Latency)&lt;/li&gt;
&lt;li&gt;首 Token 时间 (Time to First Token - TTFT)&lt;/li&gt;
&lt;li&gt;吞吐量 (Throughput)&lt;/li&gt;
&lt;li&gt;GPU 利用率&lt;/li&gt;
&lt;li&gt;服务可用性&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-11-30-ai-mo-xing-tui-li-ping-tai-jia-gou-she-ji-yu-shi-jian/018-482b1ef1.png"&gt;&lt;/p&gt;
&lt;p&gt;长期看其实还要加上模型效果指标，量化 “准确率” 与 “生成质量”。&lt;/p&gt;</description></item><item><title>今日 AI 情报</title><link>https://xiaobox.github.io/p/2025-11-09-jin-ri-ai-qing-bao/</link><pubDate>Sun, 09 Nov 2025 02:02:43 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-11-09-jin-ri-ai-qing-bao/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-11-09-jin-ri-ai-qing-bao/cover.jpg" alt="Featured image of post 今日 AI 情报" /&gt;&lt;p&gt;题图：伊丽莎白女王工程奖获奖的 AI 界群星&lt;/p&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;打败GPT5的Kimi K2 Thinking，真就只会写代码吗？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过多种场景测试评估Kimi K2 Thinking的表现，包括编程、3D模拟、创意写作、复杂推理和架构对比分析&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=Mzg3MTk3NzYzNw==&amp;amp;mid=2247501984&amp;amp;idx=1&amp;amp;sn=37f389259ce74b4a758ec0e86eab75b7&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;打败GPT5的Kimi K2 Thinking，真就只会写代码吗？&lt;/a&gt;2. Artificial Analysis评测新鲜出炉：Kimi K2 thinking位居世界第二，开源第一&lt;/p&gt;
&lt;p&gt;Artificial Analysis评测显示Kimi K2 Thinking模型在智能体任务中表现突出，以67分位居世界第二、开源第一，但存在生成冗长和延迟问题&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=Mzg3MTkxMjYzOA==&amp;amp;mid=2247509512&amp;amp;idx=1&amp;amp;sn=eed867be8beabee0832f0cb0de6ce22d&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;Artificial Analysis评测新鲜出炉：Kimi K2 thinking位居世界第二，开源第一&lt;/a&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;解析！大模型中的ScalingLaw的概念、推导以及反ScalingLaw的场景&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;全面详细介绍大模型ScalingLaw的概念、数学推导、实际应用场景及反ScalingLaw现象，为大模型训练提供理论指导&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=MzU3NjE4NjQ4MA==&amp;amp;mid=2247554991&amp;amp;idx=1&amp;amp;sn=00b7659c7515a758a2e6b131ab6af0d8&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;解析！大模型中的ScalingLaw的概念、推导以及反ScalingLaw的场景&lt;/a&gt;&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;LLM首次达到人类语言专家水平！OpenAI o1拿下拆解句法、识别歧义、推理音律&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;研究表明OpenAI o1模型在处理语言递归结构、识别句法歧义和音韵推理等方面表现出接近人类语言学专家的能力&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=MzI3MTA0MTk1MA==&amp;amp;mid=2652643197&amp;amp;idx=3&amp;amp;sn=00aa710798c4378d6ad61459a7fadaa7&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;LLM首次达到人类语言专家水平！OpenAI o1拿下拆解句法、识别歧义、推理音律&lt;/a&gt;&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;SimKO：缓解RLVR训练中的概率过度集中，优化pass@K性能&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;介绍SimKO算法如何通过非对称梯度调节解决RLVR训练中的概率过度集中问题，优化大语言模型在数学推理任务上的pass@K性能&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&amp;amp;mid=2651000611&amp;amp;idx=3&amp;amp;sn=b1a46fd93fbaeda8fac56b8843b62335&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;SimKO：缓解RLVR训练中的概率过度集中，优化pass@K性能&lt;/a&gt;&lt;/p&gt;
&lt;ol start="6"&gt;
&lt;li&gt;6.4万star的开源智能体框架全面重构！OpenHands重大升级，叫板OpenAI和谷歌&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;详细介绍了OpenHands V1智能体框架的架构重构，包括四项设计原则和技术特性，以及与OpenAI和Google产品的比较和性能评估&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&amp;amp;mid=2651000611&amp;amp;idx=2&amp;amp;sn=73884b8d2de10d1cc96af4f06d915a17&amp;amp;scene=21#wechat_redirect" target="_blank" rel="noopener"
 &gt;6.4万star的开源智能体框架全面重构！OpenHands重大升级，叫板OpenAI和谷歌&lt;/a&gt;&lt;/p&gt;
&lt;ol start="7"&gt;
&lt;li&gt;Building the First Agentic Government with Ukraine&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;介绍ElevenLabs与乌克兰政府合作建设首个代理型政府的伙伴关系，将AI应用于公共服务&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://elevenlabs.io/blog/building-the-first-agentic-government-with-ukraine" target="_blank" rel="noopener"
 &gt;https://elevenlabs.io/blog/building-the-first-agentic-government-with-ukraine&lt;/a&gt;&lt;/p&gt;
&lt;ol start="8"&gt;
&lt;li&gt;ICCV涌现自动驾驶新范式：统一世界模型VLA，用训练闭环迈向L4&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;文章深入分析理想汽车在ICCV上展示的统一世界模型VLA，介绍了自动驾驶从数据闭环到训练闭环的技术进化，以及理想在AI领域的技术布局&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.qbitai.com/2025/11/350282.html" target="_blank" rel="noopener"
 &gt;https://www.qbitai.com/2025/11/350282.html&lt;/a&gt;&lt;/p&gt;
&lt;ol start="9"&gt;
&lt;li&gt;机器人训练，北京男大有了技能玩法&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;北京通用人工智能研究院研究团队开发了COLA方法，实现了人形机器人仅依靠本体感知而无需外部传感器就能与人类协作搬运物体的技术突破&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.qbitai.com/2025/11/350301.html" target="_blank" rel="noopener"
 &gt;https://www.qbitai.com/2025/11/350301.html&lt;/a&gt;&lt;/p&gt;
&lt;ol start="10"&gt;
&lt;li&gt;LLM强化学习新框架！UCSD多智能体训练框架让LLM工具调用能力暴增5.8倍&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;研究者提出通用多智能体强化学习框架PettingLLMs，通过树状采样与角色化奖励机制，显著提升LLM工具调用能力和多智能体协作效果&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.qbitai.com/2025/11/350331.html" target="_blank" rel="noopener"
 &gt;https://www.qbitai.com/2025/11/350331.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>当“刷分”不再性感：为什么说姚顺雨的“AI下半场”是我们每个人的必修课？</title><link>https://xiaobox.github.io/p/2025-09-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/</link><pubDate>Sun, 14 Sep 2025 09:03:45 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-09-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-09-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/cover.jpg" alt="Featured image of post 当“刷分”不再性感：为什么说姚顺雨的“AI下半场”是我们每个人的必修课？" /&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;本文我将对 2025 年上半年在技术社区引发大量讨论与转引的一篇名为 《The Second Half》（AI 的下半场）著名博客进行介绍、翻译与分析，希望通过我的介绍和分析能够让各位伙伴对 AI 领域在宏观叙事上有个清晰的了解。以便在今后的学习和研究中有更好的定位和方向。&lt;/p&gt;
&lt;h2 id="作者简介"&gt;&lt;a href="#%e4%bd%9c%e8%80%85%e7%ae%80%e4%bb%8b" class="header-anchor"&gt;&lt;/a&gt;作者简介
&lt;/h2&gt;&lt;h3 id="概览"&gt;&lt;a href="#%e6%a6%82%e8%a7%88" class="header-anchor"&gt;&lt;/a&gt;概览
&lt;/h3&gt;&lt;p&gt;姚顺雨（Shunyu Yao）&lt;/p&gt;
&lt;p&gt;姚顺雨是近年“语言智能体（Language Agents）”方向的代表性研究者之一，因提出 ReAct、参与 Tree of Thoughts (ToT)、WebShop、SWE-bench / SWE-agent、τ-bench 等工作受到学界与产业关注；在 2025 年以《The Second Half》一文提出“AI 的下半场应从‘解决问题’转向‘定义问题’，评估将比训练更重要”的观点。其个人主页长期自述为“研究智能体的 OpenAI 研究员”。&lt;/p&gt;
&lt;h3 id="教育与经历"&gt;&lt;a href="#%e6%95%99%e8%82%b2%e4%b8%8e%e7%bb%8f%e5%8e%86" class="header-anchor"&gt;&lt;/a&gt;教育与经历
&lt;/h3&gt;&lt;p&gt;●中学阶段获 NOI 信息学银牌、安徽省理科高考第 3 名&lt;/p&gt;
&lt;p&gt;●本科：清华大学 交叉信息研究院“姚班”（学生时期就读于姚班，多场高校活动与官方简介均有明确表述）。在校期间担任“姚班学生联合会主席”、清华说唱社联合创始人。&lt;/p&gt;
&lt;p&gt;●博士：普林斯顿大学计算机系（导师 Karthik Narasimhan）。博士阶段获普林斯顿研究生院 Harold W. Dodds Fellowship；其博士论文主题为 Language Agents: From Next-Token Prediction to Digital Automation。&lt;/p&gt;
&lt;p&gt;●实习/合作经历（学生时期）：多场讲座与高校活动页称其曾在 Google、Microsoft、MIT 等从事研究与合作。&lt;/p&gt;
&lt;h3 id="代表性研究与贡献"&gt;&lt;a href="#%e4%bb%a3%e8%a1%a8%e6%80%a7%e7%a0%94%e7%a9%b6%e4%b8%8e%e8%b4%a1%e7%8c%ae" class="header-anchor"&gt;&lt;/a&gt;代表性研究与贡献
&lt;/h3&gt;&lt;p&gt;●ReAct（Reason + Act）：提出让大模型在“推理轨迹”与“动作”之间交替，从而一边思考一边使用工具/检索/交互，ICLR 2023。此范式被广泛用作后续智能体系统的基础能力模块。arXiv&lt;/p&gt;
&lt;p&gt;●Tree of Thoughts（ToT）：将“多路径思维”引入复杂问题求解的推理过程中，NeurIPS 2023。NeurIPS Proceedings&lt;/p&gt;
&lt;p&gt;●WebShop：一个规模化网页购物交互环境（NeurIPS 2022），推动语言智能体在真实网页环境中的训练与评估。NeurIPS Papers&lt;/p&gt;
&lt;p&gt;●SWE-bench（ICLR 2024 Oral）/ SWE-agent（NeurIPS 2024）：以前者把“修真实 GitHub issue”作为评测单位，后者设计“Agent-Computer Interface”让代理能像人一样使用电脑完成工程任务，推动贴近实际的软件工程评测与系统化落地。OpenReview NeurIPS Proceedings&lt;/p&gt;
&lt;p&gt;●τ-bench（ICLR 2025）：强调在真实领域的规则与用户交互下评测语言智能体（工具-代理-用户三方互动），契合其“评估更重要”的研究取向。OpenReview&lt;/p&gt;
&lt;h3 id="近期动态2025-年-9-月"&gt;&lt;a href="#%e8%bf%91%e6%9c%9f%e5%8a%a8%e6%80%812025-%e5%b9%b4-9-%e6%9c%88" class="header-anchor"&gt;&lt;/a&gt;近期动态（2025 年 9 月）
&lt;/h3&gt;&lt;p&gt;●已从 OpenAI 离职：彭博社报道称 OpenAI 已确认其离职，但未说明去向。&lt;/p&gt;
&lt;p&gt;●去向传闻与澄清：有媒体称其被 腾讯聘用；与此同时，腾讯方面辟谣了“上亿年薪”等细节，并未明确确认其入职与否。因此目前去向仍存不确定性。&lt;/p&gt;
&lt;h1 id="原文和翻译"&gt;&lt;a href="#%e5%8e%9f%e6%96%87%e5%92%8c%e7%bf%bb%e8%af%91" class="header-anchor"&gt;&lt;/a&gt;原文和翻译
&lt;/h1&gt;&lt;h2 id="原文"&gt;&lt;a href="#%e5%8e%9f%e6%96%87" class="header-anchor"&gt;&lt;/a&gt;原文
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://ysymyth.github.io/The-Second-Half/" target="_blank" rel="noopener"
 &gt;https://ysymyth.github.io/The-Second-Half/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="翻译"&gt;&lt;a href="#%e7%bf%bb%e8%af%91" class="header-anchor"&gt;&lt;/a&gt;翻译
&lt;/h2&gt;&lt;p&gt;AI 的下半场&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一句话总结：我们正处于人工智能（AI）的中场休息时间。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;几十年来，人工智能的发展主要围绕着开发新的训练方法和模型。这一策略卓有成效：从在国际象棋和围棋上击败世界冠军，到在 SAT（学术能力评估测试）和律师资格考试中超越大多数人类，再到斩获国际数学奥林匹克（IMO）和国际信息学奥林匹克（IOI）金牌。在这些载入史册的里程碑——深蓝（DeepBlue）、AlphaGo、GPT-4 及 o 系统模型——背后，是 AI 方法论的根本性创新：搜索、深度强化学习（deep RL）、规模化（scaling）和推理（reasoning）。一切都在随着时间不断进步。&lt;/p&gt;
&lt;p&gt;那么，现在究竟有何不同？&lt;/p&gt;
&lt;p&gt;简而言之：&lt;strong&gt;强化学习（RL）终于奏效了&lt;/strong&gt;。更准确地说：&lt;strong&gt;强化学习终于具备了泛化能力&lt;/strong&gt;。在经历了数次重要的弯路并累积了一系列里程碑之后，我们终于找到了一个行之有效的“秘方”，能够利用语言和推理解决广泛的强化学习任务。哪怕在一年前，如果你告诉大多数 AI 研究者，同一个“秘方”能够应对软件工程、创意写作、IMO 级别的数学、键鼠操作以及长篇问答等任务，他们可能会觉得你在痴人说梦。这些任务中的任何一个都极其困难，许多研究者穷尽整个博士生涯也只能专注于其中一个狭窄的领域。&lt;/p&gt;
&lt;p&gt;然而，这一切确实发生了&lt;/p&gt;
&lt;p&gt;那么，接下来会发生什么？AI 的下半场——从现在开始——将把焦点&lt;strong&gt;从解决问题转向定义问题&lt;/strong&gt;。在这个新时代，&lt;strong&gt;评估（evaluation）将比训练更加重要&lt;/strong&gt;。我们将不再仅仅追问“我们能否训练一个模型来解决 X 问题？”，而是要问“我们究竟应该训练 AI 去做什么，以及如何衡量真正的进展？” 要在下半场脱颖而出，我们需要及时转变思维模式和技能组合，或许要更像一名产品经理。&lt;/p&gt;
&lt;h3 id="上半场"&gt;&lt;a href="#%e4%b8%8a%e5%8d%8a%e5%9c%ba" class="header-anchor"&gt;&lt;/a&gt;上半场
&lt;/h3&gt;&lt;p&gt;要理解上半场，只需看看它的赢家。你认为迄今为止最具影响力的 AI 论文是哪些？&lt;/p&gt;
&lt;p&gt;我在斯坦福大学的 224N 课程上做过这个小调查，答案不出所料：Transformer、AlexNet、GPT-3 等等。这些论文有何共同之处？它们都提出了某些根本性的突破，用以训练出更好的模型。同时，它们也通过在某些基准测试（benchmarks）上展示出（显著的）性能提升而成功发表。&lt;/p&gt;
&lt;p&gt;然而，这背后还有一个潜在的共性：这些“赢家”都是&lt;strong&gt;训练方法或模型&lt;/strong&gt;，而非基准测试或任务。即便是被认为最具影响力的基准测试 ImageNet，其引用量也不及 AlexNet 的三分之一。方法与基准测试之间的这种反差在其他领域更为悬殊——例如，Transformer 模型主要使用的基准是 WMT'14，其相关研讨会报告的引用量约为 1,300 次，而 Transformer 论文的引用量已超过 160,000 次。&lt;/p&gt;
&lt;p&gt;&lt;img alt="first\\_half" 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-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/001-00c7b0a8.png"&gt;&lt;/p&gt;
&lt;p&gt;这揭示了上半场的游戏规则：&lt;strong&gt;专注于构建新的模型和方法，而评估和基准测试则处于次要地位&lt;/strong&gt;（尽管它们对于维持论文发表体系的运转是必需的）。&lt;/p&gt;
&lt;p&gt;为什么会这样？一个重要原因是，在 AI 的上半场，&lt;strong&gt;方法比任务更困难，也更激动人心&lt;/strong&gt;。从零开始创造一种新算法或模型架构——例如反向传播算法、卷积网络（AlexNet）或 GPT-3 中使用的 Transformer——需要非凡的洞察力和工程能力。相比之下，为 AI 定义任务则往往显得更为直接：我们只是将人类已有的任务（如翻译、图像识别或国际象棋）转化为基准测试。这其中并不需要太多的洞察力，甚至工程量也不大。&lt;/p&gt;
&lt;p&gt;此外，方法通常比单个任务更具通用性和广泛适用性，这使其价值尤为突出。例如，Transformer 架构最终推动了计算机视觉（CV）、自然语言处理（NLP）、强化学习（RL）等多个领域的进步，其影响远远超出了最初证明其有效性的那个单一数据集（WMT'14 翻译任务）。一个优秀的新方法之所以能够提升多个不同基准测试的性能，正是因为它既简单又通用，其影响力因此超越了单个任务的范畴。&lt;/p&gt;
&lt;p&gt;这场游戏持续了几十年，催生了改变世界的思想和突破，其成果体现在各个领域基准测试性能的不断提升上。那么，为何游戏规则会发生改变？因为这些思想和突破的积累，最终在创造一个解决任务的有效“秘方”上引发了质变。&lt;/p&gt;
&lt;h3 id="那个秘方"&gt;&lt;a href="#%e9%82%a3%e4%b8%aa%e7%a7%98%e6%96%b9" class="header-anchor"&gt;&lt;/a&gt;那个秘方
&lt;/h3&gt;&lt;p&gt;这个“秘方”是什么？不出所料，其配方包括：&lt;strong&gt;大规模语言预训练、规模化（数据和算力），以及推理与行动（reasoning and acting）&lt;/strong&gt; 的理念。这些词听起来可能像是你在旧金山每天都能听到的流行语，但为何称之为“秘方”？&lt;/p&gt;
&lt;p&gt;我们可以通过强化学习（RL） 的视角来理解这一点。RL 常被视为 AI 的“终局之战”——毕竟，从理论上讲，RL 保证能赢得游戏；从经验上看，也很难想象任何超人系统（如 AlphaGo）的诞生能脱离 RL。&lt;/p&gt;
&lt;p&gt;在 RL 中，有三个关键组成部分：&lt;strong&gt;算法（algorithm）、环境（environment）和先验知识（priors）&lt;/strong&gt;。长期以来，RL 研究者主要关注算法——即智能体学习方式的智力核心（例如 REINFORCE、DQN、TD-learning、Actor-Critic、PPO、TRPO 等）——而将环境和先验知识视为固定或次要的。例如，Sutton 和 Barto 的经典教科书通篇都在讲算法，几乎没有涉及环境或先验知识。&lt;/p&gt;
&lt;p&gt;然而，在深度强化学习时代，环境在经验层面上的重要性变得显而易见：一个算法的性能往往高度依赖于其开发和测试所处的特定环境。如果忽略环境，你可能会构建出一个只在“玩具”环境中表现优异的“最优”算法。那么，我们为何不先弄清楚我们真正想解决的环境是什么，然后再寻找最适合该环境的算法呢？&lt;/p&gt;
&lt;p&gt;这正是 OpenAI 最初的计划。它创建了 Gym，一个包含各种游戏的标准 RL 环境，随后又启动了 World of Bits 和 Universe 项目，试图将整个互联网或计算机变成一个游戏。这个计划听起来不错，不是吗？一旦我们将所有数字世界都转化为一个环境，再用聪明的 RL 算法去解决它，我们就拥有了数字化的通用人工智能（AGI）。&lt;/p&gt;
&lt;p&gt;计划虽好，但并非完全奏效。OpenAI 在这条道路上取得了巨大进展，利用 RL 解决了 Dota 游戏、机械手控制等问题。但它从未接近解决计算机通用操作或网页浏览的难题，并且在一个领域有效的 RL 智能体也无法迁移到另一个领域。&lt;strong&gt;有些东西缺失了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;直到 GPT-2 或 GPT-3 出现之后，我们才发现，那块缺失的拼图是&lt;strong&gt;先验知识&lt;/strong&gt;。你需要强大的语言预训练来将通用的常识和语言知识“蒸馏”到模型中，这些模型随后可以被微调，成为网络（WebGPT）或聊天（ChatGPT）智能体（并改变世界）。事实证明，&lt;strong&gt;RL 最重要的部分，或许既不是 RL 算法，也不是环境，而是先验知识&lt;/strong&gt;——而这些先验知识的获取方式可以与 RL 毫无关系。&lt;/p&gt;
&lt;p&gt;语言预训练为聊天任务创造了良好的先验知识，但对于控制计算机或玩视频游戏，效果却不尽相同。为什么？因为这些领域与互联网文本的分布相去甚远，简单地在这些领域上进行监督微调（SFT）或强化学习，其泛化能力很差。我在 2019 年就注意到了这个问题，当时 GPT-2 刚发布，我基于它进行 SFT/RL 来解决文字冒险游戏——由此诞生的 CALM 是世界上第一个基于预训练语言模型构建的智能体。但这个智能体需要数百万步的 RL 训练才能在一个游戏中取得进展，而且无法迁移到新的游戏。尽管这完全符合 RL 的特性，对 RL 研究者来说也见怪不怪，但我却觉得很奇怪，因为我们人类可以轻松地玩一个新游戏，并且在零样本（zero-shot）的情况下表现得好得多。然后，我迎来了人生中最早的“顿悟时刻”之一——我们之所以能够泛化，是因为我们可以选择做的不仅仅是“走向 2 号柜子”、“用 1 号钥匙打开 3 号宝箱”或“用剑杀死地牢里的怪物”，我们还可以选择去&lt;strong&gt;思考&lt;/strong&gt;，比如：“地牢很危险，我需要一把武器来战斗。这里没有现成的武器，也许我需要在锁着的箱子或宝箱里找找看。3 号宝箱在 2 号柜子里，我先去那里把它打开。”&lt;/p&gt;
&lt;p&gt;&lt;img alt="reasoning" 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-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/002-93e8700b.png"&gt;&lt;/p&gt;
&lt;p&gt;思考，或者说&lt;strong&gt;推理（reasoning）&lt;/strong&gt;，是一种奇特的行动——它不直接影响外部世界，但推理的空间却是开放式的、组合爆炸式的无限——你可以思考一个词、一个句子、一整段话，甚至是 10000 个随机的英文单词，而你周围的世界并不会立即发生改变。在经典的 RL 理论中，这简直是一场灾难，会让决策变得不可能。想象一下，你需要在两个盒子中选择一个，其中一个装有 100 万美元，另一个是空的。你的期望收益是 50 万美元。现在，想象我加入了无限个空盒子。你的期望收益就变成了零。但是，通过将推理加入任何 RL 环境的行动空间，我们利用了语言预训练的先验知识来实现泛化，并且能够在测试时为不同的决策灵活分配计算资源。这是一件非常神奇的事情，很抱歉我在这里没能完全解释清楚，或许我需要再写一篇博客来专门阐述。欢迎阅读 ReAct 论文来了解关于智能体推理的最初构想，并感受我当时的一些想法。目前，我的直观解释是：&lt;strong&gt;尽管你加入了无限个空盒子，但你在过往的各种游戏中已经见过它们无数次，选择这些空盒子的经验能让你在任何给定的游戏中更好地选中有钱的那个盒子。&lt;/strong&gt; 我的抽象解释则是：&lt;strong&gt;语言通过智能体中的推理来实现泛化&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;一旦我们拥有了正确的 RL 先验知识（语言预训练）和 RL 环境（将语言推理作为行动加入），事实证明 RL 算法本身反而是最微不足道的部分。于是，我们看到了 o-系列、R1、Deep Research 的计算机操作智能体，以及未来更多类似的模型。这是多么具有讽刺意味的转折！长期以来，RL 研究者对算法的关心远超环境，更没有人关注过先验知识——所有的 RL 实验基本上都是从零开始。但我们花了几十年的弯路才意识到，&lt;strong&gt;也许我们优先级的排序本应完全颠倒&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;但正如史蒂夫·乔布斯所说：你无法预见未来的点滴如何串联，只有在回顾过去时，才能将它们连接起来。&lt;/p&gt;
&lt;h3 id="下半场"&gt;&lt;a href="#%e4%b8%8b%e5%8d%8a%e5%9c%ba" class="header-anchor"&gt;&lt;/a&gt;下半场
&lt;/h3&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;strong&gt;这个“秘方”已经将提升基准测试性能的过程标准化和工业化了，不再需要太多新的思想&lt;/strong&gt;。 随着这个“秘方”的规模化和泛化能力越来越强，你为某个特定任务设计的新方法可能只能带来 5% 的提升，而下一个 o-系列模型即便没有专门针对这个任务，也能带来 30% 的提升。&lt;/p&gt;
&lt;p&gt;●即使我们创造出更难的基准测试，它们也很快（而且越来越快地）被这个“秘方”所解决。我的同事 Jason Wei 制作了一张精美的图表，很好地展示了这一趋势。&lt;/p&gt;
&lt;p&gt;&lt;img alt="progress" 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-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/003-f030a6f7.jpg"&gt;&lt;/p&gt;
&lt;p&gt;那么，下半场还剩下什么可玩的？如果不再需要新颖的方法，而更难的基准测试也只会被越来越快地解决，我们该做什么？&lt;/p&gt;
&lt;p&gt;我认为，我们应该&lt;strong&gt;从根本上重新思考评估&lt;/strong&gt;。这不仅仅意味着创造更新、更难的基准测试，而是要从根本上&lt;strong&gt;质疑现有的评估设定，并创造新的设定&lt;/strong&gt;，从而迫使我们去发明超越现有“秘方”的新方法。这很困难，因为人类有惯性，很少会去质疑基本的假设——你只是想当然地接受它们，而没有意识到它们是假设，而非定律。&lt;/p&gt;
&lt;p&gt;为了解释这种惯性，假设你发明了历史上最成功的评估方法之一，它基于人类的考试。这在 2021 年是一个极其大胆的想法，但 3 年后，这个方向已经饱和了。你会怎么做？很可能你会去创造一个更难的考试。或者，假设你解决了简单的编程任务。你会怎么做？很可能你会去找更难的编程任务，直到达到 IOI 金牌的水平。&lt;/p&gt;
&lt;p&gt;惯性是人之常情，但问题在于：AI 已经在国际象棋和围棋上击败了世界冠军，在 SAT 和律师资格考试中超越了大多数人类，并在 IOI 和 IMO 中达到了金牌水平。但&lt;strong&gt;世界并没有因此发生太大改变&lt;/strong&gt;，至少从经济和 GDP 的角度来看是这样。&lt;/p&gt;
&lt;p&gt;我称之为&lt;strong&gt;效用问题（utility problem）&lt;/strong&gt;，并认为这是 AI 领域最重要的问题。&lt;/p&gt;
&lt;p&gt;或许我们很快就能解决这个效用问题，或许不能。但无论如何，这个问题的根源可能简单得令人迷惑：&lt;strong&gt;我们的评估设定在很多基本方面都与真实世界的设定不同&lt;/strong&gt;。举两个例子：&lt;/p&gt;
&lt;p&gt;1.&lt;strong&gt;评估“应该”是自动运行的&lt;/strong&gt;，所以通常一个智能体接收一个任务输入，自主完成任务，然后获得一个任务奖励。但在现实中，智能体在整个任务过程中必须与人类互动——你不会只给客服发一条超长的信息，然后等 10 分钟，就指望收到一个详尽的回复解决所有问题。通过质疑这种设定，新的基准测试被发明出来，它们要么将真实人类纳入评估环路（如 Chatbot Arena），要么使用用户模拟（如 tau-bench）。&lt;/p&gt;
&lt;p&gt;&lt;img alt="tau" 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-14-dang-shua-fen-bu-zai-xing-gan-wei-shen-me-shuo-yao-shun-yu-d/004-1022aa7e.png"&gt;&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;评估“应该”是独立同分布（i.i.d.）的&lt;/strong&gt;。如果你有一个包含 500 个任务的测试集，你会独立地运行每个任务，然后对任务指标取平均，得到一个总指标。但在现实中，你是&lt;strong&gt;按顺序&lt;/strong&gt;解决任务，而非并行。一位谷歌的软件工程师随着对代码库越来越熟悉，解决问题的效率会越来越高，但一个软件工程师智能体在同一个代码库中解决多个问题时，却无法获得这种熟悉度。我们显然需要长时记忆的方法（这类方法也确实存在），但学术界没有合适的基准测试来证明这种需求的必要性，甚至没有足够的勇气去质疑作为机器学习基础的 i.i.d. 假设。&lt;/p&gt;
&lt;p&gt;这些假设“一直”以来就是如此，在 AI 的上半场，基于这些假设来开发基准测试并没有问题，因为当智能水平较低时，提升智能通常也能提升效用。但现在，通用的“秘方”在这些假设下几乎是万能的。因此，下半场的新游戏规则是：&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;strong&gt;除非你创造出能打破这个“秘方”的新假设&lt;/strong&gt;。那时，你才能做出真正改变游戏规则的研究。&lt;/p&gt;
&lt;p&gt;欢迎来到下半场！&lt;/p&gt;
&lt;h1 id="深度解析"&gt;&lt;a href="#%e6%b7%b1%e5%ba%a6%e8%a7%a3%e6%9e%90" class="header-anchor"&gt;&lt;/a&gt;深度解析
&lt;/h1&gt;&lt;p&gt;《The Second Half》 提示了我们所处的人工智能时代的一个根本性的范式转移&lt;/p&gt;
&lt;h2 id="对上半场的深刻反思"&gt;&lt;a href="#%e5%af%b9%e4%b8%8a%e5%8d%8a%e5%9c%ba%e7%9a%84%e6%b7%b1%e5%88%bb%e5%8f%8d%e6%80%9d" class="header-anchor"&gt;&lt;/a&gt;对“上半场”的深刻反思
&lt;/h2&gt;&lt;h3 id="上半场的游戏哲学更好等于更高分"&gt;&lt;a href="#%e4%b8%8a%e5%8d%8a%e5%9c%ba%e7%9a%84%e6%b8%b8%e6%88%8f%e5%93%b2%e5%ad%a6%e6%9b%b4%e5%a5%bd%e7%ad%89%e4%ba%8e%e6%9b%b4%e9%ab%98%e5%88%86" class="header-anchor"&gt;&lt;/a&gt;上半场的游戏哲学：“更好”等于“更高分”
&lt;/h3&gt;&lt;p&gt;上半场的竞争逻辑是极其纯粹且清晰的：通过创造更优秀的模型和算法，在公认的、标准化的基准测试（Benchmark）上取得更高的分数。 无论是计算机视觉领域的 ImageNet 挑战赛，还是自然语言处理领域的 GLUE、SuperGLUE 排行榜，整个学术界和工业界都被卷入了一场围绕“SOTA”（State-of-the-Art）的军备竞赛。&lt;/p&gt;
&lt;p&gt;这种模式的底层信仰是：智能本身是线性可扩展的，只要模型在基准测试上的表现越好，它在真实世界中的应用潜力就越大。 这在很长一段时间内是正确的。AlexNet 在 ImageNet 上的胜利，直接催生了计算机视觉的黄金十年；Transformer 架构的提出，则奠定了整个大语言模型时代的基础。我们专注于“造锤子”，因为市场上有无数显而易见的“钉子”等着我们去敲。&lt;/p&gt;
&lt;h3 id="成功的惯性与范式之疲的显现"&gt;&lt;a href="#%e6%88%90%e5%8a%9f%e7%9a%84%e6%83%af%e6%80%a7%e4%b8%8e%e8%8c%83%e5%bc%8f%e4%b9%8b%e7%96%b2%e7%9a%84%e6%98%be%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;成功的“惯性”与“范式之疲”的显现
&lt;/h3&gt;&lt;p&gt;然而，当一个范式取得巨大成功后，它会产生巨大的惯性，这种惯性会掩盖其底层逻辑的悄然变化。我们正面临着“上半场范式”的系统性疲劳，其症状体现在三个方面：&lt;/p&gt;
&lt;p&gt;●症状一：能力的商品化与竞争的同质化。“通用秘方”（大规模预训练 + 规模化 + 推理/行动）的出现，是一个颠覆性的事件。它意味着，世界顶级的感知、生成和基础推理能力，正在迅速地从少数巨头的“独门秘籍”变为一种类似水和电的、可按需取用的“基础设施”。无论是通过 API 调用 OpenAI 的模型，还是利用强大的开源模型（如 Llama 系列），任何一个具备基本工程能力的公司，都能站在巨人的肩膀上。这直接导致，单纯依靠基础模型能力本身来构建的护城河，其水位正在以肉眼可见的速度下降。我们正进入一个“后模型时代”，竞争的焦点必然从模型本身转移到更高维度的层面。&lt;/p&gt;
&lt;p&gt;●症状二：“效用问题”（The Utility Problem）的尖锐化。这是《The Second Half》一文最核心、也最深刻的洞察。我们看到无数令人惊叹的 Demo：AI 在 SAT、律师资格考试、甚至奥数竞赛中击败人类。但当我们把目光投向宏观经济指标，如劳动生产率的增长，却发现其影响远未达到预期的“奇点”时刻。在企业内部，我们同样能感受到这种“演示与部署之间的鸿沟” 。一个能在测试集上达到 95% 准确率的模型，部署到真实、混乱的业务流程中时，其表现可能会断崖式下跌。这种“高分低能”的现象，深刻地揭示了我们上半场评估体系的根本性缺陷：它奖励的是在无菌实验室里解决抽象问题的能力，而非在真实世界中创造可靠价值的能力。&lt;/p&gt;
&lt;p&gt;●症状三：边际成本的急剧攀升与创新动力的衰减。追逐 SOTA 的游戏，其成本正在变得越来越昂贵。将一个模型的性能从 90% 提升到 91%，可能需要消耗双倍的算力和数据。这种投入产出比的急剧下降，使得除了少数资源雄厚的玩家外，大多数公司都无法也不应参与这场“军备竞赛”。更危险的是，对“刷分”的过度关注，可能会扼杀掉那些无法立即在现有基准上体现价值、但却可能开辟全新路径的颠覆性创新。&lt;/p&gt;
&lt;h2 id="下半场的本质在不确定性世界中定义价值"&gt;&lt;a href="#%e4%b8%8b%e5%8d%8a%e5%9c%ba%e7%9a%84%e6%9c%ac%e8%b4%a8%e5%9c%a8%e4%b8%8d%e7%a1%ae%e5%ae%9a%e6%80%a7%e4%b8%96%e7%95%8c%e4%b8%ad%e5%ae%9a%e4%b9%89%e4%bb%b7%e5%80%bc" 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;○在哪凿洞？ —— 定义问题（Problem Definition）。这需要深入理解业务场景、用户痛点。&lt;/p&gt;
&lt;p&gt;○怎么算凿好了？ —— 构建评估（Evaluation Design）。这是下半场的核心竞争力。如何设计一套能够真实反映“用户价值”的评估体系，决定了你的 AI 能否在正确的方向上迭代。&lt;/p&gt;
&lt;h2 id="构建下半场的胜利引擎"&gt;&lt;a href="#%e6%9e%84%e5%bb%ba%e4%b8%8b%e5%8d%8a%e5%9c%ba%e7%9a%84%e8%83%9c%e5%88%a9%e5%bc%95%e6%93%8e" class="header-anchor"&gt;&lt;/a&gt;构建“下半场”的胜利引擎
&lt;/h2&gt;&lt;p&gt;如果说上半场的核心产物是“模型”，那么下半场的核心产物则必然是“系统”——一个能够将通用智能与我们独特的业务场景、数据、流程深度融合的智能体（Agent）系统 。我想详细阐述这个系统的架构哲学，它远比“LLM+Prompt”复杂，也坚固得多。&lt;/p&gt;
&lt;h3 id="认知核心"&gt;&lt;a href="#%e8%ae%a4%e7%9f%a5%e6%a0%b8%e5%bf%83" class="header-anchor"&gt;&lt;/a&gt;认知核心
&lt;/h3&gt;&lt;p&gt;这是 Agent 的 “大脑”，通常由一个或多个 LLM/VLM 构成。我们的战略不应是重复造轮子，而是构建一个可插拔、可路由的模型层，能根据任务的成本和复杂度，智能地选择最优模型。它至少要包括以下两部分：&lt;/p&gt;
&lt;p&gt;1.模型抽象与路由层：这是架构的基石。我们需要一个统一的接口，能够屏蔽掉不同模型（OpenAI, Anthropic, Google, 开源模型, 自研小模型）的差异。能够根据任务的复杂度、延迟要求、成本预算、安全等级，动态地将请求分发给最合适的模型。例如，一次简单的情感分类任务应该由一个本地化的、低成本的小模型处理；而一次需要复杂多步规划的请求，则路由到最强大的大模型。&lt;/p&gt;
&lt;p&gt;2.提示工程平台化（PromptOps）：Prompt 是我们与 AI 交流的语言，它不应是散落在代码各处的“魔法字符串”。我们需要一个企业级的 PromptOps 平台，对 Prompt 进行版本化管理、A/B 测试、自动化评估和持续优化。这个平台将是我们沉淀“人机交互知识”的核心资产。&lt;/p&gt;
&lt;h3 id="记忆系统"&gt;&lt;a href="#%e8%ae%b0%e5%bf%86%e7%b3%bb%e7%bb%9f" class="header-anchor"&gt;&lt;/a&gt;记忆系统
&lt;/h3&gt;&lt;p&gt;一个没有记忆的 Agent，永远只是一个强大的、但健忘的工具。记忆系统是 Agent 实现个性化、持续进化的关键，也是构建数据飞轮的核心。&lt;/p&gt;
&lt;p&gt;●短期工作记忆（Working Memory）：这是 Agent 处理当前任务的“内存”。它需要高效地管理对话历史、任务中间状态、工具调用结果等。挑战在于如何在保持长上下文的同时，有效控制成本和延迟。&lt;/p&gt;
&lt;p&gt;●长期情景记忆（Long-Term Episodic Memory）：这是 Agent 的“人生经历”。每一次成功的交互、每一次失败的尝试、每一个用户的特定偏好，都应该被向量化，并存入一个可供检索的长期记忆库。当 Agent 遇到新任务时，它能“回忆”起过去处理类似情况的经验，从而做出更优的决策。&lt;/p&gt;
&lt;p&gt;●长期语义/程序记忆（Long-Term Semantic/Procedural Memory）：这是 Agent 的“知识库”和“技能库”。前者存储了我们公司独有的领域知识（如产品文档、行业报告），后者则存储了完成特定任务的标准化流程（SOPs）。这确保了 Agent 的行为不仅是智能的，更是专业和合规的。&lt;/p&gt;
&lt;h3 id="工具箱"&gt;&lt;a href="#%e5%b7%a5%e5%85%b7%e7%ae%b1" class="header-anchor"&gt;&lt;/a&gt;工具箱
&lt;/h3&gt;&lt;p&gt;Agent 的价值最终体现在行动上。工具系统是 Agent 影响物理世界和数字世界的桥梁，其设计的优劣直接决定了 Agent 的能力边界。&lt;/p&gt;
&lt;p&gt;同时 tools 也是 Agent 的‘手脚’。我们可以将公司内外部的各种能力无论是调用一个 API、查询数据库、还是执行一个 RPA 脚本都封装成标准化的‘工具’，供 Agent 调用。我们工具箱的丰富性和可靠性，直接决定了我们 Agent 能力的天花板。但这里有几个关键的问题需要关注：&lt;/p&gt;
&lt;p&gt;●工具注册与治理：工具如何封装，如何注册，最后如何有效的进行治理 ？&lt;/p&gt;
&lt;p&gt;●执行与编排：当 Agent 决定调用工具时，谁来负责安全、可靠地执行，并处理各种现实世界的异常（如 API 超时、数据格式错误、权限不足）？&lt;/p&gt;
&lt;p&gt;●安全与审计：如何进行身份验证、权限检查与意图审计 ？&lt;/p&gt;
&lt;h3 id="认知能力的深化"&gt;&lt;a href="#%e8%ae%a4%e7%9f%a5%e8%83%bd%e5%8a%9b%e7%9a%84%e6%b7%b1%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;认知能力的深化
&lt;/h3&gt;&lt;p&gt;在我们构建了认知核心、记忆系统和工具系统之后，一个基础的 Agent 已经可以运转。它能够“看到”（感知）、“记住”（记忆）、并“行动”（工具）。然而，要让 Agent 真正能够胜任企业级的复杂、长周期任务，我们必须直面当前主流 Agent 框架（如 ReAct 模式）的固有限制。&lt;/p&gt;
&lt;p&gt;ReAct 模式本质上是一种反应式（Reactive） 的、一步一思考的决策循环。它在处理定义清晰、步骤明确的短任务时表现出色，但在面对一个模糊、宏大、且充满不确定性的长期目标时，往往会陷入局部最优，甚至迷失方向。例如，对于“将本季度用户流失率降低 5%”这样一个战略性目标，简单的“思考-行动”循环是完全不够的。&lt;/p&gt;
&lt;p&gt;因此，为了让 Agent 系统具备处理战略级任务的能力，我们需要在认知核心之上，构建一个更为高级的能力层，专注于前瞻性规划（Proactive Planning）和系统性自我校正（Systematic Self-Correction）。这并非一个独立的引擎，而是对现有认知能力的深化与扩展。&lt;/p&gt;
&lt;h4 id="从任务执行到任务分解"&gt;&lt;a href="#%e4%bb%8e%e4%bb%bb%e5%8a%a1%e6%89%a7%e8%a1%8c%e5%88%b0%e4%bb%bb%e5%8a%a1%e5%88%86%e8%a7%a3" class="header-anchor"&gt;&lt;/a&gt;从任务执行到任务分解
&lt;/h4&gt;&lt;p&gt;一个高级 Agent 必须具备将一个高层、模糊的战略意图，分解为一系列具体的、可管理的、有逻辑依赖关系的子任务的能力。这要求我们的系统：&lt;/p&gt;
&lt;p&gt;●具备多层次规划能力：对于“为新产品制定一个为期三个月的上市营销计划”这样的任务，Agent 需要能够生成一个结构化的任务树或有向无环图（DAG）。顶层是战略目标，下面分解为市场分析、内容制作、渠道投放、数据监控等多个阶段性任务，每个阶段任务再进一步分解为具体的执行动作，如“调用 API 查询竞品关键词”、“调用内部 CRM 生成潜在客户列表”等。&lt;/p&gt;
&lt;p&gt;●能够进行资源与依赖管理：规划出的任务流，必须考虑现实世界的约束，如预算限制、时间窗口、以及任务之间的前后置依赖关系。这使得 Agent 的规划更接近于一个真正的项目管理专家，而不仅仅是一个指令执行器。目前，如 Tree-of-Thought (ToT) 等研究已经展示了探索多路径规划的可行性，而将其工程化、并与企业实际流程相结合，将是我们重要的研发方向。&lt;/p&gt;
&lt;h4 id="从执行失败到归因学习"&gt;&lt;a href="#%e4%bb%8e%e6%89%a7%e8%a1%8c%e5%a4%b1%e8%b4%a5%e5%88%b0%e5%bd%92%e5%9b%a0%e5%ad%a6%e4%b9%a0" class="header-anchor"&gt;&lt;/a&gt;从执行失败到归因学习
&lt;/h4&gt;&lt;p&gt;在复杂的真实世界中，失败是常态。一个仅仅在失败时报错的系统是脆弱的。一个鲁棒的 Agent 系统，需要具备从失败中学习和恢复的能力。这要求我们建立一个系统性的错误归因与校正机制。&lt;/p&gt;
&lt;p&gt;1.精细化的错误归因：当一个任务失败时，系统不应简单地返回一个“Failed”状态。我们需要一个“事后复盘”模块，能够自动分析完整的执行日志（包括模型的思考链、工具的调用记录、环境的反馈），并像软件工程中的根本原因分析（RCA）一样，将失败定位到具体环节。例如：&lt;/p&gt;
&lt;p&gt;a.规划阶段的逻辑错误？（e.g., 错误地估计了任务的依赖关系）&lt;/p&gt;
&lt;p&gt;b.工具执行层面的技术故障？（e.g., 某个 API 超时或返回了非预期的格式）&lt;/p&gt;
&lt;p&gt;c.环境理解阶段的认知偏差？（e.g., 错误地解析了网页上的某个信息）&lt;/p&gt;
&lt;p&gt;d.还是基础模型的知识局限或幻觉？&lt;/p&gt;
&lt;p&gt;2.将经验转化为可复用的知识：在完成归因后，系统应将这次失败的案例——包括问题描述、失败路径、根本原因和（如果可能的话）正确的解决方案——进行结构化处理，并存入长期记忆库。这相当于为我们的 Agent 系统建立了一个可不断增长的“错题本”。未来在遇到类似情景时，Agent 可以检索这些经验，从而主动规避已知的陷阱。&lt;/p&gt;
&lt;p&gt;总之，将前瞻性规划与自我校正能力，深度集成到 Agent 系统中，其战略意义在于：它将 Agent 从一个被动的“任务执行者”，升级为一个具备一定自主性、能够处理复杂战略目标、并从经验中持续进化的“问题解决伙伴”。这虽然是当前 AI Agent 领域最具挑战性的前沿方向之一，但它也恰恰是构建长期、可持续技术壁垒的关键所在。&lt;/p&gt;
&lt;h2 id="下半场的北极星"&gt;&lt;a href="#%e4%b8%8b%e5%8d%8a%e5%9c%ba%e7%9a%84%e5%8c%97%e6%9e%81%e6%98%9f" class="header-anchor"&gt;&lt;/a&gt;下半场的“北极星”
&lt;/h2&gt;&lt;p&gt;如果我们认同“下半场”的逻辑，那么结论是显而易见的：评估体系的设计，是未来最重要、最核心、最能构建壁垒的竞争力。&lt;/p&gt;
&lt;p&gt;让我们用一个具体的例子来说明。假设我们用一个 AI Agent 来辅助客服。上半场的评估指标可能是“平均处理时长 ”或“首次回复准确率”。为了优化这些指标，Agent 可能会倾向于快速给出标准答案并关闭工单。表面上看，效率提升了。但真实情况可能是，用户的复杂问题并未得到根本解决，导致他不得不再次、甚至多次联系我们，最终的客户满意度和忠诚度反而下降了。这是一个典型的“指标陷阱”：我们优化了一个代理指标，却损害了最终的商业目标。&lt;/p&gt;
&lt;p&gt;所以我们的目标应该是构建一个能够衡量真实、长期、商业价值的评估引擎。至于具体怎么做，说实话，我不知道，凭我的设想，它应该包括：&lt;/p&gt;
&lt;p&gt;●高保真业务仿真环境：为我们的核心业务流程，构建一个“数字孪生” 。在这个环境中，我们可以模拟数百万次的用户交互、各种罕见的边缘案例、甚至是恶意的攻击行为。这使得我们可以在 Agent 上线前，对其进行低成本、高效率、全方位的压力测试和迭代优化。&lt;/p&gt;
&lt;p&gt;●人机回环竞技场：这是一个内部平台，让我们的一线业务专家成为 Agent 的“金牌教练”。他们可以在平台上，对 Agent 在真实（或模拟）任务中的表现进行打分、纠错、甚至提供更优的决策范例。这些高质量的、蕴含着人类专家隐性知识的数据，是我们将 Agent 从“可用”提升到“卓越”的最宝贵燃料。&lt;/p&gt;
&lt;p&gt;●长期价值归因分析：与数据分析团队紧密合作，建立严谨的因果推断模型，将 Agent 的引入，与最终的业务北极星指标（如客户 LTV 的提升、运营成本的降低、用户流失率的下降）进行强关联。这使得我们能够用商业语言，清晰地证明 AI 的价值。&lt;/p&gt;
&lt;p&gt;●引入“Agent-业务-Fit” (ABF) 的概念：或许我们应该像评估“产品-市场-Fit” (PMF) 一样，为每个 Agent 项目建立一个衡量其与业务契合度的成熟度模型。它包括了从任务成功率、操作可靠性、成本效益，到用户接受度、业务流程融合度等多个维度的综合评分。&lt;/p&gt;
&lt;h1 id="最后"&gt;&lt;a href="#%e6%9c%80%e5%90%8e" class="header-anchor"&gt;&lt;/a&gt;最后
&lt;/h1&gt;&lt;p&gt;AI 的 “下半场” 已经悄然而至，这既带来了巨大的挑战，也蕴含着前所未有的机遇。它挑战的是我们过去的成功经验和思维惯性。然而下半场的 AI，其智能的源泉，也正是我们日复一日工作中积累的、那些无法被量化、但却无比宝贵的领域知识和专业智慧。&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 模型瘦身提速：揭秘量化技术</title><link>https://xiaobox.github.io/p/2025-06-07-rang-ai-mo-xing-shou-shen-ti-su-jie-mi-liang-hua-ji-shu/</link><pubDate>Sat, 07 Jun 2025 14:30:00 +0000</pubDate><guid>https://xiaobox.github.io/p/2025-06-07-rang-ai-mo-xing-shou-shen-ti-su-jie-mi-liang-hua-ji-shu/</guid><description>&lt;img src="https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-07-rang-ai-mo-xing-shou-shen-ti-su-jie-mi-liang-hua-ji-shu/cover.jpg" alt="Featured image of post 让 AI 模型瘦身提速：揭秘量化技术" /&gt;&lt;p&gt;想象一下，如果我们能把动辄几百MB的大型AI模型“压缩”到手机里运行，是不是很神奇？这并非天方夜谭，其中的关键就是&lt;strong&gt;量化&lt;/strong&gt;技术。近年来，量化已成为人工智能领域的热门话题，通过给模型做“减法”，让AI模型变得又&lt;strong&gt;轻&lt;/strong&gt;又&lt;strong&gt;快&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="什么是量化"&gt;&lt;a href="#%e4%bb%80%e4%b9%88%e6%98%af%e9%87%8f%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;什么是量化？
&lt;/h2&gt;&lt;p&gt;通俗地说，量化就是降低数字表示的精度，把原本高精度的数值变为低精度。例如，本来AI模型的参数用32位的浮点数（FP32）表示，现在改用8位的整数（INT8）来表示。也就是说，用更少的比特位去表示同样的信息。这样做相当于给模型进行了压缩：所需存储空间大大减少，计算起来也更简单。需要注意的是，精度降低往往会带来&lt;strong&gt;量化误差&lt;/strong&gt;，也就是模型预测的细微&lt;strong&gt;准确率损失&lt;/strong&gt;。一般情况下，我们以8位量化为目标（即INT8），目前业界也已成功尝试更低的4位量化。量化过程本质上就是用压缩技术将&lt;strong&gt;更多比特&lt;/strong&gt;的数据转换为&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-06-07-rang-ai-mo-xing-shou-shen-ti-su-jie-mi-liang-hua-ji-shu/001-55013aeb.png"&gt;&lt;/p&gt;
&lt;h2 id="为什么量化很重要"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%87%8f%e5%8c%96%e5%be%88%e9%87%8d%e8%a6%81" class="header-anchor"&gt;&lt;/a&gt;为什么量化很重要？
&lt;/h2&gt;&lt;p&gt;随着AI模型（尤其是大模型）的规模爆炸式增长，模型的计算&lt;strong&gt;负担&lt;/strong&gt;和&lt;strong&gt;部署难度&lt;/strong&gt;也水涨船高。量化正是一剂“瘦身良方”，在尽量保持模型准确性的前提下，大幅降低模型的资源需求。这对现实应用而言意义重大：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;⚡ &lt;strong&gt;更快的推理速度&lt;/strong&gt;：量化把模型的计算从浮点运算变为整数运算，单次计算所需处理的位数减少，矩阵乘法等操作自然更快。这能显著降低模型响应延迟，在保持精度基本不变的同时大幅提升推理速度。对于需要实时响应的应用来说（如语音助手、实时翻译），速度提升至关重要。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📱 &lt;strong&gt;本地运行与高效部署&lt;/strong&gt;：当我们希望在&lt;strong&gt;移动设备&lt;/strong&gt;、边缘设备上运行AI模型时，量化几乎是不可或缺的工具。将浮点表示转换为低精度整数后，模型的计算与内存需求大幅下降。这意味着笔记本、平板、&lt;strong&gt;智能手机&lt;/strong&gt;甚至微控制器上都可以跑得动原本“跑不动”的模型。举例来说，采用TensorFlow Lite对模型进行INT8量化，可以让模型体积缩小&lt;strong&gt;约75%&lt;/strong&gt;，推理速度提高&lt;strong&gt;4倍&lt;/strong&gt;左右，而准确率仅轻微下降约2%。如此一来，我们的手机也能流畅运行起复杂的AI功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🔋 &lt;strong&gt;降低功耗&lt;/strong&gt;：模型计算量减小直接带来能耗降低。对于电池供电的设备（手机、笔记本、物联网传感器等），量化后的模型更省电，延长设备续航。在&lt;strong&gt;自动驾驶汽车&lt;/strong&gt;中，车辆需要依靠电池或有限的供电运行大量AI算法。通过INT8量化，这些车辆可以更快地做出实时决策，同时消耗更少能量，让电动车续航更久。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;💾 &lt;strong&gt;模型更小巧&lt;/strong&gt;：经过量化压缩，模型体积和内存占用都会大幅缩减。模型文件更小，意味着传输、存储都更方便，也降低了对硬件内存的要求。很多大型网络（如原始的VGG-16有超过500MB）无法直接部署在小设备上，但经过8位量化，内存和带宽占用最多可减少&lt;strong&gt;四分之三&lt;/strong&gt;，让原本笨重的模型变得轻盈。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🤝 &lt;strong&gt;兼容性与可移植性&lt;/strong&gt;：量化后的模型使用整数运算，这使其可以在一些&lt;strong&gt;不支持浮点运算的旧平台&lt;/strong&gt;上运行。同时，由于模型更小、更“平易近人”，普通的消费级GPU甚至CPU都能跑得动，这大大拓宽了AI模型的可部署范围。例如，一些老式嵌入式设备、本地浏览器环境等，都可能因为量化技术而得以跑起机器学习模型。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;综上所述，量化让AI模型在&lt;strong&gt;速度&lt;/strong&gt;、&lt;strong&gt;效率&lt;/strong&gt;、&lt;strong&gt;能耗&lt;/strong&gt;和&lt;strong&gt;适用性&lt;/strong&gt;方面都得到提升，堪称AI模型优化的&lt;strong&gt;利器&lt;/strong&gt;。正因为这些优势，量化已经成为从云端服务器到边缘设备各类AI部署中的关键工具。&lt;/p&gt;
&lt;h2 id="量化是如何实现的"&gt;&lt;a href="#%e9%87%8f%e5%8c%96%e6%98%af%e5%a6%82%e4%bd%95%e5%ae%9e%e7%8e%b0%e7%9a%84" class="header-anchor"&gt;&lt;/a&gt;量化是如何实现的？
&lt;/h2&gt;&lt;p&gt;量化听起来很美好，那么具体是怎么做到的呢？核心思想其实不难：&lt;strong&gt;确定一个映射规则，把原来范围很大的浮点数映射为范围较小的整数&lt;/strong&gt;。通常做法是计算一个&lt;strong&gt;缩放因子&lt;/strong&gt;，用它把32位浮点值缩放并&lt;strong&gt;四舍五入&lt;/strong&gt;到最接近的8位整数值。例如，某模型权重向量的最大值是6.2，那么以INT8范围[-127,127]来说，我们用127/6.2≈20.5作为缩放系数，把每个浮点数乘以20.5再取整，就得到对应的整数值。通过这样的&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-06-07-rang-ai-mo-xing-shou-shen-ti-su-jie-mi-liang-hua-ji-shu/002-bc46739b.png"&gt;&lt;/p&gt;
&lt;p&gt;在具体实现上，常用的量化流程主要有两种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;训练后量化 (PTQ)&lt;/strong&gt;：顾名思义，就是&lt;strong&gt;在模型训练完毕后&lt;/strong&gt;再对模型进行量化处理。直接将已有模型的权重从浮点表示转换为定点的低精度整数表示即可。这种方法&lt;strong&gt;不需要重新训练&lt;/strong&gt;模型，因而速度快、所需数据少，非常实用。当你已经有一个效果不错的模型，想让它运行更快、更省资源时，PTQ是很好的选择。然而，PTQ相当于&lt;strong&gt;事后压缩&lt;/strong&gt;模型，难免出现一些性能下降，即模型精度可能有所降低。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;量化感知训练 (QAT)&lt;/strong&gt;：这是把量化&lt;strong&gt;融入训练过程&lt;/strong&gt;的一种方法。在模型预训练或微调阶段，就模拟低精度运算来调整权重。简而言之，就是让模型在训练时就“意识到”日后要用低精度计算，从而提前学会适应。这样训练出来的模型对量化的精度损失更不敏感，因而最终精度往往比PTQ方式更高。但QAT的&lt;strong&gt;代价&lt;/strong&gt;是需要更多的计算资源和大量代表性数据来训练——等于重新训练或微调一遍模型，所以成本更高。因此，通常在有充足的数据和算力预算、且追求极致模型性能的情况下才会选用QAT。反之，如果预算有限或者模型已经足够好，那PTQ就更实惠。&lt;/p&gt;
&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-06-07-rang-ai-mo-xing-shou-shen-ti-su-jie-mi-liang-hua-ji-shu/003-b14f78ab.png"&gt;&lt;/p&gt;
&lt;p&gt;除了以上两种主要方式，还有量化过程中的一些技术细节，比如&lt;strong&gt;动态量化&lt;/strong&gt;和&lt;strong&gt;静态量化&lt;/strong&gt;。简单来说，两者差别在于如何确定量化时的取值范围（也称&lt;strong&gt;校准&lt;/strong&gt;）。动态量化是在模型运行时根据每批输入动态计算最佳范围，使模型获得更高精度；静态量化则在部署前用一批数据先离线计算出固定范围，应用于所有后续推理。动态方法往往精度好但实现复杂，而静态方法较常用但需要仔细选择校准数据。无论采用哪种策略，目标都是找到平衡精度和效率的&lt;strong&gt;最佳量化方案&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;值得一提的是，现在主流的深度学习框架（如TensorFlow、PyTorch）都提供了完善的量化工具包，帮助开发者一键将模型量化，无需事必躬亲计算缩放系数。例如，TensorFlow Lite支持直接将Keras模型转换为INT8量化的&lt;code&gt;.tflite&lt;/code&gt;模型，用于移动端或微控制器部署。这些工具让量化实施变得&lt;strong&gt;简单高效&lt;/strong&gt;，降低了技术门槛。&lt;/p&gt;
&lt;h2 id="量化的挑战"&gt;&lt;a href="#%e9%87%8f%e5%8c%96%e7%9a%84%e6%8c%91%e6%88%98" class="header-anchor"&gt;&lt;/a&gt;量化的挑战
&lt;/h2&gt;&lt;p&gt;量化有诸多优点，但也并非&lt;strong&gt;万能药&lt;/strong&gt;，在应用中需要权衡以下挑战：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;🎯 &lt;strong&gt;精度下降（准确率损失）&lt;/strong&gt;：正如前面提到的，量化引入的误差可能导致模型预测精度下降。对于一些对细节&lt;strong&gt;敏感&lt;/strong&gt;的任务（如医疗影像分析、自然语言处理）来说，哪怕1-2%的精度变化都很重要。一般来说，模型参数越多、结构越复杂，量化带来的累计误差可能越明显。特别是超大型的LLM模型，层数深参数多，如果直接量化，误差会层层叠加，造成显著性能下降。因此在应用量化时，需要通过校准、QAT等方式尽量降低精度损失，把&lt;strong&gt;量化误差&lt;/strong&gt;控制在可接受范围。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;💰 &lt;strong&gt;实现成本与复杂度&lt;/strong&gt;：采用更高级的量化方案（例如QAT）往往意味着更高的计算和时间成本。对一些资源有限的团队来说，从头训练一个量化感知模型并不现实。所以很多情况下会选择折中的PTQ，即使牺牲一点性能也无妨。这就涉及一个取舍：&lt;strong&gt;精度 vs 成本&lt;/strong&gt;。此外，不同硬件对低精度计算的支持程度不一，实现量化需要考虑软硬件配合。如果部署平台缺乏对INT8等低精度运算的优化，反而可能达不到预期的加速效果。开发者需要针对具体硬件进行测试调优。有时还需结合其他压缩手段（剪枝、蒸馏等）一起使用，才能达到理想的模型大小和速度。这些都增加了实现量化的复杂度。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总的来说，量化的挑战在于&lt;strong&gt;平衡&lt;/strong&gt;：一方面是尽可能降低模型尺寸和计算量，另一方面是尽量保持模型原有的准确率不受大的影响。这种平衡需要根据具体应用场景反复试验和拿捏。不过，随着算法和芯片的发展，量化带来的精度损失正在逐步减少，新技术甚至探索4位、2位量化还能维持不错的效果。这使得量化正越来越成熟可靠，成为AI模型优化的常规选项。&lt;/p&gt;
&lt;h2 id="实际应用场景"&gt;&lt;a href="#%e5%ae%9e%e9%99%85%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;实际应用场景
&lt;/h2&gt;&lt;p&gt;量化技术已经广泛应用于各种AI场景中，让原本笨重的模型走入寻常百姓家。以下是几个贴近生活的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;📱 智能手机上的AI&lt;/strong&gt;：我们的手机中藏着许多AI功能——相册应用的图像识别、语音助手的语音识别、摄像头的实时滤镜等等。这些功能背后的模型都受益于量化技术。通过8位量化，模型变小变快，手机才能&lt;strong&gt;离线&lt;/strong&gt;实时完成复杂计算，而不会让电池瞬间耗尽。比如，Google Lens等应用据报道就使用了INT8量化模型，在手机端流畅运行，同时不至于发热严重或很快耗电。可以说，没有量化，就没有如今手机上丰富的AI体验。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;🚗 自动驾驶与车载AI&lt;/strong&gt;：自动驾驶汽车需要依赖大量神经网络模型来处理摄像头、激光雷达等传感器数据，从中识别行人、车辆、交通标志并做出驾驶决策。这些模型必须在车载计算平台上实时运行，容不得半点延迟。通过量化，车载AI模型的推理速度大大提高，每毫秒都得到珍惜。更快的模型意味着汽车可以更及时地刹车或转向，保障行车安全。同时，量化模型计算量低，也减轻了车辆电力系统的负担。毕竟，电动汽车上一块GPU很耗电，而模型瘦身后就能在有限算力下完成任务，让自动驾驶系统运行更长时间、更稳定。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;🌐 边缘设备与物联网&lt;/strong&gt;：在农业、工业、安防等领域，越来越多的&lt;strong&gt;小型边缘设备&lt;/strong&gt;也开始搭载AI。例如，农田里的物联网传感器可能运行着一个微型的作物病虫害预测模型。这种传感器往往只靠电池供电，需要连续工作数月不更换电池。通过将模型量化为INT8，这些传感器上的“小模型”既可以快速处理数据，又将功耗控制在极低水平。有报道显示，农场里的IoT设备利用量化后的模型来预测灌溉需求或病虫害风险，量化确保模型以极低能耗实时运行，让传感器在不充电的情况下运作数月之久。同理，在安防摄像头上部署的人脸识别、在可穿戴设备上的健康监测算法等，都因为量化得以在&lt;strong&gt;计算资源有限&lt;/strong&gt;的设备上实现。这为AI的普及打开了广阔的应用空间。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上种种场景表明，量化技术正悄然推动着AI从云端走向本地，从大型服务器走向我们身边的各类小设备。无论是手机、汽车还是物联网传感器，量化让AI模型&lt;strong&gt;接地气&lt;/strong&gt;地融入各种行业和日常生活。&lt;/p&gt;
&lt;h2 id="最后"&gt;&lt;a href="#%e6%9c%80%e5%90%8e" class="header-anchor"&gt;&lt;/a&gt;最后
&lt;/h2&gt;&lt;p&gt;在AI模型优化的众多手段中，量化可谓简单却威力巨大的一招。通过让模型“瘦身”，我们能以很小的代价换来可观的性能提升和部署便利。当然，量化并非没有代价，如何在效率和准确率之间取得最佳平衡是一门艺术。但随着技术演进，这个平衡点正变得越来越高效。可以预见，未来更低比特的量化方案（如4位甚至更低）可能走向实用，为AI模型带来更&lt;strong&gt;极致&lt;/strong&gt;的压缩与加速效果。&lt;/p&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></channel></rss>