[{"data":1,"prerenderedAt":2366},["ShallowReactive",2],{"blog-article-/zh/blog/zero-hallucination-qa":3,"blog-list-zh":1447},{"id":4,"title":5,"body":6,"config":1431,"date":1432,"description":1433,"draft":1434,"extension":1435,"image":1431,"meta":1436,"navigation":1437,"path":1438,"seo":1439,"stem":1440,"tags":1441,"toolbar":1431,"translationKey":1445,"updated":1432,"__hash__":1446},"blog/zh/blog/zero-hallucination-qa.md","我是如何实现阅读器「零幻觉」问答的",{"type":7,"value":8,"toc":1395},"minimark",[9,17,32,35,40,47,52,57,75,80,93,98,132,135,139,157,164,168,183,188,225,232,236,249,274,279,396,414,421,423,427,434,449,456,476,482,484,488,491,497,499,503,526,536,597,600,611,621,628,630,634,641,647,654,658,665,673,680,684,694,737,748,754,756,760,774,782,789,792,834,844,852,858,865,869,878,884,895,897,901,907,911,918,922,945,955,957,961,967,1025,1031,1033,1037,1044,1067,1071,1091,1102,1104,1108,1119,1122,1145,1156,1162,1164,1168,1187,1198,1200,1204,1226,1237,1239,1243,1262,1268,1270,1274,1361,1368,1379],[10,11,12],"p",{},[13,14],"img",{"alt":15,"src":16},"封面：零幻觉问答","https://cdn.linghuxiong.com/resources/snapshots/ai-chat-cover.png",[18,19,20],"blockquote",{},[10,21,22,23,27,28,31],{},"本文分享 AI 阅读器 ",[24,25,26],"strong",{},"零幻觉问答"," 的工程实现：回答严格基于当前书籍原文，关键论述可 ",[24,29,30],{},"一键溯源"," 到具体段落。如果你也在做 AI 阅读、文档 QA 或 RAG 类应用，希望三次迭代的经验与最终架构能有所参考。",[33,34],"hr",{},[36,37,39],"h2",{"id":38},"一实践历程三个阶段的演进","一、实践历程：三个阶段的演进",[10,41,42,43,46],{},"零幻觉问答并非一开始就设计完备，而是在 ",[24,44,45],{},"成本、延迟和准确率"," 的拉扯中逐步演进的。下面按时间顺序回顾三个阶段，便于理解当前架构为何长成这样。",[48,49],"mermaid",{":config":50,"code":51},"config","flowchart%20LR%0A%20%20%20%20P1%5B%E9%98%B6%E6%AE%B5%E4%B8%80%EF%BC%9A%E5%85%A8%E6%96%87%E7%9B%B4%E5%A1%9E%5D%20--%3E%20P2%5B%E9%98%B6%E6%AE%B5%E4%BA%8C%EF%BC%9ALLM%20%E6%8F%90%E5%8F%96%E5%85%B3%E9%94%AE%E5%8F%A5%5D%0A%20%20%20%20P2%20--%3E%20P3%5B%E9%98%B6%E6%AE%B5%E4%B8%89%EF%BC%9A%E7%89%87%E6%AE%B5%E7%B4%A2%E5%BC%95%20%2B%20Tool%20%E6%A3%80%E7%B4%A2%5D%0A%20%20%20%20P1%20-.-%3E%7C%E6%85%A2%E3%80%81%E8%B4%B5%E3%80%81%E9%95%BF%E4%B9%A6%E4%B8%8D%E5%87%86%7C%20X1%5B%E6%B7%98%E6%B1%B0%5D%0A%20%20%20%20P2%20-.-%3E%7C%E4%B8%A2%E7%BB%86%E8%8A%82%E3%80%81%E4%BB%8D%E5%81%8F%E6%85%A2%7C%20X2%5B%E6%B7%98%E6%B1%B0%5D%0A%20%20%20%20P3%20--%3E%7C%E5%BD%93%E5%89%8D%E6%96%B9%E6%A1%88%7C%20OK%5B%E9%9B%B6%E5%B9%BB%E8%A7%89%20%2B%20%E5%8F%AF%E6%BA%AF%E6%BA%90%5D",[53,54,56],"h3",{"id":55},"阶段一全文直塞-context最简单也最先暴露问题","阶段一：全文直塞 Context（最简单，也最先暴露问题）",[10,58,59,62,63,66,67,70,71,74],{},[24,60,61],{},"做法："," 用户打开一本书提问时，将提取出的 ",[24,64,65],{},"全部正文"," 放进 System Prompt 或 User 消息，交给对话模型作答。若全书超过约 ",[24,68,69],{},"40 万字符","，则 ",[24,72,73],{},"硬截断","——只保留前面一段，后续章节对模型不可见。",[10,76,77],{},[24,78,79],{},"优点：",[81,82,83,87,90],"ul",{},[84,85,86],"li",{},"实现成本极低，几乎不需要预处理；",[84,88,89],{},"短书、结构简单的文档效果尚可——模型确实「看到了整本书」；",[84,91,92],{},"交互简单：问就能答，没有「请先等待分析」的等待态。",[10,94,95],{},[24,96,97],{},"缺点（很快变得不可接受）：",[81,99,100,106,112,122],{},[84,101,102,105],{},[24,103,104],{},"响应慢","：每次提问都要把海量文本送进模型，首 Token 延迟和总耗时随书长线性恶化；",[84,107,108,111],{},[24,109,110],{},"Token 成本高","：同一本书每问一次就重复付一遍全文的输入费用；",[84,113,114,117,118,121],{},[24,115,116],{},"长书严重失真","：超过 40 万字符后被截断，后半本、附录、结论章节等于不存在，且 UI 往往 ",[24,119,120],{},"没有明确告知"," 已截断；",[84,123,124,127,128,131],{},[24,125,126],{},"检索粒度为零","：模型要在几十万字里「大海捞针」，容易漏细节，也更容易产生 ",[24,129,130],{},"看似合理、实则无据"," 的概括——阅读场景最忌讳这类幻觉。",[10,133,134],{},"阶段一适合验证 MVP，不适合作为产品级方案。",[53,136,138],{"id":137},"阶段二用轻量-llm-提取关键句压缩-context但压缩得太狠","阶段二：用轻量 LLM 提取关键句（压缩 Context，但压缩得太狠）",[10,140,141,143,144,147,148,151,152,156],{},[24,142,61],{}," 在提问前（或首次打开书时），用 ",[24,145,146],{},"成本更低的模型"," 对正文做一轮预处理：按 Spine 分章（或整书分段），抽取 ",[24,149,150],{},"关键句","，输出时保留 ",[153,154,155],"code",{},"[f文件-起始-结束]"," 形式的位置标记，再将摘录拼成较短文本，作为后续问答的 Context。",[10,158,159,160,163],{},"典型链路是 ",[24,161,162],{},"Extract → Cache → Chat","：先离线或按需跑一遍提取并落库，之后每次提问复用同一份「关键句合集」。这与很多文档 QA 原型里「先压缩文档、再拿压缩结果做 QA」的思路相同，也是我们在阶段二实际采用过的路线。",[10,165,166],{},[24,167,79],{},[81,169,170,177,180],{},[84,171,172,173,176],{},"每次提问送入模型的文本 ",[24,174,175],{},"明显缩短","，单次 Token 消耗较阶段一显著下降；",[84,178,179],{},"预处理结果可缓存，同一本书不必每次提问都重新提取；",[84,181,182],{},"已引入位置标记，为后续溯源打下基础。",[10,184,185],{},[24,186,187],{},"缺点（长书场景下依然扛不住）：",[81,189,190,196,206,215],{},[84,191,192,195],{},[24,193,194],{},"细节大量丢失","：「关键句」由模型主观筛选，论证链上的限定条件、反例等容易被丢掉，答案容易「正确但片面」；",[84,197,198,201,202,205],{},[24,199,200],{},"长书 Context 仍然偏大","：大部头作品即便只留关键句，拼接后的输入依然可观，",[24,203,204],{},"延迟和成本只是缓解，没有根治","；",[84,207,208,211,212,205],{},[24,209,210],{},"双重 LLM 误差","：提取阶段可能漏选，问答阶段又可能误读摘录，错误会 ",[24,213,214],{},"叠加",[84,216,217,220,221,224],{},[24,218,219],{},"静态 Context","：无论用户问的是某一章细节还是全书结构，送进模型的都是 ",[24,222,223],{},"同一份预提取文本","，无法按问题动态收窄范围。",[10,226,227,228,231],{},"这一阶段的教训很明确：",[24,229,230],{},"问题不在「有没有压缩」，而在「压缩是否按需、以及能否回到原文」","。",[53,233,235],{"id":234},"阶段三片段索引-tool-按需检索-原文回传当前方案","阶段三：片段索引 + Tool 按需检索 + 原文回传（当前方案）",[10,237,238,240,241,248],{},[24,239,61],{}," 基本思路参考了 ",[242,243,247],"a",{"href":244,"rel":245},"https://github.com/VectifyAI/PageIndex",[246],"nofollow","PageIndex","，相对阶段二，核心变化有三点：",[250,251,252,258,268],"ol",{},[84,253,254,257],{},[24,255,256],{},"预处理产物是结构化索引","（目录级摘要 + 精确字符 span），而不是把摘录直接当作问答 Context；",[84,259,260,263,264,267],{},[24,261,262],{},"每次提问由模型通过 Tool Calling 按需检索","，再 ",[24,265,266],{},"拉取带位置标记的原文"," 作答；",[84,269,270,273],{},[24,271,272],{},"System Prompt 与前端联动","，约束引用格式，并支持点击角标跳转、高亮原文。",[10,275,276],{},[24,277,278],{},"三阶段对比：",[280,281,282,301],"table",{},[283,284,285],"thead",{},[286,287,288,292,295,298],"tr",{},[289,290,291],"th",{},"维度",[289,293,294],{},"阶段一（全文直塞）",[289,296,297],{},"阶段二（关键句提取）",[289,299,300],{},"阶段三（当前）",[302,303,304,323,337,351,365,382],"tbody",{},[286,305,306,310,313,316],{},[307,308,309],"td",{},"单次提问 Context",[307,311,312],{},"全书（或截断后的前半本）",[307,314,315],{},"预提取关键句合集",[307,317,318,319,322],{},"仅与问题相关的少量 ",[24,320,321],{},"原文"," 片段",[286,324,325,328,331,334],{},[307,326,327],{},"长书准确性",[307,329,330],{},"超 40 万字符后严重下降",[307,332,333],{},"依赖提取质量，易丢细节",[307,335,336],{},"按目录/span 检索，不受全书长度硬截断",[286,338,339,342,345,348],{},[307,340,341],{},"响应速度",[307,343,344],{},"慢",[307,346,347],{},"略好，长书仍慢",[307,349,350],{},"检索 + 短 Context，明显更快",[286,352,353,356,359,362],{},[307,354,355],{},"Token 成本",[307,357,358],{},"极高",[307,360,361],{},"中等偏高",[307,363,364],{},"预处理摊销 + 按需付费",[286,366,367,370,373,376],{},[307,368,369],{},"溯源能力",[307,371,372],{},"弱（难标注出处）",[307,374,375],{},"有位置标记，但内容已是二次筛选",[307,377,378,379],{},"角标对应 ",[24,380,381],{},"真实原文 span",[286,383,384,387,390,393],{},[307,385,386],{},"工程复杂度",[307,388,389],{},"低",[307,391,392],{},"中",[307,394,395],{},"高",[10,397,398,401,402,405,406,409,410,413],{},[24,399,400],{},"为何停在阶段三："," 阅读场景的零幻觉，关键不是「让模型看过尽量多的字」，而是 ",[24,403,404],{},"「作答前必须拿到与问题相关的原文证据」","。阶段一、二都在 Context ",[24,407,408],{},"体积"," 上做文章；阶段三把链路拆成 ",[24,411,412],{},"「索引（预处理）→ 检索（Tool）→ 取证（原文）→ 作答（约束生成）」","，才同时兼顾准确率、成本与可溯源性。",[10,415,416,417,420],{},"下文展开 ",[24,418,419],{},"阶段三"," 的实现细节。",[33,422],{},[36,424,426],{"id":425},"二问题定义阅读场景下幻觉比普通-chat-更致命","二、问题定义：阅读场景下，幻觉比普通 Chat 更致命",[10,428,429,430,433],{},"普通 ChatBot 偶发错误，用户往往可以容忍。但在 ",[24,431,432],{},"书籍 QA"," 里，幻觉的代价更高：",[81,435,436,443,446],{},[84,437,438,439,442],{},"用户问的是 ",[24,440,441],{},"这本书"," 说了什么，不是问模型的 parametric memory；",[84,444,445],{},"一句似是而非的「书中观点」，可能误导笔记、引用甚至二次传播；",[84,447,448],{},"没有出处，用户无法核实，产品信任很难建立。",[10,450,451,452,455],{},"因此，「零幻觉」在工程上落地为三条 ",[24,453,454],{},"可执行"," 的规则：",[250,457,458,464,470],{},[84,459,460,463],{},[24,461,462],{},"书内问题必须先查书","：凡可能与当前书籍相关的问题，模型必须先走检索（Tool），再组织答案；",[84,465,466,469],{},[24,467,468],{},"答案必须可溯源","：关键结论附带原文位置标记，前端可解析并跳转高亮；",[84,471,472,475],{},[24,473,474],{},"查不到就说查不到","：书中没有的内容应明确告知，而不是用通用知识冒充「书中观点」。",[10,477,478,479,481],{},"下文按 ",[24,480,419],{}," 的数据流，说明上述规则如何落地。",[33,483],{},[36,485,487],{"id":486},"三整体架构预处理-工具检索-约束生成-可点击溯源","三、整体架构：预处理 → 工具检索 → 约束生成 → 可点击溯源",[48,489],{":config":50,"code":490},"flowchart%20TB%0A%20%20%20%20subgraph%20prep%20%5B%E7%A6%BB%E7%BA%BF%2F%E9%A6%96%E6%AC%A1%E9%A2%84%E5%A4%84%E7%90%86%5D%0A%20%20%20%20%20%20%20%20A%5B%E6%8C%89%E7%9B%AE%E5%BD%95%E6%88%96%E9%95%BF%E5%BA%A6%E5%88%87%E5%88%86%E5%85%A8%E4%B9%A6%5D%20--%3E%20B%5BLLM%20%E7%94%9F%E6%88%90%E7%89%87%E6%AE%B5%E6%91%98%E8%A6%81%5D%0A%20%20%20%20%20%20%20%20B%20--%3E%20C%5B%E6%9C%AC%E5%9C%B0%E6%8C%81%E4%B9%85%E5%8C%96%20Segment%20%E7%BC%93%E5%AD%98%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20ask%20%5B%E7%94%A8%E6%88%B7%E6%8F%90%E9%97%AE%5D%0A%20%20%20%20%20%20%20%20D%5B%E7%94%A8%E6%88%B7%E8%BE%93%E5%85%A5%E9%97%AE%E9%A2%98%5D%20--%3E%20E%7B%E5%B7%B2%E6%9C%89%20Segment%20%E7%BC%93%E5%AD%98%3F%7D%0A%20%20%20%20%20%20%20%20E%20--%3E%7C%E5%90%A6%7C%20F%5B%E6%8F%90%E5%8F%96%E5%85%A8%E6%96%87%20%2F%20%E8%AF%A2%E9%97%AE%E6%98%AF%E5%90%A6%E9%A2%84%E5%A4%84%E7%90%86%5D%0A%20%20%20%20%20%20%20%20F%20--%3E%20prep%0A%20%20%20%20%20%20%20%20E%20--%3E%7C%E6%98%AF%7C%20G%5B%E6%B3%A8%E5%86%8C%20Tool%20Calling%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20retrieve%20%5B%E5%B7%A5%E5%85%B7%E6%A3%80%E7%B4%A2%5D%0A%20%20%20%20%20%20%20%20G%20--%3E%20H%7B%E9%97%AE%E9%A2%98%E7%B1%BB%E5%9E%8B%7D%0A%20%20%20%20%20%20%20%20H%20--%3E%7C%E5%85%A8%E4%B9%A6%E6%A6%82%E8%A7%88%2F%E4%B9%A6%E8%AF%84%7C%20I%5Bget_full_book_segment_summaries%5D%0A%20%20%20%20%20%20%20%20H%20--%3E%7C%E5%85%B7%E4%BD%93%E4%BA%8B%E5%AE%9E%2F%E4%BA%BA%E7%89%A9%2F%E7%AB%A0%E8%8A%82%7C%20J%5Bget_related_segment_summaries%5D%0A%20%20%20%20%20%20%20%20J%20--%3E%20K%5BLLM%20%E4%BB%8E%E6%91%98%E8%A6%81%E7%9B%AE%E5%BD%95%E4%B8%AD%E9%80%89%E7%9B%B8%E5%85%B3%E7%89%87%E6%AE%B5%20ID%5D%0A%20%20%20%20%20%20%20%20K%20--%3E%20L%5B%E6%8C%89%20span%20%E6%8B%89%E5%8F%96%E5%8E%9F%E6%96%87%20%2B%20%E4%BD%8D%E7%BD%AE%E6%A0%87%E8%AE%B0%5D%0A%20%20%20%20%20%20%20%20I%20--%3E%20M%5B%E6%8B%BC%E6%8E%A5%E5%85%A8%E4%B9%A6%E7%89%87%E6%AE%B5%E6%91%98%E8%A6%81%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20answer%20%5B%E7%94%9F%E6%88%90%E4%B8%8E%E5%B1%95%E7%A4%BA%5D%0A%20%20%20%20%20%20%20%20L%20--%3E%20N%5BTool%20%E7%BB%93%E6%9E%9C%E5%9B%9E%E4%BC%A0%E6%A8%A1%E5%9E%8B%5D%0A%20%20%20%20%20%20%20%20M%20--%3E%20N%0A%20%20%20%20%20%20%20%20N%20--%3E%20O%5BSystem%20Prompt%20%E7%BA%A6%E6%9D%9F%E5%BC%95%E7%94%A8%E6%A0%BC%E5%BC%8F%5D%0A%20%20%20%20%20%20%20%20O%20--%3E%20P%5B%E6%B5%81%E5%BC%8F%E8%BE%93%E5%87%BA%E7%AD%94%E6%A1%88%20%2B%20%E4%BD%8D%E7%BD%AE%E8%A7%92%E6%A0%87%5D%0A%20%20%20%20%20%20%20%20P%20--%3E%20Q%5B%E6%B8%B2%E6%9F%93%E5%8F%AF%E7%82%B9%E5%87%BB%E5%BC%95%E7%94%A8%E8%A7%92%E6%A0%87%5D%0A%20%20%20%20%20%20%20%20Q%20--%3E%20R%5B%E7%82%B9%E5%87%BB%20%E2%86%92%20%E9%A2%84%E8%A7%88%E5%8E%9F%E6%96%87%20%E2%86%92%20%E8%B7%B3%E8%BD%AC%E9%AB%98%E4%BA%AE%5D%0A%20%20%20%20end",[10,492,493,494,231],{},"核心思路可以概括为：",[24,495,496],{},"不让模型「凭记忆答题」，而是让它「先取证、再作答、并标注出处」",[33,498],{},[36,500,502],{"id":501},"四预处理把整本书变成可检索的片段索引","四、预处理：把整本书变成可检索的「片段索引」",[10,504,505,506,509,510,513,514,517,518,521,522,525],{},"若每次提问仍采用 ",[24,507,508],{},"阶段一"," 的全文 Context，长书必然爆 Token，检索粒度也过粗。阶段三的解法是：用户首次对某本书发起 AI 对话时，后台异步跑 ",[24,511,512],{},"片段摘要任务","，按 ",[24,515,516],{},"目录结构"," 或 ",[24,519,520],{},"文本长度"," 将全书切成若干 ",[153,523,524],{},"Segment","，为每个片段生成摘要，并持久化到本地 IndexedDB。",[10,527,528,529,531,532,535],{},"每个 ",[153,530,524],{}," 在数据结构上包含摘要与 ",[24,533,534],{},"正文物理位置","：",[280,537,538,548],{},[283,539,540],{},[286,541,542,545],{},[289,543,544],{},"字段",[289,546,547],{},"含义",[302,549,550,564,577,587],{},[286,551,552,561],{},[307,553,554,557,558],{},[153,555,556],{},"startFileIndex"," / ",[153,559,560],{},"endFileIndex",[307,562,563],{},"Spine 文件索引（PDF 则每页一个文件）",[286,565,566,574],{},[307,567,568,557,571],{},[153,569,570],{},"startOffset",[153,572,573],{},"endOffset",[307,575,576],{},"字符级起止偏移",[286,578,579,584],{},[307,580,581],{},[153,582,583],{},"sequence",[307,585,586],{},"线性阅读顺序",[286,588,589,594],{},[307,590,591],{},[153,592,593],{},"title",[307,595,596],{},"对应目录标题",[10,598,599],{},"切分策略兼顾精度与成本：单目录正文不超过约 20KB 时只总结该节点；同级目录会合并成批（15KB～20KB）再调用 LLM；无目录的大块正文则按 3～4 万字符区间切段。",[10,601,602,603,606,607,610],{},"摘要生成时的 System Prompt 会要求 ",[24,604,605],{},"保留原文位置标记","（格式 ",[153,608,609],{},"[f数字-数字-数字]","），以便后续 Tool 回传原文时，位置信息与 spine 字符偏移一致。核心约束如下：",[612,613,619],"pre",{"className":614,"code":616,"language":617,"meta":618},[615],"language-text","如果总结内容与原文某段相关，须保留段末位置信息，格式 [f数字-数字-数字]（如 [f1-90-109]）。\n位置标记是整体，禁止修改、合并或省略其中的任何字符或数值。\n","text","",[153,620,616],{"__ignoreMap":618},[10,622,623,624,627],{},"预处理完成后，问答不再依赖「整书 Context」，而是依赖 ",[24,625,626],{},"结构化片段索引","——这是长书场景下零幻觉的工程前提。",[33,629],{},[36,631,633],{"id":632},"五位置标记体系把出处编码进文本","五、位置标记体系：把「出处」编码进文本",[10,635,636,637,640],{},"零幻觉不仅要求内容来自原文，还要求 ",[24,638,639],{},"出处可机器解析、可在 UI 中跳转","。我们采用内联位置标记：",[612,642,645],{"className":643,"code":644,"language":617},[615],"[f{fileIndex}-{startChar}-{endChar}]\n",[153,646,644],{"__ignoreMap":618},[10,648,649,650,653],{},"例如 ",[153,651,652],{},"[f5-123-165]"," 表示：第 5 个 Spine 文件（从 0 起算）中，字符偏移 123～165 的文本区间。",[53,655,657],{"id":656},"_51-标记如何写入正文","5.1 标记如何写入正文",[10,659,660,661,664],{},"正文提取层在输出片段时，为每个小段在段末写入 ",[153,662,663],{},"[f{fileIndex}-{start}-{end}]","。示意：",[612,666,671],{"className":667,"code":669,"language":670,"meta":618},[668],"language-typescript","const position = `[f${fileIndex}-${absOffset}-${absOffset + segment.length}]`;\nfileLines.push(segment.text.trim() + position);\n","typescript",[153,672,669],{"__ignoreMap":618},[10,674,675,676,679],{},"无论是预处理摘要还是 Tool 回传的原文摘录，位置信息都与 ",[24,677,678],{},"Spine 字符偏移"," 对齐，而不是让模型「估算页码」。",[53,681,683],{"id":682},"_52-对模型输出的约束","5.2 对模型输出的约束",[10,685,686,687,693],{},"在组装 System Prompt 时，我们单独约定了 ",[24,688,689],{},[690,691,692],"span",{},"Position Citation Rules","，核心五条：",[250,695,696,706,716,722,731],{},[84,697,698,701,702,705],{},[24,699,700],{},"标准格式","：必须使用 ",[153,703,704],{},"[f_fileIndex-startChar-endChar]","，三段数字缺一不可；",[84,707,708,711,712,715],{},[24,709,710],{},"只引用当前来源","：角标须 ",[24,713,714],{},"原样复制"," 自本轮 System/User 消息或 Tool 返回文本中的标记；",[84,717,718,721],{},[24,719,720],{},"禁止伪造","：不得自行计算、修改或编造位置；",[84,723,724,727,728,205],{},[24,725,726],{},"宁缺毋滥","：当前上下文没有合法标记时，正常作答即可，",[24,729,730],{},"不要输出任何位置标记",[84,732,733,736],{},[24,734,735],{},"紧跟论述","：标记须紧跟相关句段，禁止在文末堆砌引用清单。",[10,738,739,740,743,744,747],{},"前端展示前还会过滤模型偶发输出的 ",[24,741,742],{},"两段位"," 非法标记（如 ",[153,745,746],{},"[f1-293]","），避免无效角标进入 UI。",[10,749,750],{},[13,751],{"alt":752,"src":753},"引用溯源弹窗","https://cdn.linghuxiong.com/resources/snapshots/ai-chat.png",[33,755],{},[36,757,759],{"id":758},"六tool-calling先检索再回答","六、Tool Calling：先检索，再回答",[10,761,762,763,766,767,770,771,231],{},"当对话绑定某本书（存在 ",[153,764,765],{},"resourceId","，且 ",[153,768,769],{},"chatType === 'chat'","）时，每次生成前会向模型注册两个 Tool，并挂载对应的 executor。整体遵循 OpenAI 兼容的 ",[24,772,773],{},"function calling 循环",[53,775,777,778,781],{"id":776},"_61-get_related_segment_summaries-针对具体问题查片段","6.1 ",[153,779,780],{},"get_related_segment_summaries"," —— 针对具体问题查片段",[10,783,784,785,788],{},"适用于：概念、人物、情节、章节细节等 ",[24,786,787],{},"有明确检索意图"," 的问题。",[10,790,791],{},"流程简述：",[250,793,794,801,807,814,828],{},[84,795,796,797,800],{},"模型将用户口语 ",[24,798,799],{},"改写为书中可能出现的术语","（System Prompt 中的「Optimize Search Queries」）；",[84,802,803,804,205],{},"调用 Tool，传入 ",[153,805,806],{},"question",[84,808,809,810,813],{},"将所有片段摘要按 Token 预算 ",[24,811,812],{},"分批","（单批约 3 万 Token，最多 5 批）；",[84,815,816,817,820,821,824,825,205],{},"每批发起一次 ",[24,818,819],{},"独立的 LLM 请求","，从 ",[153,822,823],{},"{ id, title, summary }"," 列表中选出相关片段 ID（最多 5 个），返回 JSON，形如 ",[153,826,827],{},"{\"Thinking\":\"...\",\"answer\":[\"1\",\"3\"]}",[84,829,830,831,833],{},"根据选中 Segment 的 span，从 Spine ",[24,832,266],{},"（不是摘要），作为 Tool 结果回传。",[10,835,836,839,840,843],{},[24,837,838],{},"关键设计：Tool 回传原文，而非摘要。"," 模型作答时看到的是真实段落 + 内联 ",[153,841,842],{},"[f…]","，避免「摘要 → 再概括」带来的漂移。",[53,845,847,848,851],{"id":846},"_62-get_full_book_segment_summaries-全书概览类问题","6.2 ",[153,849,850],{},"get_full_book_segment_summaries"," —— 全书概览类问题",[10,853,854,855,788],{},"适用于：「总结全书」「点评这本书」「整体结构/主题」等 ",[24,856,857],{},"需要全局视野",[10,859,860,861,864],{},"按阅读顺序拼接所有片段的 ",[153,862,863],{},"summary"," 回传，避免逐段相关度筛选遗漏关键章节。",[53,866,868],{"id":867},"_63-system-prompt书优先工具优先","6.3 System Prompt：书优先、工具优先",[10,870,871,872,877],{},"绑定书籍时，System Prompt 注入 ",[24,873,874],{},[690,875,876],{},"Core Principles for Reading Assistant","，核心三条：",[612,879,882],{"className":880,"code":881,"language":617},[615],"1. Book First, Tool First\n   - 任何可能与书籍相关的问题，必须先调用工具检索；\n   - 答案必须主要依据检索结果，禁止不检索就编造「书中内容」。\n\n2. General Knowledge as Fallback Only\n   - 仅当：纯闲聊 / 用户明确要求不用书 / 工具无结果时，才可使用通用知识；\n   - 若书中没有，必须先声明「书中未提及此内容」，再补充通用知识。\n\n3. Direct Style\n   - 直入主题，禁止「根据提供的材料…」「综上所述…」等套话。\n",[153,883,881],{"__ignoreMap":618},[10,885,886,887,890,891,894],{},"生成层实现标准 Tool 循环：",[153,888,889],{},"tool_calls"," → 执行 executor → 追加 ",[153,892,893],{},"role: tool"," → 继续请求，直到输出最终文本。启用 tools 时关闭 thinking 通道，避免与 function call 协议冲突。",[33,896],{},[36,898,900],{"id":899},"七前端溯源从角标到原文高亮","七、前端溯源：从角标到原文高亮",[10,902,903,904,906],{},"模型输出的 ",[153,905,652],{}," 不会直接展示，在渲染层转为可点击引用。",[53,908,910],{"id":909},"_71-角标渲染","7.1 角标渲染",[10,912,913,914,917],{},"展示前将位置标记规范化为 Markdown 链接，例如 ",[153,915,916],{},"[1]([f5-123-165])","，再渲染为序号角标；同一位置多次出现时可去重，避免 UI 堆叠。",[53,919,921],{"id":920},"_72-点击交互","7.2 点击交互",[250,923,924,933,939],{},[84,925,926,929,930,932],{},[24,927,928],{},"首次点击","：解析 ",[153,931,842],{}," → 取 fileIndex 与字符偏移 → 从 Spine 原文提取文本 → 弹出预览（可带目录标题）；",[84,934,935,938],{},[24,936,937],{},"再次点击同一角标","：关闭弹窗；",[84,940,941,944],{},[24,942,943],{},"确认跳转","：打开阅读视图，按字符区间高亮。",[10,946,947,948,951,952,231],{},"从模型复制的标记到用户看到的原文，中间 ",[24,949,950],{},"不经 LLM 二次加工","，溯源链路全程 ",[24,953,954],{},"确定、可复现",[33,956],{},[36,958,960],{"id":959},"八边界情况与诚实降级","八、边界情况与诚实降级",[10,962,963,964,535],{},"零幻觉不等于「永远有答案」，而是 ",[24,965,966],{},"没有证据时不瞎编",[280,968,969,979],{},[283,970,971],{},[286,972,973,976],{},[289,974,975],{},"场景",[289,977,978],{},"行为",[302,980,981,989,1001,1009,1017],{},[286,982,983,986],{},[307,984,985],{},"片段摘要尚未生成",[307,987,988],{},"先提取全文做摘要",[286,990,991,994],{},[307,992,993],{},"Tool 检索无结果",[307,995,996,997,1000],{},"返回 ",[153,998,999],{},"(No relevant segment excerpts found…)","，模型应声明书中未提及",[286,1002,1003,1006],{},[307,1004,1005],{},"模型输出了非法两段位标记",[307,1007,1008],{},"前端过滤，不展示无效角标",[286,1010,1011,1014],{},[307,1012,1013],{},"用户纯闲聊",[307,1015,1016],{},"System Prompt 允许脱离书籍，用通用知识回答",[286,1018,1019,1022],{},[307,1020,1021],{},"导出对话",[307,1023,1024],{},"可将角标转为阅读器深链接，便于分享或归档",[10,1026,1027],{},[13,1028],{"alt":1029,"src":1030},"对话导出","https://cdn.linghuxiong.com/resources/snapshots/ai-chat-export.png",[33,1032],{},[36,1034,1036],{"id":1035},"九设计取舍为什么不用向量-rag","九、设计取舍：为什么不用「向量 RAG」？",[10,1038,1039,1040,1043],{},"做文档 QA 的同行常会问：既然要做检索增强，为什么不走 ",[24,1041,1042],{},"Embedding + 向量库 Top-K"," 这条标准路线？",[10,1045,1046,1047,1050,1051,1054,1055,1058,1059,1062,1063,1066],{},"实际上 ",[24,1048,1049],{},"我们也在做 RAG","——每次回答前都会先查书、再生成。差别在于：社区语境里的 RAG 往往默认包含 ",[24,1052,1053],{},"向量化与相似度检索","；当前方案是 ",[24,1056,1057],{},"「片段索引 + Tool 按需拉原文」","（阶段三），",[24,1060,1061],{},"刻意不引入向量层","。下面从 ",[24,1064,1065],{},"架构约束"," 说明取舍，并非否定向量 RAG 的价值。",[53,1068,1070],{"id":1069},"界定范围不是不用检索而是不用向量检索","界定范围：不是不用检索，而是不用「向量检索」",[81,1072,1073,1082],{},[84,1074,1075,1078,1079,231],{},[24,1076,1077],{},"广义 RAG","：检索相关材料 → 再生成 → ",[24,1080,1081],{},"我们在做",[84,1083,1084,1087,1088,231],{},[24,1085,1086],{},"向量 RAG","：召回依赖 Embedding 相似度 → ",[24,1089,1090],{},"当前版本不做",[10,1092,1093,1094,1097,1098,1101],{},"全书预处理为 ",[24,1095,1096],{},"片段摘要索引","；提问时模型通过 Tool 选段，再 ",[24,1099,1100],{},"回传原文","。检索增强存在，但不依赖单独的 embedding 模型与向量索引维护。",[33,1103],{},[53,1105,1107],{"id":1106},"原因一支持自定义-llm-provider配置链路要尽量短","原因一：支持自定义 LLM Provider，配置链路要尽量短",[10,1109,1110,1111,1114,1115,1118],{},"产品允许用户自由接入 ",[24,1112,1113],{},"自有 API Key","、自定义 Base URL，或使用 ",[24,1116,1117],{},"本地 Ollama","——对话模型由用户自选，成本和数据路径可控。这对很多自托管、多模型对比的场景是硬需求。",[10,1120,1121],{},"叠加典型向量 RAG 后，集成面会明显变宽：",[81,1123,1124,1135,1138],{},[84,1125,1126,1127,1130,1131,1134],{},"除 ",[24,1128,1129],{},"Chat 模型"," 外，通常还需 ",[24,1132,1133],{},"Embedding 模型","（另一 model name，有时还是另一个 endpoint）；",[84,1136,1137],{},"Ollama 等本地部署还要单独拉 embedding 模型，并处理维度、接口兼容；",[84,1139,1140,1141,1144],{},"故障域变复杂：Chat 正常但 ",[24,1142,1143],{},"检索为空"," 时，可能是 embedding、索引或维度不一致，排查成本高于「单 Provider 全链路」。",[10,1146,1147,1148,1151,1152,1155],{},"当前方案里，",[24,1149,1150],{},"选段与作答共用同一套 Provider 配置","，避免「Chat 用 A、建索引用 B」。若你在做 ",[24,1153,1154],{},"可插拔 LLM"," 的应用，这往往比多几个点的召回率更重要。",[10,1157,1158],{},[13,1159],{"alt":1160,"src":1161},"自定义 AI 服务商","https://cdn.linghuxiong.com/resources/snapshots/ai-customize-providers.png",[33,1163],{},[53,1165,1167],{"id":1166},"原因二embedding-与索引强绑定切换-provider-成本高","原因二：Embedding 与索引强绑定，切换 Provider 成本高",[10,1169,1170,1171,1174,1175,1178,1179,1182,1183,1186],{},"向量 RAG 里常被低估的一点：",[24,1172,1173],{},"向量不是通用中间格式，而是某个 embedding 模型下的坐标。"," 建库用模型 A、查询用模型 B 时，相似度通常 ",[24,1176,1177],{},"不可比","——换模型往往意味着 ",[24,1180,1181],{},"全书重新向量化","，且不同模型的 ",[24,1184,1185],{},"向量维度","（768 / 1024 / 1536 …）会绑死存储 schema。",[10,1188,1189,1190,1193,1194,1197],{},"阶段三持久化的是 ",[24,1191,1192],{},"结构化摘要 + 字符 span","，不存向量；切换 Chat 模型时 ",[24,1195,1196],{},"无需重建索引","，证据链（原文位置）不变。这与「用户随时对比不同 LLM」的目标更一致。",[33,1199],{},[53,1201,1203],{"id":1202},"原因三有目录的长文档结构化路由往往已够用","原因三：有目录的长文档，结构化路由往往已够用",[10,1205,1206,1207,1210,1211,1214,1215,1218,1219,1225],{},"电子书、PDF 通常有 ",[24,1208,1209],{},"章节结构","；预处理已产出 ",[24,1212,1213],{},"段标题 + 摘要","。对「某一章讲了什么」「书中如何定义某概念」类问题，在摘要目录上选段再 ",[24,1216,1217],{},"拉回原文","，实践中效果稳定；且 Tool 回传的是 ",[24,1220,1221,1222,1224],{},"带 ",[153,1223,842],{}," 的原文","，零幻觉仍锚定在字符 span 上。",[10,1227,1228,1229,1232,1233,1236],{},"向量检索在语义模糊、跨语言、长段落字面匹配等场景仍有优势；在 ",[24,1230,1231],{},"有 TOC、可预处理、要强溯源"," 的阅读器里，优先把复杂度放在 ",[24,1234,1235],{},"Tool + 原文回传 + 引用约束"," 上，ROI 通常更高。",[33,1238],{},[53,1240,1242],{"id":1241},"后续方向混合召回而非推倒重来","后续方向：混合召回，而非推倒重来",[10,1244,1245,1246,1249,1250,1253,1254,1257,1258,1261],{},"不排除将来增加 ",[24,1247,1248],{},"向量粗召回","（例如 embedding 只筛 Top-N 候选章节），最终仍走 ",[24,1251,1252],{},"选段 → 原文回传 → 可点击溯源","，零幻觉规则不变。若引入，会尽量满足：Embedding ",[24,1255,1256],{},"可选","、换模型时 ",[24,1259,1260],{},"显式提示重建索引","，避免 silent wrong retrieval。",[10,1263,1264,1265,231],{},"在此之前，优先保证：",[24,1266,1267],{},"任意 OpenAI 兼容 Chat API 即可工作，换 Chat 模型不必重建本地索引",[33,1269],{},[36,1271,1273],{"id":1272},"十小结","十、小结",[280,1275,1276,1289],{},[283,1277,1278],{},[286,1279,1280,1283,1286],{},[289,1281,1282],{},"环节",[289,1284,1285],{},"手段",[289,1287,1288],{},"作用",[302,1290,1291,1302,1315,1328,1339,1350],{},[286,1292,1293,1296,1299],{},[307,1294,1295],{},"预处理",[307,1297,1298],{},"按目录/长度切分 + 片段摘要缓存",[307,1300,1301],{},"长书可检索、可定位",[286,1303,1304,1307,1312],{},[307,1305,1306],{},"位置标记",[307,1308,1309,1311],{},[153,1310,155],{}," 写入原文",[307,1313,1314],{},"出处可机器解析",[286,1316,1317,1320,1325],{},[307,1318,1319],{},"Tool 检索",[307,1321,1322,1323],{},"按问题查片段/全书摘要，回传 ",[24,1324,321],{},[307,1326,1327],{},"作答前强制取证",[286,1329,1330,1333,1336],{},[307,1331,1332],{},"System Prompt",[307,1334,1335],{},"书优先、禁止伪造角标、查不到要说",[307,1337,1338],{},"约束生成行为",[286,1340,1341,1344,1347],{},[307,1342,1343],{},"前端溯源",[307,1345,1346],{},"角标 → 预览 → 跳转高亮",[307,1348,1349],{},"用户可核验证据",[286,1351,1352,1355,1358],{},[307,1353,1354],{},"不用向量检索",[307,1356,1357],{},"单 Provider、换 Chat 模型无需重建索引",[307,1359,1360],{},"降低集成与迁移成本",[10,1362,1363,1364,1367],{},"「零幻觉」不是指望模型从不犯错，而是 ",[24,1365,1366],{},"用工程结构把输出锁在证据链上","：没有检索结果就不应冒充书中内容；有检索结果则应给出可核验的原文位置。",[10,1369,1370,1371,1374,1375,1378],{},"若你也在做 AI 阅读或文档 QA，希望 ",[24,1372,1373],{},"全文直塞 → 关键句提取 → Tool-First 按需检索"," 这条演进路径，以及 ",[24,1376,1377],{},"内联位置标记 + 原文回传"," 的做法，能作为可参考的一种实现。",[18,1380,1381],{},[10,1382,1383,1384,1389,1390,1394],{},"以上是我们在开发 ",[242,1385,1388],{"href":1386,"rel":1387},"https://reader.linghuxiong.com",[246],"令狐兄","（Foxycape）AI 阅读器实践心得，仅供参考。文末可前往 ",[242,1391,1393],{"href":1392},"/zh#download","下载页面"," 体验阅读器。",{"title":618,"searchDepth":1396,"depth":1396,"links":1397},2,[1398,1404,1405,1406,1407,1411,1418,1422,1423,1430],{"id":38,"depth":1396,"text":39,"children":1399},[1400,1402,1403],{"id":55,"depth":1401,"text":56},3,{"id":137,"depth":1401,"text":138},{"id":234,"depth":1401,"text":235},{"id":425,"depth":1396,"text":426},{"id":486,"depth":1396,"text":487},{"id":501,"depth":1396,"text":502},{"id":632,"depth":1396,"text":633,"children":1408},[1409,1410],{"id":656,"depth":1401,"text":657},{"id":682,"depth":1401,"text":683},{"id":758,"depth":1396,"text":759,"children":1412},[1413,1415,1417],{"id":776,"depth":1401,"text":1414},"6.1 get_related_segment_summaries —— 针对具体问题查片段",{"id":846,"depth":1401,"text":1416},"6.2 get_full_book_segment_summaries —— 全书概览类问题",{"id":867,"depth":1401,"text":868},{"id":899,"depth":1396,"text":900,"children":1419},[1420,1421],{"id":909,"depth":1401,"text":910},{"id":920,"depth":1401,"text":921},{"id":959,"depth":1396,"text":960},{"id":1035,"depth":1396,"text":1036,"children":1424},[1425,1426,1427,1428,1429],{"id":1069,"depth":1401,"text":1070},{"id":1106,"depth":1401,"text":1107},{"id":1166,"depth":1401,"text":1167},{"id":1202,"depth":1401,"text":1203},{"id":1241,"depth":1401,"text":1242},{"id":1272,"depth":1396,"text":1273},null,"2026-06-03","分享 AI 阅读器零幻觉问答的工程实现：回答严格基于当前书籍原文，关键论述可一键溯源到具体段落。",false,"md",{},true,"/zh/blog/zero-hallucination-qa",{"title":5,"description":1433},"zh/blog/zero-hallucination-qa",[1442,1443,1444],"阅读器","AI","技术","zero-hallucination-qa","eTMSHCpDay5ePBNbB3ZRWHkahVC0sdaI3zbi8opYj9E",[1448],{"id":4,"title":5,"body":1449,"config":1431,"date":1432,"description":1433,"draft":1434,"extension":1435,"image":1431,"meta":2363,"navigation":1437,"path":1438,"seo":2364,"stem":1440,"tags":2365,"toolbar":1431,"translationKey":1445,"updated":1432,"__hash__":1446},{"type":7,"value":1450,"toc":2331},[1451,1455,1463,1465,1467,1471,1473,1475,1485,1489,1497,1501,1523,1525,1527,1537,1541,1545,1555,1559,1583,1587,1589,1596,1612,1616,1696,1706,1710,1712,1714,1718,1728,1732,1746,1750,1752,1754,1756,1760,1762,1764,1776,1782,1830,1832,1838,1843,1847,1849,1851,1855,1860,1864,1866,1870,1875,1879,1881,1887,1915,1921,1925,1927,1929,1937,1941,1945,1947,1973,1979,1983,1987,1991,1993,1999,2004,2010,2012,2014,2018,2020,2024,2026,2042,2048,2050,2052,2056,2100,2104,2106,2108,2112,2124,2126,2140,2146,2148,2150,2156,2158,2172,2178,2182,2184,2186,2196,2202,2204,2206,2218,2224,2226,2228,2238,2242,2244,2246,2312,2316,2322],[10,1452,1453],{},[13,1454],{"alt":15,"src":16},[18,1456,1457],{},[10,1458,22,1459,27,1461,31],{},[24,1460,26],{},[24,1462,30],{},[33,1464],{},[36,1466,39],{"id":38},[10,1468,42,1469,46],{},[24,1470,45],{},[48,1472],{":config":50,"code":51},[53,1474,56],{"id":55},[10,1476,1477,62,1479,66,1481,70,1483,74],{},[24,1478,61],{},[24,1480,65],{},[24,1482,69],{},[24,1484,73],{},[10,1486,1487],{},[24,1488,79],{},[81,1490,1491,1493,1495],{},[84,1492,86],{},[84,1494,89],{},[84,1496,92],{},[10,1498,1499],{},[24,1500,97],{},[81,1502,1503,1507,1511,1517],{},[84,1504,1505,105],{},[24,1506,104],{},[84,1508,1509,111],{},[24,1510,110],{},[84,1512,1513,117,1515,121],{},[24,1514,116],{},[24,1516,120],{},[84,1518,1519,127,1521,131],{},[24,1520,126],{},[24,1522,130],{},[10,1524,134],{},[53,1526,138],{"id":137},[10,1528,1529,143,1531,147,1533,151,1535,156],{},[24,1530,61],{},[24,1532,146],{},[24,1534,150],{},[153,1536,155],{},[10,1538,159,1539,163],{},[24,1540,162],{},[10,1542,1543],{},[24,1544,79],{},[81,1546,1547,1551,1553],{},[84,1548,172,1549,176],{},[24,1550,175],{},[84,1552,179],{},[84,1554,182],{},[10,1556,1557],{},[24,1558,187],{},[81,1560,1561,1565,1571,1577],{},[84,1562,1563,195],{},[24,1564,194],{},[84,1566,1567,201,1569,205],{},[24,1568,200],{},[24,1570,204],{},[84,1572,1573,211,1575,205],{},[24,1574,210],{},[24,1576,214],{},[84,1578,1579,220,1581,224],{},[24,1580,219],{},[24,1582,223],{},[10,1584,227,1585,231],{},[24,1586,230],{},[53,1588,235],{"id":234},[10,1590,1591,240,1593,248],{},[24,1592,61],{},[242,1594,247],{"href":244,"rel":1595},[246],[250,1597,1598,1602,1608],{},[84,1599,1600,257],{},[24,1601,256],{},[84,1603,1604,263,1606,267],{},[24,1605,262],{},[24,1607,266],{},[84,1609,1610,273],{},[24,1611,272],{},[10,1613,1614],{},[24,1615,278],{},[280,1617,1618,1630],{},[283,1619,1620],{},[286,1621,1622,1624,1626,1628],{},[289,1623,291],{},[289,1625,294],{},[289,1627,297],{},[289,1629,300],{},[302,1631,1632,1644,1654,1664,1674,1686],{},[286,1633,1634,1636,1638,1640],{},[307,1635,309],{},[307,1637,312],{},[307,1639,315],{},[307,1641,318,1642,322],{},[24,1643,321],{},[286,1645,1646,1648,1650,1652],{},[307,1647,327],{},[307,1649,330],{},[307,1651,333],{},[307,1653,336],{},[286,1655,1656,1658,1660,1662],{},[307,1657,341],{},[307,1659,344],{},[307,1661,347],{},[307,1663,350],{},[286,1665,1666,1668,1670,1672],{},[307,1667,355],{},[307,1669,358],{},[307,1671,361],{},[307,1673,364],{},[286,1675,1676,1678,1680,1682],{},[307,1677,369],{},[307,1679,372],{},[307,1681,375],{},[307,1683,378,1684],{},[24,1685,381],{},[286,1687,1688,1690,1692,1694],{},[307,1689,386],{},[307,1691,389],{},[307,1693,392],{},[307,1695,395],{},[10,1697,1698,401,1700,405,1702,409,1704,413],{},[24,1699,400],{},[24,1701,404],{},[24,1703,408],{},[24,1705,412],{},[10,1707,416,1708,420],{},[24,1709,419],{},[33,1711],{},[36,1713,426],{"id":425},[10,1715,429,1716,433],{},[24,1717,432],{},[81,1719,1720,1724,1726],{},[84,1721,438,1722,442],{},[24,1723,441],{},[84,1725,445],{},[84,1727,448],{},[10,1729,451,1730,455],{},[24,1731,454],{},[250,1733,1734,1738,1742],{},[84,1735,1736,463],{},[24,1737,462],{},[84,1739,1740,469],{},[24,1741,468],{},[84,1743,1744,475],{},[24,1745,474],{},[10,1747,478,1748,481],{},[24,1749,419],{},[33,1751],{},[36,1753,487],{"id":486},[48,1755],{":config":50,"code":490},[10,1757,493,1758,231],{},[24,1759,496],{},[33,1761],{},[36,1763,502],{"id":501},[10,1765,505,1766,509,1768,513,1770,517,1772,521,1774,525],{},[24,1767,508],{},[24,1769,512],{},[24,1771,516],{},[24,1773,520],{},[153,1775,524],{},[10,1777,528,1778,531,1780,535],{},[153,1779,524],{},[24,1781,534],{},[280,1783,1784,1792],{},[283,1785,1786],{},[286,1787,1788,1790],{},[289,1789,544],{},[289,1791,547],{},[302,1793,1794,1804,1814,1822],{},[286,1795,1796,1802],{},[307,1797,1798,557,1800],{},[153,1799,556],{},[153,1801,560],{},[307,1803,563],{},[286,1805,1806,1812],{},[307,1807,1808,557,1810],{},[153,1809,570],{},[153,1811,573],{},[307,1813,576],{},[286,1815,1816,1820],{},[307,1817,1818],{},[153,1819,583],{},[307,1821,586],{},[286,1823,1824,1828],{},[307,1825,1826],{},[153,1827,593],{},[307,1829,596],{},[10,1831,599],{},[10,1833,602,1834,606,1836,610],{},[24,1835,605],{},[153,1837,609],{},[612,1839,1841],{"className":1840,"code":616,"language":617,"meta":618},[615],[153,1842,616],{"__ignoreMap":618},[10,1844,623,1845,627],{},[24,1846,626],{},[33,1848],{},[36,1850,633],{"id":632},[10,1852,636,1853,640],{},[24,1854,639],{},[612,1856,1858],{"className":1857,"code":644,"language":617},[615],[153,1859,644],{"__ignoreMap":618},[10,1861,649,1862,653],{},[153,1863,652],{},[53,1865,657],{"id":656},[10,1867,660,1868,664],{},[153,1869,663],{},[612,1871,1873],{"className":1872,"code":669,"language":670,"meta":618},[668],[153,1874,669],{"__ignoreMap":618},[10,1876,675,1877,679],{},[24,1878,678],{},[53,1880,683],{"id":682},[10,1882,686,1883,693],{},[24,1884,1885],{},[690,1886,692],{},[250,1888,1889,1895,1901,1905,1911],{},[84,1890,1891,701,1893,705],{},[24,1892,700],{},[153,1894,704],{},[84,1896,1897,711,1899,715],{},[24,1898,710],{},[24,1900,714],{},[84,1902,1903,721],{},[24,1904,720],{},[84,1906,1907,727,1909,205],{},[24,1908,726],{},[24,1910,730],{},[84,1912,1913,736],{},[24,1914,735],{},[10,1916,739,1917,743,1919,747],{},[24,1918,742],{},[153,1920,746],{},[10,1922,1923],{},[13,1924],{"alt":752,"src":753},[33,1926],{},[36,1928,759],{"id":758},[10,1930,762,1931,766,1933,770,1935,231],{},[153,1932,765],{},[153,1934,769],{},[24,1936,773],{},[53,1938,777,1939,781],{"id":776},[153,1940,780],{},[10,1942,784,1943,788],{},[24,1944,787],{},[10,1946,791],{},[250,1948,1949,1953,1957,1961,1969],{},[84,1950,796,1951,800],{},[24,1952,799],{},[84,1954,803,1955,205],{},[153,1956,806],{},[84,1958,809,1959,813],{},[24,1960,812],{},[84,1962,816,1963,820,1965,824,1967,205],{},[24,1964,819],{},[153,1966,823],{},[153,1968,827],{},[84,1970,830,1971,833],{},[24,1972,266],{},[10,1974,1975,839,1977,843],{},[24,1976,838],{},[153,1978,842],{},[53,1980,847,1981,851],{"id":846},[153,1982,850],{},[10,1984,854,1985,788],{},[24,1986,857],{},[10,1988,860,1989,864],{},[153,1990,863],{},[53,1992,868],{"id":867},[10,1994,871,1995,877],{},[24,1996,1997],{},[690,1998,876],{},[612,2000,2002],{"className":2001,"code":881,"language":617},[615],[153,2003,881],{"__ignoreMap":618},[10,2005,886,2006,890,2008,894],{},[153,2007,889],{},[153,2009,893],{},[33,2011],{},[36,2013,900],{"id":899},[10,2015,903,2016,906],{},[153,2017,652],{},[53,2019,910],{"id":909},[10,2021,913,2022,917],{},[153,2023,916],{},[53,2025,921],{"id":920},[250,2027,2028,2034,2038],{},[84,2029,2030,929,2032,932],{},[24,2031,928],{},[153,2033,842],{},[84,2035,2036,938],{},[24,2037,937],{},[84,2039,2040,944],{},[24,2041,943],{},[10,2043,947,2044,951,2046,231],{},[24,2045,950],{},[24,2047,954],{},[33,2049],{},[36,2051,960],{"id":959},[10,2053,963,2054,535],{},[24,2055,966],{},[280,2057,2058,2066],{},[283,2059,2060],{},[286,2061,2062,2064],{},[289,2063,975],{},[289,2065,978],{},[302,2067,2068,2074,2082,2088,2094],{},[286,2069,2070,2072],{},[307,2071,985],{},[307,2073,988],{},[286,2075,2076,2078],{},[307,2077,993],{},[307,2079,996,2080,1000],{},[153,2081,999],{},[286,2083,2084,2086],{},[307,2085,1005],{},[307,2087,1008],{},[286,2089,2090,2092],{},[307,2091,1013],{},[307,2093,1016],{},[286,2095,2096,2098],{},[307,2097,1021],{},[307,2099,1024],{},[10,2101,2102],{},[13,2103],{"alt":1029,"src":1030},[33,2105],{},[36,2107,1036],{"id":1035},[10,2109,1039,2110,1043],{},[24,2111,1042],{},[10,2113,1046,2114,1050,2116,1054,2118,1058,2120,1062,2122,1066],{},[24,2115,1049],{},[24,2117,1053],{},[24,2119,1057],{},[24,2121,1061],{},[24,2123,1065],{},[53,2125,1070],{"id":1069},[81,2127,2128,2134],{},[84,2129,2130,1078,2132,231],{},[24,2131,1077],{},[24,2133,1081],{},[84,2135,2136,1087,2138,231],{},[24,2137,1086],{},[24,2139,1090],{},[10,2141,1093,2142,1097,2144,1101],{},[24,2143,1096],{},[24,2145,1100],{},[33,2147],{},[53,2149,1107],{"id":1106},[10,2151,1110,2152,1114,2154,1118],{},[24,2153,1113],{},[24,2155,1117],{},[10,2157,1121],{},[81,2159,2160,2166,2168],{},[84,2161,1126,2162,1130,2164,1134],{},[24,2163,1129],{},[24,2165,1133],{},[84,2167,1137],{},[84,2169,1140,2170,1144],{},[24,2171,1143],{},[10,2173,1147,2174,1151,2176,1155],{},[24,2175,1150],{},[24,2177,1154],{},[10,2179,2180],{},[13,2181],{"alt":1160,"src":1161},[33,2183],{},[53,2185,1167],{"id":1166},[10,2187,1170,2188,1174,2190,1178,2192,1182,2194,1186],{},[24,2189,1173],{},[24,2191,1177],{},[24,2193,1181],{},[24,2195,1185],{},[10,2197,1189,2198,1193,2200,1197],{},[24,2199,1192],{},[24,2201,1196],{},[33,2203],{},[53,2205,1203],{"id":1202},[10,2207,1206,2208,1210,2210,1214,2212,1218,2214,1225],{},[24,2209,1209],{},[24,2211,1213],{},[24,2213,1217],{},[24,2215,1221,2216,1224],{},[153,2217,842],{},[10,2219,1228,2220,1232,2222,1236],{},[24,2221,1231],{},[24,2223,1235],{},[33,2225],{},[53,2227,1242],{"id":1241},[10,2229,1245,2230,1249,2232,1253,2234,1257,2236,1261],{},[24,2231,1248],{},[24,2233,1252],{},[24,2235,1256],{},[24,2237,1260],{},[10,2239,1264,2240,231],{},[24,2241,1267],{},[33,2243],{},[36,2245,1273],{"id":1272},[280,2247,2248,2258],{},[283,2249,2250],{},[286,2251,2252,2254,2256],{},[289,2253,1282],{},[289,2255,1285],{},[289,2257,1288],{},[302,2259,2260,2268,2278,2288,2296,2304],{},[286,2261,2262,2264,2266],{},[307,2263,1295],{},[307,2265,1298],{},[307,2267,1301],{},[286,2269,2270,2272,2276],{},[307,2271,1306],{},[307,2273,2274,1311],{},[153,2275,155],{},[307,2277,1314],{},[286,2279,2280,2282,2286],{},[307,2281,1319],{},[307,2283,1322,2284],{},[24,2285,321],{},[307,2287,1327],{},[286,2289,2290,2292,2294],{},[307,2291,1332],{},[307,2293,1335],{},[307,2295,1338],{},[286,2297,2298,2300,2302],{},[307,2299,1343],{},[307,2301,1346],{},[307,2303,1349],{},[286,2305,2306,2308,2310],{},[307,2307,1354],{},[307,2309,1357],{},[307,2311,1360],{},[10,2313,1363,2314,1367],{},[24,2315,1366],{},[10,2317,1370,2318,1374,2320,1378],{},[24,2319,1373],{},[24,2321,1377],{},[18,2323,2324],{},[10,2325,1383,2326,1389,2329,1394],{},[242,2327,1388],{"href":1386,"rel":2328},[246],[242,2330,1393],{"href":1392},{"title":618,"searchDepth":1396,"depth":1396,"links":2332},[2333,2338,2339,2340,2341,2345,2350,2354,2355,2362],{"id":38,"depth":1396,"text":39,"children":2334},[2335,2336,2337],{"id":55,"depth":1401,"text":56},{"id":137,"depth":1401,"text":138},{"id":234,"depth":1401,"text":235},{"id":425,"depth":1396,"text":426},{"id":486,"depth":1396,"text":487},{"id":501,"depth":1396,"text":502},{"id":632,"depth":1396,"text":633,"children":2342},[2343,2344],{"id":656,"depth":1401,"text":657},{"id":682,"depth":1401,"text":683},{"id":758,"depth":1396,"text":759,"children":2346},[2347,2348,2349],{"id":776,"depth":1401,"text":1414},{"id":846,"depth":1401,"text":1416},{"id":867,"depth":1401,"text":868},{"id":899,"depth":1396,"text":900,"children":2351},[2352,2353],{"id":909,"depth":1401,"text":910},{"id":920,"depth":1401,"text":921},{"id":959,"depth":1396,"text":960},{"id":1035,"depth":1396,"text":1036,"children":2356},[2357,2358,2359,2360,2361],{"id":1069,"depth":1401,"text":1070},{"id":1106,"depth":1401,"text":1107},{"id":1166,"depth":1401,"text":1167},{"id":1202,"depth":1401,"text":1203},{"id":1241,"depth":1401,"text":1242},{"id":1272,"depth":1396,"text":1273},{},{"title":5,"description":1433},[1442,1443,1444],1780489852789]