极简 RAG 实现及 AI Agent 应用:1 分钟带你跑通第一个向量检索

📅 2026/7/2 2:17:46
极简 RAG 实现及 AI Agent 应用:1 分钟带你跑通第一个向量检索
我们一听到RAG检索增强生成脑海里立刻浮现出的是AI、ChromaDB、Milvus、向量数据库、复杂的 Python 依赖…… 还没开始写代码就已经被繁琐的部署环境劝退了。其实RAG 的底层逻辑极其简单无非就是三步向量化Embedding把文本变成一串浮点数数组。向量存储把这些浮点数存起来。计算相似度计算两个数组之间的“夹角”余弦距离找出最接近的。在本文中我们不用任何专业的向量数据库只用TypeScript Node.js 22 自带的 SQLite手把手带大家在 1 分钟内跑通一个真正的 RAG 工具检索系统。通过这个实例我们不仅能亲手写出 RAG还能看到“跨语言语义检索”用中文匹配英文代码工具的奇妙效果。️ 第一步环境准备仅需 10 秒新建一个空文件夹初始化项目并安装唯一的依赖项dotenv用于读取智谱的 API Keymkdir rag-demo cd rag-demonpm init -ynpm install dotenvnpm install -D tsx typescript types/node在根目录下创建一个.env文件填入你的智谱 API Key你可以去 智谱大模型开放平台[1] 免费申请一个ZHIPU_API_KEY你的智谱API_KEY使智谱的 embedding 模型是因为它对跨语言的语义检索有非常好的支持在这个例子中在数据库中保存的是英语read file的向量但是在搜索时会使用中文相似的语义进行搜索非常方便 第二步手写极简 RAG只要一个文件创建index.ts把下面的代码直接复制进去或者让 AI 按这个文件生成一个可以运行的项目Claude Code 或 Codex 都行。为了做到“极简启动”我们直接使用 Node.js 22 的内置 SQLite在内存中:memory:建表、写入向量并进行相似度计算。当然也可以使用一个本地db文件可以更加清楚地看到保存的数据。import { DatabaseSync } fromnode:sqlite;import dotenv fromdotenv;dotenv.config();constAPI_KEY process.env.ZHIPU_API_KEY;if (!API_KEY) {console.error(❌ 请先在 .env 文件中配置 ZHIPU_API_KEY); process.exit(1);}// // 1. 定义我们要检索的工具数据 (Tools)// constTOOLS {read_file: Read a file from disk and return its contents. View source code, config files, logs.,bash: Run shell commands on the server. Install packages, git operations, builds.,web_search: Quick single web lookup for a fact, current event, latest/current information.,manage_calendar: Calendar event management: list, create, update, delete events.};// // 2. 向量数学工具归一化 点积计算// // 归一化把向量模长缩放到 1保持方向不变functionnormalize(v: Float32Array): Float32Array {let sum 0.0;for (let i 0; i v.length; i) sum v[i] * v[i];const norm Math.sqrt(sum);if (norm 0) { for (let i 0; i v.length; i) v[i] / norm; }return v;}// 两个已归一化向量的点积完全等同于它们的余弦相似度functiondotProduct(a: Float32Array, b: Float32Array): number {let score 0.0;for (let i 0; i a.length; i) score a[i] * b[i];return score;}// // 3. 智谱 Embedding 接口对接// asyncfunctiongetEmbeddings(texts: string[]): PromiseFloat32Array[] {const res awaitfetch(https://open.bigmodel.cn/api/paas/v4/embeddings, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${API_KEY}, }, body: JSON.stringify({ model: embedding-3, // 智谱最新第三代向量模型 input: texts, dimensions: 1024, // 输出 1024 维度的向量 }), });const data await res.json();return data.data.map((item: any) normalize(newFloat32Array(item.embedding)));}// // 4. 主程序运行// asyncfunctionmain() {console.log( 正在初始化内存 SQLite 数据库...);const db newDatabaseSync(:memory:); // 内存数据库进程退出自动销毁 db.exec( CREATE TABLE tool_index ( name TEXT PRIMARY KEY, description TEXT, embedding BLOB ) );// A. 索引阶段生成向量并写入 SQLiteconsole.log( 正在调用 API 为工具描述生成向量...);const names Object.keys(TOOLS);const descriptions Object.values(TOOLS);const vectors awaitgetEmbeddings(descriptions);const insertStmt db.prepare(INSERT INTO tool_index (name, description, embedding) VALUES (?, ?, ?));for (let i 0; i names.length; i) { // Float32Array 转换为 Node 的二进制 Buffer 存入 BLOB const buffer Buffer.from(vectors[i].buffer); insertStmt.run(names[i], descriptions[i], buffer); }console.log(✅ 成功将 ${names.length} 个工具向量化存入 SQLite BLOB 字段。\n);// B. 检索阶段模拟用户提问const userQuery 帮我提取一下那个配置文件的内容;console.log( 用户提问: ${userQuery});console.log(⏳ 正在检索最匹配的工具...);// 1. 将用户的提问向量化const queryVector (awaitgetEmbeddings([userQuery]))[0];// 2. 从 SQLite 读出所有向量在内存中进行相似度比对constrows: any[] db.prepare(SELECT name, description, embedding FROM tool_index).all();const results rows.map(row { // 从二进制 BLOB 中恢复出 Float32Array const buffer row.embedding; const vector newFloat32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4); // 计算点积得分 const score dotProduct(queryVector, vector); return { name: row.name, score }; });// 3. 排序并展示前 3 个结果 results.sort((a, b) b.score - a.score);console.log(\n 检索推荐结果); results.slice(0, 3).forEach((res, index) { console.log( [${index 1}] 工具名: ${res.name.padEnd(18)} 相似度得分: ${res.score.toFixed(4)}); });}main().catch(console.error);‍♂️ 第三步一键运行仅需 10 秒在终端直接运行这个 TS 文件npx tsx index.ts运行后你将看到如下输出 正在初始化内存 SQLite 数据库... 正在调用 API 为工具描述生成向量...✅ 成功将 4 个工具向量化存入 SQLite BLOB 字段。 用户提问: 帮我提取一下那个配置文件的内容⏳ 正在检索最匹配的工具... 检索推荐结果 [1] 工具名: read_file 相似度得分: 0.6899 [2] 工具名: bash 相似度得分: 0.4435 [3] 工具名: web_search 相似度得分: 0.3541核心知识点拆解真正理解 RAG在这几十行代码中其实隐藏了向量检索中最核心的数学思想和工程取舍。我们逐一拆解1. 向量数学三剑客点积、余弦、归一化为什么我们能把繁琐的相似度计算简化为简单的“乘加循环”这背后是一套精妙的数学简化• 点积Dot Product数学公式为 。它是把两个向量对应位置的数相乘再相加。•问题点积不仅受“方向”影响还深受向量“长度模长”的影响。如果一个词在文章里重复了 100 遍它的向量长度会变长导致算出来的点积异常大。这在搜索中会导致“长文章霸榜”的灾难。• 余弦相似度Cosine Similarity为了消除长度的干扰余弦相似度在点积的基础上除以了两个向量的模长乘积这样无论文章长短它只关注向量的夹角语义方向值域永远在 之间。• 向量归一化L2 Normalization归一化就是把向量的长度缩放到恒等于 即单位向量单位圆上的点但保持它的方向不变。• 魔法时刻一旦两个向量 和 在存入/查询前都被归一化了那么它们的模长 且 。• 此时余弦公式的分母 。• 余弦相似度公式直接简化为点积• 工程意义这帮我们在高频的检索循环中彻底消除了开平方根Math.sqrt和浮点数除法这两个最耗 CPU 周期的指令本地比对速度直接飙升数倍。2. 架构对比SQLite 内存算法 vs 向量数据库为什么我们的 Demo 不用 ChromaDB 这种专业的向量数据库反而能跑得更快向量数据库如 Chroma, Milvus, pgvector它们使用 HNSW分层可导航小世界 算法。这是一种近似最近邻ANN检索。它不会傻傻地把库里所有向量都比对一遍而是通过构建“树状/图状索引”实现类似二分查找的 检索速度。我们的 SQLite 内存暴力检索Flat Search这是最原始的 遍历——把所有向量全读出来挨个算点积。为什么小规模更快因为在数据量极小比如几十个工具描述时构建和查询 HNSW 索引树的系统开销远远大于直接暴力遍历。更重要的是我们省去了跨进程/跨网络的 IPC 通信延迟通常为 2~10ms内存循环计算 50 个向量仅需 0.02 毫秒。在我们的实例中只有几条 Tools 数据那么全部读取出来后每条都对比一下归一后的相似度与读取数据库的速度相比时间基本可以多忽略不计(在归一化后只会计算乘法和加法速度非常快)作为一个 Demo (后面会讲到的在 AI Agent中的使用场景)可以更加快速地理解 RAG 的核心机制。3. 技术选型指南以后遇到项目怎么选在实际的 Agent 和 RAG 开发中面对不同的数据规模我们应该采取不同的技术选型是 否 是 否 确定数据规模 - 向量条数 小于 500 条? 极简方案: 本地 SQLite 存储 内存点积计算 零依赖, 响应 1ms 500 ~ 10,000 条? 轻量方案: SQLite sqlite-vec 向量扩展 或 PostgreSQL pgvector 企业方案: 独立向量数据库Chroma / Qdrant / Milvus启用 HNSW 索引选型决策表场景特点数据规模向量数推荐架构选型理由轻量级检索工具检索/个性化记忆/菜单匹配 500 条内存计算 SQLite 存储性能最高开发最快完全不增加系统架构的复杂度。中型知识库单机文档库/个人笔记 RAG500 ~ 10,000 条嵌入式扩展如 sqlite-vec 插件不需要搭建独立服务直接通过 SQL 插件实现单机 检索。企业级应用百万文档库/高并发 SaaS 搜索 10,000 条独立向量数据库Chroma / Milvus / Qdrant需要处理分布式横向扩展、高并发连接池以及超大规模 HNSW 索引的内存开销。 在 AI Agent 中的实战场景在 AI Agent 的架构设计中核心是 LLM Contex上下文的管理为了更加有地利用上下文空间需要对 Agent 需要涉及的 Tools 以及 Skills 进行精心的设计确保它们足够但是又不能太多。如果我们的 Agent 拥有 50 个工具比如查邮件、写文件、调 API、跑脚本…把所有工具的详细说明都塞进 System Prompt不仅每次对话消耗巨大 Token大模型还容易产生“幻觉”在复杂的工具列表中选错工具。最后在看一个项目时发现它使用了将 Tools 工具进行向量化处理的方法操作流程如下用户的 Prompt 进来比如“帮我查一下昨天关于苹果发布会的新闻”。在本地 SQLite 向量库里快速比对。发现得分最高的是web_search得分0.38和web_fetch。动态把这两个工具的 Schema 和使用指南塞进当前的 System Prompt 发给大模型。运行结束下次对话重新匹配。通过这套极简 RAGAgent 就可以轻松拥有上百个工具而不需要担心 Prompt 的长度限制。而工具的定义大体如下const TOOLS { read_file: Read a file from disk and return its contents. View source code, config files, logs., bash: Run shell commands on the server. Install packages, git operations, builds., web_search: Quick single web lookup for a fact, current event, latest/current information., manage_calendar: Calendar event management: list, create, update, delete events., .........};这里需要解决几个问题• 在入库时使用的是英文而用户的 prompt 可能是任何语言比如我们例子中是中文,是否能跨语言匹配• 这种 RAG 处理后的准确度如何从我们做的几个实验来看准确度是基本有保证的而且我们并不是只需要匹配最合适的那个可能需要有多个工具的话是可以形成一个工具列表的。结语RAG 从来不是什么高不可攀的技术。对于小规模、高频的本地检索如工具检索、个性化偏好匹配、小知识库内存计算 轻量存储才是最高效、最清爽的架构。动手跑通这几十行 TypeScript 代码就已经迈出了走向 RAG 实战开发的最关键一步。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】