使用 OpenAI 的 Embedding模型 构建知识向量库并进行相似搜索

文章介绍了如何使用OpenAI的embedding模型将文本转换为词向量,构建知识向量库,并通过余弦相似度计算实现相似文本的查询。作者通过实例演示了从API获取词向量,创建知识库,以及查询过程中使用余弦相似度的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenAI的embedding模型的使用

       首先第一篇文章中探讨和使用了ChatGPT4的API-Key实现基础的多轮对话和流式输出,完成了对GPT-API的一个初探索,那第二步打算使用OpenAI的embedding模型来构建一个知识向量库,其实知识向量库本质上就是一个包含着一组向量的数组,然后通过查询输入文本生成的向量和数据库文本中的向量的余弦相似度来进行相似度判断,在使用的过程中还是非常舒服的。

前置文章:ChatGPT4 API-Key初探-本地调用API进行多轮对话方和流式输出

1.什么是Embedding


       Embedding在AI领域被翻译成词嵌入,但是光看这三个字其实不好理解,如果用一句话解释的话:embedding就是将文字转换成一个向量


在这里插入图片描述

图: Embedding的工作过程


  • 那为什么要转换成向量?
    因为要获得两段文字在空间中的关系进行运算,例如后续需要做的计算两个词的相似度,就需要首先经过embedding模型将两端文字转换成向量,然后算两个向量的余弦相似度。

       如果你不是研究自然语言处理的研究生或者算法工程师,那你只需要了解这一点就可以了,至于怎么转换的这一点可以不用深究,就像你可能不了解计算机组成原理但是你依然可以熟练的使用计算机。

2.使用OpenAI的embedding模型生成一个词向量


       OpenAI为我们提供了了一个方便的API接口来将输入文本直接转换为词向量,在官方文档的代码中其实并没有新手向的代码的表达都会集成一些功能一起发布,但是为了学习和理解要把其中最简单和核心的部分抽出来。

       下面的代码使用的是OpenAI的text-embedding-3-small模型将文本"父亲"转换为词向量。经过API之后得到了一个长度为1536的向量。

from openai import OpenAI
import numpy as np

# client = OpenAI(api_key="your-api-key-here") # 如果想在代码中设置Api-key而不是全局变量就用这个代码
client = OpenAI()

model = "text-embedding-3-small"


def get_embedding(text, model=model):
    return client.embeddings.create(input=text, model=model).data[0].embedding


text = '父亲'
vector = np.array(get_embedding(text))
print(vector.shape)
# (1536,)

3.使用OpenAI的embedding模型获得一个知识向量库


       OK那既然一条文本能转换成向量,那多条文本那就必然能转换成多个词向量,且词向量的长度是一致的,然后将这些词向量转换成数组然后保存这样就得到了一个知识向量库,本质上就是保存一个数组,返璞归真。

       首先我们得有一段文本,我让ChatGPT给我生成了50个医疗词汇,每个词汇一行,文本内容我放在文章最后。接下来给出代码。

       下列代码将本文中的医疗词汇逐行读取然后转换成词向量,保存到一个numpy数组当中,然后再将Numpy数组保存到本地,这样就得到了一个知识向量库。

from openai import OpenAI
import pandas as pd
import numpy as np
import time

# client = OpenAI(api_key="your-api-key-here") # 如果想在代码中设置Api-key而不是全局变量就用这个代码
client = OpenAI()

model = "text-embedding-3-small"

with open('test.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

embedding = [client.embeddings.create(input=i.strip(), model=model).data[0].embedding for i in lines]

t = time.time()
np.save('embedding.npy', np.array(embedding))
print(time.time() - t)
# 0.002991914749145508 (运行时间/s)

测试用的文本内容

糖尿病
高血压
抑郁症
阿尔茨海默症
慢性阻塞性肺疾病(COPD)
骨折
哮喘
乳腺癌
心肌梗塞
脑卒中
化疗
放射疗法
心脏搭桥手术
经皮冠状动脉介入治疗(PCI)
腹腔镜手术
物理疗法
认知行为疗法
血液透析
绝育手术
骨髓移植
MRI扫描仪
CT扫描仪
心电图机
超声波设备
血糖仪
血压计
吸氧机
呼吸机
脉搏血氧仪
自动体外除颤器(AED)
青霉素
阿司匹林
他汀类药物
阿片类镇痛药
抗生素
抗抑郁药
胰岛素
利尿剂
抗凝血药
抗病毒药
免疫疗法
基因编辑
微创手术
患者健康记录(PHR)
电子医疗记录(EMR)
临床试验
医疗保健大数据
精准医疗
遥感监测
医疗伦理

3.从知识向量库中进行相似文本的查询


       首先在介绍查询方法之需要说一下计算相似度的余弦相似度,当两个向量夹角越小的时候两个向量的相似度越高,其计算公式如下:


cosine similarity ( A , B ) = A ⋅ B ∥ A ∥ ∥ B ∥ = ∑ i = 1 n A i B i ∑ i = 1 n A i 2 ∑ i = 1 n B i 2 \text{cosine similarity}(\mathbf{A}, \mathbf{B}) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n}A_iB_i}{\sqrt{\sum_{i=1}^{n}A_i^2} \sqrt{\sum_{i=1}^{n}B_i^2}} cosine similarity(A,B)=A∥∥BAB=i=1nAi2 i=1nBi2 i=1nAiBi


       在查询任务中我们需要计算输入文本的向量和知识向量库中所有文本向量的余弦相似度,然后进行排序,当然作为一个算法工程师我们当然不能直接用for循环进行计算,本文基于numpy的广播机制,自己实现了一个高效的计算一个向量和一群向量的余弦相似度的代码。同时由于算法本身使用的是numpy,基于numpy底层为C语言实现,因此本程序的效率较高,作为新手的话只需要知道输入输出是什么就行了。代码如下。

import numpy as np

def cos_similarity(target, embedding):
    numerator = np.sum(target * embedding, axis=1)
    denominator = np.sqrt(np.sum(np.square(target)) * np.sum(np.square(embedding),axis=1))
    return numerator / denominator


if __name__ == '__main__':

    x = np.array([1, 2])
    y = np.array([[1, 2], [1, 1]])

    print(cos_similarity(x, y))
	# [1.        0.9486833]

将知识向量库中的文本按照相似度从大到小输出,代码如下:

  • 生成知识向量库和查询使用的模型得是一个模型别忘了,不然会报维度错误。
import numpy as np
from openai import OpenAI

model="text-embedding-3-small"
# client = OpenAI(api_key="your-api-key-here") # 如果想在代码中设置Api-key而不是全局变量就用这个代码
client = OpenAI()

def get_embedding(text, model=model):
   return client.embeddings.create(input=text, model=model).data[0].embedding

def cos_similarity(target, embedding):
    numerator = np.sum(target * embedding, axis=1)
    denominator = np.sqrt(np.sum(np.square(target)) * np.sum(np.square(embedding),axis=1))
    return numerator / denominator

with open('test.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

# 获得文本数据
name = np.array([i.strip() for i in lines])
# 获得向量库
embedding = np.load("embedding.npy",allow_pickle=True)


# 获取用户的输入文本
search_text = input("User:")
# 获取用户输入文本使用embedding模型转换得到的词向量
search_embedding = get_embedding(search_text)
# 计算用户输入文本
embedding_similarity = cos_similarity(search_embedding,embedding)


# 由上到下输入相似度
for i in np.argsort(embedding_similarity)[::-1]:
    print(name[i],embedding_similarity[i])

接下来让GPT解释一下这段代码助于理解,我看了一下基本没有问题。

  1. 导入所需的库:使用了numpy库来处理数学运算和数组操作,以及OpenAI的API客户端来获取文本的嵌入向量。

  2. 设置模型和客户端:选择了一个特定的模型text-embedding-3-small来从OpenAI获取文本嵌入。这里有一段被注释掉的代码,用于手动设置API密钥,但在这个例子中,默认使用了全局变量设置的API密钥。

  3. 定义函数获取嵌入向量get_embedding函数通过OpenAI的API将文本转换成嵌入向量。这个向量是文本的数学表示,用于计算相似度。

  4. 定义余弦相似度函数cos_similarity函数计算两组向量之间的余弦相似度,这是衡量向量相似度的一种方法。余弦相似度越接近1,表示两个向量越相似。

  5. 读取文本数据:从test.txt文件中读取每行文本,每行代表一个可查询的项,并将其存储在名为name的数组中。

  6. 加载嵌入向量库:从embedding.npy文件加载预先计算好的嵌入向量,这些向量对应于test.txt文件中的文本项。

  7. 获取用户输入:通过input函数获取用户的查询文本。

  8. 获取查询文本的嵌入向量:使用get_embedding函数将用户的查询文本转换为嵌入向量。

  9. 计算相似度:使用cos_similarity函数计算用户查询的嵌入向量与嵌入向量库中所有向量之间的余弦相似度。

输出结果如下,这里就不全部粘贴了,把前面的几个粘贴上。

User:糖尿病
糖尿病 1.0
血糖仪 0.6027716430115105
高血压 0.4807989892102901
乳腺癌 0.46976679922966263
利尿剂 0.44671493260605705
抑郁症 0.3989793244972647
胰岛素 0.3678633339750386
心肌梗塞 0.3630205294730911
阿尔茨海默症 0.3554829250733137
血压计 0.3527248065537073
抗病毒药 0.3223748925983246

在这里插入图片描述

结束


官方文档:https://platform.openai.com/docs/guides/embeddings/embedding-models
目前支持的Embedding模型如下。
在这里插入图片描述
       在官方文档中还详细讲了很多的使用方式,例如如何进行可视化,如何进行机器学习技术等,但是文章中的内容是我抽出主要内容然后加上自己的理解实现的。如果有什么不对或者更好的方式非常欢迎交流。

<think>好的,用户现在想了解Dify节点的相关信息或配置,特别是节点的配置和使用方法。让我先回顾一下之前的对话历史和提供的参考资料。用户之前询问了如何下载Dify源码,现在转向节点的具体配置和使用。 首先,用户提供的引用中提到了零基础AI开发系列教程中的Dify节点详细介绍,分为上、中、下三部分,这可能涉及节点的类型、功能以及具体操作步骤。另外,引用[2]提到了HTTP请求节点的认证方式,引用[3]则讨论了变量聚合节点的作用。这些信息都是关键点,需要整合到回答中。 用户的具体问题是如何配置和使用Dify节点,因此需要分步骤解释,包括节点类型、配置步骤、常见节点的操作示例,以及注意事项。可能需要结合之前的回答中提到的源码结构和相关模块,如蓝图控制器,来增强回答的专业性。 需要注意的是,用户可能对Dify的工作流设计不太熟悉,因此需要从基础开始解释,例如节点的概念、如何添加到工作流、配置参数等。同时,结合引用中的HTTP节点和变量聚合节点作为例子,能够具体说明配置过程,帮助用户理解。 另外,用户之前的问题涉及源码下载和依赖项,因此在回答节点配置时,可能需要提到环境准备,比如确保Docker和相关服务已正确安装,这部分在之前的回答中已经提到过,可以引用之前的建议作为参考。 还需要考虑用户可能的后续问题,比如遇到配置错误如何处理,或如何调试节点,所以应在注意事项中涵盖这些方面,或者生成相关问题引导用户进一步探索。 最后,确保回答结构清晰,分点说明,正确引用提供的资料,比如引用[1]的教程系列,引用[2]的HTTP节点认证,引用[3]的变量聚合节点功能。同时,使用中文,符合格式要求,行内公式用$...$,独立公式用$$...$$,但可能这里公式较少,重点在配置步骤和代码示例。</think>### Dify 节点配置与使用详解 Dify 的节点是工作流设计的核心组件,用于实现数据处理、逻辑控制和结果聚合等功能。以下是节点配置与使用的关键要点及操作示例: --- #### 一、节点基础配置 1. **节点类型与功能** - **输入节点**:接收外部数据(如用户输入、API请求) - **处理节点**:执行逻辑操作(如LLM调用、条件分支、变量聚合[^3]) - **输出节点**:返回最终结果(如API响应、文件生成) 2. **通用配置步骤** ```bash # 示例:通过Dify界面配置节点的基本流程 1. 创建工作流 -> 拖拽节点至画布 -> 连接节点 2. 双击节点 -> 填写参数 -> 保存配置 ``` - **必填字段**:节点名称、输入/输出变量映射 - **动态参数**:支持通过 `{{variable}}` 语法引用上下文变量 --- #### 二、常见节点操作示例 1. **HTTP请求节点** *(适用于调用外部API)* - **认证配置**: 使用Bearer Token认证时,需在请求头添加: ```http Authorization: Bearer {{your_api_key}}[^2] ``` - **参数映射**: 将上游节点的输出变量(如 `{{query_result}}`)映射到请求体参数 2. **变量聚合节点** *(整合多分支结果)* ```yaml # 配置示例:聚合分类结果 branches: - path: A output_vars: {category: "科技"} - path: B output_vars: {category: "生活"} aggregated_var: unified_category[^3] ``` - **作用**:将不同分支的 `category` 变量统一映射为 `unified_category` 3. **LLM调用节点** *(核心AI处理单元)* - **模型选择**:支持本地部署模型(如DeepSeek)或云端API - **提示词模板**: 使用动态变量增强灵活性: ```python "请根据{{user_input}}生成摘要,限制{{max_length}}字" ``` --- #### 三、高级配置技巧 1. **条件分支控制** ```python # 通过表达式实现动态路由 if {{input.score}} > 0.7: route_to = "positive_feedback" else: route_to = "default_process" ``` 2. **错误处理机制** - **重试策略**:配置HTTP节点的超时时间与重试次数 - **异常捕获**:添加备用处理节点应对API调用失败 3. **性能优化** - **行执行**:对无依赖关系的节点启用行处理 - **缓存设置**:为LLM节点配置结果缓存(需启动Redis服务[^1]) --- #### 四、注意事项 1. **环境依赖** 确保已部署 PostgreSQL(数据库)、Redis(缓存)、Weaviate(向量搜索)等基础设施[^1] 2. **调试工具** 使用工作流的 **"测试运行"** 功能实时观察变量传递状态 3. **版本兼容** 升级Dify版本时需检查节点配置变更(参考《Dify升级指南》[^1])
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩浩的科研笔记

这我为您答疑发送资源的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值