Embedding 基础使用:用 Ollama 和 LangChain.js 生成文本向量

发布时间:2026/10/6 5:47:06

Embedding 基础使用:用 Ollama 和 LangChain.js 生成文本向量 前言Embedding 的基本使用流程并不复杂文本 ↓ Embedding 模型 向量本文会完成以下内容使用 Ollama 在本地运行 Embedding 模型通过 Ollama HTTP API 生成向量使用 LangChain.js 调用 Embedding 模型理解embedQuery()和embedDocuments()。本文只关注最基础的向量生成过程暂时不展示相似度计算和语义搜索的具体实现也不引入向量数据库和完整 RAG 项目。一、Embedding 的输入和输出Embedding 模型接收文本返回一个固定长度的数字数组。例如“如何重置密码” ↓ Embedding 模型 [0.12, -0.35, 0.81, ..., 0.27]在 TypeScript 中一条文本生成的向量可以表示为const vector: number[] [0.12, -0.35, 0.81, 0.27];多条文本则会得到多个向量const vectors: number[][] [ [0.12, -0.35, 0.81, 0.27], [0.09, -0.31, 0.77, 0.30], ];真实模型输出的向量通常包含数百或数千个数字。为了便于阅读示例中只展示前几个值。向量中的单个数字通常不适合被单独解释。真正有用的是不同向量之间的整体关系语义相近的文本其向量通常也更接近。二、准备 Ollama 和 Embedding 模型1. Ollama 是什么Ollama 是一个本地模型运行工具。它负责下载、管理和运行模型并向应用程序提供 HTTP API。这里需要区分两个概念Ollama 运行模型的服务 nomic-embed-text 实际把文本转换成向量的模型Ollama 本身不是 Embedding 模型。2. 下载模型安装并启动 Ollama 后下载本文使用的模型ollama pull nomic-embed-text查看已经下载的模型ollama list正常情况下可以在列表中看到nomic-embed-text。3. 确认 Ollama 服务地址Ollama 默认提供本地服务http://localhost:11434如果 Ollama 桌面程序没有自动启动服务可以执行ollama serve三、通过 Ollama HTTP API 生成向量在使用 LangChain.js 之前可以先直接调用 Ollama API观察 Embedding 模型的原始返回结果。执行curl http://localhost:11434/api/embed \ -H Content-Type: application/json \ -d { model: nomic-embed-text, input: 如何重置密码 }返回结果的结构类似{ model: nomic-embed-text, embeddings: [ [0.012, -0.035, 0.081, 0.027] ] }其中model表示使用的模型input是需要转换的文本embeddings是模型生成的向量列表。即使只传入一条文本embeddings仍然是二维数组因为接口也支持批量输入curl http://localhost:11434/api/embed \ -H Content-Type: application/json \ -d { model: nomic-embed-text, input: [ 如何重置密码, 忘记密码后怎样重新设置, 今天天气怎么样 ] }三条文本会按输入顺序得到三个向量。至此我们已经完成了最基础的调用文本 → Ollama API → nomic-embed-text → 向量四、使用 LangChain.js 调用 Embedding 模型直接调用 HTTP API 没有问题但在 LangChain.js 应用中通常会使用OllamaEmbeddings。它是 LangChain 对 Ollama Embedding API 的客户端封装。调用关系如下TypeScript 程序 ↓ OllamaEmbeddings ↓ HTTP Ollama 服务 ↓ nomic-embed-text ↓ 数值向量1. 安装依赖在 TypeScript 或 Node.js 项目中安装npm install langchain/ollama2. 创建 Embedding 客户端import { OllamaEmbeddings } from langchain/ollama; const embeddings new OllamaEmbeddings({ model: nomic-embed-text, baseUrl: http://localhost:11434, });两个主要参数分别是参数作用model指定 Ollama 中使用的 Embedding 模型baseUrl指定 Ollama 服务地址创建OllamaEmbeddings对象时主要是在保存客户端配置。真正调用向量生成方法时才会向 Ollama 发出请求。五、使用embedQuery()生成单个向量embedQuery()接收一条文本返回一个向量const vector await embeddings.embedQuery(如何重置密码); console.log(vector.length); console.log(vector.slice(0, 5));返回值类型可以理解为number[]完整示例import { OllamaEmbeddings } from langchain/ollama; const embeddings new OllamaEmbeddings({ model: nomic-embed-text, baseUrl: http://localhost:11434, }); const vector await embeddings.embedQuery(如何重置密码); console.log(向量维度, vector.length); console.log(前 5 个值, vector.slice(0, 5));embedQuery()通常用于查询阶段例如把用户输入的问题转换成查询向量。需要注意它只负责生成向量不会自动搜索文档也不会生成自然语言回答。六、使用embedDocuments()批量生成向量embedDocuments()接收多条文本返回多个向量const vectors await embeddings.embedDocuments([ 如何重置密码, 忘记密码后怎样重新设置, 今天天气怎么样, ]);返回值类型可以理解为number[][]可以检查返回数量和向量维度console.log(向量数量, vectors.length); console.log(每个向量的维度, vectors[0].length);输入文本与输出向量按顺序对应texts[0] → vectors[0] texts[1] → vectors[1] texts[2] → vectors[2]embedDocuments()通常用于索引阶段为多个文档片段批量生成向量。两个方法可以这样记忆embedQuery(text) → 一条文本 → 一个向量 embedDocuments(texts) → 多条文本 → 多个向量它们的区别主要体现在调用语义和输入数量上。部分模型还会针对“查询”和“文档”使用不同的编码方式因此在实际项目中应按照用途选择正确的方法。七、基础使用中的重要规则1. 文档和查询必须使用同一个模型正确方式文档 → nomic-embed-text → 文档向量 问题 → nomic-embed-text → 查询向量错误方式文档 → 模型 A → 文档向量 问题 → 模型 B → 查询向量不同模型生成的向量通常不在同一个语义空间中。即使两个模型输出的维度相同也不代表它们可以直接比较。因此更换 Embedding 模型后通常需要重新生成所有文档向量。2. 向量维度必须一致计算余弦相似度时两个向量必须具有相同维度。如果一个向量是 768 维另一个是 1024 维就不能直接进行对应位置的计算。3. 相似度高不等于事实正确Embedding 判断的是“语义是否接近”而不是“内容是否真实”。两段内容可能表达相似但同时包含错误信息。因此语义相似度不能代替事实校验。4. 不要直接照搬固定阈值不能简单认为相似度大于 0.8 就一定相关不同模型、文本长度、语言和业务数据的分数分布都可能不同。阈值应该使用真实样本进行评估后再确定。5. 长文档通常需要先分块虽然部分模型支持较长输入但不建议把包含多个主题的整篇文档直接生成一个向量。例如一篇文档同时包含用户注册密码重置权限管理订单支付。如果整篇文档只生成一个向量具体主题可能被稀释。实际检索系统通常先把文档切成多个语义相对完整的片段再分别生成向量。6. 索引时尽量批量生成向量为大量文档建立索引时应优先使用embedDocuments()批量处理而不是对每条文本单独调用一次embedQuery()。批量调用通常可以减少请求次数提高索引效率。具体批次大小需要根据模型服务的输入限制和机器资源进行调整。八、常见问题1. 为什么提示连接不到 Ollama先确认 Ollama 服务正在运行并检查地址是否正确http://localhost:11434可以使用以下命令启动服务ollama serve如果应用运行在 Docker 容器或另一台机器中localhost指向的是应用自身所在的环境需要改成应用能够访问的 Ollama 地址。2. 为什么提示模型不存在通常是因为模型尚未下载。执行ollama pull nomic-embed-text然后通过ollama list确认模型名称与代码中的model配置一致。3.OllamaEmbeddings会保存向量吗不会。它只负责请求模型并返回向量。向量需要由应用程序自行保存或者交给向量数据库管理。4.OllamaEmbeddings能生成自然语言回答吗不能。它调用的是 Embedding 模型输出是数值向量。生成自然语言回答需要聊天模型或其他大语言模型客户端。5. 为什么相似文本的分数没有想象中高可能原因包括模型对当前语言支持有限文本过短缺少足够上下文两段文本属于特定专业领域使用了不适合当前任务的模型固定阈值并不适合当前模型的分数分布。判断效果时不要只检查一组文本。更可靠的方式是准备一批相关和不相关样本观察整体排序表现。6. 可以把向量打印出来直接分析吗可以打印但通常很难从单个数字中直接理解模型学到了什么。更有意义的检查方式是比较相似度查看检索排序检查正确结果是否出现在 Top-K 中使用真实问题构建评估集。
延伸阅读

更多相关文章

2026/10/5 3:49:50

Solana实现750 TPS的技术原理与高性能DApp开发实践

如果你最近关注区块链性能优化,可能会注意到一个让人惊讶的数字:Solana 网络在 7 月有望达到 750 token/秒的处理速度。这个数字背后不仅仅是技术参数的提升,更意味着区块链基础设施正在经历从"够用"到"实用"的关键转折点…

2026/10/6 15:51:39

深入解析C++ std::list:双向链表的迭代器稳定性与实战应用

1. 项目概述:为什么我们需要再次审视std::list?在C的日常开发中,std::vector因其连续内存和缓存友好性,几乎成了默认的“首选容器”。但作为一名有经验的C开发者,我常常发现,当新手甚至一些中级开发者遇到需…

2026/9/27 2:21:39

C/C++实现LU分解:从算法原理到高性能工程实践

1. 项目概述:为什么LU分解是数值计算的基石如果你写过C或C程序来处理线性方程组,比如在图形学里做坐标变换,或者在物理模拟中求解受力平衡,那你大概率绕不开一个核心算法:LU分解。我第一次接触它是在大学的一门数值分析…

2026/10/6 23:59:55

回溯法详解:LeetCode 46. 全排列

一、 问题描述给定一个不含重复数字的数组 nums,返回其所有可能的全排列。你可以按任意顺序返回答案。示例:输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]二、 核心思路:回溯 (Backtrac…

2026/10/6 23:59:55

【Web全栈进阶】PostgreSQL上手:Docker跑库 + 把早报站从SQLite迁过去

今天不写新功能,做一次“搬家”:把早报站的数据从SQLite搬进PostgreSQL——这是整个二季的地基工程。 🎯 本篇产出:一个跑在Docker里的PostgreSQL、一份可重复执行的数据迁移脚本、以及“为什么换”的完整决策链。含代码约60行。 …

2026/10/6 23:59:55

AI获客怎样减少重复线索?意客AI的原文复用与版本筛选

销售昨天看过一条办公室搬迁需求,今天又在“新线索”里看到它。如果对方已经暂停搬迁,第二次出现带来的只是一次重复阅读;如果需求范围变了,沿用昨天的沟通准备还可能问错问题。 星河卓越旗下意客AI根据业务描述寻找匹配需求&…

2026/10/6 23:59:55

装配车间MES落地指南:SimpleMES工单流转、BOM与齐套检查实战

简介:一套基于.NET 4.0的SimpleMES加工装配模拟系统,面向MES系统学习者、课程设计或毕业设计人员,以及需要快速搭建制造执行原型的开发者。服务端与客户端分工明确:服务端包含基础档案、加工与装配计划管理、实时看板和数据初始化…

2026/10/6 23:54:55

26年程序员转AI指南:收藏这份学习路线,轻松拥抱大模型时代!

文章分享了程序员如何成功转型AI领域的心得与经验。核心内容围绕五个学习阶段展开:先理解大模型调用本身,再学习AI应用开发所需能力,重点掌握RAG,随后学习Agent,最后通过项目实践积累经验。强调理解模型、业务和工程的…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/6 4:01:51

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/6 17:46:51

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑