用免费的github的key调用gpt实现一个简单的rag自动打分评测系统,不用任何框架

news2025/3/28 7:57:47

1.环境准备

!pip install pymupdf numpy openai

2.导入依赖

import fitz
import os
import numpy as np
import json
from openai import OpenAI

3.pdf提取文本

def extract_text_from_pdf(pdf_path):
    """
    从 PDF 文件中提取文本内容。

    参数:
    pdf_path (str): PDF 文件的路径。

    返回:
    str: 提取出的完整文本内容。
    """
    # 打开 PDF 文件
    mypdf = fitz.open(pdf_path)
    all_text = ""  # 初始化一个空字符串,用于存储所有页的文本

    # 遍历 PDF 的每一页
    for page_num in range(mypdf.page_count):
        page = mypdf[page_num]  # 获取当前页
        text = page.get_text("text")  # 提取当前页的纯文本内容
        all_text += text  # 将当前页的文本追加到总文本中

    return all_text  # 返回所有提取出的文本

4.将上个步骤提取的文本按固定长度分段

def chunk_text(text, n, overlap):
    """
    将输入文本按固定长度进行分段,支持设置重叠部分。

    参数:
    text (str): 需要被分段的原始文本。
    n (int): 每个文本块的字符数。
    overlap (int): 相邻文本块之间重叠的字符数。

    返回:
    List[str]: 分段后的文本块列表。
    """
    chunks = []  # 初始化一个空列表,用于存储所有的文本块

    # 以步长 (n - overlap) 遍历整个文本
    for i in range(0, len(text), n - overlap):
        # 从当前位置 i 开始,取 n 个字符,作为一个 chunk 添加到列表中
        chunks.append(text[i:i + n])

    return chunks  # 返回所有分好的文本块

5.初始化openai实例

import os
from openai import OpenAI

token = ""
endpoint = "https://models.inference.ai.azure.com"
model_name = "gpt-4o"

client = OpenAI(
    base_url=endpoint,
    api_key=token,
)

6.从指定pdf文件中提取文本内容

# 定义 PDF 文件的路径
pdf_path = "/content/设计前沿-ai文生图.pdf"

# 调用自定义函数,从 PDF 文件中提取纯文本内容
extracted_text = extract_text_from_pdf(pdf_path)

# 将提取到的文本进行分块处理
# 每个块包含 1000 个字符,块与块之间有 200 个字符的重叠部分
text_chunks = chunk_text(extracted_text, 1000, 200)

# 打印生成的文本块数量
print("Number of text chunks:", len(text_chunks))

# 打印第一个文本块的内容,查看是否提取和分块成功
print("\nFirst text chunk:")
print(text_chunks[0])

7.将文本转换为向量

def create_embeddings(text, model="text-embedding-3-small"):
    """
    使用指定的 OpenAI 模型为输入文本创建嵌入向量(embeddings)。

    参数:
    text (str 或 List[str]): 要进行嵌入的文本或文本列表。
    model (str): 使用的嵌入模型名称,默认使用 "text-embedding-3-small"。

    返回:
    object: 来自 OpenAI API 的响应结果,包含嵌入向量信息。
    """
    # 使用 OpenAI 客户端调用嵌入接口,生成文本的向量表示
    response = client.embeddings.create(
        model=model,  # 使用的嵌入模型
        input=text     # 传入待编码的文本(可以是字符串或字符串列表)
    )

    return response  # 返回包含嵌入信息的 API 响应

8.计算两个向量(用户问题和检索到的文本块)的相似度

def cosine_similarity(vec1, vec2):
    """
    计算两个向量之间的余弦相似度(Cosine Similarity)。

    参数:
    vec1 (np.ndarray): 第一个向量(numpy 数组)。
    vec2 (np.ndarray): 第二个向量(numpy 数组)。

    返回:
    float: 两个向量之间的余弦相似度,取值范围 [-1, 1],越接近 1 表示越相似。
    """
    # 计算两个向量的点积(内积)
    dot_product = np.dot(vec1, vec2)

    # 分别计算两个向量的模(长度)
    norm_vec1 = np.linalg.norm(vec1)
    norm_vec2 = np.linalg.norm(vec2)

    # 用点积除以两个模的乘积,得到余弦相似度
    similarity = dot_product / (norm_vec1 * norm_vec2)

    return similarity  # 返回余弦相似度得分

9.检索逻辑

def semantic_search(query, text_chunks, embeddings, k=5):
    """
    使用语义相似度在文本块中检索与查询最相关的内容。

    参数:
    query (str): 用户输入的查询问题。
    text_chunks (List[str]): 需要检索的文本块列表。
    embeddings (List[dict]): 每个文本块对应的嵌入向量(OpenAI 返回的数据结构)。
    k (int): 返回与查询最相关的前 k 个文本块。默认值为 5。

    返回:
    List[str]: 与查询最相关的前 k 个文本块(按相似度排序)。
    """
    # 为用户查询生成嵌入向量
    query_embedding = create_embeddings(query).data[0].embedding

    similarity_scores = []  # 初始化一个列表,用于存储每个文本块与查询的相似度得分

    # 遍历所有文本块的嵌入向量,与查询向量计算相似度
    for i, chunk_embedding in enumerate(embeddings):
        # 提取该文本块的向量并计算与查询向量的余弦相似度
        similarity_score = cosine_similarity(
            np.array(query_embedding),
            np.array(chunk_embedding.embedding)
        )
        # 将文本块的索引和相似度添加到结果列表中
        similarity_scores.append((i, similarity_score))

    # 按相似度从高到低排序
    similarity_scores.sort(key=lambda x: x[1], reverse=True)

    # 获取前 k 个最相关文本块的索引
    top_indices = [index for index, _ in similarity_scores[:k]]

    # 返回对应的文本块内容
    return [text_chunks[index] for index in top_indices]

用户输入 query
     ↓
生成 query 向量
     ↓
与每个 chunk 的向量计算余弦相似度
     ↓
相似度排序 → 选前 k 个
     ↓
返回最相关的文本块(用于回答生成)
10. 从pdf提取的文本中找到与问题最相似的前两个文本(通过向量找)

# 从 JSON 文件中加载验证数据(val.json 文件中存有多个问答对)
with open('/content/ val.json') as f:
    data = json.load(f)

# 从验证数据中提取第一个问题(用户查询)
query = data[0]['question']

# 使用语义检索,从文本块中找出与该问题最相关的前 2 个文本块
top_chunks = semantic_search(query, text_chunks, response.data, k=2)

# 打印用户提问的内容
print("Query:", query)

# 打印检索到的前 2 个最相关的文本块,用作后续生成回答的上下文
for i, chunk in enumerate(top_chunks):
    print(f"Context {i + 1}:\n{chunk}\n=====================================")

11.定义提示词实现对问题的回答

# 定义 AI 助手的系统提示词(设定它的行为准则)
# 要求它必须基于上下文回答;如果上下文中找不到答案,就明确说没有信息。
system_prompt = (
    "You are an AI assistant that strictly answers based on the given context. "
    "If the answer cannot be derived directly from the provided context, respond with: "
    "'I do not have enough information to answer that.'"
)

# 定义生成 AI 回答的函数
def generate_response(system_prompt, user_message, model="gpt-4o"):
    """
    使用指定的大语言模型生成回答。

    参数:
    system_prompt (str): 系统提示词,引导 AI 的行为(定义身份、回答风格等)。
    user_message (str): 用户的消息(包括上下文和问题)。
    model (str): 使用的模型名称,默认使用 gpt-4o(也可以替换为其他兼容模型)。

    返回:
    dict: 模型生成的完整响应对象(包含回答内容等)。
    """
    # 调用 Chat 接口,生成回答
    response = client.chat.completions.create(
        model=model,        # 指定使用的模型
        temperature=0,      # 温度设置为 0,表示尽可能确定性回答(减少随机性)
        messages=[
            {"role": "system", "content": system_prompt},  # 系统设定
            {"role": "user", "content": user_message}      # 用户输入(包含上下文 + 问题)
        ]
    )
    return response  # 返回完整响应对象

12.结合上步给出的答案以及真正的答案进行打分


# 定义评分系统的提示词(system prompt)
# 告诉 AI 你是一个智能评估系统,要根据回答的准确性打分:
# 1 分:完全正确;0.5 分:部分正确;0 分:错误或答非所问。
evaluate_system_prompt = (
    "You are an intelligent evaluation system tasked with assessing the AI assistant's responses. "
    "If the AI assistant's response is very close to the true response, assign a score of 1. "
    "If the response is incorrect or unsatisfactory in relation to the true response, assign a score of 0. "
    "If the response is partially aligned with the true response, assign a score of 0.5."
)
# 构造评估任务的完整提示内容(evaluation_prompt)
# 包括:
# - 用户问题(User Query)
# - AI 的实际回答(AI Response)
# - 标准答案(True Response)
# - 评分规则(evaluate_system_prompt)
evaluation_prompt = (
    f"User Query: {query}\n"
    f"AI Response:\n{ai_response.choices[0].message.content}\n"
    f"True Response: {data[0]['ideal_answer']}\n"
    f"{evaluate_system_prompt}"
)
# 使用之前定义的 generate_response 函数,调用模型进行评分
# 评分系统会根据 AI 的回答和真实答案之间的匹配程度输出评分(0, 0.5, 1)
evaluation_response = generate_response(evaluate_system_prompt, evaluation_prompt)
# 打印模型生成的评分结果(通常会包含得分和简要理由)
print(evaluation_response.choices[0].message.content)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2321436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQLServer列转行操作及union all用法

1.创建测试表及数据sql如下 create table ScoresTable( Name varchar(50), ChineseScore int, MathScore int ) insert into ScoresTable values(小张,90,95) insert into ScoresTable values(小王,98,99) 2.表中查询结果如下 3.现需列转行显示,每行显示 姓名…

【GL010】C++

1.C中的const关键字有哪些用法? 1.修饰变量:表示变量的值不可修改。 const int a 10; 2.修饰指针: const int* p: // 指针指向的内容不可修改。 int* const p: // 指针本身不可修改。 const int* const…

(Arxiv-2025)MagicDistillation:用于大规模人像少步合成的弱到强视频蒸馏

MagicDistillation:用于大规模人像少步合成的弱到强视频蒸馏 paper是HKUST发布在Arxiv 2025的工作 paper title:MagicDistillation: Weak-to-Strong Video Distillation for Large-Scale Portrait Few-Step Synthesis Project page:地址 Abst…

Excel(进阶篇):powerquery详解、PowerQuery的各种用法,逆透视表格、双行表头如何制作透视表、不规则数据如何制作数据透视表

目录 PowerQuery工具基础修改现有数据理规则PowerQuery抓取数据的两种方式多文件合并透视不同表结构多表追加数据透视追加与合并整理横向表格:逆透视 数据用拆分工具整理数据算账龄 不等步长值组合合并文件夹中所有文件PowerQuery处理CSV文件双行表头、带合并单元格如何做数据…

Simple-BEV的bilinear_sample 作为view_transformer的解析,核心是3D-2D关联点生成

文件路径models/view_transformers 父类 是class BiLinearSample(nn.Module)基于https://github.com/aharley/simple_bev。 函数解析 函数bev_coord_to_feature_coord的功能 将鸟瞰图3D坐标通过多相机(针孔/鱼眼)内外参投影到图像特征平面&#xff0…

同一个局域网的话 如何访问另一台电脑的ip

在局域网内访问另一台电脑,可以通过以下几种常见的方法来实现: ‌直接通过IP地址访问‌: 首先,确保两台电脑都连接在同一个局域网内。获取目标电脑的IP地址,这可以通过在目标电脑上打开命令提示符(Windows系…

基于SpringBoot的名著阅读网站

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

Excel(实战):INDEX函数和MATCH函数、INDEX函数实战题

目录 经典用法两者嵌套查值题目解题分析 INDEX巧妙用法让数组公式,自动填充所有、有数据的行/列INDEX函数和SEQUENCE函数 经典用法两者嵌套查值 题目 根据左表查询这三个人的所有数据 解题分析 INDEX函数的参数:第1个参数是选定查找范围&#xff0c…

uniapp超简单ios截屏和上传app store构建版本方法

​ 假如使用windows开发ios的应用,上架的时候,你会发现,上架需要ios应用多种尺寸的ios设备的截图,和需要xcode等工具将打包好的ipa文件上传到app store的构建版本。 大部分情况下,我们的公司都没有这么多款ios设备来…

Netty源码—5.Pipeline和Handler一

大纲 1.Pipeline和Handler的作用和构成 2.ChannelHandler的分类 3.几个特殊的ChannelHandler 4.ChannelHandler的生命周期 5.ChannelPipeline的事件处理 6.关于ChannelPipeline的问题整理 7.ChannelPipeline主要包括三部分内容 8.ChannelPipeline的初始化 9.ChannelPi…

MySQL小练习

目录 一、单表查询 二、多表查询 一、单表查询 素材: 表名:worker-- 表中字段均为中文,比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float…

Apache Hive:基于Hadoop的分布式数据仓库

Apache Hive 是一个基于 Apache Hadoop 构建的开源分布式数据仓库系统,支持使用 SQL 执行 PB 级大规模数据分析与查询。 主要功能 Apache Hive 提供的主要功能如下。 HiveServer2 HiveServer2 服务用于支持接收客户端连接和查询请求。 HiveServer2 支持多客户端…

检波、限幅、钳位电路

检波电路: 类似调制收音机信号:输入的基波和载波叠加成调制信号(信号需要长距离里传输,频率要高,M级别的频率,所以要把低频信号叠在高频信号,才能把低频信号长距离传输,最后到达接收…

学习threejs,使用TextGeometry文本几何体

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.TextGeometry1.1.1 ☘…

Go红队开发—CLI框架(一)

CLI开发框架 命令行工具开发,主要是介绍开发用到的包,集成了一个框架,只要学会了基本每个人都能开发安全工具了。 该文章先学flags包,是比较经典的一个包,相比后面要学习的集成框架这个比较自由比较细化点&#xff0…

高效团队开发的工具与方法 引言

引言 在现代软件开发领域,团队协作的效率和质量直接决定了项目的成败。随着项目规模的扩大和技术复杂度的增加,如何实现高效团队开发成为每个开发团队必须面对的挑战。高效团队开发不仅仅是个人技术能力的简单叠加,更需要借助合适的工具和方…

【Java全栈进阶架构师实战:从设计模式到SpringCloudAlibaba,打造高可用系统】

🌟 分享一个教程,助刚踏入IT行业、工作几年的老油条、或热爱学习的工作党们更上一层楼的! 🌟 ​适合人群:初中级Java开发者、求职面试备战者、技术提升党! 📚 ​内容亮点: 1️⃣ ​…

[蓝桥杯 2023 省 A] 异或和之和

题目来自洛谷网站&#xff1a; 暴力思路&#xff1a; 先进性预处理&#xff0c;找到每个点位置的前缀异或和&#xff0c;在枚举区间。 暴力代码&#xff1a; #include<bits/stdc.h> #define int long long using namespace std; const int N 1e520;int n; int arr[N…

TDengine 3.3.2.0 集群报错 Post “http://buildkitsandbox:6041/rest/sql“

修复&#xff1a; vi /etc/hosts将buildkitsandbox映射为本机节点

vue数据重置

前言 大家在开发后台管理系统的过程中&#xff0c;一定会遇到一个表格的条件查询重置功能吧&#xff0c;如果说查询条件少&#xff0c;重置起来还算是比较简单&#xff0c;如果元素特别多呢&#xff0c;那玩意写起来可遭老罪喽&#xff0c;那今天就给大家整一个如何快速重置数…