langchain 入门指南 - 文本分片及向量化

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: langchain 入门指南 - 文本分片及向量化

前面的内容中关于数据或者上下文的传递我们都是通过 Prompt 来完成的,而这样我们会面临以下挑战:

  1. Prompt 的内容大小限制:成本,处理耗时
  2. 使用大量数据的成本
  3. 并非所有数据都会用于解决当前问题

解决大量数据/文本的设想 - 分治

分割成数据块 -> 选取相关数据块(多次) -> 发送至大模型

如何根据用户的问题选择相关的数据块?

有一种办法就是:使用语义检索。(不同于关键词检索,关键词检索是要严格匹配上关键词才能检索,但语义检索可以检索到相关的文本)

语义检索是一种基于文本内容和意义的信息检索方法,它试图理解查询和文档的语义,

以便更准确地找到与查询相关地文档。

向量化(embedding) 是将文本数据转换为数值向量的过程。向量化后的文本可以用于计算文本之间的相似性,

如余弦相似度、欧几里得距离等度量。这使得语义检索能够根据查询和文档之间的语义相似性来对文档进行排序和检索,从而提高检索的准确性和效率。

embedding 示例 - 计算相似性

下面的例子中,我们会看到 np.dot(embedding1, embedding3) 的值是最大的,这说明 sentence1sentence3 的相似性最高。

from langchain_openai import OpenAIEmbeddings
import os
os.environ['OPENAI_API_KEY'] = "your key"
os.environ['OPENAI_BASE_URL'] = "https://api.openai-hk.com/v1"
embedding = OpenAIEmbeddings()
sentence1 = "我是一名软件工程师"
sentence2 = "小张从事法律工作"
sentence3 = "我是一名程序员"
embedding1 = embedding.embed_query(sentence1)
embedding2 = embedding.embed_query(sentence2)
embedding3 = embedding.embed_query(sentence3)
import numpy as np
print(np.dot(embedding1, embedding2))
print(np.dot(embedding1, embedding3))
print(np.dot(embedding2, embedding3))

输出:

0.7987314936103257
0.9586440032651322
0.7990728512968016

numpy.dot 方法用于在机器学习中衡量两个向量的相似度。点积越大,两个向量越相似。

处理大文本

我们可以使用如下函数对我们的文本进行切割:

def split_file_into_chunks(file_path, chunk_size):
    chunks = []
    with open(file_path, 'r', encoding='utf-8') as file:
        while True:
            chunk = file.read(chunk_size)
            if not chunk:
                break
            chunks.append(chunk)
    return chunks
print(split_file_into_chunks('service_design.txt', 100))

向量化

然后,我们可以对每个文本块进行向量化:

from langchain_openai import OpenAIEmbeddings
def embed(chunks):
    embedding = OpenAIEmbeddings()
    return [embedding.embed_query(chunk) for chunk in chunks]
embeddings = embed(split_file_into_chunks('service_design.txt', 100))

向量检索

最后,我们可以使用向量检索来找到与查询最相关的文本块:

def find_k_largest_indices(input_list, k):
    """
    input_list: 点积列表
    k: 返回前 k 个最大值的索引
    """
    sorted_indices = sorted(range(len(input_list)), key=lambda i: input_list[i], reverse=True)
    print(input_list)
    print(sorted_indices)
    return sorted_indices[:k]
def search(chunks, embeddings, top_k, txt):
    import numpy as np
    embedding = OpenAIEmbeddings(chunk_size=1)
    embedded_text = embedding.embed_query(txt)
    # 计算输入文本与每个分块的相似度
    distances = [np.dot(embedded_text, emb) for emb in embeddings]
    # 返回前 k 个最相似的分块的索引
    ret_idx = find_k_largest_indices(distances, top_k)
    return [chunks[i] for i in ret_idx]
print(search(split_file_into_chunks('service_design.txt', 100), embeddings, 3, "字段长度"))

使用向量检索到的块来作为 prompt

上面通过向量检索拿到相关的文本块之后,我们可以将这一小部分文本块作为上下文传递给大模型。

然后就可以大模型就可以根据这些文本块来回答用户的问题。

这个时候,你就可以针对你的文档内容提问题了。

from openai import OpenAI
client = OpenAI(
  api_key="your key",
  base_url="https://api.openai-hk.com/v1"
)
def answer_question_with_doc(question, chunks, embeddeds):
    relevent_chunks = search(chunks, embeddeds, 2, question)
    prompt = """
    仅通过总结以下的文字片段回答用户问题,注意保持回答的语义通顺(字数在 30 字以内)
    ---
    """
    for chunks in relevent_chunks:
        prompt = prompt + "\n'" + chunks + "'"
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": prompt},
            {"role": "user", "content": question}
        ],
        temperature=0.9,
        max_tokens=200
    )
    return response.choices[0].message.content
print(answer_question_with_doc("如何做字段取舍", split_chunks, embeddings))

输出:

尽可能减少字段暴露,考虑敏感信息如客户地址、手机号等,斟酌是否必要暴露,若必需则考虑脱敏和加解密。

总结

在本文中,我们讨论了如何通过对文本进行切割,然后对这些文本块进行向量化处理,

最后,再对这些文本块做向量化搜索,以找到与查询最相关的文本块。

在搜索到相关的文本块之后,我们可以将这些文本块作为上下文传递给大模型,以回答用户的问题。

优点:

  1. 不用传递大量的文本作为上下文给大模型。节省成本的同时也减少了大模型的处理时间。


相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
目录
相关文章
|
28天前
langchain 入门指南 - 使用 Agent
langchain 入门指南 - 使用 Agent
84 0
|
28天前
|
安全 API 数据库
langchain 入门指南 - 函数调用
langchain 入门指南 - 函数调用
46 1
|
28天前
|
机器学习/深度学习
langchain 入门指南 - In-context Learning
langchain 入门指南 - In-context Learning
37 0
|
28天前
langchain 入门指南 - 链式请求
langchain 入门指南 - 链式请求
31 0
|
28天前
|
前端开发 人机交互
langchain 入门指南 - ReAct 模式
langchain 入门指南 - ReAct 模式
32 1
|
28天前
|
存储 人工智能 缓存
langchain 入门指南 - 让 AI 记住你说过的话
langchain 入门指南 - 让 AI 记住你说过的话
23 1
|
28天前
|
人工智能 搜索推荐 API
langchain 入门指南 - 让 AI 从互联网获取信息
langchain 入门指南 - 让 AI 从互联网获取信息
39 1
|
28天前
|
Linux
langchain 入门指南 - 使用提示词模板
langchain 入门指南 - 使用提示词模板
67 1
|
28天前
|
SQL 程序员 Ruby
langchain 入门指南(四)- 指定大语言模型的角色
langchain 入门指南(四)- 指定大语言模型的角色
33 1
|
28天前
|
JSON Go 数据格式
langchain 入门指南 - 让 LLM 自动选择不同的 Prompt
langchain 入门指南 - 让 LLM 自动选择不同的 Prompt
39 0

热门文章

最新文章