<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AI编程 on Kalend's Blog</title><link>https://blog.kalend.top/categories/ai%E7%BC%96%E7%A8%8B/</link><description>Recent content in AI编程 on Kalend's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Fri, 31 Jul 2026 08:30:00 +0800</lastBuildDate><atom:link href="https://blog.kalend.top/categories/ai%E7%BC%96%E7%A8%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>Kiro IDE上手：AWS的Spec驱动编程，和Cursor/Claude Code有何不同</title><link>https://blog.kalend.top/2026/07/31/2026-07-31-kiro-ide-guide.html/</link><pubDate>Fri, 31 Jul 2026 08:30:00 +0800</pubDate><guid>https://blog.kalend.top/2026/07/31/2026-07-31-kiro-ide-guide.html/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;当所有AI IDE都在比谁生成代码更快时，Kiro说：先停下来写需求文档。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="先说结论"&gt;先说结论
&lt;/h2&gt;&lt;p&gt;Kiro是AWS推出的Agentic AI IDE，2025年7月预览、2026年5月正式版。它基于VS Code (Code OSS)，和Cursor、Windsurf同源。&lt;/p&gt;
&lt;p&gt;但Kiro的核心卖点不是&amp;quot;写代码更快&amp;quot;，而是&lt;strong&gt;Spec-Driven Development&lt;/strong&gt;——先规划后执行。这和Cursor的对话式编程、Claude Code的终端式Agent形成了三种截然不同的方法论。&lt;/p&gt;
&lt;p&gt;值得试，但不必all-in。Free tier 50 credits够体验Spec模式。&lt;/p&gt;
&lt;h2 id="一kiro是什么aws为什么要做ide"&gt;一、Kiro是什么？AWS为什么要做IDE
&lt;/h2&gt;&lt;p&gt;Kiro（读作 keer-oh）的官方口号是&amp;quot;Move beyond AI coding to agentic engineering&amp;quot;。&lt;/p&gt;
&lt;p&gt;翻译成人话：别再vibe coding了，该升级了。&lt;/p&gt;
&lt;p&gt;AWS做IDE的战略意图很明确——从云基础设施延伸到开发者工具链。你用Kiro写代码，部署大概率用AWS，形成闭环。&lt;/p&gt;
&lt;p&gt;技术栈上，Kiro基于Code OSS（VS Code 的开源版本），和Cursor、Windsurf是同一个底座。如果你用过VS Code，上手零成本。&lt;/p&gt;
&lt;p&gt;52+ 个内置集成（Figma、Postman、Datadog、Stripe、Supabase、Terraform等），AWS生态的优势在这里体现得很明显。&lt;/p&gt;
&lt;h2 id="二spec-driven-developmentkiro的核心差异"&gt;二、Spec-Driven Development——Kiro的核心差异
&lt;/h2&gt;&lt;p&gt;这是Kiro和其他所有AI IDE的最大区别。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么是Spec？&lt;/strong&gt; 就是把&amp;quot;一句话需求&amp;quot;拆成三份结构化文档：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;阶段&lt;/th&gt;
					&lt;th&gt;产出文件&lt;/th&gt;
					&lt;th&gt;内容&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Requirements&lt;/td&gt;
					&lt;td&gt;requirements.md&lt;/td&gt;
					&lt;td&gt;用户故事 + 验收标准&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Design&lt;/td&gt;
					&lt;td&gt;design.md&lt;/td&gt;
					&lt;td&gt;技术架构 + 序列图 + 数据流&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Tasks&lt;/td&gt;
					&lt;td&gt;tasks.md&lt;/td&gt;
					&lt;td&gt;可追踪的离散任务列表&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;两种Spec类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Feature Specs&lt;/strong&gt;：构建新功能，支持Requirements-First和Design-First两种变体&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bugfix Specs&lt;/strong&gt;：系统化诊断和修复bug，防止回归&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还有个&lt;strong&gt;Quick Spec&lt;/strong&gt;模式，跳过审批门，一步生成全部三个文件。适合赶工期的场景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;和Cursor的本质区别是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cursor是&amp;quot;边聊边写&amp;quot;——你和AI对话，AI直接吐代码。快，但容易失控。需求改了，之前生成的代码可能全废。&lt;/p&gt;
&lt;p&gt;Kiro是&amp;quot;先规划后执行&amp;quot;——需求锁定、设计评审、任务拆分，然后才开始写代码。慢一点，但每一步都有文档可追溯。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;类比&lt;/strong&gt;：Cursor像直接上手做饭，边做边尝；Kiro像先写菜谱，再按步骤执行。前者灵活但不可复制，后者可复制但缺灵活性。&lt;/p&gt;
&lt;p&gt;这个区别对个人hack影响不大，但对团队协作意义重大。Spec可共享，产品经理和工程师可以在同一份文档上协作。&lt;/p&gt;
&lt;h2 id="三并行agent--正确性验证"&gt;三、并行Agent + 正确性验证
&lt;/h2&gt;&lt;h3 id="并行agent执行"&gt;并行Agent执行
&lt;/h3&gt;&lt;p&gt;Kiro是少数内置并行Agent的AI IDE——它会分析tasks.md的依赖关系，构建依赖图，然后把独立任务分组为Wave。&lt;/p&gt;
&lt;p&gt;Wave之间顺序执行，Wave内任务并发。理论上比逐个执行快很多。&lt;/p&gt;
&lt;h3 id="property-based-testing"&gt;Property-Based Testing
&lt;/h3&gt;&lt;p&gt;这个很有意思。Kiro不只跑单元测试，还用属性测试（property-based testing）做正确性验证。&lt;/p&gt;
&lt;p&gt;区别在哪？单元测试是&amp;quot;输入A，期望输出B&amp;quot;。属性测试是&amp;quot;对任意输入，这个规则都应该成立&amp;quot;。&lt;/p&gt;
&lt;p&gt;比如一个排序函数，单元测试可能测5个case都过了，但属性测试会随机生成1000个数组，验证&amp;quot;输出是否始终有序&amp;quot;这种不变量。&lt;/p&gt;
&lt;p&gt;Kiro甚至在写代码前就用自动推理技术检查需求的矛盾和缺口。这是&amp;quot;测试左移&amp;quot;做到极致的体现。&lt;/p&gt;
&lt;h3 id="agent-hooks"&gt;Agent Hooks
&lt;/h3&gt;&lt;p&gt;基于触发器自动执行任务。比如提交代码时自动跑单测、更新文档。类似Git Hooks，但由AI执行。&lt;/p&gt;
&lt;h2 id="四多端统一--模型生态"&gt;四、多端统一 + 模型生态
&lt;/h2&gt;&lt;h3 id="四端支持"&gt;四端支持
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;端&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;IDE&lt;/td&gt;
					&lt;td&gt;桌面端，macOS/Windows/Linux&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CLI&lt;/td&gt;
					&lt;td&gt;终端工作流，bash/zsh/fish + 500+ CLI 自动补全&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Web&lt;/td&gt;
					&lt;td&gt;浏览器端，云端沙箱，关机后继续运行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Mobile&lt;/td&gt;
					&lt;td&gt;iOS&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Web端很关键——云端沙箱意味着你可以在手机上启动一个任务，关掉电脑，让它在云端跑完。这对长时间构建场景很实用。&lt;/p&gt;
&lt;h3 id="模型生态"&gt;模型生态
&lt;/h3&gt;&lt;p&gt;Kiro的模型丰富度在AI IDE里属于第一梯队：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auto模式（推荐）&lt;/strong&gt;：自动为每个任务选最优模型，综合考虑质量、延迟、成本。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anthropic Claude全系&lt;/strong&gt;：从Haiku 4.5（0.4x credit）到Opus 5（2.2x，实验性），覆盖所有场景。上下文最高1M tokens。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OpenAI GPT-5.6 首次登陆&lt;/strong&gt;（7/13）：三个变体——Sol（2.4x，最难任务）、Terra（1.2x，日常开发）、Luna（0.6x，性价比）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;开源/开放权重模型&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qwen3 Coder Next（0.05x，最便宜）&lt;/li&gt;
&lt;li&gt;DeepSeek 3.2（0.25x）&lt;/li&gt;
&lt;li&gt;MiniMax M2.1/M2.5（0.15x-0.25x）&lt;/li&gt;
&lt;li&gt;GLM-5（0.5x）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;开源模型的credit倍率极低，Qwen3 Coder Next只要0.05x，适合 CLI 长时间跑 Agent。&lt;/p&gt;
&lt;h3 id="开放标准"&gt;开放标准
&lt;/h3&gt;&lt;p&gt;支持ACP（Agent Client Protocol）、AGENTS.md、Skills.md、MCP。VS Code 扩展和设置可直接导入。&lt;/p&gt;
&lt;h2 id="五定价与性价比分析"&gt;五、定价与性价比分析
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;计划&lt;/th&gt;
					&lt;th&gt;月费&lt;/th&gt;
					&lt;th&gt;Credits&lt;/th&gt;
					&lt;th&gt;模型权限&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Free&lt;/td&gt;
					&lt;td&gt;$0&lt;/td&gt;
					&lt;td&gt;50&lt;/td&gt;
					&lt;td&gt;开源模型 + Claude Sonnet 4.5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pro&lt;/td&gt;
					&lt;td&gt;$20&lt;/td&gt;
					&lt;td&gt;1,000&lt;/td&gt;
					&lt;td&gt;全部模型&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pro+&lt;/td&gt;
					&lt;td&gt;$40&lt;/td&gt;
					&lt;td&gt;2,000&lt;/td&gt;
					&lt;td&gt;全部模型&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pro Max&lt;/td&gt;
					&lt;td&gt;$100&lt;/td&gt;
					&lt;td&gt;5,000&lt;/td&gt;
					&lt;td&gt;全部模型&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Power&lt;/td&gt;
					&lt;td&gt;$200&lt;/td&gt;
					&lt;td&gt;10,000&lt;/td&gt;
					&lt;td&gt;全部模型&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键细节&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;超额购买：$0.04/credit（个人版手动购买，团队版可自动超额）&lt;/li&gt;
&lt;li&gt;新用户首充送$20 credit&lt;/li&gt;
&lt;li&gt;学生计划：1,000 credits/月，免费1年&lt;/li&gt;
&lt;li&gt;月度重置，未用credits不累积&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;和Cursor对比&lt;/strong&gt;：Cursor Pro也是$20/月，但不按credit计费，按请求次数。Kiro的credit制更透明——你可以精确知道每个操作花了多少钱。&lt;/p&gt;
&lt;p&gt;不同模型消耗credit的倍率不同。同一个任务，用Sonnet 4.6是Auto的1.3x，用Opus是2.2x，用Qwen3 Coder Next只有0.05x。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实际体感&lt;/strong&gt;：Pro $20/月1000 credits，如果主要用Auto模式，日常开发够用。如果频繁用Opus做复杂任务，可能不够。&lt;/p&gt;
&lt;h2 id="六和cursorclaude-code的实操对比"&gt;六、和Cursor/Claude Code的实操对比
&lt;/h2&gt;&lt;h3 id="方法论差异"&gt;方法论差异
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;Kiro&lt;/th&gt;
					&lt;th&gt;Cursor&lt;/th&gt;
					&lt;th&gt;Claude Code&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;方法论&lt;/td&gt;
					&lt;td&gt;Spec-Driven + Vibe双模式&lt;/td&gt;
					&lt;td&gt;Chat-Based + Tab补全&lt;/td&gt;
					&lt;td&gt;纯对话式Agent&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;形态&lt;/td&gt;
					&lt;td&gt;IDE + CLI + Web + Mobile&lt;/td&gt;
					&lt;td&gt;IDE&lt;/td&gt;
					&lt;td&gt;CLI&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;开发流程&lt;/td&gt;
					&lt;td&gt;需求→设计→任务→实现&lt;/td&gt;
					&lt;td&gt;对话→代码生成&lt;/td&gt;
					&lt;td&gt;对话→代码生成&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文档化&lt;/td&gt;
					&lt;td&gt;自动生成三份Spec文档&lt;/td&gt;
					&lt;td&gt;无内置文档化&lt;/td&gt;
					&lt;td&gt;依赖AGENTS.md&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;并行Agent&lt;/td&gt;
					&lt;td&gt;内置依赖图+Wave并发&lt;/td&gt;
					&lt;td&gt;无内置并行&lt;/td&gt;
					&lt;td&gt;无内置并行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;正确性验证&lt;/td&gt;
					&lt;td&gt;Property-based testing&lt;/td&gt;
					&lt;td&gt;依赖单元测试&lt;/td&gt;
					&lt;td&gt;依赖单元测试&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;模型选择&lt;/td&gt;
					&lt;td&gt;多厂商多模型&lt;/td&gt;
					&lt;td&gt;多厂商&lt;/td&gt;
					&lt;td&gt;仅Claude&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;定价&lt;/td&gt;
					&lt;td&gt;$0-200/月，credit制&lt;/td&gt;
					&lt;td&gt;$0-40/月&lt;/td&gt;
					&lt;td&gt;按token计费&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="适合场景对比"&gt;适合场景对比
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;选Kiro的场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;团队协作，需要结构化开发流程&lt;/li&gt;
&lt;li&gt;需求复杂，需要先规划再执行&lt;/li&gt;
&lt;li&gt;重视文档化，Spec可作为项目资产&lt;/li&gt;
&lt;li&gt;已在AWS生态内&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;选Cursor的场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人开发，快速原型&lt;/li&gt;
&lt;li&gt;习惯对话式交互，边聊边写&lt;/li&gt;
&lt;li&gt;预算敏感（$20/月固定，不按量计费）&lt;/li&gt;
&lt;li&gt;需要Tab补全这种细粒度辅助&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;选Claude Code的场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;终端党，不想离开命令行&lt;/li&gt;
&lt;li&gt;只信任Claude模型&lt;/li&gt;
&lt;li&gt;需要深度理解大型代码库&lt;/li&gt;
&lt;li&gt;按token计费对轻度用户更划算&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="七结论与建议"&gt;七、结论与建议
&lt;/h2&gt;&lt;p&gt;Kiro的真正价值不是IDE本身，而是Spec方法论。&lt;/p&gt;
&lt;p&gt;你完全可以在Cursor里用类似的工作流——先让AI写需求文档，再拆任务，再逐个实现。但Kiro把这个流程产品化了，自动化了，并且加了并行Agent和属性测试。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我的建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先用Free tier体验Spec模式，看看&amp;quot;先写需求再写代码&amp;quot;是否适合你的工作方式&lt;/li&gt;
&lt;li&gt;如果你已经在用Cursor且满意，不必急着切换——Spec方法论可以手动在Cursor里实践&lt;/li&gt;
&lt;li&gt;团队场景值得重点评估——Spec可共享这点是Cursor和Claude Code都没有的&lt;/li&gt;
&lt;li&gt;开源模型的credit倍率极低（Qwen3 0.05x），预算有限可以主打开源模型&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;AWS入场AI IDE，最大的意义不是多了一个选择，而是把&amp;quot;Spec-Driven&amp;quot;这个概念推到了台面上。不管最终用不用Kiro，&amp;ldquo;先规划后执行&amp;quot;这个思路值得每个开发者思考。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;作者：varkm&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Claude Code、Codex、OpenCode、ZCode 四款AI编程Agent怎么选：工具是方法论的载体</title><link>https://blog.kalend.top/2026/07/11/2026-07-11-four-ai-coding-agents-guide.html/</link><pubDate>Sat, 11 Jul 2026 08:00:00 +0800</pubDate><guid>https://blog.kalend.top/2026/07/11/2026-07-11-four-ai-coding-agents-guide.html/</guid><description>&lt;p&gt;Claude Code 对应 Context Engineering 阶段，Codex 对应安全工程阶段，OpenCode 对应自由探索阶段，ZCode 对应可视化协作阶段。四款工具不是同一赛道的四匹马，而是四个方法论阶段的代表作。选工具之前，先搞清楚你想停在哪个阶段。&lt;/p&gt;
&lt;h2 id="为什么选工具选阶段"&gt;为什么&amp;quot;选工具=选阶段&amp;quot;
&lt;/h2&gt;&lt;p&gt;Vibe Coding → Context Coding → Agentic Engineering，这是 AI 编程方法论的三阶进化。我在之前的文章里详细拆过这三个阶段的演进逻辑，这里只说核心：每个阶段对&amp;quot;人机协作的信任边界&amp;quot;定义完全不同。&lt;/p&gt;
&lt;p&gt;Vibe Coding 阶段，你把 AI 当高级自动补全，写一行说一行。Context Coding 阶段，你给 AI 写一份&amp;quot;施工图纸&amp;quot;，让它按图执行。Agentic Engineering 阶段，你给 AI 一个目标和约束，让它自己规划路径。&lt;/p&gt;
&lt;p&gt;四款工具的设计哲学，恰好对应这四个坐标点。&lt;/p&gt;
&lt;h2 id="claude-codecontext-engineering-的代表作"&gt;Claude Code：Context Engineering 的代表作
&lt;/h2&gt;&lt;p&gt;Claude Code 的核心设计哲学是&amp;quot;先规划后执行&amp;quot;。&lt;/p&gt;
&lt;p&gt;CLAUDE.md 文件是它的核心。在项目根目录放一个 CLAUDE.md，写清楚项目架构、编码规范、关键约束，Claude Code 在每次对话开始时自动加载。这不是一个配置文件，这是一份&amp;quot;工程合同&amp;quot;——你和 AI 之间的权责边界白纸黑字写在上面。&lt;/p&gt;
&lt;p&gt;Permission mode 是另一个关键设计。开启 plan-first 模式后，Claude Code 在做多文件重构之前会先输出一份 Plan 文档，你审批通过后才动手。这不是多余的步骤，这是 Context Engineering 的核心：让 AI 先把思路亮出来，人类确认方向正确再执行。&lt;/p&gt;
&lt;p&gt;Headless 模式支持无人值守，配合 Git worktrees 可以让 Claude Code 在独立分支上干活，不影响你的主分支。MCP 协议集成让它能连接外部工具链。&lt;/p&gt;
&lt;p&gt;模型方面，Opus 4.8 是目前推理能力最强的编码模型，适合架构级决策。Sonnet 5 更快，适合日常编码。上下文策略是激进压缩——保留用户消息不动，压缩模型自己的历史输出。&lt;/p&gt;
&lt;p&gt;定价：Pro $20/月，Max $200/月，或 API 按量付费。&lt;/p&gt;
&lt;p&gt;适合场景：大型项目重构、架构级修改、需要深度推理的多文件协同变更。如果你的项目超过 5 万行代码，Claude Code 的 Context Engineering 能力是四款里最强的。&lt;/p&gt;
&lt;h2 id="codex-cli安全优先的工程实践"&gt;Codex CLI：安全优先的工程实践
&lt;/h2&gt;&lt;p&gt;Codex CLI 的设计哲学是&amp;quot;不信任但验证&amp;quot;。&lt;/p&gt;
&lt;p&gt;三级审批模式是它的核心卖点。suggest 模式只给建议不改文件，auto-edit 模式可以自动修改代码但不执行命令，full-auto 才是完全自主执行。这三级模式不是可选的装饰，而是默认的安全策略。你不需要记住哪些操作需要审批，沙箱自动帮你隔离风险。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--ask-for-approval&lt;/code&gt; 参数控制审批粒度。你可以设置&amp;quot;修改文件前必须确认&amp;quot;，也可以设置&amp;quot;只在执行危险命令时确认&amp;quot;。粒度完全由你控制。&lt;/p&gt;
&lt;p&gt;并行 Agent 能力是 Codex 的另一个优势。你可以同时启动多个 Agent 处理不同任务，它们各自在独立沙箱里运行，互不干扰。&lt;/p&gt;
&lt;p&gt;模型方面，GPT-5.6 是 OpenAI 最新发布的模型家族，针对编码场景有专门优化。上下文策略是&amp;quot;用户消息一字不动，模型自己的全部可压&amp;quot;——和 Claude Code 的激进压缩有微妙但重要的区别。&lt;/p&gt;
&lt;p&gt;定价包含在 ChatGPT Plus/Pro 订阅中，或 API 按量付费。CLI 本身开源。&lt;/p&gt;
&lt;p&gt;适合场景：安全敏感的企业环境、需要并行执行多个编码任务、已经在 OpenAI 生态里的团队。&lt;/p&gt;
&lt;h2 id="opencode最大自由度的开源方案"&gt;OpenCode：最大自由度的开源方案
&lt;/h2&gt;&lt;p&gt;OpenCode 的设计哲学是&amp;quot;你的模型，你的规则&amp;quot;。&lt;/p&gt;
&lt;p&gt;BYOK（Bring Your Own Key）支持 75+ 个 LLM 提供商。你可以接 OpenAI、Anthropic、Google，也可以接国产模型——DeepSeek、Qwen、GLM 都行。这意味着你可以用同一个工具，在不同项目里用不同模型，成本完全可控。&lt;/p&gt;
&lt;p&gt;它自带 Zen 模型精选，是社区维护的&amp;quot;针对编程优化过的模型推荐列表&amp;quot;。不知道选什么模型的时候，Zen 列表是个不错的起点。&lt;/p&gt;
&lt;p&gt;Subagent 架构支持子代理并行。隐私优先设计保证数据不离开本地。桌面版目前在 Beta 阶段，降低了 CLI 的使用门槛。&lt;/p&gt;
&lt;p&gt;上下文管理采用&amp;quot;可逆隐藏&amp;quot;策略——历史对话不会被真正删除，理论上可以恢复。这在需要回溯 AI 决策过程时很有价值。&lt;/p&gt;
&lt;p&gt;180K+ GitHub Stars 说明社区认可度。免费开源，模型费用自付。接国产模型的话，日常编码成本可以压到接近零。&lt;/p&gt;
&lt;p&gt;适合场景：预算敏感、想用国产模型、隐私优先、中等规模项目（1-2 万行）。但要注意：项目超过 5 万行或有复杂跨模块依赖时，OpenCode 的 orchestration 层不如 Claude Code 流畅。&lt;/p&gt;
&lt;h2 id="zcode-30可视化的国产方案"&gt;ZCode 3.0：可视化的国产方案
&lt;/h2&gt;&lt;p&gt;ZCode 3.0 的设计哲学是&amp;quot;把开发流程塞进桌面应用&amp;quot;。&lt;/p&gt;
&lt;p&gt;它是四款里唯一的桌面 ADE（Agentic Development Environment）。不想用 CLI？不想配环境变量？打开桌面应用就能开始写代码。这个定位对非终端用户非常友好。&lt;/p&gt;
&lt;p&gt;GLM-5.2 是智谱自研的旗舰模型，1M 上下文窗口。作为原生适配的模型，ZCode 对 GLM-5.2 的调用效率和效果优化是其他工具接 API 做不到的。&lt;/p&gt;
&lt;p&gt;多 Agent 协作和技能系统（Skills）是 ZCode 的差异化特性。需求理解 → 计划拆解 → 代码修改 → 验证，全流程在可视化界面里完成。&lt;/p&gt;
&lt;p&gt;定价：首次 5 天免费，每天 300 万 token，之后走 GLM Coding Plan 订阅。&lt;/p&gt;
&lt;p&gt;适合场景：不想用 CLI 的开发者、中文场景、想免费体验国产最强编程模型。&lt;/p&gt;
&lt;h2 id="方法论适配度对比"&gt;方法论适配度对比
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;Claude Code&lt;/th&gt;
					&lt;th&gt;Codex CLI&lt;/th&gt;
					&lt;th&gt;OpenCode&lt;/th&gt;
					&lt;th&gt;ZCode&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;安全模型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Permission mode 审批制&lt;/td&gt;
					&lt;td&gt;三级审批模式隔离&lt;/td&gt;
					&lt;td&gt;本地优先不外传&lt;/td&gt;
					&lt;td&gt;桌面隔离&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;上下文策略&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;激进压缩，保留用户消息&lt;/td&gt;
					&lt;td&gt;保留用户消息，压缩模型输出&lt;/td&gt;
					&lt;td&gt;可逆隐藏，历史可恢复&lt;/td&gt;
					&lt;td&gt;桌面界面管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;模型灵活度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;仅 Claude 系列&lt;/td&gt;
					&lt;td&gt;仅 GPT 系列&lt;/td&gt;
					&lt;td&gt;75+ 提供商自由切换&lt;/td&gt;
					&lt;td&gt;仅 GLM 系列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;交互形态&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;终端优先&lt;/td&gt;
					&lt;td&gt;终端 + VSCode&lt;/td&gt;
					&lt;td&gt;终端 + 桌面(Beta) + IDE&lt;/td&gt;
					&lt;td&gt;桌面 ADE&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;并行能力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Headless + worktrees&lt;/td&gt;
					&lt;td&gt;并行 Agent&lt;/td&gt;
					&lt;td&gt;Subagent 架构&lt;/td&gt;
					&lt;td&gt;多 Agent 协作&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;学习曲线&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;中（需写 CLAUDE.md）&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;低（可视化）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;开源&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
					&lt;td&gt;CLI 开源&lt;/td&gt;
					&lt;td&gt;完全开源&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;中文优化&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;一般&lt;/td&gt;
					&lt;td&gt;一般&lt;/td&gt;
					&lt;td&gt;一般&lt;/td&gt;
					&lt;td&gt;原生支持&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="决策树四条路径选哪条"&gt;决策树：四条路径，选哪条
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;你重视安全隔离吗？&lt;/strong&gt; 在企业环境里写代码，或者处理敏感数据，需要沙箱级别的权限隔离 → 选 Codex CLI。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你重视推理深度吗？&lt;/strong&gt; 项目规模大、架构复杂、需要 AI 先理解全局再动手，愿意花时间写 CLAUDE.md → 选 Claude Code。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你重视模型自由度和预算吗？&lt;/strong&gt; 想在不同项目里用不同模型，或者想接国产模型把成本压到接近零，项目规模中等 → 选 OpenCode。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你不想用 CLI / 要中文优化吗？&lt;/strong&gt; 不想配环境、不想记命令、想要可视化界面、中文场景优先 → 选 ZCode。&lt;/p&gt;
&lt;p&gt;如果以上四条你都犹豫，说明你还在 Vibe Coding 阶段——用什么都行，先用起来再说。等你写够 5000 行 AI 辅助代码之后，自然知道自己需要什么。&lt;/p&gt;
&lt;h2 id="结论"&gt;结论
&lt;/h2&gt;&lt;p&gt;没有&amp;quot;最好的工具&amp;quot;，只有&amp;quot;最适合你阶段的工具&amp;quot;。Claude Code 的 CLAUDE.md 是工程纪律，Codex 的沙箱是安全底线，OpenCode 的 BYOK 是自由选择，ZCode 的可视化是降低门槛。这四款工具更新很快，但方法论的演进方向不会变：从&amp;quot;我说你做&amp;quot;到&amp;quot;你理解我的意图自己做&amp;quot;。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;varkm&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Vibe Coding 三阶进化：从「帮我写代码」到「Agent 自己干」，你还在第几层？</title><link>https://blog.kalend.top/2026/07/05/2026-07-05-vibe-coding-methodology.html/</link><pubDate>Sun, 05 Jul 2026 10:00:00 +0800</pubDate><guid>https://blog.kalend.top/2026/07/05/2026-07-05-vibe-coding-methodology.html/</guid><description>&lt;h2 id="karpathy-自己都认输了"&gt;Karpathy 自己都认输了
&lt;/h2&gt;&lt;p&gt;2025 年 2 月，他发了条推文。&lt;/p&gt;
&lt;p&gt;给这种编程方式起了个名字——Vibe Coding。&lt;/p&gt;
&lt;p&gt;原话是「完全沉浸在氛围中，忘记代码」。&lt;/p&gt;
&lt;p&gt;一年后，画风突变。&lt;/p&gt;
&lt;p&gt;2026 年 4 月 AI Ascent 大会上，他说：&lt;/p&gt;
&lt;p&gt;「从没觉得自己这么落后过。」&lt;/p&gt;
&lt;p&gt;不是我危言耸听。&lt;/p&gt;
&lt;p&gt;这套方法论，已经偷偷迭代了三代。&lt;/p&gt;
&lt;p&gt;而大多数人，还停在第一代。&lt;/p&gt;
&lt;h2 id="一三阶进化你卡在哪一层"&gt;一、三阶进化：你卡在哪一层？
&lt;/h2&gt;&lt;p&gt;直接上结论，三张面孔一目了然：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;阶段&lt;/th&gt;
					&lt;th&gt;核心理念&lt;/th&gt;
					&lt;th&gt;典型操作&lt;/th&gt;
					&lt;th&gt;致命问题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;1.0 氛围编程&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;忘记代码，只管描述&lt;/td&gt;
					&lt;td&gt;「帮我写个登录页」&lt;/td&gt;
					&lt;td&gt;代码不可控，质量靠运气&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;2.0 Context Coding&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;上下文工程决定产出质量&lt;/td&gt;
					&lt;td&gt;写 AGENTS.md、喂规则文件&lt;/td&gt;
					&lt;td&gt;需要前期投入，但 ROI 极高&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;3.0 Agentic Engineering&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Agent 自主拆解+执行+验证&lt;/td&gt;
					&lt;td&gt;给目标，它自己规划编码测试&lt;/td&gt;
					&lt;td&gt;需要信任，但也要审查机制&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="10-氛围编程祈祷式开发"&gt;1.0 氛围编程：祈祷式开发
&lt;/h3&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;/p&gt;
&lt;p&gt;赌运气好，赌 AI 今天状态在线。&lt;/p&gt;
&lt;p&gt;像让实习生独自交付核心模块，你连 review 都跳过了。&lt;/p&gt;
&lt;h3 id="20-context-coding给-ai-一本操作手册"&gt;2.0 Context Coding：给 AI 一本操作手册
&lt;/h3&gt;&lt;p&gt;你开始写规则文件。&lt;/p&gt;
&lt;p&gt;告诉它项目用 React 不用 Vue。&lt;/p&gt;
&lt;p&gt;告诉它提交前必须跑测试。&lt;/p&gt;
&lt;p&gt;告诉它哪些目录不能动。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;质量从玄学变成了工程。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同一个需求，有没有上下文，产出天差地别。&lt;/p&gt;
&lt;p&gt;这一层的 ROI 最高，投入一小时能省十小时返工。&lt;/p&gt;
&lt;h3 id="30-agentic-engineering当-ai-成了你的同事"&gt;3.0 Agentic Engineering：当 AI 成了你的同事
&lt;/h3&gt;&lt;p&gt;你不再描述「怎么做」。&lt;/p&gt;
&lt;p&gt;你只说「做什么」。&lt;/p&gt;
&lt;p&gt;Agent 自己拆任务、写代码、跑测试、提 PR。&lt;/p&gt;
&lt;p&gt;你只需要审查结果，而不是审查每一行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是质变，不是量变。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但别误会，信任不等于放任。&lt;/p&gt;
&lt;h2 id="二四款工具方法论适配度横评"&gt;二、四款工具方法论适配度横评
&lt;/h2&gt;&lt;p&gt;先说清楚：&lt;strong&gt;这不是工具评测。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;是看每款工具，把你推向哪个阶段。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;Claude Code&lt;/th&gt;
					&lt;th&gt;Codex CLI&lt;/th&gt;
					&lt;th&gt;OpenCode&lt;/th&gt;
					&lt;th&gt;ZCode&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Anthropic 官方&lt;/td&gt;
					&lt;td&gt;OpenAI 官方&lt;/td&gt;
					&lt;td&gt;开源社区（18万+ Star）&lt;/td&gt;
					&lt;td&gt;智谱（GLM-5.2 原生）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;方法论适配&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;2.0→3.0&lt;/td&gt;
					&lt;td&gt;3.0&lt;/td&gt;
					&lt;td&gt;2.0&lt;/td&gt;
					&lt;td&gt;2.0→3.0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;杀手锏&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;跨会话记忆、CLAUDE.md 上下文工程&lt;/td&gt;
					&lt;td&gt;沙箱隔离+自主执行&lt;/td&gt;
					&lt;td&gt;模型自由度最高&lt;/td&gt;
					&lt;td&gt;可视化操作、国产模型原生适配&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;适合谁&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;重度开发者&lt;/td&gt;
					&lt;td&gt;安全敏感场景&lt;/td&gt;
					&lt;td&gt;想自选模型、预算敏感&lt;/td&gt;
					&lt;td&gt;国内开发者、不想折腾 CLI&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="claude-code上下文工程的教科书"&gt;Claude Code：上下文工程的教科书
&lt;/h3&gt;&lt;p&gt;它最懂「规则文件」这件事。&lt;/p&gt;
&lt;p&gt;你写好 CLAUDE.md，它能记住项目约定。&lt;/p&gt;
&lt;p&gt;跨会话不遗忘，连续性极强。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;适配阶段 2.0→3.0，是渐进式升级的最佳载体。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;适合愿意投入上下文工程的重度开发者。&lt;/p&gt;
&lt;h3 id="codex-cli安全第一的执行机器"&gt;Codex CLI：安全第一的执行机器
&lt;/h3&gt;&lt;p&gt;OpenAI 的安全基因刻在骨子里。&lt;/p&gt;
&lt;p&gt;默认沙箱隔离，不碰敏感文件。&lt;/p&gt;
&lt;p&gt;它会自主执行，但你始终能拉住缰绳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;适配阶段 3.0，但「不信任但验证」做得最彻底。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;适合金融、安全敏感场景的用户。&lt;/p&gt;
&lt;h3 id="opencode模型自由度之王"&gt;OpenCode：模型自由度之王
&lt;/h3&gt;&lt;p&gt;18 万 Star 的开源社区在背后。&lt;/p&gt;
&lt;p&gt;75+ 模型可选，想用哪个用哪个。&lt;/p&gt;
&lt;p&gt;但自由度高也意味着——上下文你得自己搭。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;适配阶段 2.0，灵活但需要自配规则。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;适合预算敏感、想掌控模型选择的开发者。&lt;/p&gt;
&lt;h3 id="zcode国产模型的原生适配者"&gt;ZCode：国产模型的原生适配者
&lt;/h3&gt;&lt;p&gt;智谱出品，GLM-5.2 模型原生集成。&lt;/p&gt;
&lt;p&gt;可视化操作界面，不用对着黑框敲命令。&lt;/p&gt;
&lt;p&gt;对国内开发者友好，理解中文需求更精准。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;适配阶段 2.0→3.0，ADE 一体化做得好。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;适合不想折腾 CLI、偏好可视化操作的人。&lt;/p&gt;
&lt;h2 id="三不绑定工具的四条心法"&gt;三、不绑定工具的四条心法
&lt;/h2&gt;&lt;p&gt;工具会换代，方法论不会。&lt;/p&gt;
&lt;p&gt;这才是 2026 年真正该学的东西。&lt;/p&gt;
&lt;h3 id="心法一写好-agentsmd-比选对工具重要十倍"&gt;心法一：写好 AGENTS.md 比选对工具重要十倍
&lt;/h3&gt;&lt;p&gt;Context Engineering 是所有工具的底层逻辑。&lt;/p&gt;
&lt;p&gt;不管你用 Claude Code 还是 Codex，底层都一样。&lt;/p&gt;
&lt;p&gt;同一款工具，有上下文文件和没有，产出质量天差地别。&lt;/p&gt;
&lt;p&gt;这就像同一个实习生，给他项目文档和不给他，结果完全不同。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你的规则文件，就是 AI 的入职手册。写得越细，产出越稳。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="心法二任务拆解粒度决定成败"&gt;心法二：任务拆解粒度决定成败
&lt;/h3&gt;&lt;p&gt;小任务直接描述：修个 bug、加个按钮。&lt;/p&gt;
&lt;p&gt;大任务先出方案：重构模块、新功能，确认后再执行。&lt;/p&gt;
&lt;p&gt;一口气丢个大需求，结果一定让你崩溃。&lt;/p&gt;
&lt;p&gt;Agent 会按自己的理解拆解，往往跟你想的完全不一样。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;小步快跑，永远比一次梭哈靠谱。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="心法三审查--不信任"&gt;心法三：审查 ≠ 不信任
&lt;/h3&gt;&lt;p&gt;Agent 产出必须验证，这不是不信任。&lt;/p&gt;
&lt;p&gt;是 Code Review 的 Agent 化。&lt;/p&gt;
&lt;p&gt;不看每一行代码，但要跑测试、查边界、review 关键逻辑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信任是给空间的，验证是兜底的。两者不矛盾。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="心法四迭代循环不是一次生成完事"&gt;心法四：迭代循环，不是一次生成完事
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Vibe Coding 迭代闭环 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────┐ ┌──────┐ ┌──────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 生成 │───▶│ 验证 │───▶│ 修正 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────┘ └──────┘ └──────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▲ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 再验证 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;你不会让实习生一次交付完美代码。&lt;/p&gt;
&lt;p&gt;Agent 也一样。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生成 → 验证 → 修正 → 再验证，才是正确姿势。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="说在最后"&gt;说在最后
&lt;/h2&gt;&lt;p&gt;工具会变，方法论不会。&lt;/p&gt;
&lt;p&gt;Claude Code 明天可能就被别的工具超越。&lt;/p&gt;
&lt;p&gt;但「上下文工程 + 任务拆解 + 验证迭代」这套心法，五年内不会过时。&lt;/p&gt;
&lt;p&gt;2026 年真正该学的，不是哪个工具更强。&lt;/p&gt;
&lt;p&gt;而是怎么跟 AI 高效协作。&lt;/p&gt;
&lt;p&gt;这，才是你的护城河。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;关注「varkm」，一起学习，一起成长。&lt;/p&gt;</description></item><item><title>MCP 安全血案：5条攻击路径、20万台服务器中招、你装的插件可能有毒</title><link>https://blog.kalend.top/2026/06/29/2026-06-29-mcp-security-vulnerabilities.html/</link><pubDate>Mon, 29 Jun 2026 08:30:00 +0800</pubDate><guid>https://blog.kalend.top/2026/06/29/2026-06-29-mcp-security-vulnerabilities.html/</guid><description>&lt;h2 id="开篇你装的-mcp-插件可能正在偷你的密钥"&gt;开篇：你装的 MCP 插件，可能正在偷你的密钥
&lt;/h2&gt;&lt;p&gt;上周有个朋友找我，说他用 Cursor 写代码，某天突然发现 &lt;code&gt;.ssh&lt;/code&gt; 目录被读过，AWS 凭证疑似泄露。排查了两天，最后定位到一个两周前从社区 registry 装的 MCP 服务器——一个号称「数据库查询工具」的 npm 包，后台默默把环境变量打包发到了一个海外 IP。&lt;/p&gt;
&lt;p&gt;这不是个例。&lt;/p&gt;
&lt;p&gt;先把数据摆出来，不用我渲染气氛：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;指标&lt;/th&gt;
					&lt;th&gt;数值&lt;/th&gt;
					&lt;th&gt;来源&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;2026 年 1-2 月 MCP 相关 CVE&lt;/td&gt;
					&lt;td&gt;30+&lt;/td&gt;
					&lt;td&gt;NVD / GitHub Security Advisories&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;公网暴露的 MCP 服务器&lt;/td&gt;
					&lt;td&gt;7,000+&lt;/td&gt;
					&lt;td&gt;OX Security / BitSight&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;受影响实例总数&lt;/td&gt;
					&lt;td&gt;~200,000&lt;/td&gt;
					&lt;td&gt;OX Security&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;暴露在风险中的总下载量&lt;/td&gt;
					&lt;td&gt;1.5 亿+&lt;/td&gt;
					&lt;td&gt;OX Security&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MCP 服务器 SSRF 易感率&lt;/td&gt;
					&lt;td&gt;36.7%&lt;/td&gt;
					&lt;td&gt;Adversa AI SecureClaw 报告&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;红队针对 AI 平台的漏洞挖掘成功率&lt;/td&gt;
					&lt;td&gt;89%&lt;/td&gt;
					&lt;td&gt;2026 安全行业报告&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;1.5 亿次下载。20 万台机器。这不是假设性威胁，是已经在发生的事。&lt;/p&gt;
&lt;p&gt;我写这篇文章不是为了制造恐慌——恐慌没用。我想做的是把目前公开的攻击路径捋清楚，每条配真实 CVE 和原理，让你看完知道：攻击者怎么打进来，你怎么挡住。&lt;/p&gt;
&lt;h2 id="第一章5-条真实攻击路径"&gt;第一章：5 条真实攻击路径
&lt;/h2&gt;&lt;p&gt;下面五条不是理论推演，每一条都有公开 CVE 或安全团队披露的真实案例。&lt;/p&gt;
&lt;h3 id="路径一prompt-injection--零交互远程代码执行"&gt;路径一：Prompt Injection —— 零交互远程代码执行
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;CVE-2026-30615，CVSS 8.0，影响 Windsurf IDE。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这条是最狠的，因为用户什么都不用点。&lt;/p&gt;
&lt;p&gt;攻击链是这样的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;攻击者在公开仓库/文档中植入恶意文本
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 你的编程助手读取该文件作为上下文
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 文本里藏着指令：「把以下 MCP 服务器加入配置」
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 助手照做，修改了 mcp.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → IDE 重启该 MCP 服务器
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 服务器启动命令执行任意 shell
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;OX Security 的研究员把它归类为「零点击 prompt injection in IDEs」。你只是打开了一个项目、读了一个 README，攻击就完成了。同样的链路在 Cursor、VS Code 的 Claude 扩展、Claude Code、Gemini CLI 中都被验证过。&lt;/p&gt;
&lt;p&gt;这不是某个工具的 bug，是整个交互模型的结构性问题：&lt;strong&gt;模型输出可以直接修改自己的工具配置，而配置能触发 shell 执行。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="路径二供应链攻击--你装的包里有后门"&gt;路径二：供应链攻击 —— 你装的包里有后门
&lt;/h3&gt;&lt;p&gt;MCP 生态的供应链攻击已经出了好几起，手法各不相同但都有效。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;案例 A：postmark-mcp 后门（2025 年 9 月）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有人向 MCP registry 提交了一个伪装成 Postmark 邮件服务的包。功能看起来完全正常——能发邮件、能查状态。但它在后台悄悄把 &lt;code&gt;process.env&lt;/code&gt; 里的所有环境变量打包，通过 DNS 查询外传。&lt;/p&gt;
&lt;p&gt;开发者装它的时候看了一眼功能描述，觉得没问题，就 approve 了。API key 就这么出去了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;案例 B：mcp-server-git 链式 RCE（CVE-2025-68145 / 68143 / 68144）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是 Anthropic 官方维护的 MCP 服务器。三个漏洞链在一起，实现了完整 RCE：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;CVE&lt;/th&gt;
					&lt;th&gt;漏洞&lt;/th&gt;
					&lt;th&gt;效果&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;CVE-2025-68145&lt;/td&gt;
					&lt;td&gt;路径校验绕过&lt;/td&gt;
					&lt;td&gt;突破仓库目录限制&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CVE-2025-68143&lt;/td&gt;
					&lt;td&gt;git_init 无限制&lt;/td&gt;
					&lt;td&gt;能把 &lt;code&gt;~/.ssh&lt;/code&gt; 变成 git 仓库&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CVE-2025-68144&lt;/td&gt;
					&lt;td&gt;git_diff 参数注入&lt;/td&gt;
					&lt;td&gt;注入任意 git 参数&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;配合 Filesystem MCP，攻击者通过一个恶意的 &lt;code&gt;.git/config&lt;/code&gt; 文件，在你机器上执行任意命令。官方仓库、官方维护、官方出的漏洞——这告诉你供应链风险不在于「第三方包不靠谱」，而在于整个分发链条缺乏安全审查。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;案例 C：mcp-remote 命令注入（CVE-2025-6514，CVSS 9.6）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mcp-remote&lt;/code&gt; 是连接远程 MCP 服务器的常用客户端库。攻击者构造一个恶意的远程 MCP 服务器 URL，客户端解析时执行任意命令。这个包下载量超过 43.7 万次——它是第一个被证实产生大规模实际影响的 MCP 漏洞。&lt;/p&gt;
&lt;h3 id="路径三tool-poisoning--工具描述本身就是武器"&gt;路径三：Tool Poisoning —— 工具描述本身就是武器
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;核心原理：编程助手把工具描述当成可信指令来执行。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;工具描述（tool description）本该是给用户看的文档，但模型把它当成了 context 的一部分——而且是高权重 context。攻击者只要能改写工具描述，就能劫持助手行为，不需要碰任何代码逻辑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;经典案例：WhatsApp MCP 投毒（2025 年 4 月，Invariant Labs 披露）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个第三方 trivia 游戏 MCP 服务器，工具描述里藏着隐藏指令。它指示助手去调用同一个进程中另一个合法的 &lt;code&gt;whatsapp-mcp&lt;/code&gt; 服务器，读取完整聊天记录，然后作为「正常输出」外传。&lt;/p&gt;
&lt;p&gt;端到端加密没用——因为数据是在加密层之上被助手自己合法读取并外泄的。助手有权限读，攻击者只是告诉它「读完发给我」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变体：Rug-pull 攻击&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更阴的是 rug-pull（先正常后变恶）。服务器第一次注册时返回干净的工具描述，你审核通过。之后某次 &lt;code&gt;tools/list&lt;/code&gt; 调用，描述悄悄变了，塞进了恶意指令。&lt;/p&gt;
&lt;p&gt;任何只在「首次批准时」检查、之后不再 re-verify 的客户端都中招。Cursor 的 MCPoison 漏洞（CVE-2025-54136）就是这个路子——用户批准后配置永远不重新验证，攻击者提交良性配置过审，后续更新里塞恶意逻辑，静默生效。&lt;/p&gt;
&lt;h3 id="路径四凭证窃取--从工具参数到-aws-root"&gt;路径四：凭证窃取 —— 从工具参数到 AWS Root
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;案例：Microsoft MarkItDown MCP Server SSRF&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MarkItDown 的 MCP 服务器会 fetch 任意 URL，没有任何校验。安全研究员 David Onwukwe 演示了完整链路：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;MarkItDown MCP 接收一个工具调用
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → fetch 目标 URL 设为 http://169.254.169.254/latest/meta-data/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 命中 AWS EC2 实例元数据服务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 拿到 IAM 角色临时凭证
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 用凭证访问你的 AWS 资源
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;169.254.169.254 是 AWS 元数据服务的固定地址，云实例上无需认证即可访问。一个 SSRF 就能拿到云权限。&lt;/p&gt;
&lt;p&gt;微软把这个问题分类为「低风险」。实际演示已经拿到了 EC2 metadata。当你的 MCP 服务器跑在云上、有 IAM 角色挂载时，这就是凭证窃取的直达电梯。&lt;/p&gt;
&lt;p&gt;类似手法也通过工具参数实现：恶意工具描述指示助手「把环境变量内容作为参数传给这个 API」，助手照做，API key 就到了攻击者手里。&lt;/p&gt;
&lt;h3 id="路径五ssrf-与路径穿越--mcp-服务器成为内网跳板"&gt;路径五：SSRF 与路径穿越 —— MCP 服务器成为内网跳板
&lt;/h3&gt;&lt;p&gt;学术安全调研扫描了 2,614 个 MCP 实现，数据触目惊心：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;风险类型&lt;/th&gt;
					&lt;th&gt;占比&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;文件操作存在路径穿越风险&lt;/td&gt;
					&lt;td&gt;82%&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;存在代码注入风险&lt;/td&gt;
					&lt;td&gt;67%&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;存在命令注入风险&lt;/td&gt;
					&lt;td&gt;34%&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SSRF 暴露率&lt;/td&gt;
					&lt;td&gt;36.7%&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;案例 A：Fetch MCP Server SSRF（CVE-2025-65513，CVSS 7.5）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mcp-fetch-server&lt;/code&gt; 的 &lt;code&gt;is_ip_private()&lt;/code&gt; 函数没能正确识别私有 IP 地址。攻击者让服务器请求内网地址（&lt;code&gt;http://10.0.0.1/admin&lt;/code&gt;、&lt;code&gt;http://169.254.169.254/...&lt;/code&gt;），函数判断「不是私有 IP」，请求放行。MCP 服务器变成了攻击者进入你内网的跳板。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;案例 B：filesystem-mcp 路径穿越（CVE-2025-67366）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;配置了只能访问 &lt;code&gt;/home/user/project&lt;/code&gt; 的文件系统 MCP，攻击者用 &lt;code&gt;../../etc/shadow&lt;/code&gt; 穿越出去，读到了任意文件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;案例 C：Zen MCP Server 路径穿越（CVE-2025-66689）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;is_dangerous_path()&lt;/code&gt; 函数用精确字符串匹配黑名单。&lt;code&gt;/etc/shadow&lt;/code&gt; 被拦了，但 &lt;code&gt;/etc/shadow/../../../home/user/.ssh/id_rsa&lt;/code&gt; 没被拦——因为不在黑名单的精确匹配里。一个子目录穿越就绕过了「敏感路径保护」。&lt;/p&gt;
&lt;h2 id="第二章为什么-mcp-天生不安全"&gt;第二章：为什么 MCP 天生不安全
&lt;/h2&gt;&lt;p&gt;拆完攻击路径，往上抬一层看架构。MCP 的安全问题不是「实现写得烂」，是设计层面就有几个结构性缺陷。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缺陷一：工具描述被默认当作权威指令&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;传统 API 安全模型里，文档是文档，执行是执行，两者隔离。Swagger 文档里写什么不会影响服务端行为。&lt;/p&gt;
&lt;p&gt;MCP 打破了这个隔离。工具描述直接进入模型 context，模型把它当指令执行。这意味着——文档即攻击面。任何能改工具描述的环节（服务器更新、中间人、供应链）都等于拿到了模型的部分控制权。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缺陷二：服务器代码跑在你机器上，但行为由远程定义&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MCP 服务器作为子进程跑在你本地，有你用户的全部权限——能读 &lt;code&gt;.ssh&lt;/code&gt;、能读 &lt;code&gt;.aws&lt;/code&gt;、能访问内网。但它的行为逻辑（工具定义、执行逻辑）由远程 npm/PyPI 包决定，随时可以更新。&lt;/p&gt;
&lt;p&gt;你的机器提供了权限和信任，远程服务提供了行为，两者之间没有隔离层。这就像你在自己家里装了一个别人能远程操控的锁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缺陷三：没有人工审核的默认信任链&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;多数 MCP 客户端用「首次信任」（TOFU）模型。你第一次批准一个服务器，之后它的所有更新和工具调用默认放行，不再重新验证。Cursor 的 MCPoison 就是钻了这个空子。&lt;/p&gt;
&lt;p&gt;工具调用链可以跨安全域：一个你信任的 MCP 服务器，被恶意指令引导去调用另一个你授权的 MCP 服务器，数据就跨域流动了。上面 WhatsApp 投毒就是这个模式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缺陷四：协议规范只管传输，不管安全&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MCP 规范定义了消息格式和传输层（stdio / SSE），但认证、响应完整性、审计——全是生态各自为政。82% 的实现有路径穿越风险，不是因为开发者菜，是因为协议没提供安全基线，每个人都在重新发明轮子，而且发明得都不好。&lt;/p&gt;
&lt;h2 id="第三章真实伤亡清单"&gt;第三章：真实伤亡清单
&lt;/h2&gt;&lt;p&gt;把受影响面拉个清单，让你知道自己在不在射程内。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IDE / 编程工具全线中招：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;受影响情况&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Cursor&lt;/td&gt;
					&lt;td&gt;MCPoison 信任绕过（CVE-2025-54136）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;VS Code（Claude 扩展）&lt;/td&gt;
					&lt;td&gt;零点击 prompt injection 链&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Windsurf&lt;/td&gt;
					&lt;td&gt;CVE-2026-30615，CVSS 8.0 RCE&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Claude Code&lt;/td&gt;
					&lt;td&gt;通过 hooks/MCP config/env 攻击链&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Gemini CLI&lt;/td&gt;
					&lt;td&gt;MCP 工具链受影响&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LangChain / LangFlow / Flowise&lt;/td&gt;
					&lt;td&gt;未认证 UI 注入 RCE&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LiteLLM&lt;/td&gt;
					&lt;td&gt;CVE-2025-45809，SQL 注入&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OX Security 评估：这些工具背后的 MCP 生态总下载量超过 1.5 亿次，约 20 万个实例存在被利用风险。&lt;/p&gt;
&lt;p&gt;Anthropic 对核心设计缺陷的回应是：「这是设计行为，sanitize 是开发者的责任。」&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vulnerablemcp.info 数据库现状：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;社区维护的漏洞数据库 The Vulnerable MCP Project 已收录 50+ 个漏洞，其中 13 个评为 Critical。这个数字还在涨，每周都有新 CVE 进来。&lt;/p&gt;
&lt;p&gt;如果你在生产环境跑 MCP 服务器，或者哪怕只是在本地用 Cursor 配了几个 MCP 插件，你都在这个射程内。&lt;/p&gt;
&lt;h2 id="第四章开发者自保指南"&gt;第四章：开发者自保指南
&lt;/h2&gt;&lt;p&gt;不废话，直接上操作。&lt;/p&gt;
&lt;h3 id="5-条核心防护措施"&gt;5 条核心防护措施
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1. 审查你装的每一个 MCP 服务器&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 查看当前配置的所有 MCP 服务器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Cursor: Settings → MCP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Claude Code: ~/.claude/mcp.json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# VS Code: 命令面板 → &amp;#34;MCP: List Servers&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 检查 git 历史里有没有可疑改动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --all --since&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2 weeks ago&amp;#34;&lt;/span&gt; -- mcp.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 移除不用的服务器——每一个都是攻击面&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;对于每一个服务器：确认发布者身份、检查 GitHub 仓库近期活跃度和 issue 区有没有安全报告。不认识的服务器，删掉。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 沙箱隔离&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MCP 服务器进程不该有你用户的所有权限。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 用 Docker 跑，只挂载项目目录，不挂 ~/.ssh、~/.aws&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -it --rm &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;:/workspace &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -w /workspace &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; your-mcp-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 或者用 Dev Container，VS Code 原生支持&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;原则：MCP 进程不该接触到「泄露了会很惨」的凭证。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 最小权限&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API key 用只读 scope，别给 root key&lt;/li&gt;
&lt;li&gt;文件系统 MCP 限定到项目目录，别给 home 目录&lt;/li&gt;
&lt;li&gt;网络 MCP 加出站白名单，别让它随便 fetch&lt;/li&gt;
&lt;li&gt;用了之后立刻 revoke 不再需要的凭证&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. 固定版本，不用 @latest&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 危险&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx @some-package/mcp-server@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;npx @some-package/mcp-server@1.2.3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;供应链 rug-pull 靠的就是你无感知地拉到恶意更新。锁版本 + 监控更新日志，至少能让你知道什么时候变了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. 用 mcp-scan 做安全扫描&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Invariant Labs 出的 &lt;code&gt;mcp-scan&lt;/code&gt; 是目前最实用的免费工具：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 需要 Python 3.10+ 和 uv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class="p"&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 扫描你的 MCP 配置，自动检测工具投毒和已知漏洞&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx mcp-scan
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# CI/CD 集成——发现 critical 问题直接失败&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx mcp-scan --exit-code
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它能检测工具描述里的投毒指标、匹配已知漏洞数据库、检查版本是否受影响。30 秒跑完，建议每周扫一次。&lt;/p&gt;
&lt;h3 id="mcp-服务器选型-checklist"&gt;MCP 服务器选型 Checklist
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;检查项&lt;/th&gt;
					&lt;th&gt;通过标准&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;发布者身份&lt;/td&gt;
					&lt;td&gt;可验证的 GitHub 组织/个人，有历史信誉&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;源码可审&lt;/td&gt;
					&lt;td&gt;公开仓库，能读到完整源码&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;活跃度&lt;/td&gt;
					&lt;td&gt;近 3 个月有提交，issue 有回应&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;认证机制&lt;/td&gt;
					&lt;td&gt;有 auth 层，不裸奔&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;权限范围&lt;/td&gt;
					&lt;td&gt;只请求必要权限，不做 read+write 全要&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;社区反馈&lt;/td&gt;
					&lt;td&gt;搜索 CVE + 安全报告，无未修复的高危项&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="推荐工具"&gt;推荐工具
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;用途&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;mcp-scan&lt;/td&gt;
					&lt;td&gt;免费开源&lt;/td&gt;
					&lt;td&gt;工具投毒检测 + 漏洞匹配&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Snyk Agent Scan&lt;/td&gt;
					&lt;td&gt;免费/付费&lt;/td&gt;
					&lt;td&gt;依赖链漏洞扫描，CI/CD 集成&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SecureClaw&lt;/td&gt;
					&lt;td&gt;企业级&lt;/td&gt;
					&lt;td&gt;55 项审计，合规报告&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;agent-audit&lt;/td&gt;
					&lt;td&gt;开源&lt;/td&gt;
					&lt;td&gt;OWASP Agentic Top 10 对标审计&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;个人开发者：mcp-scan 起步，Snyk 补依赖链。企业环境：上 SecureClaw 做持续监控。&lt;/p&gt;
&lt;h2 id="第五章总结与展望"&gt;第五章：总结与展望
&lt;/h2&gt;&lt;p&gt;先说结论：&lt;strong&gt;MCP 的安全不是「以后再说」的事，是现在就得管的事。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;30 个 CVE 用 60 天砸下来，已经把 MCP 从「有前景的开放标准」打成了「活跃攻击面」。而根因——工具描述当指令执行、远程定义本地行为、协议不管安全——不是修几个 bug 能解决的。&lt;/p&gt;
&lt;p&gt;好在社区在动：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;协议层&lt;/strong&gt;：MCP 规范团队在推内置认证标准、工具描述签名、服务器 attestation。这些能从根源上解决工具投毒和供应链问题，但落地还要几个月。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Registry 审查&lt;/strong&gt;：主要 MCP registry 在上线发布者验证 + 自动安全扫描，供应链风险会降但不会消失。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;客户端防御&lt;/strong&gt;：越来越多客户端加了细粒度权限控制和定期 re-verify，TOFU 模型在松动。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但这些都是未来的事。今天的现实是：你装的 MCP 插件可能有毒，你配的服务器可能暴露在公网，你的凭证可能已经被打包外传了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你现在该做的三件事：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开你的 IDE MCP 设置，删掉所有不认识的服务器&lt;/li&gt;
&lt;li&gt;跑一遍 &lt;code&gt;uvx mcp-scan&lt;/code&gt;，修掉 critical 项&lt;/li&gt;
&lt;li&gt;把敏感凭证从 MCP 进程能触及的环境里挪走&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;做完这三步，你的风险面至少砍掉一大半。剩下的，等协议和工具成熟。&lt;/p&gt;
&lt;p&gt;安全从来不是等来的，是防出来的。MCP 生态还在野蛮生长，你不变靶子，就只能自己穿甲。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;数据来源：OX Security 供应链 advisory、The Vulnerable MCP Project（vulnerablemcp.info）、Adversa AI SecureClaw 报告、Invariant Labs 工具投毒披露、NVD/GitHub Security Advisories。 CVE 详情可在对应数据库查询。&lt;/em&gt;&lt;/p&gt;</description></item><item><title>ChromaDB + Python：5分钟搭建个人知识库</title><link>https://blog.kalend.top/2026/06/24/2026-06-24-chromadb-knowledge-base.html/</link><pubDate>Wed, 24 Jun 2026 08:30:00 +0800</pubDate><guid>https://blog.kalend.top/2026/06/24/2026-06-24-chromadb-knowledge-base.html/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;上一篇用 FAISS 搭语义搜索引擎，有人问我：有没有不用自己管索引文件的方案？有，ChromaDB 就是为这个场景生的。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="先说结论"&gt;先说结论
&lt;/h2&gt;&lt;p&gt;ChromaDB 是面向开发者的&amp;quot;零配置&amp;quot;向量数据库。pip install 就能用，不需要 Docker，不需要外部服务，自带持久化，支持元数据过滤，几行代码接入 embedding 模型。&lt;/p&gt;
&lt;p&gt;一句话定位：&lt;strong&gt;向量数据库里的 SQLite&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你只是想快速搭一个知识库、文档搜索、RAG 原型，ChromaDB 是门槛最低的选择。等数据量到百万级、需要高并发了，再考虑 Qdrant 或 Milvus。&lt;/p&gt;
&lt;h2 id="向量数据库-60-秒科普"&gt;向量数据库 60 秒科普
&lt;/h2&gt;&lt;p&gt;上一篇 FAISS 文章讲过原理，这里用图书馆的类比快速过一遍。&lt;/p&gt;
&lt;p&gt;你去图书馆找书，有两种方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;索引卡方式&lt;/strong&gt;（关键词搜索）：翻目录卡片，按书名精确匹配。搜&amp;quot;Python 入门&amp;quot;只能找到标题里有这几个字的书&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问管理员方式&lt;/strong&gt;（语义搜索）：跟管理员说&amp;quot;我想学编程&amp;quot;，他理解你的意思，给你推荐相关的书，不管书名叫什么&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;向量数据库干的就是&amp;quot;管理员&amp;quot;的活。它把每条文档编码成向量（一串数字），搜索时把你的查询也编码成向量，然后计算向量间的距离找最接近的。&lt;/p&gt;
&lt;p&gt;ChromaDB 在此基础上多做了一件事：它把这些向量连同原始文本和元数据一起存好，不用你操心存储细节。FAISS 是搜索库，你得自己管存储；ChromaDB 是完整数据库，存储、索引、元数据一站式搞定。&lt;/p&gt;
&lt;h2 id="5-分钟快速上手"&gt;5 分钟快速上手
&lt;/h2&gt;&lt;h3 id="第一步安装"&gt;第一步：安装
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;pip install chromadb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ChromaDB 自带一个内置 embedding 模型（all-MiniLM-L6-v2），英文场景开箱即用。但如果你处理中文，建议额外装一个中文模型：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;pip install chromadb sentence-transformers
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;sentence-transformers&lt;/code&gt; 提供了丰富的中文 embedding 模型，下面的代码我会用它接入 &lt;code&gt;BAAI/bge-small-zh-v1.5&lt;/code&gt;（约 100MB，首次自动下载）。&lt;/p&gt;
&lt;h3 id="第二步创建客户端和集合"&gt;第二步：创建客户端和集合
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;chromadb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;chromadb.utils.embedding_functions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformerEmbeddingFunction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 用中文 embedding 模型（默认模型偏英文，中文效果差）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformerEmbeddingFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;BAAI/bge-small-zh-v1.5&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersistentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./my_knowledge_base&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建集合时指定 embedding 函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_or_create_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my_docs&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="cl"&gt; &lt;span class="n"&gt;embedding_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ef&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;PersistentClient&lt;/code&gt; 和 FAISS 的最大区别：数据自动落盘。程序关了再开，数据还在。不用手动 &lt;code&gt;write_index&lt;/code&gt; / &lt;code&gt;read_index&lt;/code&gt;，不用维护&amp;quot;索引 ID → 原始文本&amp;quot;的映射表。&lt;/p&gt;
&lt;p&gt;底层存储用的是 SQLite 数据库（&lt;code&gt;chroma.sqlite3&lt;/code&gt;），向量索引用二进制文件存储，全部放在你指定的 &lt;code&gt;path&lt;/code&gt; 目录下。这意味着你甚至可以用 sqlite3 直接查看元数据，备份只需要拷贝整个目录。&lt;/p&gt;
&lt;p&gt;如果你只想做内存测试，用 &lt;code&gt;chromadb.Client()&lt;/code&gt; 即可，退出即丢。&lt;/p&gt;
&lt;h3 id="第三步添加文档"&gt;第三步：添加文档
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 添加文档，ChromaDB 自动帮你做 embedding&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;documents&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="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Python 是一门解释型编程语言，语法简洁易读&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="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Java 是面向对象的编程语言，跨平台运行&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="cl"&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="cl"&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="cl"&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="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadatas&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="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&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;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;wiki&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="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&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;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;wiki&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="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&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;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;diary&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="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&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;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;faq&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="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&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;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;faq&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="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ids&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;doc1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc5&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="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意：这里指定了中文 embedding 模型，&lt;code&gt;add()&lt;/code&gt; 的时候 ChromaDB 自动把文本转成向量存进去。ChromaDB 内置的默认模型（all-MiniLM-L6-v2）偏英文，对中文语义理解较差，所以处理中文数据时强烈建议换成中文模型。&lt;/p&gt;
&lt;h3 id="第四步查询"&gt;第四步：查询
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 语义搜索&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query_texts&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;编程语言有哪些&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="cl"&gt; &lt;span class="n"&gt;n_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;documents&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 class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;distances&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="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[距离: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.4f&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;doc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[距离: 0.3133] Java 是面向对象的编程语言，跨平台运行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[距离: 0.3375] Python 是一门解释型编程语言，语法简洁易读
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[距离: 0.7588] 今天天气真不错，适合出门散步
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;搜&amp;quot;编程语言有哪些&amp;quot;，前两条命中 Python 和 Java，第三条天气明显不相关。距离越小越相似。&lt;/p&gt;
&lt;p&gt;补充一点：&lt;code&gt;distances&lt;/code&gt; 返回的是向量距离，不是相似度分数。ChromaDB 默认用余弦距离，值域 [0, 2]，0 表示完全一致，2 表示完全相反。实际使用中，距离小于 1.0 的结果通常比较相关，大于 1.2 就可以当噪音忽略了。&lt;/p&gt;
&lt;h3 id="第五步元数据过滤"&gt;第五步：元数据过滤
&lt;/h3&gt;&lt;p&gt;这是 ChromaDB 相比 FAISS 的杀手级功能——&lt;strong&gt;先筛选再搜索&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 只在&amp;#34;客服&amp;#34;分类里搜索&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query_texts&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;退款&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="cl"&gt; &lt;span class="n"&gt;n_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;where&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;category&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="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;documents&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;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[&amp;#39;如何申请退款？请在订单页面点击退款按钮&amp;#39;, &amp;#39;我想把钱退回来，应该怎么操作&amp;#39;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;where&lt;/code&gt; 条件支持 &lt;code&gt;$eq&lt;/code&gt;（等于）、&lt;code&gt;$ne&lt;/code&gt;（不等于）、&lt;code&gt;$in&lt;/code&gt;（包含）等操作符：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 多值过滤&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;where&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;category&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;$in&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;编程&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;where&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;$and&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;faq&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="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&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="cl"&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;想象一个场景：你有 10000 篇文档，10 个分类。用户只想搜&amp;quot;技术&amp;quot;分类下的内容。FAISS 需要你自己实现过滤逻辑，ChromaDB 一个 &lt;code&gt;where&lt;/code&gt; 参数搞定。&lt;/p&gt;
&lt;h2 id="完整实战搭建个人知识库"&gt;完整实战：搭建个人知识库
&lt;/h2&gt;&lt;p&gt;把上面的模块组合起来，做一个能增删查的迷你知识库：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;span class="lnt"&gt;68
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;chromadb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;chromadb.utils.embedding_functions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformerEmbeddingFunction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./my_kb&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="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersistentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;db_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="cl"&gt; &lt;span class="n"&gt;ef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformerEmbeddingFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;BAAI/bge-small-zh-v1.5&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="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_or_create_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;notes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embedding_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ef&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&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 class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;未分类&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;添加一条笔记&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;doc_id&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;doc_id&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;note_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;1000&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&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="cl"&gt; &lt;span class="n"&gt;metadatas&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;category&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;doc_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;doc_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;语义搜索，可选按分类过滤&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;where&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;category&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="k"&gt;else&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="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query_texts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;n_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt; &lt;span class="n"&gt;hits&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="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;documents&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="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;distances&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="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;metadatas&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="cl"&gt; &lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;distance&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;meta&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collection&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;kb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;notes&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="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Python 列表推导式比 for 循环快，因为底层用 C 实现&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Python&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="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Git rebase 会重写提交历史，谨慎在公共分支使用&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Git&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="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Docker 容器隔离靠 namespace 和 cgroups&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Docker&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="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Python 装饰器本质是接受函数返回函数的高阶函数&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Python&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="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Git stash 暂存当前工作区改动，不提交到分支&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Git&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="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;kb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&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 class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;知识库共 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;kb&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 条笔记&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 语义搜索：搜&amp;#34;循环优化&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;=== 搜索: 循环优化 ===&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;kb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;循环优化&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;meta&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;category&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;hit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;text&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 搜索：只在 Git 分类下搜&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;=== 搜索: 分支管理 (仅 Git) ===&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="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;kb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;分支管理&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Git&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="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;meta&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;category&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;hit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;text&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;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;运行后重启程序，数据还在——因为 &lt;code&gt;PersistentClient&lt;/code&gt; 自动落盘了。这就是 ChromaDB 和 FAISS 最大的体验差异：你不用管索引文件，数据自己活着。&lt;/p&gt;
&lt;p&gt;补充两个实用技巧：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;批量添加&lt;/strong&gt;比逐条添加快得多。上面的示例为了清晰逐条 &lt;code&gt;add()&lt;/code&gt;，实际使用时建议一次传入列表：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 批量添加，比循环 add() 快 10 倍以上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;documents&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;文档1&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 class="s2"&gt;&amp;#34;文档3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadatas&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;cat&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cat&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cat&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c&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="cl"&gt; &lt;span class="n"&gt;ids&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;d1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;d2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;d3&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="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;换更强的中文模型&lt;/strong&gt;。如果你的数据量更大、精度要求更高，可以把 &lt;code&gt;bge-small-zh-v1.5&lt;/code&gt; 换成 &lt;code&gt;BAAI/bge-large-zh-v1.5&lt;/code&gt;（1024 维，约 1.3GB）。注意：同一个集合内不能混用不同模型，换模型必须新建集合。&lt;/p&gt;
&lt;h2 id="选型对比chromadb-vs-faiss-vs-qdrant"&gt;选型对比：ChromaDB vs FAISS vs Qdrant
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;ChromaDB&lt;/th&gt;
					&lt;th&gt;FAISS&lt;/th&gt;
					&lt;th&gt;Qdrant&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;部署方式&lt;/td&gt;
					&lt;td&gt;pip install，零配置&lt;/td&gt;
					&lt;td&gt;pip install，纯库&lt;/td&gt;
					&lt;td&gt;需 Docker 或独立服务&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;内置 embedding&lt;/td&gt;
					&lt;td&gt;有（all-MiniLM-L6-v2）&lt;/td&gt;
					&lt;td&gt;无，需自己编码&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;持久化&lt;/td&gt;
					&lt;td&gt;自动落盘&lt;/td&gt;
					&lt;td&gt;手动 save/load&lt;/td&gt;
					&lt;td&gt;自动&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;元数据过滤&lt;/td&gt;
					&lt;td&gt;where 条件，开箱即用&lt;/td&gt;
					&lt;td&gt;无，需自己实现&lt;/td&gt;
					&lt;td&gt;有，filter API&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;适用规模&lt;/td&gt;
					&lt;td&gt;&amp;lt;100万&lt;/td&gt;
					&lt;td&gt;任意（看索引类型）&lt;/td&gt;
					&lt;td&gt;千万级&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;典型场景&lt;/td&gt;
					&lt;td&gt;知识库、RAG 原型&lt;/td&gt;
					&lt;td&gt;高性能向量搜索&lt;/td&gt;
					&lt;td&gt;生产级语义搜索&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;我的选型建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人知识库、文档搜索、RAG 原型 → &lt;strong&gt;ChromaDB&lt;/strong&gt;。零配置，内置 embedding，5 分钟跑通&lt;/li&gt;
&lt;li&gt;纯追求搜索速度、数据量可控 → &lt;strong&gt;FAISS&lt;/strong&gt;。最轻最快，但要自己管存储和元数据&lt;/li&gt;
&lt;li&gt;生产环境、高并发、需要精确过滤 → &lt;strong&gt;Qdrant&lt;/strong&gt;。功能全性能好，代价是要部署一个服务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话总结：&lt;strong&gt;个人和原型用 ChromaDB，生产高并发用 Qdrant，纯速度用 FAISS。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="结语"&gt;结语
&lt;/h2&gt;&lt;p&gt;ChromaDB 的定位很清晰：向量数据库里的 SQLite。不需要服务端，不需要 Docker，pip install 之后几行代码就能跑，数据自动持久化，接入 embedding 模型就能开箱即用。&lt;/p&gt;
&lt;p&gt;它不追求极限性能，不追求分布式高可用，但它把&amp;quot;存储 + 索引 + embedding + 元数据过滤&amp;quot;打包成一个极简的包。对于个人知识库、文档语义搜索、RAG 原型验证这些场景，ChromaDB 是目前最省心的选择。Python 开发者十分钟就能搭出一个能用的知识库，这个门槛在两年前是不可想象的。&lt;/p&gt;
&lt;p&gt;上一篇 FAISS 文章解决了&amp;quot;怎么把向量搜得快&amp;quot;，这一篇解决了&amp;quot;怎么用得省心&amp;quot;。两者互补：FAISS 适合想完全掌控底层细节的极客，ChromaDB 适合想快速出结果的开发者。如果你刚接触向量检索，建议从 ChromaDB 开始——先跑通流程，理解语义搜索的价值，再根据实际需求决定是否需要换到 FAISS 或 Qdrant。&lt;/p&gt;
&lt;p&gt;试试用自己的文档笔记跑一遍上面的代码，把日常积累的技术笔记、读书摘录、工作文档丢进去，你会发现语义搜索比关键词搜索好用太多。搜&amp;quot;性能优化&amp;quot;能找到&amp;quot;降低延迟&amp;quot;的笔记，搜&amp;quot;部署&amp;quot;能找到&amp;quot;Docker 配置&amp;quot;的记录——这在传统的搜索方式下几乎不可能。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;关注 varkm，一起学习，一起成长&lt;/p&gt;</description></item><item><title>别再用 LIKE 搜数据库了：20 行代码搭一个语义搜索引擎</title><link>https://blog.kalend.top/2026/06/21/2026-06-21-faiss-vector-search.html/</link><pubDate>Sun, 21 Jun 2026 08:53:00 +0800</pubDate><guid>https://blog.kalend.top/2026/06/21/2026-06-21-faiss-vector-search.html/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;你在文档里搜&amp;quot;退款&amp;quot;，结果一个都没有。但文档里明明写着&amp;quot;我想退钱&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="先说结论"&gt;先说结论
&lt;/h2&gt;&lt;p&gt;传统搜索靠关键词匹配，搜&amp;quot;退款&amp;quot;找不到&amp;quot;退钱&amp;quot;，因为机器只认字不认意思。&lt;/p&gt;
&lt;p&gt;向量检索把文字变成数字（向量），按语义相似度搜索。搜&amp;quot;退款&amp;quot;能命中&amp;quot;我想退钱&amp;quot;，因为它俩意思一样。&lt;/p&gt;
&lt;p&gt;Sentence-Transformers 负责编码，FAISS 负责搜索。&lt;/p&gt;
&lt;p&gt;20 行 Python，搭一个比 MySQL LIKE 强 100 倍的语义搜索引擎。数据量从一千条到十亿条，都有对应的方案。&lt;/p&gt;
&lt;p&gt;下面我从原理到代码，一步步带你跑通。&lt;/p&gt;
&lt;h2 id="第一章向量检索是什么3-分钟搞懂原理"&gt;第一章：向量检索是什么（3 分钟搞懂原理）
&lt;/h2&gt;&lt;h3 id="文本变向量让机器理解意思"&gt;文本变向量：让机器理解&amp;quot;意思&amp;quot;
&lt;/h3&gt;&lt;p&gt;embedding（嵌入）把一段文字编码成一串数字，比如 768 维的浮点数组。&lt;/p&gt;
&lt;p&gt;这串数字就是文字的&amp;quot;语义指纹&amp;quot;。意思相近的文字，指纹也相近；意思无关的文字，指纹差很远。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;退款&amp;quot;和&amp;quot;退钱&amp;quot;的关键词不同，但编码出来的向量非常接近。&amp;ldquo;退款&amp;quot;和&amp;quot;天气预报&amp;quot;的向量则差了十万八千里。&lt;/p&gt;
&lt;h3 id="相似度怎么算余弦-vs-l2"&gt;相似度怎么算：余弦 vs L2
&lt;/h3&gt;&lt;p&gt;算两个向量有多接近，常用两种方式：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方式&lt;/th&gt;
					&lt;th&gt;原理&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;余弦相似度&lt;/td&gt;
					&lt;td&gt;算向量夹角的余弦值&lt;/td&gt;
					&lt;td&gt;值域 [-1,1]，越大越相似&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;L2 距离&lt;/td&gt;
					&lt;td&gt;算欧氏距离&lt;/td&gt;
					&lt;td&gt;值域 [0,∞)，越小越相似&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;大多数语义搜索场景用余弦相似度。配合向量归一化（让每个向量的长度变成 1），余弦相似度等价于向量内积，计算更快。&lt;/p&gt;
&lt;h3 id="为什么不用-mysql-like"&gt;为什么不用 MySQL LIKE
&lt;/h3&gt;&lt;p&gt;LIKE 做的是字面匹配。搜&amp;quot;退款&amp;rdquo;，数据库遍历每一条记录，看有没有&amp;quot;退&amp;quot;和&amp;quot;款&amp;quot;这两个字挨在一起。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;如何申请退款&amp;rdquo; → 命中 ✓&lt;/li&gt;
&lt;li&gt;&amp;ldquo;我想把钱退回来&amp;rdquo; → 不命中 ✗&lt;/li&gt;
&lt;li&gt;&amp;ldquo;退订服务&amp;rdquo; → 不命中 ✗&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但这三条说的是同一件事。LIKE 的本质缺陷：&lt;strong&gt;它不理解语义，只匹配字符&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;向量检索的思路完全不同：先把所有文本编码成向量，搜索时把查询也编码成向量，然后找最近的几个。它匹配的是&amp;quot;意思&amp;rdquo;，不是&amp;quot;字面&amp;quot;。&lt;/p&gt;
&lt;h2 id="第二章sentence-transformers--让文本变成向量"&gt;第二章：Sentence-Transformers — 让文本变成向量
&lt;/h2&gt;&lt;h3 id="安装和一行代码上手"&gt;安装和一行代码上手
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;pip install sentence-transformers faiss-cpu
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;加载模型、编码文本，三行搞定：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 加载中文 embedding 模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BAAI/bge-small-zh-v1.5&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;texts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span 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="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# (3, 512) — 3条文本，每条512维&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出 &lt;code&gt;(3, 512)&lt;/code&gt; 表示 3 条文本各编码成了 512 维的向量。&lt;/p&gt;
&lt;h3 id="中文模型怎么选"&gt;中文模型怎么选
&lt;/h3&gt;&lt;p&gt;这是新手最纠结的问题。我直接给你结论：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模型&lt;/th&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;大小&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;bge-small-zh-v1.5&lt;/td&gt;
					&lt;td&gt;512&lt;/td&gt;
					&lt;td&gt;~100MB&lt;/td&gt;
					&lt;td&gt;入门首选，速度快&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;m3e-base&lt;/td&gt;
					&lt;td&gt;768&lt;/td&gt;
					&lt;td&gt;~210MB&lt;/td&gt;
					&lt;td&gt;社区流行，中文适配好&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;bge-large-zh-v1.5&lt;/td&gt;
					&lt;td&gt;1024&lt;/td&gt;
					&lt;td&gt;~1.3GB&lt;/td&gt;
					&lt;td&gt;精度最高，生产推荐&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;BGE-m3&lt;/td&gt;
					&lt;td&gt;1024&lt;/td&gt;
					&lt;td&gt;~2.3GB&lt;/td&gt;
					&lt;td&gt;多语言+多功能，最强&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;我的建议&lt;/strong&gt;：学习阶段用 bge-small-zh-v1.5，小快够用。上生产了换 bge-large-zh-v1.5 或 BGE-m3。&lt;/p&gt;
&lt;h3 id="避坑维度不一致不能混用"&gt;避坑：维度不一致不能混用
&lt;/h3&gt;&lt;p&gt;这是 90% 的新手会踩的坑。&lt;/p&gt;
&lt;p&gt;bge-small 输出 512 维，m3e-base 输出 768 维。&lt;/p&gt;
&lt;p&gt;如果你用 bge-small 建了索引，后来换成 m3e-base 编码查询，FAISS 直接报错——维度对不上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;规则&lt;/strong&gt;：编码模型和建索引模型必须是同一个。换模型 = 重建索引，没有例外。&lt;/p&gt;
&lt;h2 id="第三章faiss--让向量搜起来飞快"&gt;第三章：FAISS — 让向量搜起来飞快
&lt;/h2&gt;&lt;h3 id="安装"&gt;安装
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;pip install faiss-cpu &lt;span class="c1"&gt;# CPU 版，够用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pip install faiss-gpu # GPU 版，百万级以上考虑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="3-分钟跑通第一个索引"&gt;3 分钟跑通第一个索引
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;faiss&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 假设你已经有 1000 条文本的向量（512维）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faiss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IndexFlatL2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;索引中有 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ntotal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 条向量&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 搜索：找最相似的 5 条&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rand&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="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;distances&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;最相似的5条索引:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&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="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;对应的L2距离:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;distances&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;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="四种索引类型决策树"&gt;四种索引类型决策树
&lt;/h3&gt;&lt;p&gt;这是这篇文章的核心价值。FAISS 有十几种索引，但 99% 的场景只需要搞懂这四种：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;索引类型&lt;/th&gt;
					&lt;th&gt;数据量级&lt;/th&gt;
					&lt;th&gt;速度&lt;/th&gt;
					&lt;th&gt;精度&lt;/th&gt;
					&lt;th&gt;典型场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;IndexFlatL2&lt;/td&gt;
					&lt;td&gt;&amp;lt;10万&lt;/td&gt;
					&lt;td&gt;慢&lt;/td&gt;
					&lt;td&gt;100%精确&lt;/td&gt;
					&lt;td&gt;原型开发、小数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;IndexIVFFlat&lt;/td&gt;
					&lt;td&gt;百万级&lt;/td&gt;
					&lt;td&gt;快&lt;/td&gt;
					&lt;td&gt;近似（可调）&lt;/td&gt;
					&lt;td&gt;中等规模生产&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;IndexHNSWFlat&lt;/td&gt;
					&lt;td&gt;千万级&lt;/td&gt;
					&lt;td&gt;最快&lt;/td&gt;
					&lt;td&gt;高召回率&lt;/td&gt;
					&lt;td&gt;低延迟在线搜索&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;IndexIVFPQ&lt;/td&gt;
					&lt;td&gt;十亿级&lt;/td&gt;
					&lt;td&gt;快&lt;/td&gt;
					&lt;td&gt;有损压缩&lt;/td&gt;
					&lt;td&gt;超大规模+省内存&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;怎么选&lt;/strong&gt;：别想太多，从 IndexFlatL2 开始。数据量到 10 万条以后再考虑换。&lt;/p&gt;
&lt;p&gt;我把四种索引的适用场景画个决策路径：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你的数据有多少条？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── &amp;lt; 10万 → IndexFlatL2（暴力搜索，100%精确，不用调参）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── 10万~100万 → IndexIVFFlat（聚类分区，平衡速度和精度）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── 100万~1000万 → IndexHNSWFlat（图索引，速度最快）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── &amp;gt; 1000万 → IndexIVFPQ（乘积量化压缩，省内存）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="索引的保存和加载"&gt;索引的保存和加载
&lt;/h3&gt;&lt;p&gt;90% 的新手忘的一步。程序退出，内存里的索引就没了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 保存索引到磁盘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;faiss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;my_index.faiss&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faiss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my_index.faiss&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：FAISS 只保存向量和索引结构，不保存原始文本。你需要自己维护一个&amp;quot;索引ID → 原始文本&amp;quot;的映射（比如存一个 JSON 或列表）。&lt;/p&gt;
&lt;h2 id="第四章实战--搭一个能用的中文语义搜索引擎"&gt;第四章：实战 — 搭一个能用的中文语义搜索引擎
&lt;/h2&gt;&lt;h3 id="完整可运行代码"&gt;完整可运行代码
&lt;/h3&gt;&lt;p&gt;下面这段代码复制就能跑。我准备了 10 条模拟 FAQ 数据，展示语义搜索的效果。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;faiss&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;faqs&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="cl"&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="cl"&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="cl"&gt; &lt;span class="s2"&gt;&amp;#34;退款多久能到账？一般3-5个工作日。&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="cl"&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="cl"&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="cl"&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="cl"&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="cl"&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="cl"&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="cl"&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="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BAAI/bge-small-zh-v1.5&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;faqs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faiss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IndexFlatIP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== 4. 搜索 ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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;搜索: &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;&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="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;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="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indices&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="cl"&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scores&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="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.4f&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;faqs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&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="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;indices&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== 5. 效果展示 ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;search&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="cl"&gt;&lt;span class="n"&gt;search&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="cl"&gt;&lt;span class="n"&gt;search&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="cl"&gt;&lt;span class="n"&gt;search&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="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ========== 6. 性能测试 ==========&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;测试查询&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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;1000次搜索耗时: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s (含编码时间)&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="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;平均每次(含编码): 约 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="运行效果"&gt;运行效果
&lt;/h3&gt;&lt;p&gt;搜&amp;quot;退款&amp;quot;命中&amp;quot;如何申请退款&amp;quot;和&amp;quot;我想把钱退回来&amp;quot;——关键词完全不同，但语义命中。&lt;/p&gt;
&lt;p&gt;搜&amp;quot;取消购买&amp;quot;命中&amp;quot;怎么取消已经付款的购买&amp;quot;和&amp;quot;取消订单的步骤&amp;quot;——&amp;ldquo;取消&amp;quot;和&amp;quot;购买&amp;quot;拆开了照样匹配。&lt;/p&gt;
&lt;p&gt;这就是语义搜索的威力：&lt;strong&gt;它理解意思，不依赖关键词重合&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="性能数据"&gt;性能数据
&lt;/h3&gt;&lt;p&gt;10 条数据的搜索时间几乎为 0（亚毫秒级）。扩展到 1000 条，纯索引搜索（不含编码）仍在 1ms 以内。&lt;/p&gt;
&lt;p&gt;对比 MySQL LIKE 查询 1000 条记录，需要全表扫描 + 逐行字符匹配，通常在 5-50ms。向量检索在语义理解上有质的飞跃，速度也不逊色。&lt;/p&gt;
&lt;h2 id="第五章数据量增长后怎么办"&gt;第五章：数据量增长后怎么办
&lt;/h2&gt;&lt;h3 id="索引迁移路径"&gt;索引迁移路径
&lt;/h3&gt;&lt;p&gt;数据量增长到一定程度，IndexFlatL2 的暴力搜索会变慢。这时候该换索引了：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IndexFlatL2 (暴力)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 数据量 &amp;gt; 10万，搜索开始变慢
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IndexIVFFlat (聚类分区)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 数据量 &amp;gt; 100万，需要更高吞吐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IndexHNSWFlat (图索引)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 数据量 &amp;gt; 1000万，内存吃紧
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IndexIVFPQ (乘积量化)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;切换时机&lt;/strong&gt;：当你感觉搜索延迟不可接受（比如超过 100ms）的时候，就该考虑换索引了。不要过早优化。&lt;/p&gt;
&lt;h3 id="faiss-vs-其他方案"&gt;FAISS vs 其他方案
&lt;/h3&gt;&lt;p&gt;FAISS 是一个搜索库，不是完整的数据库。它没有增删改查 API，没有持久化层，需要你自己管理。&lt;/p&gt;
&lt;p&gt;如果不想自己管这些，可以考虑封装好的向量数据库：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方案&lt;/th&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;适用规模&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;FAISS&lt;/td&gt;
					&lt;td&gt;嵌入式库&lt;/td&gt;
					&lt;td&gt;任意&lt;/td&gt;
					&lt;td&gt;轻量无依赖，需自己管持久化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ChromaDB&lt;/td&gt;
					&lt;td&gt;轻量数据库&lt;/td&gt;
					&lt;td&gt;&amp;lt;100万&lt;/td&gt;
					&lt;td&gt;开箱即用，内置持久化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Qdrant&lt;/td&gt;
					&lt;td&gt;数据库&lt;/td&gt;
					&lt;td&gt;千万级&lt;/td&gt;
					&lt;td&gt;Rust 写的，高性能，API 友好&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Milvus&lt;/td&gt;
					&lt;td&gt;分布式数据库&lt;/td&gt;
					&lt;td&gt;十亿级&lt;/td&gt;
					&lt;td&gt;生产级，支持分布式&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;我的建议&lt;/strong&gt;：原型阶段用 FAISS，够轻够快。产品化了再按需升级。别一上来就上 Milvus，运维成本会吃掉你。&lt;/p&gt;
&lt;h3 id="核心建议"&gt;核心建议
&lt;/h3&gt;&lt;p&gt;别过早优化。从 IndexFlatL2 开始，能跑就先跑着。&lt;/p&gt;
&lt;p&gt;等数据量真到了瓶颈再换索引，迁移成本远低于你从第一天就过度设计的成本。这句话适用于 99% 的项目。&lt;/p&gt;
&lt;h2 id="结论"&gt;结论
&lt;/h2&gt;&lt;p&gt;向量检索不是黑魔法。&lt;/p&gt;
&lt;p&gt;Sentence-Transformers 把文本编码成向量，FAISS 把向量搜得飞快。两个库，20 行代码，你就拥有了一个能理解语义的搜索引擎。&lt;/p&gt;
&lt;p&gt;搜&amp;quot;退款&amp;quot;能找到&amp;quot;退钱&amp;rdquo;，搜&amp;quot;取消购买&amp;quot;能命中&amp;quot;取消订单&amp;quot;。这就是语义搜索和关键词搜索的本质区别。&lt;/p&gt;
&lt;p&gt;记住三个要点：从 IndexFlatL2 开始、编码模型和索引维度必须一致、别忘了保存索引到磁盘。&lt;/p&gt;
&lt;p&gt;剩下的，动手跑一遍代码就懂了。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;关注 varkm，一起学习，一起成长&lt;/p&gt;</description></item><item><title>用 DeepSeek V4 做 Vibe Coding：免费平替 Claude Code？</title><link>https://blog.kalend.top/2026/06/14/2026-06-14-deepseek-v4-vibe-coding.html/</link><pubDate>Sun, 14 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.kalend.top/2026/06/14/2026-06-14-deepseek-v4-vibe-coding.html/</guid><description>&lt;p&gt;Claude Code 的输出价格是每百万 tokens 25 美元。&lt;/p&gt;
&lt;p&gt;DeepSeek V4-Pro 是每百万 6 块人民币。&lt;/p&gt;
&lt;p&gt;差距大约 29 倍。&lt;/p&gt;
&lt;p&gt;这不是标题党，是实打实的账单差异。&lt;/p&gt;
&lt;p&gt;Claude Code 确实强，终端里跟一个资深工程师结对编程，体验拉满。但每个月烧几百美刀，还得搞海外信用卡。封号风险像悬在头上的刀。&lt;/p&gt;
&lt;p&gt;DeepSeek V4 发布后，编程能力已经能打了。我花了几天时间实测了三种方案。&lt;/p&gt;
&lt;p&gt;让 DeepSeek V4 驱动 Claude Code、Cline、Aider，逐一对比。&lt;/p&gt;
&lt;p&gt;什么是 Vibe Coding？就是用自然语言描述需求，让 AI 帮你写代码。不用一行行手敲，跟 AI 对话就能完成开发。&lt;/p&gt;
&lt;p&gt;Andrej Karpathy 去年提出这个概念后，整个行业都在往这个方向跑。&lt;/p&gt;
&lt;p&gt;Claude Code 是目前最强的 Vibe Coding 工具，但也是最贵的。&lt;/p&gt;
&lt;p&gt;结论先放这：日常开发成本降 98%，能力差距可控。&lt;/p&gt;
&lt;h2 id="为什么选-deepseek-v4"&gt;为什么选 DeepSeek V4
&lt;/h2&gt;&lt;p&gt;先看一组数据。&lt;/p&gt;
&lt;p&gt;V4 的推理性能在数学、代码竞赛等基准测试中，超越了所有公开评测的开源模型。（来源：量子位）&lt;/p&gt;
&lt;p&gt;编程能力比肩世界顶级闭源模型，在部分评测中接近 ChatGPT-5.5 水平。（来源：智源社区）&lt;/p&gt;
&lt;p&gt;V4 官方报告公开了 484 天的研发历程，从 V3 到 V4 的跨越不只是参数堆叠。推理架构做了深度优化，代码生成的准确率和连贯性都有质的提升。&lt;/p&gt;
&lt;p&gt;具体到编程场景，V4 在以下方面有明显进步。&lt;/p&gt;
&lt;p&gt;理解复杂需求的能力更强，一次对话能处理更复杂的指令。生成的代码结构更清晰，变量命名更规范。&lt;/p&gt;
&lt;p&gt;跨文件修改时的上下文关联能力也有提升。&lt;/p&gt;
&lt;p&gt;不过要注意，V4 的能力提升主要体现在单文件和中等复杂度任务上。超大规模代码库的全局理解，跟 Claude Opus 还有差距。&lt;/p&gt;
&lt;p&gt;价格更是碾压级。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;对比项&lt;/th&gt;
					&lt;th&gt;DeepSeek V4-Pro&lt;/th&gt;
					&lt;th&gt;Claude Opus 4.7&lt;/th&gt;
					&lt;th&gt;Claude Sonnet&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;输出价格&lt;/td&gt;
					&lt;td&gt;6 元/百万 tokens&lt;/td&gt;
					&lt;td&gt;$25/百万 tokens&lt;/td&gt;
					&lt;td&gt;$15/百万 tokens&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;输入价格&lt;/td&gt;
					&lt;td&gt;3 元/百万 tokens&lt;/td&gt;
					&lt;td&gt;$5/百万 tokens&lt;/td&gt;
					&lt;td&gt;$3/百万 tokens&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;上下文窗口&lt;/td&gt;
					&lt;td&gt;1M&lt;/td&gt;
					&lt;td&gt;200k&lt;/td&gt;
					&lt;td&gt;200k&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;新用户福利&lt;/td&gt;
					&lt;td&gt;500 万 tokens 免费&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;数据来源：DeepSeek 官网定价页（api-docs.deepseek.com）、火山引擎开发者文档、SMZDM 实测。&lt;/p&gt;
&lt;p&gt;V4-Pro 永久降价 75% 后，输出价格只有原来的四分之一。缓存命中时的输入价格低到 0.025 元每百万 tokens，几乎可以忽略。&lt;/p&gt;
&lt;p&gt;什么是缓存命中？你发送的 prompt 如果跟之前的请求有重叠部分，重叠部分走缓存。&lt;/p&gt;
&lt;p&gt;价格只有正常的几十分之一。实际开发中大量请求都有重叠，所以真实成本比标价更低。&lt;/p&gt;
&lt;p&gt;上下文窗口也是碾压级。V4 支持 1M tokens 上下文，是 Claude 的 5 倍。整个项目代码库一次性喂进去都没问题。&lt;/p&gt;
&lt;p&gt;新用户注册送 500 万 tokens，按中等强度开发估算，免费用一周没问题。&lt;/p&gt;
&lt;p&gt;补充一点：DeepSeek 的 API 兼容 OpenAI 格式。这意味着几乎所有支持自定义 API 地址的编程工具都能接入，不只是本文提到的三种。&lt;/p&gt;
&lt;h2 id="方案一claude-code-router最推荐"&gt;方案一：Claude Code Router（最推荐）
&lt;/h2&gt;&lt;p&gt;这是目前最火的方案，GitHub 上 3.5 万 Star。&lt;/p&gt;
&lt;p&gt;原理很简单：在本地跑一个代理服务，拦截 Claude Code 发出的请求，转发给 DeepSeek API。&lt;/p&gt;
&lt;p&gt;对 Claude Code 来说完全透明，它以为自己在跟官方服务器通信。&lt;/p&gt;
&lt;p&gt;整个流程是这样的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你输入指令 → Claude Code 发请求
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → Claude Code Router 拦截
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 转换格式，转发给 DeepSeek V4 API
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → DeepSeek 返回结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → Router 转换回 Claude Code 格式
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → Claude Code 显示结果
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装四步搞定。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一步：装 Claude Code&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;npm install -g @anthropic-ai/claude-code
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第二步：装 Claude Code Router&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;npm install -g tiktoken
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install -g @musistudio/claude-code-router
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;tiktoken 是分词依赖，不装可能报错。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三步：写配置文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;配置文件在 &lt;code&gt;~/.claude-code-router/config.json&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这是纯 DeepSeek 方案（极致性价比），直接复制改 Key 就能用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Providers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deepseek&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;api_base_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://api.deepseek.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;api_key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sk-你的APIKEY&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;models&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;deepseek-v4-pro&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;transformer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;use&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;deepseek&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;deepseek-v4-pro&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;use&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tooluse&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="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Router&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deepseek,deepseek-v4-pro&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;background&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deepseek,deepseek-v4-pro&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;think&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deepseek,deepseek-v4-pro&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="cl"&gt; &lt;span class="nt"&gt;&amp;#34;longContext&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deepseek,deepseek-v4-pro&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&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="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型名用 &lt;code&gt;deepseek-v4-pro&lt;/code&gt;，对应 V4 满血版，输出 6 元/百万 tokens。追求极致性价比可以改成 &lt;code&gt;deepseek-v4-flash&lt;/code&gt;，输出只要 2 元/百万 tokens，日常 CRUD 够用。旧的 &lt;code&gt;deepseek-chat&lt;/code&gt;/&lt;code&gt;deepseek-reasoner&lt;/code&gt; 对应 Flash 档，将于 2026 年 7 月底弃用，建议直接用新名称。&lt;/p&gt;
&lt;p&gt;Router 配置说明：&lt;code&gt;default&lt;/code&gt; 处理日常对话，&lt;code&gt;think&lt;/code&gt; 走思考模式做复杂推理。V4-Pro 同时支持两种模式，通过 Router 自动切换。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;background&lt;/code&gt; 处理后台任务，&lt;code&gt;longContext&lt;/code&gt; 处理长文本场景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第四步：启动&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;ccr code
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;看到欢迎界面就成功了。首次运行建议输入 &lt;code&gt;/init&lt;/code&gt; 初始化项目配置。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;三种进阶配置怎么选？&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方案&lt;/th&gt;
					&lt;th&gt;模型组合&lt;/th&gt;
					&lt;th&gt;上下文&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;纯 DeepSeek&lt;/td&gt;
					&lt;td&gt;V4-Pro&lt;/td&gt;
					&lt;td&gt;1M&lt;/td&gt;
					&lt;td&gt;日常开发，成本最低&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DeepSeek + Qwen&lt;/td&gt;
					&lt;td&gt;V4 + Qwen3-32B&lt;/td&gt;
					&lt;td&gt;1M + 128k&lt;/td&gt;
					&lt;td&gt;特定语言能力互补&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DeepSeek + Gemini&lt;/td&gt;
					&lt;td&gt;V4 + Gemini 2.5 Pro&lt;/td&gt;
					&lt;td&gt;1M + 百万级&lt;/td&gt;
					&lt;td&gt;多模态/超长文档分析&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;混合方案的价值不再是补上下文——V4 自身 1M 已经够用。价值在于能力互补：不同模型在不同任务上各有所长。&lt;/p&gt;
&lt;p&gt;日常走 DeepSeek V4-Pro 的 1M 上下文，遇到特定场景才切到其他模型。比如多模态分析切 Gemini，特定框架生态切 Qwen。&lt;/p&gt;
&lt;p&gt;Gemini 接入需要通过开源项目 openai-gemini 配合 Cloudflare Workers 实现，具体步骤参考 GitHub 上的 yzfly/claude-code-deepseek-quickstart 项目，有详细教程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实际体验&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;响应速度：V4-Pro 非思考模式基本秒回，思考模式需要等几秒。&lt;/p&gt;
&lt;p&gt;代码质量：日常 CRUD、bug 修复、单元测试，完全够用。&lt;/p&gt;
&lt;p&gt;复杂架构重构偶尔会跑偏，需要多次纠正。但比起 Claude Code 动不动几美刀一轮对话，这点耐心值得。&lt;/p&gt;
&lt;p&gt;踩坑提醒：&lt;code&gt;transformer&lt;/code&gt; 里的 &lt;code&gt;tooluse&lt;/code&gt; 很关键，不加的话文件读写会失效。后面的踩坑实录有详细排查。&lt;/p&gt;
&lt;p&gt;在会话中可以用 &lt;code&gt;/model&lt;/code&gt; 命令随时切换模型：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/model deepseek,deepseek-v4-pro
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;处理复杂问题时确保走思考模式，日常聊天用默认即可，灵活搭配。&lt;/p&gt;
&lt;h2 id="方案二clinevscode-集成派"&gt;方案二：Cline（VSCode 集成派）
&lt;/h2&gt;&lt;p&gt;Claude Code Router 是终端方案，有些人更喜欢在编辑器里操作。Cline 就是这个定位。&lt;/p&gt;
&lt;p&gt;Cline 是一个开源的 VSCode 插件，支持任意 AI 提供商。GitHub 项目：cline/cline。&lt;/p&gt;
&lt;p&gt;它的核心特性是 Plan/Act 双模式：先规划再执行，不会一上来就乱改代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;配置 DeepSeek V4 步骤：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;VSCode 扩展商店搜索 Cline 安装&lt;/li&gt;
&lt;li&gt;打开 Cline 面板，点击设置图标&lt;/li&gt;
&lt;li&gt;API Provider 选择 DeepSeek&lt;/li&gt;
&lt;li&gt;填入你的 DeepSeek API Key&lt;/li&gt;
&lt;li&gt;Model 选 &lt;code&gt;deepseek-v4-pro&lt;/code&gt;（满血版）或 &lt;code&gt;deepseek-v4-flash&lt;/code&gt;（省钱版）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不需要写配置文件，全程图形界面操作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plan/Act 模式怎么用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Plan 模式下，你描述需求，Cline 先分析代码库，给出一个完整的执行计划。&lt;/p&gt;
&lt;p&gt;你确认计划没问题后，切到 Act 模式，它才开始改代码。&lt;/p&gt;
&lt;p&gt;这个流程比 Claude Code 的&amp;quot;边想边干&amp;quot;更稳。尤其适合改动范围较大的重构任务，先看清楚再动手。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对比 Claude Code Router&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;Claude Code Router&lt;/th&gt;
					&lt;th&gt;Cline&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;运行环境&lt;/td&gt;
					&lt;td&gt;终端&lt;/td&gt;
					&lt;td&gt;VSCode&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;配置方式&lt;/td&gt;
					&lt;td&gt;JSON 文件&lt;/td&gt;
					&lt;td&gt;图形界面&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;工作模式&lt;/td&gt;
					&lt;td&gt;对话式&lt;/td&gt;
					&lt;td&gt;Plan/Act 双模式&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;适合人群&lt;/td&gt;
					&lt;td&gt;终端党&lt;/td&gt;
					&lt;td&gt;编辑器党&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多模型切换&lt;/td&gt;
					&lt;td&gt;/model 命令&lt;/td&gt;
					&lt;td&gt;下拉菜单&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;我的建议：习惯终端就选 Router，习惯 VSCode 就选 Cline。&lt;/p&gt;
&lt;h2 id="方案三aider轻量级终端助手"&gt;方案三：Aider（轻量级终端助手）
&lt;/h2&gt;&lt;p&gt;Aider 的定位更轻：一个 git 友好的终端编程助手。&lt;/p&gt;
&lt;p&gt;它不像 Claude Code 那么重，启动快，适合小项目快速修改。每次改动自动 git commit，回滚很方便。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;配置 DeepSeek V4：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&gt;&lt;span class="c1"&gt;# 设置环境变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;你的APIKEY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aider --model deepseek/deepseek-v4-pro
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Aider 底层用 litellm 库，原生支持 DeepSeek。&lt;code&gt;deepseek/&lt;/code&gt; 前缀告诉 litellm 走 DeepSeek 路由。&lt;/p&gt;
&lt;p&gt;也可以写到配置文件 &lt;code&gt;~/.aider.conf.yml&lt;/code&gt; 里：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&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="cl"&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 class="l"&gt;deepseek/deepseek-v4-pro&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;auto-commits&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;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适合什么场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;小 bug 修复、写个脚本、快速原型验证。偶尔需要 AI 帮忙写几行代码，Aider 比 Claude Code 轻量得多。&lt;/p&gt;
&lt;p&gt;不太适合大型项目重构。Aider 的上下文管理不如 Claude Code 精细，复杂任务容易丢上下文。&lt;/p&gt;
&lt;p&gt;另外提一句，2026 年 AI 编程工具的格局已经很清晰了。&lt;/p&gt;
&lt;p&gt;Cursor 月费 10 到 39 美元，IDE 集成体验最好。Claude Code 最强但最贵。Cline 开源免费，Aider 轻量终端派。&lt;/p&gt;
&lt;p&gt;加上 DeepSeek V4 的成本优势，组合空间非常大。&lt;/p&gt;
&lt;h2 id="成本算账"&gt;成本算账
&lt;/h2&gt;&lt;p&gt;这才是最关心的部分。按中等强度开发估算。&lt;/p&gt;
&lt;p&gt;日均消耗假设：输入 50 万 tokens，输出 10 万 tokens。这是一个全职开发者中等强度使用的合理估算。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;估算项&lt;/th&gt;
					&lt;th&gt;Claude Code 官方&lt;/th&gt;
					&lt;th&gt;DeepSeek V4 方案&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;日均输入&lt;/td&gt;
					&lt;td&gt;~50 万 tokens&lt;/td&gt;
					&lt;td&gt;~50 万 tokens&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;日均输出&lt;/td&gt;
					&lt;td&gt;~10 万 tokens&lt;/td&gt;
					&lt;td&gt;~10 万 tokens&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;日均费用&lt;/td&gt;
					&lt;td&gt;~$5&lt;/td&gt;
					&lt;td&gt;~0.7 元&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;月度成本&lt;/td&gt;
					&lt;td&gt;~$150&lt;/td&gt;
					&lt;td&gt;~21 元&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;年度成本&lt;/td&gt;
					&lt;td&gt;~$1,800&lt;/td&gt;
					&lt;td&gt;~252 元&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;数据来源：DeepSeek 官网定价页、火山引擎开发者文档。&lt;/p&gt;
&lt;p&gt;Claude Code 日均费用按 Opus 4.7 输出 $25/M、输入 $5/M 计算。DeepSeek 按 V4-Pro 输出 6 元/M 计算，输入走缓存。&lt;/p&gt;
&lt;p&gt;一年省下来的钱，够买一台 MacBook Pro。&lt;/p&gt;
&lt;p&gt;当然这是理想情况。实际使用中复杂任务需要多次对话，token 消耗会更高。&lt;/p&gt;
&lt;p&gt;但即便翻三倍，DeepSeek 方案的年成本也就 800 块左右。跟 Claude Code 的 1800 美刀完全不在一个量级。&lt;/p&gt;
&lt;p&gt;新用户还有 500 万 tokens 免费额度。按上面的日均消耗，能免费用 8 天左右。&lt;/p&gt;
&lt;h2 id="踩坑实录"&gt;踩坑实录
&lt;/h2&gt;&lt;p&gt;用了几天，坑确实有几个。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;坑一：文件读写突然失效，AI 只能说不能做&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Claude Code 的核心能力是读写文件。但接入 DeepSeek 后，有时候 AI 只输出文字，不执行任何文件操作。&lt;/p&gt;
&lt;p&gt;原因：&lt;code&gt;transformer&lt;/code&gt; 里的 &lt;code&gt;tooluse&lt;/code&gt; 配置遗漏或格式错误。DeepSeek 的函数调用格式跟 Claude 原生不同，需要 tooluse 做转换。没有这层转换，工具调用指令发不出去。&lt;/p&gt;
&lt;p&gt;解法：确认 config.json 里 &lt;code&gt;deepseek-v4-pro&lt;/code&gt; 下面有 &lt;code&gt;&amp;quot;use&amp;quot;: [&amp;quot;tooluse&amp;quot;]&lt;/code&gt;。前面方案一的配置示例已经包含，直接复制不要删。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;坑二：复杂多文件重构能力有差距&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;让 DeepSeek V4 同时改 10 个文件的接口，它偶尔会漏掉联动修改。Claude Code 在这种场景下更靠谱。&lt;/p&gt;
&lt;p&gt;解法：拆小任务。一次让它改 2-3 个文件，确认没问题再继续。别一口气丢整个模块给它。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;坑三：中文注释偶尔编码异常&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;生成的代码里偶尔会有中文注释乱码。频率不高，大概十次出一次。&lt;/p&gt;
&lt;p&gt;解法：在项目根目录的 CLAUDE.md 里加一行&amp;quot;所有注释用英文&amp;quot;。Claude Code Router 会读取这个文件作为系统提示。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;坑四：网络稳定性&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;DeepSeek API 在高峰期偶尔会慢，5-10 秒延迟。思考模式时间更长，复杂问题可能等 30 秒以上。&lt;/p&gt;
&lt;p&gt;Claude Code Router 配置里有个 &lt;code&gt;API_TIMEOUT_MS&lt;/code&gt; 参数，默认 600 秒。一般不用改。&lt;/p&gt;
&lt;p&gt;遇到超时报错的话，适当调大这个值就行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;坑五：DeepSeek 账号注册&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;DeepSeek 需要手机号注册，目前支持中国大陆手机号。注册后在控制台创建 API Key，复制到配置文件里就行。&lt;/p&gt;
&lt;p&gt;整个过程不需要海外信用卡，不需要特殊网络环境。这是相比 Claude Code 最大的便利之一。&lt;/p&gt;
&lt;h2 id="结论与建议"&gt;结论与建议
&lt;/h2&gt;&lt;p&gt;什么场景可以放心用 DeepSeek V4 平替？&lt;/p&gt;
&lt;p&gt;日常 CRUD 开发、bug 修复、写单元测试、代码审查、文档生成。这些占开发工作量的 80% 以上，DeepSeek V4 完全胜任。&lt;/p&gt;
&lt;p&gt;什么场景还是建议用 Claude？&lt;/p&gt;
&lt;p&gt;超大型项目重构、跨模块接口设计、需要顶级推理深度的复杂分析。这些场景 Claude 的工程化能力优势明显。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最佳组合策略：日常 DeepSeek + 复杂任务 Claude。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;90% 的日常开发用 DeepSeek V4，省钱又够用。遇到啃不动的硬骨头，临时切换到 Claude Code 处理。&lt;/p&gt;
&lt;p&gt;这样月成本能控制在几十块，而不是几百美刀。&lt;/p&gt;
&lt;p&gt;具体行动建议：&lt;/p&gt;
&lt;p&gt;如果你还没装过 Claude Code，先试 Router + DeepSeek 方案。四步装完，免费 500 万 tokens 够你跑一周。&lt;/p&gt;
&lt;p&gt;体验满意再决定要不要充 Claude。&lt;/p&gt;
&lt;p&gt;如果你已经在用 Claude Code，加一个 Router 做 fallback。&lt;/p&gt;
&lt;p&gt;复杂任务用 Claude，简单任务切 DeepSeek，&lt;code&gt;/model&lt;/code&gt; 命令随时切换。&lt;/p&gt;
&lt;p&gt;作者：varkm&lt;/p&gt;
&lt;p&gt;关注 varkm，一起学习，一起成长&lt;/p&gt;</description></item></channel></rss>