使用Ollama从头构建Embedding和RAG系统

本文介绍了如何使用RAG(检索增强生成)技术,通过Ollama库操作文档,利用嵌入向量描述抽象概念,实现对文档内容的高效检索,以找到与查询最相关的部分,并演示了如何构建脚本以在本地处理自定义文档。

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

检索增强生成(RAG)赋予大型语言模型新的能力,使其能够与任何大小的文档或数据集进行互动。接下来,请跟随我一起了解如何解析和操作文档,探讨如何利用嵌入向量来描述抽象概念,实现一种简单而强大的方法,以找出文档中与特定查询最相关的部分,并最终构建一个脚本,使本地托管的大型语言模型能够处理您自己的文档。

创建环境

# set up environment
ollama pull nomic-embed-text
python -m venv .venv
source .venv/bin/activate
python -m pip install ollama numpy

RAG+Ollama

import ollama
import time
import os
import json
import numpy as np
from numpy.linalg import norm


# open a file and return paragraphs
def parse_file(filename):
    with open(filename, encoding="utf-8-sig") as f:
        paragraphs = []
        buffer = []
        for line in f.readlines():
            line = line.strip()
            if line:
                buffer.append(line)
            elif len(buffer):
                paragraphs.append((" ").join(buffer))
                buffer = []
        if len(buffer):
            paragraphs.append((" ").join(buffer))
        return paragraphs


def save_embeddings(filename, embeddings):
    # create dir if it doesn't exist
    if not os.path.exists("embeddings"):
        os.makedirs("embeddings")
    # dump embeddings to json
    with open(f"embeddings/{filename}.json", "w") as f:
        json.dump(embeddings, f)


def load_embeddings(filename):
    # check if file exists
    if not os.path.exists(f"embeddings/{filename}.json"):
        return False
    # load embeddings from json
    with open(f"embeddings/{filename}.json", "r") as f:
        return json.load(f)


def get_embeddings(filename, modelname, chunks):
    # check if embeddings are already saved
    if (embeddings := load_embeddings(filename)) is not False:
        return embeddings
    # get embeddings from ollama
    embeddings = [
        ollama.embeddings(model=modelname, prompt=chunk)["embedding"]
        for chunk in chunks
    ]
    # save embeddings
    save_embeddings(filename, embeddings)
    return embeddings


# find cosine similarity of every chunk to a given embedding
def find_most_similar(needle, haystack):
    needle_norm = norm(needle)
    similarity_scores = [
        np.dot(needle, item) / (needle_norm * norm(item)) for item in haystack
    ]
    return sorted(zip(similarity_scores, range(len(haystack))), reverse=True)


def main():
    SYSTEM_PROMPT = """You are a helpful reading assistant who answers questions 
        based on snippets of text provided in context. Answer only using the context provided, 
        being as concise as possible. If you're unsure, just say that you don't know.
        Context:
    """
    # open file
    filename = "peter-pan.txt"
    paragraphs = parse_file(filename)

    embeddings = get_embeddings(filename, "nomic-embed-text", paragraphs)

    prompt = input("what do you want to know? -> ")
    # strongly recommended that all embeddings are generated by the same model (don't mix and match)
    prompt_embedding = ollama.embeddings(model="nomic-embed-text", prompt=prompt)["embedding"]
    # find most similar to each other
    most_similar_chunks = find_most_similar(prompt_embedding, embeddings)[:5]

    response = ollama.chat(
        model="mistral",
        messages=[
            {
                "role": "system",
                "content": SYSTEM_PROMPT
                + "\n".join(paragraphs[item[1]] for item in most_similar_chunks),
            },
            {"role": "user", "content": prompt},
        ],
    )
    print("\n\n")
    print(response["message"]["content"])


if __name__ == "__main__":
    main()
### Ollama RAG 技术概述 Ollama RAG(Retrieval-Augmented Generation)是一种结合检索增强生成的技术,在处理自然语言任务时能够显著提高准确性与上下文关联度[^3]。传统的大规模语言模型依赖于预训练阶段获取的知识,而RAG允许动态查询外部数据库或索引,从而确保信息更新并更加精确。 对于IT领域而言,应用RAG可以实现更高效的代码片段搜索、API文档解析等功能。例如,在面对复杂的企业级开发环境配置问题时,可以通过RAG快速定位相关解决方案技术讨论帖子,帮助开发者节省大量时间成本。 具体到实施层面,构建一个基于Python的简单RAG框架可能涉及以下几个方面: 1. **建立或接入现有知识库**:这可能是公司内部积累的技术文档集合或者是公开可用的编程问答平台。 2. **设计高效检索机制**:利用Elasticsearch或其他全文搜索引擎来加速文本匹配过程。 3. **集成大型语言模型**:借助开源工具包如Hugging Face Transformers加载预训练好的LLM,并对其进行微调以适应特定应用场景需求。 ```python import os from elasticsearch import Elasticsearch from transformers import pipeline # 设置临时文件夹路径 TEMP_FOLDER = os.getenv('TEMP_FOLDER', './_temp') os.makedirs(TEMP_FOLDER, exist_ok=True) # 初始化Elasticsearch客户端实例 es_client = Elasticsearch() # 加载预训练的语言模型管道 nlp_pipeline = pipeline("question-answering") def retrieve_and_generate(query): # 执行检索操作... # 使用LLM生成最终回复... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

落难Coder

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值