用 Genkit Ollama 搭本地 RAG不花 API 费用的 Pokémon 问答应用【免费下载链接】genkitOpen-source framework for building agentic apps in JavaScript, Go, Dart, and Python, built and used in production by Google项目地址: https://gitcode.com/GitHub_Trending/ge/genkit1. 为什么把大模型搬到自己电脑上调用公网大模型 API 时你的每条 prompt 都要走一次公网还按 token 计费。如果数据敏感、想离线使用或者不想为测试环境持续付费这条路就不合适了。检索增强生成RAG让模型先查资料再回答的范式 全本地推理就是解法。下面用 Genkit 仓库里的 Ollama 示例演示一条完整的本地 RAG 链路数据不出本机、零 API 费用、断网也能跑。2. 先搞懂嵌入、检索、生成三步把 RAG 想象成图书馆查书嵌入Embedding相当于给馆藏每一页书贴上语义条码——一串数字向量意思越接近的书条码越相似检索Retrieval把你的问题也编成条码扫描全馆找出条码最接近的几页书生成Generation模型带着这几页参考资料作答而不是凭空回忆。这样回答既快又不跑题且只依赖查到的那几条资料。本文的示例数据是 5 只 Pokémon 的描述文本问题如哪只 Pokémon 会电击。3. 理清模型与服务的分工角色名字职责嵌入模型nomic-embed-text把文本变成 768 维向量语义条码生成模型phi3.5:latest根据检索到的上下文产出最终回答本地服务Ollama托管上述两个模型本地起 HTTP 服务编排框架Genkit把嵌入、检索、生成统一封装成可调用的 Flow 两个模型都只在 Ollama 里Genkit 负责指挥它们按顺序工作。4. 安装 Ollama 并拉取两个本地模型前置条件只有两个Node.js 18和Ollama。从 Ollama 官网安装后启动服务端ollama serve ollama pull nomic-embed-text ollama pull phi3.5:latest服务默认监听http://localhost:11434。Genkit 的 Ollama 插件在不配置serverAddress时使用的正是这个默认地址见 ollama 插件源码 中的DEFAULT_OLLAMA_SERVER_ADDRESS常量。为什么不用单独npm install插件示例位于 Genkit monorepo 内package.json 里genkit和genkitx-ollama都写的是workspace:*即直接链接仓库里的当前源码装一次 workspace 依赖即可。5. 走读核心链路索引、检索、生成全部逻辑在 src/index.ts 里先给插件做初始化声明const ai genkit({ plugins: [ ollama({ embedders: [{ name: nomic-embed-text, dimensions: 768 }], requestHeaders: async (params) { console.log(Using server address, params.serverAddress); await new Promise((resolve) setTimeout(resolve, 200)); return { Authorization: Bearer my-token }; }, }), ], });接收一个插件配置对象 → 注册名为ollama/nomic-embed-text的嵌入 action并可注入请求头这里是演示用的模拟鉴权→ 输出配置好的ai实例。先嵌入文档async function embedPokemon() { for (const pokemon of pokemonList) { pokemon.embedding ( await ai.embed({ embedder: ollama.embedder(nomic-embed-text), content: pokemon.description, }) )[0].embedding; } }接收 5 条 Pokémon 描述 → 逐条 POST 到 Ollama 的/api/embed接口取回向量见 embeddings.ts→ 把 768 维数组写回每条记录的embedding字段。这就是贴条码。再用余弦距离检索 Top-Nfunction findNearestPokemon(inputEmbedding: number[], topN 3) { if (pokemonList.some((pokemon) pokemon.embedding null)) throw new Error(Some Pokemon are not yet embedded); const distances pokemonList.map((pokemon) ({ pokemon, distance: cosineDistance(inputEmbedding, pokemon.embedding!), })); return distances .sort((a, b) a.distance - b.distance) .slice(0, topN) .map((entry) entry.pokemon); }接收问题向量 → 先校验所有记录都已嵌入否则抛错再对每条记录算余弦距离升序排序后取前topN条 → 输出最相关的 3 只 Pokémon。余弦距离公式为1 - 点积 / (向量A模长 × 向量B模长)两向量方向越一致距离越接近 0完全同向越大表示语义越远。topN截断的意义在于——只把最相关的 3 条塞进 prompt避免上下文过长导致答案漂移。⚠️ 这种内存线性扫描只适合教学文档多了之后应换成向量数据库做近似最近邻ANN检索。最后带着上下文生成async function generateResponse(question: string) { const inputEmbedding ( await ai.embed({ embedder: ollama.embedder(nomic-embed-text), content: question, }) )[0].embedding; const nearest findNearestPokemon(inputEmbedding); const context nearest .map((p) ${p.name}: ${p.description}) .join(\n); return await ai.generate({ model: ollama.model(phi3.5:latest), prompt: Context: ${context}\nQuestion: ${question}\nAnswer:, }); }接收用户问题 → 先把问题嵌入与文档同一语义空间检索出 3 条记录拼成名字: 描述的上下文块 → 调phi3.5:latest走 Ollama 的 chat 接口生成回答。6. 封装成 Flow 并开启流式输出三个拿来即用的要点Zod 定义输入输出ai.defineFlow里用inputSchema: z.string()/outputSchema: z.string()描述契约Dev UI 据此渲染表单运行时还自动校验参数类型运行时动态切模型model参数默认gemma3:latest可在调用时传任何本地已pull的模型名插件会动态解析sendChunk 流式输出把ai.generate的onChunk直接挂到 Flow 的sendChunk上增量片段实时推给调用方前端逐字显示。export const joker ai.defineFlow( { name: joker, inputSchema: z.object({ model: z.string().default(gemma3:latest), subject: z.string().default(AI), }), outputSchema: z.string() }, async ({ subject, model }, { sendChunk }) { const { text } await ai.generate({ prompt: tell me joke about ${subject}, model: ollama.model(model), onChunk: sendChunk, }); return text; } );示例还导出了PokedexFlow输入z.string()、输出z.string()内部按嵌入 → 生成回答的顺序串起上面三步是 Dev UI 里直接可调用的 RAG 入口。7. 速览参数映射与端点选择Genkit 配置项到 Ollamaoptions的映射默认值见 插件源码Genkit 配置Ollama options默认值temperaturetemperature0.80.0~1.0topKtop_k40topPtop_p0.90~1.0stopSequencesstop—maxOutputTokensnum_predict—端点由模型type决定chat默认走POST /api/chat支持多轮消息与工具调用generate走POST /api/generate把 prompt 与 system 消息拆到prompt/system字段。也就是说ai.generate({ config: { temperature: 0.2 } })这类写法可以直接控制采样参数。8. 解决四个最常见的坑报Make sure the Ollama server is running.服务没启动或端口不对 → 执行ollama serve确认http://localhost:11434可访问README 亦如此提示。模型找不到或调用报错模型未拉取或名字拼错 → 确认ollama pull已完成且ollama.model()里的名字与本地完全一致插件按ollama/name动态注册。报Some Pokemon are not yet embedded检索跑在了嵌入之前 → 先执行完embedPokemon()再调用检索函数。需要注入鉴权头Ollama 挂在代理后面需要 token → 给requestHeaders传静态对象或异步函数函数内可基于serverAddress动态取 token。9. 选一个下一步扩展方向换模型ollama pull新模型后在插件配置的models/embedders里声明即可业务代码不动。上向量库把线性扫描换成 pinecone、postgresql 或 dev-local-vectorstore 等 Genkit 插件。索引与检索分离嵌入是一次性离线任务运行时只向量化查询语句示例里每次调用都重新嵌入只是演示。用 Dev UI 调试genkit ui:start可视化查看每个 Flow 的输入、输出与耗时定位检索召回或生成质量问题。启动方式进入js/testapps/ollama执行pnpm run genkit:dev再跑genkit ui:start打开界面即可。把两个模型拉下来在 Dev UI 里对PokedexFlow 问一句Which Pokemon can use electric attacks?——看到本地生成的那一刻你就拥有了第一条完整的本地 RAG 链路。【免费下载链接】genkitOpen-source framework for building agentic apps in JavaScript, Go, Dart, and Python, built and used in production by Google项目地址: https://gitcode.com/GitHub_Trending/ge/genkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
Comp AI CRM 中的 NestJS Guards 实践:用声明式守卫统一认证与授权边界 Comp AI CRM 中的 NestJS Guards 实践:用声明式守卫统一认证与授权边界 【免费下载链接】crm Comp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM. 项目地址: https://gitcode.com/gh_mirrors/crm48/crm
导读
本篇文章以 Comp … · 2026/9/24 14:09:30
WSABuilds 安装教程:Windows 10/11 上部署带 Play 商店和 Root 的安卓子系统 WSABuilds 安装教程:Windows 10/11 上部署带 Play 商店和 Root 的安卓子系统 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk … · 2026/9/24 14:09:30
复金汇商学院:如何选择真正有效的老板培训课程? 在当前快速变化的商业环境中,企业领导者需要不断更新自己的知识和技能,以应对新的挑战。然而,市场上五花八门的培训课程让许多企业家感到困惑,不知道如何选择真正有效的老板培训课程。本文将从多个角度出发,结合具体数… · 2026/9/24 14:09:29
SemIf Phase 1 结果全解:开源 4B 模型在 RTX 3090 上复现语义决策算子(质量、速度与边界) 【免费下载链接】SemIf Semantic ifs from open models, on a 3090 at home. Independent; not affiliated with Jev or TypeSafe. 项目地址: https://gitcode.com/gh_mirrors/op/SemIf 点击查看 免费下载 本篇技术指南围绕 docs/RESULTS.md 展开,系统解… · 2026/9/24 15:17:27
RK3538与RK3572芯片选型对比:从边缘计算到AIoT的架构解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 15:17:27
SDR++ Android NDK 编译指南——三步配出跨架构软件无线电 SDR Android NDK 编译指南——三步配出跨架构软件无线电 【免费下载链接】SDRPlusPlus Cross-Platform SDR Software 项目地址: https://gitcode.com/GitHub_Trending/sd/SDRPlusPlus
列车驶过的瞬间,手机瀑布图上亮起了信号。完成 SDR Android NDK 编译后就… · 2026/9/24 15:17:19
ESP32-P4 + ST7703 RGB屏视频轮播器:MIPI-DSI驱动与24fps实现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 15:17:19
CKAD 实战:Multi-container Pods(10%)多容器与 Init 容器考点全解析 CKAD 实战:Multi-container Pods(10%)多容器与 Init 容器考点全解析 【免费下载链接】CKAD-exercises A set of exercises to prepare for Certified Kubernetes Application Developer exam by Cloud Native Computing Foundation 项目地址… · 2026/9/24 15:17:19
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44