网站的域名都有哪些重庆网站优化公司怎么样
2026/2/19 6:08:54 网站建设 项目流程
网站的域名都有哪些,重庆网站优化公司怎么样,wordpress 安装不了,人才市场招聘网站公司年报智能问答比赛任务简介 比赛的任务是基于公司年度报告构建一个问答系统。简单来说#xff0c;比赛当天的流程如下#xff1a; 我们会收到来自随机挑选公司的 100 份年度报告#xff0c;并需要在 2.5 小时内解析这些报告并构建一个数据库。这些报告是 PDF 格式…公司年报智能问答比赛任务简介比赛的任务是基于公司年度报告构建一个问答系统。简单来说比赛当天的流程如下我们会收到来自随机挑选公司的 100 份年度报告并需要在 2.5 小时内解析这些报告并构建一个数据库。这些报告是 PDF 格式每份最长可达 1000 页。然后系统会生成 100 个随机问题基于预设模板我们的系统必须尽可能快速地回答这些问题。所有问题都必须有确定的答案例如是/否公司名称某些情况下是多个公司名称领导职位头衔、推出的产品名称数值指标营收、商店数量等。每个答案都必须注明引用的页码作为证据确保系统是真正从原文中得出答案而不是输出虚假信息hallucinate。获胜方案获胜方案在基础步骤之外还加入了两个路由器router和 LLM 重排序模块LLM reranking。我们可以在这里查看我们的最佳系统生成的问答对(https://github.com/IlyaRice/RAG-Challenge-2/blob/main/data/erc2_set/answers_1st_place_o3-mini.json)接下来我们将深入探讨构建该系统的每一个步骤我们在过程中遇到的波折与困难以及在此过程中摸索出的最佳实践。RAG 快速指南RAGRetrieval-Augmented Generation检索增强生成是一种通过与任意大小的知识库结合从而扩展大语言模型LLM能力的 方法。基础 RAG系统的开发流程主要包含以下阶段**解析 (Parsing)**为知识库准备数据包括收集文档、将其转换 为文本格式并清理无关的噪点信息。**数据摄取 (Ingestion)**创建并载入知识库。**检索 (Retrieval)**构建一个工具根据用户查询查找并返回相关 数据通常在向量数据库中进行语义搜索。**回答 (Answering)**使用检索到的数据丰富用户的提示词prompt 将其发送给 LLM并返回最终答案。1. 解析 (Parsing)要开始填充任何数据库首先必须将 PDF 文档转换为纯文本。PDF 解析是一项远非易事的工作其中充满了无数细微的难题保留表格结构保留关键的格式元素例如标题和项目符号列表识别多栏文本处理图表、图片、公式、页眉/页脚等等。遇到但没时间解决的有趣的 PDF 解析问题大型表格有时会旋转 90 度导致解析器产生乱码或无法阅读的文本。* 图表 部分由图片、部分由文本层组成。有些文档存在字体编码问题视觉上看文本是没问题的但尝试复制或解析时会得到一堆乱七八糟的字符。有意思的是我们单独调查了这个 问题发现文本是可以解码的——它是一个凯撒密码Caesar cipher每个单词的 ASCII 位移量都不同。这让我们产生了许多疑問。如果有人故意加密了一份公开可查的公司报告以阻止复制——为什么如果是在转换过程中字体出了问题——为什么偏偏是这种方式选择解析器我们尝试了大约二十几种 PDF 解析器小众解析器知名的解析器基于前沿机器学习算法训练的解析器支持 API 访问的商业解析器。我们可以肯定地说目前没有任何解析器可以处理所有细微之处并在不丢失部分重要信息的情况下将 PDF 内容完全还原为文本。在 RAG 挑战赛中表现最好的解析器是相对知名的Docling。有趣的是它的开发方是比赛的协办方之一——IBM。文件解析优化尽管 Docling 的结果非常优秀但它缺乏一些基本能力。这些功能部分存在但分散在不同的配置中无法组合在一起。因此我们卷起袖子彻底研究了库的源代码并重写了几个方法以满足我们的需求从而在解析后得到了一个包含所有必要元数据的 JSON 文件。利用这个 JSON 我们构建了一个 Markdown 文档其格式经过修正并且表格结构从 PDF 转换为 Markdown 甚至 HTML这在后来证明非常有用的还原度接近完美。这个库相当快但仍然不够快到能在 2.5 小时内在个人笔记本电脑上解析 1.5 万页文档。为了解决这个问题我们利用了 GPU 加速解析并在比赛期间租用了一台配备 4090 GPU 的虚拟机每小时花费 70 美分。Runpod GPU rental example解析所有 100份文档耗时约 40 分钟根据其他参赛者的报告和评论这 是极高的解析速度。至此我们的报告已被解析为 JSON 格式。现在我们可以填充数据库了吗还没。首先我们必须清除文本中的噪点信息并对表格进行预处理。文本清理和表格预处理有时部分文本从 PDF 中解析出来时会出错包含特定的语法降低了可读性和意义。我们使用了一批十几个正则表达式来处理这个问题。解析不佳的文本示例之前提到的凯撒密码文档也通过正则表达式模式检测到了。我们试图解码它们但即使修复后它们仍然包含许多伪影artifact。因此我们干脆直接对这些文档进行了完整的 OCR 识别。表格序列化在大型表格中度量名称横向表头通常离纵向表头太远削弱了语义连贯性。有 1500 个不相关的 token将纵向和横向表头隔开这显著降低了在向量搜索中 chunk 的相关性更不用说表格完全装不进一个 chunk 的情况了。此外LLM 在处理大型表格时也很难将度量名称与表头对应起来可能会返回错误的值。表格序列化Serialization of tables成为了解决方案。关于这个主题的研究很少所以我们不得不独立探索。我们可以搜索 Row-wise Serialization行式序列化、Attribute-Value Pairing属性-值对匹配或者阅读https://arxiv.org/pdf/2402.17944。序列化的核心是将一个大表格转化为一系列小的、上下文独立的字符串。在经过大量的提示词prompts和结构化输出 schema 实验后我们发现了一种解决方案即使是 GPT-4o-mini 也能几乎无损地序列化大型表格。最初我们以Markdown 格式向 LLM 输入表格但后来改用 HTML 格式这就是它派上用场的地方。语言模型对 HTML 的理解程度要高得多而且 HTML 可以描述包含合并单元格、子标题和其他复杂结构的表格。要回答诸如“这家公司 2021 年的股东权益是多少”之类的问题只需向 LLM 输入一个句子而非一个包含许多“噪点”的大型结构这就足够了。在序列化过程中整个表格被转换成这样一组独立的块subject_core_entity_Shareholders’ equity股东权益_information_block_截至 2012/3 至 2022/3 年的股东权益如下637,422 百万日元2012/3535,422 百万日元2013/3679,160 百万日元2014/3782,556 百万日元2015/3540,951 百万日元2016/3571,983 百万日元2017/3511,242 百万日元2018/3525,064 百万日元2019/3513,335 百万日元2020/3577,782 百万日元2021/3以及 1,274,570 百万日元2022/3。_获得表格的序列化版本后我们将其放在原表格下方作为每一个元素的文本标注。我们可以在项目的仓库中查看序列化的提示词和逻辑tables_serialization.py*尽管序列化潜力巨大但获胜的解决方案最终并未采用它。我们将在文章末尾解释原因。2. 内容提取 (Ingestion)报告已从 PDF 转换为干净的 Markdown 文本。现在让我们用它们来创建数据库。统一术语在搜索系统領域如 Google Search、全文搜索、Elastic Search、向量搜索等一个**文档 (document)**是系统返回的单一索引元素作为查询结果。一个文档可以是一个句子、段落、页面、网站、图片——不重要。但就个人而言这个定义总是让我们困惑因为它有一个更常用、更日常的含义**文档 (document)**作为一份报告、合同或证书。因此从现在起我们将使用文档在其日常含义上。存储在数据库中的元素我们称之为**块 (chunk)**因为我们存储的只是被切分过的文本片段。分块 (Chunking)根据比赛规则我们必须指明包含相关信息的页码。企业系统也采用同样的方法引用允许验证模型的答案是否是虚假信息hallucinated。这不仅使系统对用户更透明也简化了开发过程中的调试。最简单的选择是将文档的整页作为一个块因为页面很少超过几千个 token。但让我们再次思考查询和文档文本块之间的语义连贯性。通常情况下足以回答问题的信息片段不超过十个句子。因此从逻辑上讲一个包含目标语句的小段落将比同样语句稀释在一整页相关性较弱的文本中获得更高的相似度得分。我们将每页的文本分割成 300 个 token约 15 个句子的块。为了切分文本我们使用了带有自定义 Markdown 词典的递归拆分器。为了避免信息在两个块之间被切断而丢失我们添加了一个小的文本重叠50 个 token。如果我们担心重叠不能完全消除切分不当带来的风险可以搜索一下“语义拆分器 (Semantic splitter)”。如果我们计划只将找到的块插入到上下文中这一点尤其重要。然而切分的精确度对我们的检索系统几乎没有影响。每个块都存储其 ID 及其在元数据metadata中的父页面编号。向量化 (Vectorization)我们的块集合已准备就绪现在让我们创建向量数据库——或者更确切地说是多个数据库。100 个数据库其中 1 个数据库 1 个文档。因为为什么要 将所有公司的信息混合在一起之后再试图将一个公司的收入与另一个公司分开呢答案的目标信息总是严格限制在单个文档内。我们只需根据给定的问题确定要查询哪个数据库稍后会详细介绍。为了创建、存储和搜索向量数据库我们使用了FAISS。关于向量数据库格式的一些说明数据库使用IndexFlatIP方法创建。Flat 索引的优点是所有向量都“原样”存储没有压缩或量化。搜索使用暴力搜索精度更高。缺点是这种搜索计算和内存消耗显著更高。如果我们的数据库至少有十万个元素可以考虑 IVFFlat 或 HNSW。这些格式速度快得多尽管创建数据库时需要稍多一些资源。但速度的提升是以牺牲精度为代价的因为它使用的是近似最近邻搜索ANN。将所有文档的块分离到不同的索引中我们得以使用 Flat 数据库。IP内积用于通过余弦相似度计算相关性得分。除了 IP还有 L2——它通过欧氏距离计算相关性得分。IP 通常能提供更好的相关性评分。为了将块和查询嵌入到向量表示中我们使用了text-embedding-3-large。3. 检索 (Retrieval)创建好数据库后是时候进入 RAG 系统的“R”检索部分了。检索器Retriever是一个通用的搜索系统它接收查询作为输入并返回包含回答所需信息的 相关文本。在基础实现中它只是对向量数据库发起查询提取 Top N 个结果。这是 RAG 系统中尤其关键的部分如果 LLM 在查询上下文中没有接收到必要信息它就无法提供正确答案——无论我们如何精心微调解析或回答提示词。“垃圾进 → 垃圾出Junk in → Junk out。”提高检索器质量的方法有很多。以下是我们在比赛期间探索过的方法混合搜索vDB BM25混合搜索Hybrid search结合了基于向量的语义搜索和传统的基于关键词的文本搜索 BM25 算法。理论上它通过不仅考虑文本含义还考虑精确关键词匹配来提高检索准确性。通常两种方法的搜索结果会合并并根据综合得分进行重排序。我们并不是特别喜欢这种方法在它的基础实现中它通常会降低检索质量而不是提高。总的来说混合搜索是一個不错的技巧通过修改输入查询可以進一步优化。最简单地说LLM 可以重述问题以去除噪点并增加关键词密度。如果我们在混合搜索方面有积极的经验特别是关于潜在问题和解决方案请在评论区分享。无论如何我们心中有更具前景的替代方案于是決定不再进一步探索这个方向。交叉编码器重排序 (Cross-encoder reranking)使用交叉编码器模型Cross-encoder models对向量搜索结果进行重排序看起来很有前景。简单来说交叉编码器能给出更精确的相似度分數但速度较慢。交叉编码器介于嵌入模型例如双编码器 bi-encoder和 LLM 之间。与通过文本的向量表示这 inherently 会丢失一些信息进行比较不同交叉编码器直接评估两个文本之间的语义相似度从而给出更准确的分数。然而对查询与数据库中每个元素的成对比较耗时太长。因此交叉编码器重排序仅适用于 向量编码器过滤出一小部分块。在比赛的最后一刻我们放弃了这种方法原因是通过API 提供的交叉编码器重排序模型稀缺。无论是 OpenAI 还是其他大型提供商都没有提供而我们不想为了管理另一个 API 余额而麻烦。但如果我们有兴趣尝试交叉编码器重排序我们推荐Jina Reranker。它在基准测试中表现出色而且注册后 Jina 会提供慷慨的免费请求额度。最终我们选择了更具吸引力的替代方案LLM 重排序LLM 重排序 (LLM reranking)这很简单将文本和问题传递给 LLM并问“这段文本有助于回答问题吗有多大帮助它的相关性评分从 0 到 1 是多少”直到最近由于强大的 LLM 模型成本高昂这种方法还不可行。但现在我们有了快速、廉价且足够智能的 LLM 模型。和交叉编码器重排序一样我们也在通过向量搜索初步过滤后应用此方法。我们开发了一个详细的提示词描述了通用指导和精确到 0.1 的显式相关性标准0 完全不相关文本块与查询没有任何联系或关联。0.1 基本不相关仅与查询有非常轻微或模糊的关联。0.2 非常微弱相关包含极其微小或切线式的关联。…LLM 查询被格式化为结构化输出Structured output包含两个字段reasoning让模型解释其判断和relevance_score可以直接从 JSON 中提取无需额外解析。我们进一步优化了流程在一个请求中同时发送三页内容提示 LLM 同时返回三个页面的分数。这提高了速度降低了成本 并因相邻文本块能为模型的评估提供更多上下文而略微提高了评分的一致性。修正后的相关性得分使用加权平均计算vector_weight 0.3llm_weight 0.7理论上我们可以直接跳过向量搜索将每一页都直接传递给 LLM。有些参赛者就这样做了而且取得了成功。然而我们相信使用嵌入embedding进行更便宜、更快速的过滤仍然是必要的。对于一份 1000 页的文档有些文档就是这么大仅仅回答一个问题就可能花费约 25 美分——太昂贵了。而且归根结底我们是在参加一场 RAG 挑战赛不是吗通过 GPT-4o-mini 进行重排序的成本对我们来说每个问题不到一美分这种方法在质量、速度和成本之间取得了出色的平衡——这正是我们选择它的原因。我们可以在这里查看重排序提示词prompts.py父页面检索 (Parent Page Retrieval)还记得我们之前提到将文本分割成更小的块吗好吧这里有一个小但重要的注意事项。是的回答问题的核心信息通常集中在一个小的块中——这正是将文本分解成小块能提高检索质量的原因。但该页上剩余的文本可能仍然包含次要的——但仍然重要——的细节。因此在找到 Top N 个相关块后我们只将它们用作指向整个页面的指针然后将完整的页面添加到上下文context中。这正是我们在每个块的元数据中记录页面编号的原因。整合后的检索器 (Assembled Retriever)Assembled Retriever diagram让我们回顾一下最终检索器的步骤对查询进行向量化。根据查询向量找到 Top 30 个相关块。 3.通过块的元数据提取对应的页面记得去重。通过 LLM 重排序器处理这些页面。调整页面的相关性得分。返回得分最高的 Top 10 页在每一页前面加上页码并将它们合并成一个字符串。我们的检索器现在准备就绪了4. 增强 (Augmentation)Augmentation process diagram我们的向量数据库已建立检索器已准备好。RAG 系统中的“R”检索部分至此已完成我们现在进入“A”增强部分这部分相当直接主要包括 f-string 和字符串拼接操作。一个有趣的地方是我们组织提示词存储的方式。在多个项目中尝试了不同的方法后我们最终确定了以下方法我们将提示词存储在一个专门的prompts.py文件中通常将提示词分割成逻辑块核心系统指令定义 LLM 返回响应格式的 Pydantic schema用于创建单次示例one-shot/少次示例few-shot提示词的问答对示例用于插入上下文和查询的模板。一个小型函数会根据需要将这些块组合成最终的提示词配置。这种方法允许灵活测试不同的提示词配置例如比较不同示例对单次示例提示词的有效性。某些指令可能会在多个提示词中重复出现。以前修改这类指令意味着需要在所有使用它们的提示词中同步更新这很容易导致错误。模块化方法解决了这个问题。现在我们将重复出现的指令放入一个共享块中并在多个提示词中重用。此外当提示词变得过长时模块化块也简化了处理。所有提示词都可以在项目仓库中查看prompts.py5. 生成 (Generation)RAG 中的第三个部分“G”生成是最耗费精力的。要在这一阶段实现高质量需要巧妙地应用几种基本技术。将查询路由到数据库这是 RAG 系统中最简单却最有用的部分之一。回想一下每份报告都有其独立的向量数据库。问题生成器设计成公司名称始终明确出现在问题中。我们也有所有公司名称的列表比赛开始时与 PDF 报告一同提供。因此从查询中提取公司名称甚至不需要 LLM我们只需遍历列表通过re.search()从问题中提取名称并将其与相应的数据库匹配。在实际应用场景中将查询路由到数据库比在我们受控、理想的环境中更复杂。我们很可能还会需要额外的预处理任务为数据库打标签或者使用 LLM 从问题中提取实体然后将其与数据库匹配。但在概念上方法保持不变。总结一下找到公司名称 → 匹配到相应的向量数据库 → 只在该数据库中搜索。搜索空间缩小了 100 倍。将查询路由到提示词Query routingto prompts diagram比赛的一个要求是回答的格式。每个答案必须简洁并严格符合数据类型就像直接将其存入公司数据库一样。每个问题旁边都明確給出了预期的数据类型——int/float、bool、str或list[str]。每种类型都涉及 3到 6 个需要在回答时考虑的细微之处。例如如果问题询问某个指标的数值答案必须是纯数字不包含评论、货币符号等。对于金钱指标报告中的货币必须与问题中提到的货币一致并且数字必须规范化——例如报告中常写“$1352 (in thousands)”系统必须回覆“1352000”。如何确保 LLM 同时考虑所有这些细微之处而不出错简单地说我们做不到。给 LLM 的规则越多它忽视它们的可能性就越高。即使只有八条规则对当前的 LLM 来说也多得危险。模型的认知能力是有限的额外的规则会分散其回答核心问题的注意力。这逻辑上得出了一个结论我们应该尽量减少每个查询的规则数量。一个方法是将一个查询分解为一系列更简单的查詢。然而在我们的案例中由于明确提供了预期的响应类型我们可以实现一个更简单的解决方案——根据不同的答案类型我们們只向提示詞提供相应的指令集。我们编写了四种提示词变体並使用简单的if else语句选择正确的那个。复合查询路由Compound query routing diagram比赛还包括比较多家公司指标的问题。这类问题与那些更简单的查询不符因为它们需要额外的步骤来回答。问题示例苹果和微软谁的营收更高我们想想人会如何處理这个任务首先他们會分别查找每家公司的营收然后进行比较。我们将同样的思维嵌入到我们的系统中。我们将最初的比较问题传递给 LLM并要求它创建更简单的子问题以分别提取每家公司的指标。在我们的例子中更简单的子问题将是苹果的营收是多少和微软的营收是多少现在我们可以通过标准流程分别处理每家公司的这些更简单的查询。收集到每家公司的答案后我们将它们作为上下文传递给 LLM以回答最初的问题。这种模式适用于任何复杂的查询。关键在于识别它们并确定所需的子步骤。思维链 (Chain of Thoughts, CoT)思维链CoT通过让模型在给出最终答案之前“出声思考”显著提高了答案质量。LLM 不会立即给出答案而是生成一系列导致解决方案的中间推理步骤。就像人类一样LLM 在将复杂問題分解為更小、更簡單的問題時處理得更好。CoT 幫助模型避免遗漏关键细节有条不紊地處理信息并得出正确结论。在上下文包含可能误导模型的“陷阱”时它尤其有用。我们无疑听说过那句标志性的话一步步思考 (Think step by step)。这是最早试图通过提示词prompting来提高答案质量的尝试之一。它实际上催生了奇特的“提示词工程prompt engineering”。然而对于严肃的任务这种通用指令是不够的。LLM 有时会“虚假推理fake reasoning”——例如先给出即时答案然后倒过来找理由解释或者编造不存在的事实。这个问题在像 GPT-4o-mini 或 Llama 8b 这样较弱的模型中尤为常见。为了确保CoT 有益我们必须清晰地引导模型如何进行推理。解釋推理步驟、目標并提供示例。根据提示词指令明确地构建推理步骤可以显著增强规则的遵循。在 RAG 中当报告中缺乏完全符合要求的指标时上下文可能包含相似但不完全相同的信息。模型可能會試圖扭曲提供的数据以符合请求的指标。由于模型被训练得乐于助人它们偏向于提供某个答案而不是承认不知道。仅仅要求模型保持怀疑态度来对抗这种偏见确实有效——但并非始终如一也并非在所有情况下都有效。相反明确提示模型从不同角度或视角分析信息会更有帮助。我们特別指示模型重点评估问题和上下文之间指标的兼容性。这显著减少了虚假信息的生成。带有模糊上下文的推理示例问题Ritter Pharmaceuticals Inc. 的研发设备按成本计是多少模型的推理步骤问题询问 Ritter Pharmaceuticals Inc. 的“研发设备按成本计”。这表明需要从资产负债表中提取一个特定数值代表专门用于研发的设备的原始购置成本不包含任何累计折旧。上下文第 35 页显示“不动产和设备净额”为 12,500 美元。这是一个净值已扣除折旧而且是一个更广泛的类别包含所有不动产和设备而不仅仅是研发设备。上下文第 37 页还提到“机械和设备”的“累计折旧”为 110,000 美元。这代表了总的折旧而不是原始成本更重要的是它没有说明这些设备专门用于研发。这两个指标都不完全符合请求的指标。“不动产和设备净额”范围太广且是折旧后的价值。“累计折旧”仅显示折旧而非成本并且缺乏研发的针对性。5. 由于上下文没有提供仅用于研发设备的原始成本且我们無法進行假設、計算或組合信息因此答案是“N/A”。结构化输出 (Structured outputs)结构化输出Structured OutputSO是一种强制模型以严格定义的格式响应的方式。它通常作为一个单独的参数传递给 API例如一个 Pydantic 或 JSON schema模式。这保证了模型总是返回符合所提供 schema 的有效JSON 数据。字段描述也可以包含在响应 schema 中。这些不影响结构但会被 LLM 视为提示词的一部分来处理。例如以下是用于 LLM 重排序的 Pydantic schemaclass RetrievalRankingSingleBlock(BaseModel): Rank retrieved text block relevance to a query. reasoning: str Field( description( Analysis of the block, identifying key information and how it relates to the query ) ) relevance_score: float Field( description( Relevance score from 0 to 1, where 0 is Completely Irrelevant and 1 is Perfectly Relevant ) )有了这个 schemaLLM 总是会返回一个包含两个字段的 JSON——第一个是字符串第二个是数字。CoT SO 思维链结合结构化输出上述方法可以理想地结合使用。在生成阶段模型有一个专门用于推理的字段还有一个单独的字段用于最终答案。这使得我们可以直接提取答案而无需从冗长的推理步骤中进行解析。可以在结构化输出中以多种方式实现思维链。例如您可以使用多个 JSON 字段每个字段引导模型得出中间结论这些结论的组合最终引导它得出正确的最终答案。然而由于回答比赛问题所需的逻辑无法通过预定义的一组 分步指令来描述我们采用了更通用的方法为模型提供一个单一的推理字段并直接在提示词中定义推理序列。在我们用于回答比赛问题的主要schema 中只有四个字段step_by_step_analysis——初步推理思维链本身。reasoning_summary——前一个字段的精简摘要用于更轻松地跟踪模型的逻辑。relevant_pages——答案引用的报告页码。final_answer——根据比赛要求格式化后的简洁答案。前三个字段在为不同答案类型量身定制的四种提示词中被重用。第四个字段每次都有所不同指定答案类型并描述模型必須 Consideration 的具體細微之處。例如确保final_answer字段始终是数字或“N/A”是这样实现的final_answer: Union[float, int, Literal[N/A]]SO 重解析器 (SO Reparser)并非所有 LLM 都支持结构化输出因为只有它才能保证完全遵守 schema。如果一个模型没有专门的结构化输出功能我们仍然可以直接在提示词中呈现输出 schema。在大多数情况下模型通常足够智能可以返回有效的 JSON。然而部分答案不可避免地会偏离 schema导致代码出错。小型模型尤其如此大约一半的时间都无法符合要求。为了解决这个问题我们编写了一个回退方法它使用schema.model_validate(answer)来验证模型的响应是否符合 schema。如果验证失败该方法会将响应重新发送给 LLM提示它遵守 schema。这种方法将 schema 合规率提高到 100%即使对于 8b 模型也是如此。这是提示词本身。单次示例提示词 (One-shot Prompts)这是另一种常见且相当显而易见的方法在提示词中添加一个问答示例对可以提高响应质量和一致性。我们在每个提示词中都添加了一对“问题 → 答案”答案以结构化输出定义的 JSON 格式编写。这个示例同时服务于多种目的展示一个示例性的分步推理过程。进一步阐明在困难情况下的正确行为帮助重新校准模型的偏见。演示模型回答应该遵循的 JSON 结构尤其对缺乏原生 SO 支持的模型有用。我们非常重视精心编写这些示例答案。提示词中示例的质量可以提升或降低响应质量因此每个示例必须与指令完全一致并且总体上几乎无懈可击。如果示例答案与指令矛盾模型就会变得困惑这会对其表现产生负面影响。我们仔细地修改了示例中的分步推理字段手动调整了推理结构和每个短语的措辞。指令细化 (Instruction Refinement)这一部分的工作量与整个数据准备阶段不相上下因为需要进行无止境的迭代调试、校对答案以及手动分析模型的推理过程。分析问题在编写提示词之前我们徹底研究了响应要求和问题生成器。构建一个以 LLM 为核心的优秀系统的关键在于理解客户需求。通常这需要深入的专业领域知識和对问题的细致检查。我们坚信除非我们清晰地理解问题本身以及如何找到答案否则不可能为企业构建真正高质量的问答系统如果有人能说服我们我们会很高兴。这种理解也是澄清用户问题中所有隐含意义所必需的。让我们考虑问题示例**ACME inc 的 CEO 是谁**在一个理想的世界里报告总是会明确地提供答案不留误解 的余地现由 John Doe 负责 CEO 职责RAG 系统会在报告中找到这句话将其添加到查询上下文用户会收到一个明确的答案John Doe然而我们生活在现实世界中成千上万的公司以各种方式表达信息伴随着无数额外的细微之处。这就引出了一个问题到底什么可以归入“CEO”这个称谓之下系统应该多么字面地理解客户的问题客户是想知道担任类似管理角色的人的名字还是严格来说就是那个特定的职位头衔稍微偏离字面解释是否可以接受偏离多远算太远潜在地以下职位可能被包括在内首席执行官 (Chief Executive Officer)——显然就是 CEO 的全称。董事总经理 (Managing Director, MD), 总裁 (President), 执行董事 (Executive Director)——稍不那么明显。不同国家对这个角色使用不同的头衔英国和欧洲是 MD美国和日本是 President英国、亚洲国家以及非营利组织是 Executive Director。首席运营官 (Chief Operating Officer), 首席执行官 (Principal Executive Officer), 总经理 (General Manager), 行政长官 (Administrative Officer), 代表董事 (Representative Director)——甚至更不明显。根据国家和公司结构的不同可能没有直接等同于 CEO 的职位尽管这些角色最接近 CEO但它们在职责和权限上的重叠程度各不相同——从 90% 到 50% 不等。我们不确定是否存在对此已有的术语但我们个人将其称为“解释自由度阈值”问题。当响应是自由格式时解释自由度阈值相对容易解决。在模棱两可的情况下LLM 会尝试涵盖用户查询中所有隐含的含义并添加一些澄清。这是一个真实示例的 ChatGPT 回复根据提供的上下文Ethan Caldwell是董事总经理这是该公司中最接近 CEO 的职位。但是由于正在进行的监管调查他已被正式暂停了积极的行政职责。虽然他保留了头衔但目前不参与公司运营领导权已暂时移交给董事会监督下的高级管理团队。然而如果系统架构要求简洁的答案就像 RAG 挑战赛这样模型在这些情况下表现就不稳定了依赖其内部的“直觉”。因此解释自由度阈值必须提前定义和校准。但由于无法明确定义和量化这个阈值必须识别所有主要的边缘情况制定通用的查询解释规则并与客户澄清模糊之处。除了理解问题外还可能出现一些普遍的困境。例如ACME inc 是否宣布了股息政策的任何变更系统是否应该将报告中缺乏信息解读为没有宣布任何变更Rinat比赛组织者可以证实——在比赛准备期间我们用几十个类似的问题和困境轰炸了他 提示词创建 (Prompt Creation)比赛开始前一周问题生成器的代码公开了。 मैं तुरंत 生成了 一百个问题并从中创建了一个验证集。手动回答问题相当繁琐但这在两个关键领域帮助了我们当我们进行改进时验证集可以客观地衡量系统的质量。通过在该集合上运行系统我们可以监控它正确回答了多少问题以及最常在哪里出错。这种反馈循环有助于迭代改进提示词和其他流水线组件。手动分析问题突出了问题和报告中不明显的细节和歧义。这让我们能与 Rinat 核实回答要求并将这些规则明确地反映在提示词中。我们将所有这些澄清纳入提示词中作为指令集。指令示例答案类型 数字如果提供的指标与问题中提到的货币不同则返回“N/A”。如果上下文没有直接说明指标即使可以从上下文中的其他指标計算得出则返回“N/A”。特别注意上下文是否提到指标是以单位、千或百万为单位报告的以便在最終答案中相应地调整数字不作任何更改、添加三个零或六个零。注意值是否用括号括起来这意味着该值为负数。答案类型 名称如果问题询问职位例如职位的变动则仅返回职位头衔不包括姓名或任何其他信息。任命新的领导职位也應算作职位的变动。如果提到与同一头衔的职位相关的几次变动只返回该职位头衔一次。职位头衔始终应使用单数形式。如果问题询问新推出的产品则仅返回上下文中的产品名称完全按照原文。新产品候选者或测试阶段的产品不应计为新推出的产品。模型很容易遵循某些指令由于固有的偏见而抗拒其他指令并且在某些指令上遇到了困难导致错误。例如模型在跟踪计量单位千、百万时反复出错忘记在最终答案中添加必要的零。于是我们在指令中补充了一个简短的示例千为单位的数字示例上下文中的值4970,5 (in thousands $)最终答案4970500最终我们为每种问题格式编写了提示词并编写了几个辅助提示词数字类型问题最终提示词名称类型问题最终提示词名称列表类型问题最终提示词布尔类型问题最终提示词比较类型问题最终提示词用于通过多查询路由比较多个公司的答案比较类型问题的复述提示词用于初步在报告中查找指标LLM 重排序提示词SO 重解析器提示词对指令的细致优化结合单次示例和结构化输出思维链带来了显著的好处。最终的提示词彻底改变了系统中不必要的偏见并极大地提高了对细微之处的关注度即使对于较弱的模型也是如此。系统速度最初RAG 挑战赛的规则更严格要求系统在 10 分钟内回答所有 100 个问题才有资格获得奖金。我们认真对待这项要求并力求充分利用 OpenAI 的每分钟 token 限制。即使在 Tier 2限额也很慷慨——GPT-4o-mini 每分钟 2 百万 tokenGPT-4o 每分钟 45万 token。我们估算了每个问题的 token 消耗量并分批处理 25 个问题。系统仅用了 2 分钟就完成了所有 100 个问题。最后提交解决方案的时间被大大延长了——其他参赛者根本无法及时完成 系统质量拥有一个验证集不仅帮助改进了提示词也使整个系统受益。我们将所有关键功能配置化以便衡量它们的实际效果并微调超参数。以下是一些示例配置字段class RunConfig: use_serialized_tables: bool False parent_document_retrieval: bool False use_vector_dbs: bool True use_bm25_db: bool False llm_reranking: bool False llm_reranking_sample_size: int 30top_n_retrieval: int 10 api_provider: str openai answering_model: str gpt-4o-mini-2024-07-18在测试不同配置时我们惊讶地发现我们对它寄予厚望的表格序列化功能不仅没有改进系统反而略微降低了其有效性。显然Docling 从PDF 解析表格的能力足够好检索器也能有效地找到它们而 LLM 在没有额外帮助的情况下也能充分理解它们的结构。而向页面添加更多文本只会降低信噪比。我们还为比赛准备了多种配置以便在所有类别中快速运行各种系统。最终系统在使用开源模型和商业模型时都表现出色Llama 3.3 70b 的得分仅比 OpenAI 的 o3-mini 低几个点。 even 微小的 Llama 8b 在总榜上都超过了 80% 的参赛者。6. 结论最终赢得 RAG 挑战赛并非因为找到了某个神奇的解决方案而是因为采取了系统化的方法深思熟虑地结合和微调了各种技术并深入钻研了任务细节。关键的成功因素包括高质量的解析、高效的检索、智能的路由以及——最值得一提的——LLM 重排序和精心设计的提示词这些使得即使使用紧凑的模型也能取得出色的结果。这场比赛的主要启示很简单RAG 的魔力在于细节。我们越了解任务就能越精确地微调每个流水线组件从最简单的技术中也能获得更大的收益。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询