当前位置: 首页 > news >正文

7种RAG查询预处理方案详解:告别检索效果差,提升回复质量!

本文深入探讨了RAG系统中查询预处理的重要性,系统梳理了7种查询预处理方案,包括Passthrough、规则/统计方法、小模型NER+关键词提取、LLM查询改写、HyDE、Multi-Query和Step-Back Prompting,详细阐述了每种方案的原理、关键细节和提示词设计。通过合理的查询预处理,可以有效提升RAG系统的检索效果和回复质量,为用户带来更精准、更智能的问答体验。


你的 RAG 系统检索效果不好?80% 的原因出在查询预处理上。本文系统梳理 7 种查询预处理方案,重点讲清原理、关键细节和提示词设计。


一、为什么查询预处理如此重要?

在 RAG 系统中,有一个被大多数人忽略的关键环节——「查询预处理(Query Preprocessing)」

看一个典型场景:

用户:什么是 Transformer?助手:Transformer 是一种基于自注意力机制的神经网络架构……用户:它和 RNN 有什么区别?

最后一句"它和 RNN 有什么区别?"——如果直接拿这句话去向量数据库检索,「向量数据库完全不知道"它"指的是 Transformer」,检索结果大概率跑偏。

查询预处理要解决的核心问题就是:「将用户的原始查询转化为更适合检索的形式。」

一个好的查询预处理,可以将检索的「Recall@10 提升 15%~40%」,直接决定最终回答的质量。


二、查询预处理的整体架构

┌──────────────┐│ 用户提问 │└──────┬───────┘ ↓┌──────────────────────────┐│ 第一层:查询预处理 │ ← 本文重点│ 查询改写/意图识别/查询扩展 │└──────────┬───────────────┘ ↓┌──────────────────────────┐│ 第二层:向量检索(粗排) │└──────────┬───────────────┘ ↓┌──────────────────────────┐│ 第三层:精排 Reranker │└──────────┬───────────────┘ ↓┌──────────────────────────┐│ 第四层:LLM 生成回答 │└──────────────────────────┘

在深入各方案之前,先看一下接口抽象。不管用哪种方案,对外暴露的接口应该是统一的:

// Enhancer 查询增强器接口type Enhancer interface { EnhanceQuery(ctx context.Context, req *Request) (*Enhanced, error)}type Request struct { Query string // 用户当前查询 History []Message // 对话历史}type Enhanced struct { Enhanced string // 增强后的查询 Keywords []string // 提取的关键词}

有了统一接口,不同方案可以自由切换和组合。接下来逐一剖析。


三、方案一:Passthrough(直接透传)

原理

最简单的方案——「什么都不做」,直接把用户的原始查询传给检索模块。

用户查询: "Go语言怎么做依赖注入?" ↓检索查询: "Go语言怎么做依赖注入?" (原封不动)

关键实现

type PassthroughEnhancer struct{}func (p *PassthroughEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { return &Enhanced{ Enhanced: req.Query, Keywords: []string{req.Query}, }, nil}

适用场景

  • 「单轮对话」,用户查询本身完整、自包含
  • 「MVP 快速上线」,先跑通 RAG 全流程
  • 「成本敏感」,不愿为每次查询额外调用模型
  • ❌ 多轮对话,口语化查询

一句话总结

零延迟、零成本、零依赖,但完全依赖用户输入质量。适合作为起步方案和降级兜底。


四、方案二:规则/统计方法(Rule-Based)

原理

通过预定义的规则和统计方法对查询进行预处理:

原始查询: "请问一下 trasformer 的 self atention 机制是怎么运作的呢?" ↓ 停用词移除 → "trasformer self atention 机制 运作" ↓ 拼写纠错 → "transformer self attention 机制 运作" ↓ 同义词扩展 → keywords: ["transformer", "self-attention", "自注意力", "机制"]

四个核心操作:

  1. 「停用词移除」——去掉"的"、“了”、"请问"等无意义词
  2. 「同义词扩展」——将"ML"扩展为"Machine Learning"
  3. 「拼写纠错」——将"Trasformer"纠正为"Transformer"
  4. 「词干提取」——将"running"还原为"run"(英文场景)

关键实现

核心数据结构就是两张表——停用词表和同义词表:

type RuleBasedEnhancer struct { stopWords map[string]bool // 停用词表 synonyms map[string][]string // 同义词映射}func (e *RuleBasedEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { tokens := tokenize(req.Query) // 1. 移除停用词 filtered := make([]string, 0, len(tokens)) for _, t := range tokens { if !e.stopWords[strings.ToLower(t)] { filtered = append(filtered, t) } } // 2. 同义词扩展(扩充关键词列表,不改变主查询) keywords := make([]string, 0) for _, t := range filtered { keywords = append(keywords, t) if syns, ok := e.synonyms[strings.ToLower(t)]; ok { keywords = append(keywords, syns...) } } return &Enhanced{ Enhanced: strings.Join(filtered, " "), Keywords: keywords, }, nil}

「关键细节:同义词表的维护策略」

同义词表不是随便写的,需要按优先级分层:

层级来源示例
通用缩写行业通用k8s→kubernetes,db→database
领域术语业务知识库DI→dependency injection→依赖注入
口语映射用户行为日志挂了→服务不可用,卡了→性能问题

适用场景

  • ✅ 有明确的行业术语/缩写词表
  • ✅ 延迟要求极高(<1ms)
  • ✅ 搜索引擎式关键词匹配场景
  • ❌ 无法处理语义理解、多轮上下文

一句话总结

延迟极低、可控性强、可解释,但需要人工维护词表,无法处理复杂语义。


五、方案三:基于小模型的 NER + 关键词提取

原理

使用轻量 NLP 模型从查询中提取结构化信息:

原始查询: "谷歌在2017年提出的Transformer架构是怎么处理长序列问题的?" ↓ NER 实体提取 实体: [谷歌(ORG), 2017(DATE), Transformer(TECH)] ↓ 关键词提取 + TF-IDF 排序 关键词: ["Transformer", "长序列", "架构"] ↓ 组合 增强查询: "Transformer架构 长序列处理"

两个核心任务:

  1. 「命名实体识别(NER)」——提取人名、组织名、技术名词等实体
  2. 「关键词提取」——用 TF-IDF 或词性标注识别最重要的术语

关键实现

Go 中常用 jieba 分词 + 词性标注来实现:

type NERKeywordEnhancer struct { segmenter *gojieba.Jieba idf map[string]float64}func (e *NERKeywordEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { // 分词 + 词性标注 words := e.segmenter.Tag(req.Query) // 只保留名词(n)、专有名词(nr/ns/nt)、英文(eng) keywords := make([]string, 0) for _, w := range words { word, pos, _ := strings.Cut(w, "/") if strings.HasPrefix(pos, "n") || pos == "eng" { keywords = append(keywords, word) } } // TF-IDF 排序,保留 Top-5 sort.Slice(keywords, func(i, j int) bool { return e.idf[keywords[i]] > e.idf[keywords[j]] }) iflen(keywords) > 5 { keywords = keywords[:5] } return &Enhanced{ Enhanced: strings.Join(keywords, " "), Keywords: keywords, }, nil}

「关键细节:词性过滤规则」

不是所有词性都有检索价值,经验上保留的词性标签:

保留词性说明
n/nr/ns/nt名词、人名、地名、机构名
eng英文词(通常是技术术语)
vn动名词(如"编程"、“部署”)
v/d/p/c/u动词、副词、介词、连词、助词

适用场景

  • ✅ 混合检索(关键词检索 + 向量检索)
  • ✅ 延迟可接受 10~50ms
  • ✅ 可离线部署,不依赖外部 API
  • ❌ 无法处理多轮上下文和深度语义理解

一句话总结

低延迟可离线,适合从查询中提取结构化信息辅助检索,但语义理解能力有限。


六、方案四:LLM 查询改写(Query Rewriting)⭐

这是当前**「最主流」**的方案,重点讲。

原理

将用户的**「对话历史」「当前查询」发给 LLM,LLM 理解上下文后输出一个「独立的、适合检索的查询」**。

对话历史: 用户: 什么是 Transformer? 助手: Transformer 是一种基于自注意力机制的神经网络架构... 用户: 它和 RNN 有什么区别? ↓ [LLM 查询改写] ↓改写结果: "Transformer架构与RNN循环神经网络的区别对比"

🔑 提示词设计(核心)

提示词是这个方案的灵魂。设计要点:

「System Prompt」——定义角色和规则:

你是一个查询改写助手。你的任务是将用户的对话式查询改写为适合向量数据库检索的独立查询。规则:1. 改写后的查询必须是独立的,不依赖对话上下文即可理解2. 解析所有指代词("它"、"这个"、"那个"等),替换为具体名词3. 保留关键技术术语,不要过度简化4. 改写结果应该是一个陈述性的短语或短句,不要用疑问句5. 如果当前查询已经足够明确,保持原样即可,不要过度改写6. 只输出改写后的查询,不要解释

「User Prompt」——动态构建:

对话历史:用户:什么是 gRPC?助手:gRPC 是 Google 开发的高性能 RPC 框架...当前查询:它支持哪些语言?请改写上述查询。

「为什么提示词要这样写?几个关键细节:」

  1. 「“陈述性短语,不要疑问句”」——向量数据库中的文档是陈述性的,用陈述句检索相似度更高
  2. 「“不要过度改写”」——有些 LLM 会把简单查询"润色"得面目全非,反而降低检索效果
  3. 「“只输出改写后的查询”」——避免 LLM 输出"好的,改写结果如下:…"这类废话
  4. 「Temperature 设为 0」——查询改写需要确定性输出,不需要创造性

关键实现

const queryRewriteSystemPrompt = `你是一个查询改写助手。你的任务是将用户的对话式查询改写为适合向量数据库检索的独立查询。规则:1. 改写后的查询必须是独立的,不依赖对话上下文即可理解2. 解析所有指代词("它"、"这个"、"那个"等),替换为具体名词3. 保留关键技术术语,不要过度简化4. 改写结果应该是一个陈述性的短语或短句,不要用疑问句5. 如果当前查询已经足够明确,保持原样即可,不要过度改写6. 只输出改写后的查询,不要解释示例:对话历史:用户:什么是 gRPC?助手:gRPC 是 Google 开发的高性能 RPC 框架...当前查询:它支持哪些语言?改写结果:gRPC 支持的编程语言列表`type LLMQueryRewriter struct { client LLMClient model string}func (r *LLMQueryRewriter) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { prompt := r.buildUserPrompt(req) resp, err := r.client.ChatCompletion(ctx, &ChatRequest{ Model: r.model, Messages: []Message{ {Role: "system", Content: queryRewriteSystemPrompt}, {Role: "user", Content: prompt}, }, MaxTokens: 200, // 改写查询不需要太长 Temperature: 0.0, // 确定性输出 }) if err != nil { // 降级:返回原始查询,不要让预处理失败阻断整个流程 return &Enhanced{Enhanced: req.Query, Keywords: []string{req.Query}}, nil } enhanced := strings.TrimSpace(resp.Content) return &Enhanced{Enhanced: enhanced, Keywords: extractKeywords(enhanced)}, nil}func (r *LLMQueryRewriter) buildUserPrompt(req *Request) string { var sb strings.Builder iflen(req.History) > 0 { sb.WriteString("对话历史:\n") for _, msg := range req.History { role := "用户" if msg.Role == "assistant" { role = "助手" } sb.WriteString(fmt.Sprintf("%s:%s\n", role, msg.Content)) } sb.WriteString("\n") } sb.WriteString(fmt.Sprintf("当前查询:%s\n\n请改写上述查询。", req.Query)) return sb.String()}

模型选择

查询改写任务**「不需要大模型」**,7B~8B 的轻量模型完全够用:

模型延迟成本推荐度
GPT-4o-mini~300ms~$0.0001/次⭐⭐⭐⭐⭐
DeepSeek-V3~400ms~$0.0001/次⭐⭐⭐⭐⭐
Qwen2.5-7B(自部署)~100ms自部署成本⭐⭐⭐⭐

适用场景

  • 「多轮对话」(必须方案)
  • ✅ 口语化查询、跨语言检索
  • ❌ 超低延迟场景(200~500ms 额外延迟)
  • ❌ 完全离线环境

一句话总结

效果最好的通用方案,多轮对话的刚需。注意降级策略和 Temperature 设为 0。


七、方案五:HyDE(假想文档嵌入)

原理

HyDE(Hypothetical Document Embedding)由 CMU 在 2022 年提出,思路非常巧妙:

「不直接用查询去检索,而是先让 LLM 生成一个"假想的回答文档",用这个假想文档的 Embedding 去检索真实文档。」

用户查询: "Go语言怎么做依赖注入?" ↓ LLM 生成假想回答假想文档: "在Go语言中,依赖注入通常通过构造函数参数传递来实现。 常见模式包括:构造函数注入、Functional Options 模式、 Wire 框架的编译时注入、接口驱动设计……" ↓ 对假想文档做 Embedding ↓ 用该向量检索真实文档

「为什么有效?」

向量空间中,「"问题"和"回答"的向量距离通常较远」。用问题向量检索回答文档,天然存在语义鸿沟:

向量空间: 问题向量 ● ↗ ↖ (距离远)真实文档A ● ● 真实文档B ↑(距离近)假想文档 ● ← 用这个向量检索,和真实文档天然更近

假想文档本身就是"回答"的形式,它的向量和知识库中的真实文档向量天然更接近。

🔑 提示词设计(核心)

HyDE 的提示词有两个关键要求:

  1. 「生成的内容要像一篇文档片段」,而不是对话式回答
  2. 「要尽量覆盖相关术语」,因为最终目的是用 Embedding 做检索
请针对以下问题,写一段专业的技术文档片段。要求:1. 直接给出内容,不要包含"根据"、"以下是"等引导语2. 尽量覆盖相关的技术术语和概念3. 内容格式应该像知识库中的文档,而不是聊天回答4. 长度控制在 150~200 字问题:{query}

「关键细节:为什么要强调"像文档而不是聊天回答"?」

因为你的知识库里存的是文档,如果假想文档的语体是"首先我来给你解释一下……",它的 Embedding 会偏向对话风格,反而和文档的距离变远。

关键实现

type HyDEEnhancer struct { llmClient LLMClient model string}func (h *HyDEEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { hypoDoc, err := h.generateHypotheticalDoc(ctx, req.Query) if err != nil { return &Enhanced{Enhanced: req.Query, Keywords: []string{req.Query}}, nil } // 返回假想文档作为增强查询,后续 Retriever 会对它做 Embedding 并检索 return &Enhanced{Enhanced: hypoDoc, Keywords: extractKeywords(hypoDoc)}, nil}func (h *HyDEEnhancer) generateHypotheticalDoc( ctx context.Context, query string,) (string, error) { prompt := fmt.Sprintf(`请针对以下问题,写一段专业的技术文档片段。要求:1. 直接给出内容,不要包含"根据"、"以下是"等引导语2. 尽量覆盖相关的技术术语和概念3. 内容格式应该像知识库中的文档,而不是聊天回答4. 长度控制在 150~200 字问题:%s`, query) resp, err := h.llmClient.ChatCompletion(ctx, &ChatRequest{ Model: h.model, Messages: []Message{ {Role: "user", Content: prompt}, }, MaxTokens: 300, Temperature: 0.7, // 稍高温度,覆盖更多术语 }) if err != nil { return"", fmt.Errorf("generate hypothetical document: %w", err) } return strings.TrimSpace(resp.Content), nil}

「注意 Temperature 设为 0.7」——和查询改写不同,这里希望生成的内容更丰富、覆盖更多术语,所以温度稍高。

适用场景

  • 「简短查询」——用户只输入几个词,但需要匹配长文档
  • 「专业领域」——用户查询和文档之间存在术语鸿沟
  • ❌ 实时性要求高(500ms~2s 延迟)
  • ❌ LLM 幻觉敏感场景(假想文档可能包含错误信息)

一句话总结

巧妙地用"假想回答"弥补问题和文档之间的语义鸿沟,对简短查询效果显著。注意提示词要强调"像文档不像聊天"。


八、方案六:Multi-Query(多查询扩展)

原理

核心思路:「一个问题从不同角度生成多个查询变体」,分别检索后用排序融合算法合并结果。

原始查询: "如何优化 Go 程序的内存使用?" ↓ LLM 生成多个变体┌─────────────────────────────────────┐│ 变体1: "Go语言内存优化最佳实践" ││ 变体2: "Golang 减少内存分配和GC压力" ││ 变体3: "Go内存泄漏排查和pprof使用" ││ 变体4: "Go sync.Pool对象池内存复用" │└─────────────────┬───────────────────┘ ↓ 分别检索 → RRF 融合排序 → 更全面的结果

🔑 提示词设计(核心)

Multi-Query 的提示词有一个核心要求——「变体之间要有差异化」,不能换个措辞说同一件事:

请从不同角度改写以下查询,生成 4 个搜索查询变体。原始查询:{query}要求:1. 每行一个查询变体,不要编号2. 每个变体必须是独立的、完整的查询3. 变体之间要有明确的角度差异,例如: - 概念解释角度 - 实现方法角度 - 最佳实践角度 - 常见问题/排错角度4. 不要只是换个措辞说同一件事5. 只输出查询变体,不要其他内容

「关键细节:"不要只换措辞"这条为什么重要?」

如果 4 个变体只是同义改写(“优化内存”、“减少内存”、“内存性能调优”、“内存管理优化”),它们检索到的文档高度重叠,Multi-Query 就退化成了普通查询改写,白白多花了 4 倍检索成本。

RRF 排序融合算法

Multi-Query 的检索结果需要用「Reciprocal Rank Fusion(RRF)」合并:

公式:RRF_score(doc) = Σ 1/(k + rank_i) 其中 k 通常取 60示例(3 个查询变体):查询1排序: [文档A, 文档B, 文档C]查询2排序: [文档C, 文档A, 文档E]查询3排序: [文档A, 文档E, 文档C]文档A: 1/(60+0) + 1/(60+1) + 1/(60+0) = 0.0498 ← 排第1文档C: 1/(60+2) + 1/(60+0) + 1/(60+2) = 0.0489 ← 排第2文档E: 0 + 1/(60+2) + 1/(60+1) = 0.0325 ← 排第3

关键实现

type MultiQueryEnhancer struct { llmClient LLMClient model string numQueries int}func (m *MultiQueryEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { variants, err := m.generateVariants(ctx, req.Query) if err != nil { return &Enhanced{Enhanced: req.Query, Keywords: []string{req.Query}}, nil } // 原始查询 + 变体 allQueries := append([]string{req.Query}, variants...) return &Enhanced{ Enhanced: strings.Join(allQueries, "\n"), Keywords: dedup(extractAllKeywords(allQueries)), }, nil}// RRF 融合排序(配合 Retriever 使用)func rrfFusion(results [][]Document, k int) []Document { scores := make(map[string]float64) docs := make(map[string]Document) for _, ranking := range results { for rank, doc := range ranking { scores[doc.ID] += 1.0 / float64(k+rank) docs[doc.ID] = doc } } // 按 RRF 分数降序排列 type scored struct { doc Document score float64 } sorted := make([]scored, 0, len(docs)) for id, doc := range docs { sorted = append(sorted, scored{doc: doc, score: scores[id]}) } sort.Slice(sorted, func(i, j int) bool { return sorted[i].score > sorted[j].score }) result := make([]Document, len(sorted)) for i, s := range sorted { result[i] = s.doc } return result}

适用场景

  • 「高召回率要求」——不能漏掉任何相关文档
  • 「复杂问题」——涉及多个维度和子主题
  • ❌ 实时对话(总延迟 1~3s)
  • ❌ 成本敏感(多次 LLM 调用 + 多次检索)

一句话总结

召回率最高的方案,但延迟和成本也最高。提示词的关键是确保变体之间有真正的角度差异。


九、方案七:Step-Back Prompting(后退提示)

原理

由 Google DeepMind 在 2023 年提出,核心思路:

「不直接检索具体问题,而是先"后退一步",将问题抽象为更高层次的概念性问题,用抽象问题检索背景知识,再结合原始问题检索具体细节。」

原始查询(具体): "gRPC-Go 中如何实现双向流式 RPC?" ↓ Step-Back 抽象抽象查询(通用): "gRPC 流式通信的类型和实现模式" ↓ 用抽象查询检索 → 背景知识(流式 RPC 的四种类型、原理) 用原始查询检索 → 具体细节(Go 代码实现) ↓ 合并两组结果,LLM 同时拿到背景和细节来回答

🔑 提示词设计(核心)

Step-Back 的提示词需要精确控制"后退"的粒度——太粗会检索到不相关的内容,太细等于没后退:

你是一个搜索专家。给定一个具体的技术问题,请"后退一步",生成一个更高层次的概念性问题,用于检索回答原始问题所需的背景知识。规则:1. 抽象问题应该覆盖原始问题所属的知识领域2. 保留核心主题,不要太笼统("什么是编程?"就太笼统了)3. 只输出一个问题,不要解释示例:具体问题:Python 3.12 中 type 语句的语法是什么?抽象问题:Python 类型系统和类型注解的语法特性具体问题:React useEffect 的依赖数组为空时会怎样?抽象问题:React Hooks 中 useEffect 的生命周期和依赖机制具体问题:{query}抽象问题:

「关键细节:为什么要给示例?」

Step-Back 的"后退粒度"很难用规则描述清楚,但「few-shot 示例可以隐式传达粒度标准」。示例中"Python 3.12 type 语句 → Python 类型系统"就是一个恰到好处的后退——退到了所属知识领域,但没退到"什么是 Python"。

关键实现

type StepBackEnhancer struct { llmClient LLMClient model string}func (s *StepBackEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { abstractQuery, err := s.generateStepBack(ctx, req.Query) if err != nil { return &Enhanced{Enhanced: req.Query, Keywords: []string{req.Query}}, nil } // 同时返回原始查询和抽象查询,后续分别检索再合并 combined := req.Query + "\n" + abstractQuery keywords := dedup(append( extractKeywords(req.Query), extractKeywords(abstractQuery)..., )) return &Enhanced{Enhanced: combined, Keywords: keywords}, nil}

适用场景

  • ✅ **「需要背景知识才能回答」**的问题
  • 「教程/文档检索」——知识库中有概念文档和实操文档
  • ❌ 简单直接的事实性问题("Go 的 goroutine 上限是多少?"不需要后退)

一句话总结

通过"后退一步"检索背景知识,让回答更有深度。提示词的关键是用 few-shot 示例控制后退粒度。


十、方案对比总结

全维度对比

维度Passthrough规则方法小模型NERLLM改写HyDEMulti-QueryStep-Back
「延迟」0ms<1ms10-50ms200-500ms0.5-2s1-3s300-600ms
「成本」免费免费中高
「精度提升」很高最高
「多轮支持」⚠️
「实现复杂度」极低

选型决策树

你的场景是什么?│├─ 单轮 + 查询质量高? → Passthrough├─ 有多轮对话? → LLM 查询改写(必须)│ ├─ 还需要更高召回率?→ + Multi-Query│ └─ 术语鸿沟大? → + HyDE├─ 延迟要求 < 10ms? → 规则方法├─ 延迟要求 < 50ms? → 小模型 NER└─ 需要背景知识? → Step-Back + LLM 改写

十一、实战建议

从简单开始,逐步升级

  1. 「MVP 阶段」:Passthrough,跑通全流程
  2. 「优化阶段」:加入 LLM 查询改写
  3. 「精细化阶段」:按需引入 HyDE / Multi-Query

降级策略是必须的

任何使用外部模型的方案,都**「必须」**有降级处理。LLM 挂了不能让整个 RAG 挂:

func (r *LLMQueryRewriter) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { result, err := r.callLLM(ctx, req) if err != nil { log.WarnfContext(ctx, "LLM rewrite failed, falling back: %v", err) return r.fallback.EnhanceQuery(ctx, req) // 降级到规则方法或 Passthrough } return result, nil}

缓存可以大幅降低成本

对于重复查询,缓存改写结果可以同时省时间和省钱:

type CachedEnhancer struct { inner Enhancer cache *lru.Cache}func (c *CachedEnhancer) EnhanceQuery( ctx context.Context, req *Request,) (*Enhanced, error) { key := buildCacheKey(req) if cached, ok := c.cache.Get(key); ok { return cached.(*Enhanced), nil } result, err := c.inner.EnhanceQuery(ctx, req) if err != nil { returnnil, err } c.cache.Add(key, result) return result, nil}

提示词设计的通用原则

回顾全文,各方案的提示词有一些共性原则:

原则说明反例
「限制输出格式」“只输出改写结果,不要解释”LLM 输出"好的,改写如下:…"
「给 few-shot 示例」示例比规则描述更直观只写规则不给示例,LLM 理解偏差
「明确边界」“如果已经足够明确,保持原样”LLM 过度改写简单查询
「控制温度」改写用 0,生成用 0.7改写用高温度导致不稳定
「匹配目标形式」HyDE 要"像文档",改写要"陈述句"HyDE 生成对话式回答

十二、写在最后

查询预处理是 RAG 系统中被严重低估的环节。很多团队花大量时间调优 Embedding 模型和 Reranker,却忽略了最前面的查询预处理。

「记住一句话:Garbage In, Garbage Out。」

如果查询本身有问题,后面的检索和排序做得再好也无济于事。

选择适合你场景的方案,从简单开始,逐步优化——这才是 RAG 优化的正确姿势。

最后唠两句

为什么AI大模型成为越来越多程序员转行就业、升职加薪的首选

很简单,这些岗位缺人且高薪

智联招聘的最新数据给出了最直观的印证:2025年2月,AI领域求职人数同比增幅突破200% ,远超其他行业平均水平;整个人工智能行业的求职增速达到33.4%,位居各行业榜首,其中人工智能工程师岗位的求职热度更是飙升69.6%。

AI产业的快速扩张,也让人才供需矛盾愈发突出。麦肯锡报告明确预测,到2030年中国AI专业人才需求将达600万人,人才缺口可能高达400万人,这一缺口不仅存在于核心技术领域,更蔓延至产业应用的各个环节。

那0基础普通人如何学习大模型 ?

深耕科技一线十二载,亲历技术浪潮变迁。我见证那些率先拥抱AI的同行,如何建立起效率与薪资的代际优势。如今,我将积累的大模型面试真题、独家资料、技术报告与实战路线系统整理,分享于此,为你扫清学习困惑,共赴AI时代新程。

我整理出这套 AI 大模型突围资料包【允许白嫖】:

  • ✅从入门到精通的全套视频教程
  • ✅AI大模型学习路线图(0基础到项目实战仅需90天)
  • ✅大模型书籍与技术文档PDF
  • ✅各大厂大模型面试题目详解
  • ✅640套AI大模型报告合集
  • ✅大模型入门实战训练

这份完整版的大模型 AI 学习和面试资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

①从入门到精通的全套视频教程

包含提示词工程、RAG、Agent等技术点

② AI大模型学习路线图(0基础到项目实战仅需90天)

全过程AI大模型学习路线

③学习电子书籍和技术文档

市面上的大模型书籍确实太多了,这些是我精选出来的

④各大厂大模型面试题目详解

⑤640套AI大模型报告合集

⑥大模型入门实战训练

如果说你是以下人群中的其中一类,都可以来智泊AI学习人工智能,找到高薪工作,一次小小的“投资”换来的是终身受益!

应届毕业生‌:无工作经验但想要系统学习AI大模型技术,期待通过实战项目掌握核心技术。

零基础转型‌:非技术背景但关注AI应用场景,计划通过低代码工具实现“AI+行业”跨界‌。

业务赋能 ‌突破瓶颈:传统开发者(Java/前端等)学习Transformer架构与LangChain框架,向AI全栈工程师转型‌。

👉获取方式:
有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

http://www.jsqmd.com/news/658353/

相关文章:

  • 腾讯AI 应用开发 面经,一次过
  • Unity游戏窗口自定义:实现标题栏与边框的动态控制
  • PyCharm里用pip装Seaborn总失败?试试这3种更稳的安装方式(含Anaconda对比)
  • 为什么会选择美国洛杉矶代理IP来做TikTok业务?
  • 超详细!Hermes Agent 一键部署全流程指南,轻松上手不踩坑
  • 接口返回blob,如何实现小程序下载
  • 告别Batch Size焦虑:用PyTorch手把手实现Group Normalization(附完整代码)
  • 如何获取并定制化订货系统源码以适应企业需求?
  • Java转大模型,8个月上岸
  • HPH构造一看就懂!核心部件和工作原理
  • 2026国产适合企业的Ai智能体平台选型推荐:架构师视角下的非侵入式集成与提效避坑指南
  • 一份就懂的PyOpenGL实战指南,从零到一构建3D小游戏!
  • ESP32编译固件内存信息解读
  • **剪枝模型实战:用Python实现轻量化神经网络优化,从理论到代码全解析**
  • OpenClaw为何疯狂“吃”Token?
  • 有赞对接金蝶云星空全链路技术解决方案
  • ceph的monitor集群和osd集群
  • Siemens 6DS1311-8AE 总线驱动
  • 鱼眼双目测距实战:从OpenCV标定到SGBM匹配的完整流程解析
  • Vue 3 技术演进全景
  • 你的游戏本性能被锁定了吗?解锁秘籍来了!
  • 地图开发避坑指南:手把手教你合法合规地使用第三方瓦片服务(高德/百度/腾讯)
  • 5款常用的漏洞扫描工具,网安人员不能错过!
  • 从理论到实践:基于MATLAB的TCPA与DCPA算法实现与避碰应用
  • 从RNN到Transformer:为什么相对位置编码对长文本任务(如翻译、摘要)更友好?
  • 智能代码生成数据构建实战手册(含GPT-4o/CodeLlama双基准验证数据集)
  • 从游戏地图到无人驾驶:Opendrive格式如何成为高精地图的“通用语言”?
  • M12连接器的工作原理:如何在极端环境下保证信号零丢失
  • 保姆级教程:用RV1126开发板+EASY-EAI-Toolkit,30分钟搞定一个RTSP网络摄像头
  • 终极GIMP批量图像处理插件BIMP完全指南:免费自动化解决方案