RAG实战指南 Day 24:上下文构建与提示工程

【RAG实战指南 Day 24】上下文构建与提示工程

文章内容

开篇

欢迎来到"RAG实战指南"系列的第24天!今天我们将深入探讨RAG系统中至关重要的上下文构建与提示工程技术。在检索增强生成系统中,如何有效地组织检索到的文档片段,并将其转化为适合大语言模型(LLM)处理的提示,直接决定了最终生成结果的质量。本文将系统讲解上下文构建的最佳实践和高级提示工程技术,帮助您构建更精准、更可靠的RAG应用。

理论基础

关键概念

  1. 上下文窗口:LLM能够同时处理的最大文本长度,不同模型有不同限制
  2. 提示工程:设计输入提示以引导模型产生期望输出的技术
  3. 上下文相关性:检索内容与用户查询的语义匹配程度
  4. 信息密度:单位文本中包含的有价值信息量

核心挑战

  1. 如何从检索结果中选择最具信息量的片段
  2. 如何组织多个文档片段以避免信息冲突
  3. 如何设计提示模板使LLM充分利用上下文
  4. 如何平衡上下文长度和信息密度

技术解析

1. 上下文构建策略
策略名称核心思想适用场景
截断法保留最相关的前N个token简单查询,上下文有限
滑动窗口重叠分块保留边界信息长文档连续信息提取
层次聚合先提取关键句再扩展上下文需要保持文档结构
动态融合根据查询动态重组片段复杂多文档查询
2. 提示工程设计模式
from typing import List, Dict
from pydantic import BaseModelclass Document(BaseModel):content: strmetadata: Dict[str, str]relevance_score: floatclass PromptBuilder:def __init__(self, system_prompt: str):self.system_prompt = system_promptself.context_token_limit = 4000  # 假设模型上下文窗口为4kdef build_prompt(self, query: str, documents: List[Document]) -> str:"""构建RAG提示的核心方法"""# 1. 上下文选择与截断selected_context = self._select_context(documents)# 2. 构建结构化提示prompt = f"""{self.system_prompt}### 背景知识:{selected_context}### 用户问题:{query}### 回答要求:- 仅基于提供的背景知识回答- 如果信息不足请回答"根据现有信息无法确定"- 保持专业、准确的语气"""return promptdef _select_context(self, documents: List[Document]) -> str:"""选择最相关的上下文片段"""# 按相关性排序sorted_docs = sorted(documents, key=lambda x: x.relevance_score, reverse=True)selected_texts = []current_length = 0for doc in sorted_docs:doc_length = len(doc.content.split())  # 简单以词数计算if current_length + doc_length <= self.context_token_limit:selected_texts.append(f"来源: {doc.metadata.get('source', '未知')}\n内容: {doc.content}")current_length += doc_lengthelse:breakreturn "\n\n".join(selected_texts)
3. 高级提示技术
  1. 多轮提示:将复杂问题分解为多个子问题
  2. 自洽性检查:要求模型验证自己的回答
  3. 思维链:引导模型展示推理过程
  4. 模板变量:动态插入上下文片段
class AdvancedPromptBuilder(PromptBuilder):def build_analytic_prompt(self, query: str, documents: List[Document]) -> str:"""构建带有分析过程的提示"""context = self._select_context(documents)prompt = f"""{self.system_prompt}请按照以下步骤分析问题:1. 理解问题: "{query}"2. 分析相关背景知识: {context}3. 逐步推理得出结论4. 验证结论的合理性请按上述步骤给出最终答案,并标注每个步骤的思考过程。"""return promptdef build_multi_turn_prompt(self, conversation: List[Dict], documents: List[Document]) -> str:"""构建多轮对话提示"""context = self._select_context(documents)# 构建对话历史history = "\n".join([f"{msg['role']}: {msg['content']}" for msg in conversation[:-1]])current_query = conversation[-1]['content']prompt = f"""{self.system_prompt}对话历史:{history}当前问题: {current_query}相关背景:{context}请基于以上信息继续对话。"""return prompt

代码实现

完整实现一个支持多种提示策略的RAG上下文处理器:

import re
from typing import List, Optional
from rank_bm25 import BM25Okapiclass ContextProcessor:def __init__(self, chunk_size: int = 500, chunk_overlap: int = 50):self.chunk_size = chunk_sizeself.chunk_overlap = chunk_overlapdef split_text(self, text: str) -> List[str]:"""基础文本分块"""words = text.split()chunks = []start = 0while start < len(words):end = min(start + self.chunk_size, len(words))chunk = " ".join(words[start:end])chunks.append(chunk)start = end - self.chunk_overlapreturn chunksdef rerank_by_query(self, query: str, documents: List[str]) -> List[float]:"""基于查询对文档片段重新排序"""tokenized_docs = [doc.split() for doc in documents]tokenized_query = query.split()bm25 = BM25Okapi(tokenized_docs)scores = bm25.get_scores(tokenized_query)return scoresdef build_context(self,query: str,documents: List[str],strategy: str = "simple",max_length: int = 4000) -> str:"""根据策略构建上下文"""if strategy == "simple":return self._simple_context(query, documents, max_length)elif strategy == "analytical":return self._analytical_context(query, documents, max_length)else:raise ValueError(f"未知策略: {strategy}")def _simple_context(self, query: str, documents: List[str], max_length: int) -> str:"""简单拼接策略"""current_length = 0selected = []for doc in documents:doc_length = len(doc.split())if current_length + doc_length <= max_length:selected.append(doc)current_length += doc_lengthelse:remaining = max_length - current_lengthif remaining > 100:  # 至少保留有意义的片段selected.append(" ".join(doc.split()[:remaining]))breakreturn "\n".join(selected)def _analytical_context(self, query: str, documents: List[str], max_length: int) -> str:"""分析型上下文构建"""# 1. 提取关键句key_sentences = []for doc in documents:sentences = re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s', doc)for sent in sentences:if len(sent.split()) > 10:  # 忽略过短句子key_sentences.append(sent)# 2. 重排序scores = self.rerank_by_query(query, key_sentences)scored_sents = sorted(zip(key_sentences, scores), key=lambda x: x[1], reverse=True)# 3. 构建上下文selected = []current_length = 0for sent, score in scored_sents:sent_length = len(sent.split())if current_length + sent_length <= max_length:selected.append(f"[相关性: {score:.2f}] {sent}")current_length += sent_lengthreturn "\n".join(selected)# 单元测试
if __name__ == "__main__":processor = ContextProcessor()# 测试数据docs = ["深度学习是机器学习的分支,专注于使用深度神经网络。","Transformer模型是当前最先进的NLP架构,基于自注意力机制。","BERT是一种预训练的Transformer模型,广泛用于各种NLP任务。","RAG系统结合了检索和生成技术,提升大语言模型的准确性。"]query = "什么是BERT模型?"print("=== 简单上下文 ===")print(processor.build_context(query, docs, "simple", 100))print("\n=== 分析型上下文 ===")print(processor.build_context(query, docs, "analytical", 150))

案例分析:法律咨询RAG系统

业务场景
为律师事务所构建智能法律咨询系统,需要从大量法律文档中检索相关信息并生成准确回答。

挑战

  1. 法律文本复杂冗长
  2. 需要精确引用相关法条
  3. 回答必须严谨无歧义

解决方案

  1. 使用分析型上下文构建策略
  2. 设计专业法律提示模板
  3. 实现引用溯源功能
class LegalPromptBuilder:def __init__(self):self.system_prompt = """你是一位专业法律AI助手,请严格按照以下要求回答问题:1. 只基于提供的法律条文和判例回答2. 明确标注引用来源(条款号/判例编号)3. 如无明确依据,应回答"需要进一步法律分析"4. 避免任何主观解释或推测"""def build_legal_prompt(self, query: str, contexts: List[Dict]) -> str:"""构建法律专业提示"""context_str = ""for ctx in contexts:context_str += f"【{ctx['source']}{ctx['content']}\n\n"return f"""{self.system_prompt}### 相关法律依据:{context_str}### 咨询问题:{query}### 回答格式要求:1. 法律定性2. 适用条款3. 相关判例(如有)4. 结论"""# 使用示例
if __name__ == "__main__":builder = LegalPromptBuilder()legal_contexts = [{"source": "民法典第584条","content": "当事人一方不履行合同义务或者履行合同义务不符合约定,给对方造成损失的...",},{"source": "(2022)最高法民终123号","content": "关于合同违约金的计算标准,应当综合考虑实际损失和合同履行情况...",}]query = "合同违约后如何计算赔偿金额?"prompt = builder.build_legal_prompt(query, legal_contexts)print(prompt)

优缺点分析

优势

  1. 显著提升生成结果的相关性和准确性
  2. 减少LLM的幻觉问题
  3. 支持复杂问题的分步解答
  4. 可适应不同领域的专业要求

局限性

  1. 提示设计需要领域专业知识
  2. 复杂提示可能增加计算成本
  3. 对上下文质量高度依赖
  4. 需要针对不同模型调整策略

总结

今天我们深入探讨了RAG系统中的上下文构建与提示工程技术:

  1. 学习了多种上下文构建策略及其适用场景
  2. 实现了完整的提示构建器类,支持多种高级技术
  3. 分析了法律咨询系统的实际案例
  4. 讨论了不同技术的优缺点

核心技术要点

  • 上下文选择比数量更重要
  • 结构化提示显著提升生成质量
  • 领域特定的提示设计是关键
  • 多轮和分步提示适合复杂问题

实践建议

  1. 从简单策略开始逐步优化
  2. 针对领域特点定制提示模板
  3. 建立提示版本控制系统
  4. 持续监控生成质量

明天我们将探讨【Day 25: 响应生成策略与幻觉减少】,学习如何优化RAG系统的最终输出质量,减少错误信息生成。

参考资料

  1. Prompt Engineering Guide
  2. Advanced RAG Techniques
  3. LegalAI Applications
  4. Context Management in LLMs

文章标签

RAG, Retrieval-Augmented Generation, Prompt Engineering, Context Management, NLP

文章简述

本文是"RAG实战指南"系列的第24篇,深入讲解检索增强生成系统中的上下文构建与提示工程技术。文章系统介绍了多种上下文组织策略、高级提示设计模式,并提供了完整的Python实现代码。通过法律咨询系统的实际案例,展示了如何将这些技术应用于专业领域。读者将学习到如何优化RAG系统的上下文利用率、设计有效的提示模板,以及平衡信息密度与生成质量。本文内容既有理论深度又有实践价值,提供的代码可直接集成到现有RAG系统中。

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

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

相关文章

AWD的攻击和防御手段

一、AWD相关介绍 AWD&#xff08;Attack With Defence&#xff09;是 CTF 线下赛中最接近真实攻防场景、观赏性和对抗性最强的赛制之一。 赛制本质 人人对抗&#xff1a;所有战队互为攻击者与防守者。 零和记分&#xff1a;你拿到的每一分都是别人的失分&#xff0c;总积分恒…

泛微OA8前台SQL注入

漏洞URL&#xff1a; http://106.15.190.147/js/hrm/getdata.jsp?cmdgetSelectAllId&sql***注入点 在getdata.jsp中&#xff0c;直接将request对象交给 weaver.hrm.common.AjaxManager.getData(HttpServletRequest, ServletContext) : 方法处理 在getData方法中&#xff0…

Android 蓝牙学习

在Android中&#xff0c;进行蓝牙设备扫描startDiscovery需要申请位置权限&#xff0c;但有的时候并不需要申请位置权限&#xff0c;就有了android:usesPermissionFlags"neverForLocation"&#xff0c;设置这个就不用申请位置权限来进行蓝牙扫描。 android:usesPerm…

Earth靶机攻略

一.环境准备 1.1Earth靶机环境准备 首先将我们解压好的的Earth.ova放入虚拟机里&#xff0c;并配置环境 将网络连接换成NET连接 二.信息搜集 2.1ip搜集 2.1.1使用netdiscover命令扫描靶机的ip地址,发现地址为192.168.182.137 2.2端口扫描 2.2.1使用nmap工具对目标机进行端…

java8 List常用基本操作(去重,排序,转换等)

参考简述网址: java8 List 根据对象某个字段或多个字段去重、筛选、List转Map、排序、分组、统计计数等等 list简单方法示例如下&#xff1a; 一、先定义一个订单对象&#xff08;Order&#xff09; public class Order {private Long id;private Long userId;private Strin…

【linux】HAProxy七层代理

HAPorxy简介HAProxy&#xff08;High Availability Proxy&#xff09;是一款高性能、开源的负载均衡器与反向代理服务器&#xff0c;主要用于 TCP 和 HTTP 协议的流量分发&#xff0c;广泛应用于高并发、高可用的网络架构中核心特性超高性能与低资源消耗基于单进程、多线程模型…

Android 的16 KB内存页设备需要硬件支持吗,还是只需要手机升级到Android15系统就可以

Android 的16 KB内存页设备需要硬件支持吗&#xff0c;还是只需要手机升级到Android15系统就可以&#xff1f; deepseek回答&#xff1a; DeepSeek R1 思考 3 秒 思考过程 好的&#xff0c;用户现在问的是Android的16 KB内存页设备是否需要硬件支持&#xff0c;还是只需要升级到…

相机内外参矩阵:从3D世界坐标到2D像素坐标变换

相机内外参矩阵&#xff1a;从3D世界坐标到2D像素坐标变换介绍**1. 内参矩阵&#xff08;Intrinsic Matrix, K&#xff09;****2. 外参矩阵&#xff08;Extrinsic Matrix, [R|t]&#xff09;****3. 完整投影过程&#xff08;世界坐标 → 像素坐标&#xff09;****步骤1&#xf…

哈希指针与数据结构:构建可信数字世界的基石

一、哈希指针的核心原理哈希指针是一种创新型数据结构&#xff0c;融合了传统指针的定位功能与密码学哈希的验证能力&#xff1a;双重功能&#xff1a;既存储数据地址&#xff0c;又包含该数据的哈希值&#xff0c;实现数据定位与完整性验证的统一。抗篡改机制&#xff1a;数据…

java实现一个方法,isTure则程序继续往下,为false则return的链式写法

以下是实现链式条件检查的Java方法&#xff0c;采用函数式风格设计。代码包含一个Chainable类&#xff0c;支持连续的check方法和多个终止操作&#xff08;如then, orElse等&#xff09;&#xff0c;满足在条件为false时中断链式调用并返回默认值的需求&#xff1a;import java…

数据结构学习之堆

本篇我们将学习新的数据结构——二叉树。 作者的个人gitee&#xff1a;楼田莉子 (riko-lou-tian) - Gitee.com 目录 树的概念 树形结构 非树形结构 树的相关术语 树的表示 树在实际生活上的应用 二叉树 慢二叉树 完全二叉树 二叉树的储存结构 二叉树的存储结构 顺序结构…

【csdn问答社区分析】前端开发热点问题全解析

前端时间我在csdn问答社区的前端部分"视察”了一圈发现了大家的问题主要集中在以下方面一、框架与组件库使用问题 Vue相关问题 组件化开发&#xff1a;如avue-crud组件自定义样式不生效、el-select大数据分页懒加载、element-plus表格动态列校验等。功能实现&#xff1a;包…

Pycharm2025 安装教程 免费分享 没任何套路

Pycharm 安装也是很简单的&#xff0c;简单过一下流程&#xff0c;如果需要的可以转存下载到自己电脑上。我用夸克网盘分享了「pycharm2025」&#xff0c;复制链接浏览器打开转存后即可下载。链接&#xff1a;https://pan.quark.cn/s/4bb74a939332备注&#xff1a;附带2023-202…

Javaweb————什么是超文本传输协议?

&#x1f3cd;️&#x1f3cd;️&#x1f3cd;️引言&#xff1a;什么是协议&#xff1f; 协议是一种约定&#xff0c;规定好一种信息的格式&#xff0c;如果发送方按照这种请求格式发送信息,那么接 收端就要按照这样的格式解析数据,否则就会出错&#xff0c;这就是协议 常用协…

UniappDay03

1.热门推荐-准备工作// 用defineProps获取页面参数,query const query defineProps<{type: string }>() const currHot hotMap.find((v) > v.type query.type) // 动态设置标题 uni.setNavigationBarTitle({ title: currHot!.title }) </script>2.获取热门推…

基于动态增强的 LLM 置信度方法研究

基于动态增强的 LLM 置信度方法研究 一、引言(Introduction) 大型语言模型(LLM)的性能提升高度依赖于对模型内部表征的精准调控 —— 表征工程通过优化模型中间层隐藏状态的传递规律,能够在不改变模型参数的前提下显著提升任务适应性(Wei et al., 2022)。当前主流方法中…

ComfyUI中运行Wan 2.1工作流,电影级视频,兼容Mac Windows

魔当(LM Downloader)是一个大模型应用下载工具 &#xff0c;目前 魔当 已经支持ComfyUI下载Wan 2.1视频模型。 魔当下载地址 https://seemts.com/ 先看生成效果 原始图片&#xff0c;你可以保存到自己电脑上测试 生成视频&#xff1a; 推荐提示词&#xff1a; A futurist…

CentOS 7 Linux 用 yum 安装 Docker,含 Docker 镜像无法拉取问题(即 docker pull 失败)的解决方案

CentOS 7 Linux 用 yum 安装 Docker,含 Docker 镜像无法拉取问题(即 docker pull 失败)的解决方案 本文对应的讲解视频链接:https://www.bilibili.com/video/BV1C48wzqE6T/ 文章目录 CentOS 7 Linux 用 yum 安装 Docker,含 Docker 镜像无法拉取问题(即 docker pull 失败…

XML的简略知识点

文章目录1. 基本概念2. 基本语法3. 示例4. 相关技术5. 应用场景XML&#xff08;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言&#xff0c;核心特点是可扩展性和自我描述性。以下是其核心知识点&#xff1a; 1. 基本概念 用途&#xff1a;主要用于数据的存储…

RustDesk 完整部署教程:支持 Web 管理后台和网页客户端远程,保姆级教学来了!

RustDesk API本项目使用 Go 实现了 RustDesk 的 API&#xff0c;并包含了 Web Admin 和 Web 客户端。RustDesk是一个远程桌面软件&#xff0c;提供了自托管的解决方案&#xff0c;官方API是收费的&#xff0c;这次咱们用到的是Github开源的第三方API源码。✅特性PC端API支持 …