使用 `llama_index` 构建智能问答系统:多种文档切片方法的评估

使用 `llama_index` 构建智能问答系统:多种文档切片方法的评估

    • 代码优化与解析
      • 1. **代码结构优化**
      • 2. **日志管理**
      • 3. **环境变量管理**
      • 4. **模型初始化**
      • 5. **提示模板更新**
      • 6. **问答函数优化**
      • 7. **索引构建与查询引擎**
      • 8. **节点解析器测试**
    • 总结

在现代自然语言处理(NLP)应用中,构建一个高效的问答系统是一个常见的需求。llama_index 是一个强大的工具,可以帮助我们快速构建基于文档的问答系统。本文将介绍如何优化和解析一个基于 llama_index 的问答系统代码,并逐步解析其核心功能。


代码优化与解析

1. 代码结构优化

我们将代码拆分为多个函数,使得代码结构更清晰,便于维护和扩展。以下是优化后的代码结构:

  • update_prompt_template:用于动态更新查询引擎的提示模板。
  • ask_question:向查询引擎提问并输出结果。
  • load_documents:加载指定目录下的文档。
  • build_index_and_query_engine:构建索引并创建查询引擎。
  • main:主函数,负责程序的整体逻辑。

这种模块化的设计使得代码更易于理解和扩展。


2. 日志管理

为了避免不必要的警告信息干扰,我们使用 logging.basicConfig(level=logging.ERROR) 来设置日志级别为 ERROR。这样可以确保只有重要的错误信息被输出。

import logging
logging.basicConfig(level=logging.ERROR)

3. 环境变量管理

我们使用 dotenv 库加载 .env 文件中的环境变量,确保敏感信息(如 API Key)不会硬编码在代码中。

from dotenv import find_dotenv, load_dotenv
load_dotenv(find_dotenv())

4. 模型初始化

我们初始化 OpenAI 的 LLM 和 Embedding 模型,确保模型配置一致且易于修改。

llm_client = OpenAI(model="gpt-4",api_base=os.environ["OPENAI_BASE_URL"],api_key=os.environ["OPENAI_API_KEY"],is_chat_model=True,seed=42,
)embed_client = OpenAIEmbedding(model="text-embedding-3-large",api_base=os.environ["OPENAI_EMBED_BASE_URL"],api_key=os.environ["OPENAI_API_KEY"],
)

5. 提示模板更新

update_prompt_template 函数用于动态更新查询引擎的提示模板,确保问答系统能够根据需求调整回答风格。

def update_prompt_template(query_engine, qa_prompt_tmpl_str=None):if qa_prompt_tmpl_str is None:qa_prompt_tmpl_str = ("你叫公司小蜜,是公司的答疑机器人。你需要仔细阅读参考信息,然后回答大家提出的问题。""注意事项:\n""1. 根据上下文信息而非先验知识来回答问题。\n""2. 如果是工具咨询类问题,请务必给出下载地址链接。\n""3. 如果员工部门查询问题,请务必注意有同名员工的情况,可能有2个、3个甚至更多同名的人\n""以下是参考信息。""---------------------\n""{context_str}\n""---------------------\n""问题:{query_str}\n。""回答:")qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)query_engine.update_prompts({"response_synthesizer:text_qa_template": qa_prompt_tmpl})return query_engine

6. 问答函数优化

ask_question 函数负责处理用户的问题,输出问题和回答,并展示参考文档。通过检查 response 对象是否有 print_response_stream 方法,确保兼容不同的响应类型。

def ask_question(question, query_engine):update_prompt_template(query_engine)print('=' * 50)print(f'🤔 问题:{question}')print('=' * 50 + '\n')response = query_engine.query(question)print('🤖 回答:')if hasattr(response, 'print_response_stream') and callable(response.print_response_stream):response.print_response_stream()else:print(str(response))print('\n' + '-' * 50)print('📚 参考文档:\n')for i, source_node in enumerate(response.source_nodes, start=1):print(f'文档 {i}:')print(source_node)print()print('-' * 50)return response

7. 索引构建与查询引擎

build_index_and_query_engine 函数负责构建索引并创建查询引擎。根据不同的节点解析器(如 TokenTextSplitterSentenceSplitter 等),生成不同的查询引擎。

def build_index_and_query_engine(documents, embed_model, llm, node_parser, postprocessors=None):print(f"\n{'=' * 50}")print(f"🔍 正在使用 {node_parser.__class__.__name__} 方法进行测试...")print(f"{'=' * 50}\n")print("📑 正在处理文档...")nodes = node_parser.get_nodes_from_documents(documents)index = VectorStoreIndex(nodes, embed_model=embed_model)query_engine = index.as_query_engine(similarity_top_k=5,streaming=True,llm=llm,node_postprocessors=postprocessors if postprocessors else [])return query_engine

8. 节点解析器测试

我们使用不同的节点解析器(如 TokenTextSplitterSentenceSplitter 等)对文档进行处理,并测试其效果。对于 SentenceWindowNodeParser,还需要使用 MetadataReplacementPostProcessor 进行后处理。

node_parsers = [TokenTextSplitter(chunk_size=1024, chunk_overlap=20),SentenceSplitter(chunk_size=512, chunk_overlap=50),SentenceWindowNodeParser.from_defaults(window_size=3,window_metadata_key="window",original_text_metadata_key="original_text"),SemanticSplitterNodeParser(buffer_size=1,breakpoint_percentile_threshold=95,embed_model=embed_client),MarkdownNodeParser()
]for parser in node_parsers:if isinstance(parser, SentenceWindowNodeParser):postprocessors = [MetadataReplacementPostProcessor(target_metadata_key="window")]else:postprocessors = Nonequery_engine = build_index_and_query_engine(documents, embed_client, llm_client, parser, postprocessors)ask_question(question, query_engine)

总结

通过优化代码结构、模块化处理、日志管理和环境变量管理,代码的可读性和可维护性得到了显著提升。同时,通过不同的节点解析器对文档进行处理,可以更好地理解不同解析器的效果和适用场景。希望这篇博客对你理解和使用 llama_index 库有所帮助!

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

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

相关文章

开源平台Kubernetes的优势是什么?

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统,其服务、支持和工具的使用范围广泛。 Kubernetes 这个名字源于希腊语,意…

INT305 Machine Learning

W1 Introduction Nearest Neighbor Preliminaries and Nearest Neighbor Methods • Suppose we’re given a novel input vector 𝑥 we’d like to classify. • The idea: find the nearest input vector to 𝑥 in the training set and copy …

如何存储和分析爬取的数据

在数据爬取过程中,存储和分析数据是至关重要的环节。正确的存储方式可以确保数据的安全性和可访问性,而有效的数据分析则可以提取出有价值的信息。以下是关于如何存储和分析爬取数据的详细介绍,包括具体的代码示例。 数据存储 存储爬取的数…

2025_0105_生活记录

3号去内蒙看了流星雨。还记得上次看流星的时间是2018年,也是冬天,大家在雁栖湖校区的操场上仰望星空。那个时候幸运的看到了一颗流星,便迅速地在心里许愿。这次看到了三颗流星,我也许了愿,希望实现。 24年走过了十多个…

Docker安装Prometheus和Grafana

概念简述 安装prometheus 第一步:确保安装有docker 第二步:拉取镜像 第三步:准备相关挂载目录及文件 第四步:启动容器 第五步:访问测试 安装grafana 第一步:确保安装有docker 第二步:拉…

详解GPT-信息抽取任务 (GPT-3 FAMILY LARGE LANGUAGE MODELS)

GPT-3 FAMILY LARGE LANGUAGE MODELS Information Extraction 自然语言处理信息提取任务(NLP-IE):从非结构化文本数据中提取结构化数据,例如提取实体、关系和事件 [164]。将非结构化文本数据转换为结构化数据可以实现高效的数据处…

通过blob请求后端导出文件

后端controller PostMapping("/exportPlanProject2")public void exportActive(RequestBody USER user, HttpServletResponse httpServletResponse) throws IOException {}后端service public void exportExcel2(HttpServletResponse response) throws IOException {…

【跨域】解决SpringBoot和openresty跨域问题

平时后端只需要写一个配置类就可以解决跨域但是最近的新项目死活不行 先说结论 项目中的权限校验(也可以是其他的)拦截器优先级高于跨域拦截器导致跨域处理失效 解决办法 1.在addCorsMappings上增加 Order(value -100)// 跨域优先级最高 2.nginx放行OPTIONS请求 SpringBo…

数据结构9.3 - 文件基础(C++)

目录 1 打开文件字符读写关闭文件 上图源自&#xff1a;https://blog.csdn.net/LG1259156776/article/details/47035583 1 打开文件 法 1法 2ofstream file(path);ofstream file;file.open(path); #include<bits/stdc.h> using namespace std;int main() {char path[]…

k8s基础(3)—Kubernetes-Deployment

一、 Deployment概述 ‌ Kubernetes Deployment‌是Kubernetes中的一个核心概念&#xff0c;它是一种高级别的控制器&#xff0c;用于管理Pod和ReplicaSet&#xff0c;确保应用程序的高可用性和稳定性。Deployment通过声明式配置来创建和更新Pod和ReplicaSet&#xff0c;从而…

JS获取URL中参数值的4种方法

方法1&#xff1a;现代浏览器都支持 URL 和 URLSearchParams 对象&#xff0c;可以很方便地从URL中提取参数 // 假设当前URL为 "https://example.com/?nameJohn&age30" const url new URL(window.location.href); // 或者你可以直接传入一个URL字符串 const n…

ubuntu开启root用户

Ubuntu 启用 root 账户 在 Ubuntu 中&#xff0c;默认情况下 root 账户是被禁用的。为了启用 root 账户&#xff0c;你需要设置 root 用户的密码。以下是如何在 Ubuntu 上启用 root 账户的步骤&#xff1a; 打开终端。 输入以下命令来设置 root 用户的密码&#xff1a; sud…

C#跨窗口传递Halcon图像/参数

Demo目的&#xff0c;图像同步到附属窗口&#xff0c;通过附属窗口各类操作&#xff08;参数设置&#xff0c;ROI重置等&#xff09;简化主界面 本文主要演示图像传递 主界面 附属界面 运行效果 主界面代码 using System; using System.Collections.Generic; using System.C…

JavaScript 随机 数用法

在 JavaScript 中,生成随机数通常是使用 Math.random() 方法。这个方法生成一个伪随机浮点数,范围从 0(包括)到 1(不包括)。以下是一些常见的随机数用法和技巧: 1. 生成一个 [0, 1) 范围内的随机浮点数 let randomNum = Math.random(); console.log(randomNum); // 输

32单片机从入门到精通之开发环境——调试工具(七)

在人生的道路上&#xff0c;困难和挫折时常会出现。但是我们不能因此放弃&#xff0c;而是要坚持努力&#xff0c;克服困难&#xff0c;实现自己的梦想。成功不是一蹴而就的&#xff0c;它需要付出大量的努力和坚持不懈的精神。每一次的失败都是一次宝贵的经验&#xff0c;它能…

查询docker overlay2文件夹下的 c7ffc13c49xxx是哪一个容器使用的

问题背景 查询docker overlay2文件夹下的 c7ffc13c49xxx是哪一个容器使用的 [root@lnops overlay2]# du -sh * | grep G 1.7G 30046eca3e838e43d16d9febc63cc8f8bb3d327b4c9839ca791b3ddfa845e12e 435G c7ffc13c49a43f08ef9e234c6ef9fc5a3692deda3c5d42149d0070e9d8124f71 1.…

LeetCode:700.二叉搜索树中的搜索

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;700.二叉搜索树中的搜索 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你…

美食烹饪互动平台

本文结尾处获取源码。 一、相关技术 后端&#xff1a;Java、JavaWeb / Springboot。前端&#xff1a;Vue、HTML / CSS / Javascript 等。数据库&#xff1a;MySQL 二、相关软件&#xff08;列出的软件其一均可运行&#xff09; IDEAEclipseVisual Studio Code(VScode)Navica…

单片机从入门到放弃教程001

1. 单片机介绍 单片微型计算机(Single Chip Microcomputer)简称单片机&#xff0c;是典型的嵌入式微处理器(Micro Controller Unit简称MCU)&#xff0c;是一种将中央处理器&#xff08;CPU&#xff09;、内存、输入输出接口以及其他功能模块集成在单一芯片上的微型计算机。 1…

2024数据湖架构实践案例(附资料)

2024年数据湖架构的一些实践情况&#xff1a; 技术趋势 湖仓架构融合&#xff1a;湖仓架构的采用在2024年持续发展&#xff0c;它结合了数据湖的可扩展性和数据仓库的分析性能&#xff0c;能够处理多种数据类型和复杂的工作流程&#xff0c;为企业提供更全面的数据视图。例如…