召回与引用
检索与引用
相关源文件
本章引用的主要源码文件:
.devcontainer/github_known_hosts.secretsignorebackend/onyx/chat/chat_state.pybackend/onyx/chat/chat_utils.pybackend/onyx/chat/llm_loop.pybackend/onyx/chat/llm_step.pybackend/onyx/chat/models.pybackend/onyx/chat/process_message.pybackend/onyx/chat/prompt_utils.pybackend/onyx/context/search/models.pybackend/onyx/context/search/pipeline.pybackend/onyx/db/chat.pybackend/onyx/deep_research/dr_loop.pybackend/onyx/prompts/chat_prompts.pybackend/onyx/prompts/deep_research/__init__.pybackend/onyx/prompts/deep_research/dr_tool_prompts.pybackend/onyx/prompts/deep_research/orchestration_layer.pybackend/onyx/prompts/deep_research/research_agent.pybackend/onyx/prompts/prompt_utils.pybackend/onyx/prompts/tool_prompts.pybackend/onyx/server/query_and_chat/chat_backend.pybackend/onyx/server/query_and_chat/models.pybackend/onyx/tools/fake_tools/research_agent.pybackend/onyx/tools/models.pybackend/onyx/tools/tool_implementations/search/search_tool.pybackend/onyx/tools/tool_runner.pybackend/tests/unit/onyx/chat/test_llm_loop.pybackend/tests/unit/onyx/chat/test_llm_step.pyweb/lib/opal/src/components/buttons/open-button/README.mdweb/lib/opal/src/components/buttons/select-button/README.mdweb/src/app/app/message/CodeBlock.tsxweb/src/app/app/message/MemoizedTextComponents.tsxweb/src/app/app/message/messageComponents/MessageToolbar.tsxweb/src/components/chat/MinimalMarkdown.test.tsxweb/src/components/search/DocumentDisplay.tsxweb/src/components/search/results/Citation.tsxweb/src/lib/search/interfaces.tsweb/src/lib/search/utils.test.tsweb/src/lib/search/utils.tsweb/src/lib/utils.test.tsweb/src/lib/utils.tsweb/src/refresh-components/buttons/source-tag/SourceTag.tsxweb/tests/e2e/chat/chat_message_rendering.spec.tsweb/tests/e2e/utils/chatMock.ts
目的与范围
本文档描述了 Onyx 如何从各种来源检索文档并生成引用以支持 AI 响应。内容涵盖查找相关文档的搜索管线、将文档引用映射到引用编号的引用追踪系统,以及引用从检索经过大语言模型(LLM)生成到前端展示的完整流程。
有关配置数据源和连接器的信息,请参阅连接器框架概述。有关工具构建和执行的详细信息,请参阅工具集成。有关聊天消息处理的整体流程,请参阅消息处理流程。
检索与引用流程概览
检索与引用系统在多个阶段运行:查询生成、文档检索、引用映射、带引用标记的大语言模型(LLM)生成以及引用数据包发送。系统在整个过程中维护一个引用映射(CitationMapping = dict[int, str]),该映射将引用编号与文档 ID 关联起来。
图:端到端检索与引用流程
来源:backend/onyx/tools/tool_implementations/search/search_tool.py:4-35,backend/onyx/chat/llm_loop.py:9-72,backend/onyx/chat/llm_step.py:13-55
搜索与检索管线
SearchTool 架构
backend/onyx/tools/tool_implementations/search/search_tool.py:219-812 中的 SearchTool 类实现了内部文档搜索,采用多阶段管线:
- 查询:大语言模型(LLM)根据聊天历史生成多个查询以扩大覆盖面
backend/onyx/tools/tool_implementations/search/search_tool.py:4-8。 - 重组:使用加权倒数排名融合(RRF)合并结果,并合并相邻片段
backend/onyx/tools/tool_implementations/search/search_tool.py:13-17。 - 选择:大语言模型(LLM)选择最有前景的文档片段进行读取,以减少噪声
backend/onyx/tools/tool_implementations/search/search_tool.py:19-22。 - 扩展:选定的片段会扩展包含周围的上下文片段
backend/onyx/tools/tool_implementations/search/search_tool.py:24-29。 - 提示构建:结果以 JSON 字符串形式返回给大语言模型(LLM),同时以富对象形式提供给用户界面
backend/onyx/tools/tool_implementations/search/search_tool.py:31-34。
图:SearchTool 多查询管线
来源:backend/onyx/tools/tool_implementations/search/search_tool.py:432-812
查询生成与扩展
系统会生成多个查询变体以最大化召回率:
| 查询类型 | 函数 | 权重 | 用途 |
|---|---|---|---|
| 原始查询 | 用户的精确查询 | 2.0 | 直接匹配基线 |
| 语义查询 | semantic_query_rephrase | 1.75 | 针对混合搜索优化 |
| 大语言模型查询 | LLM 生成的查询 | 1.5 | 将复杂查询分解为子查询 |
| 关键词查询 | keyword_query_expansion | 1.25 | 覆盖关键词密集型术语 |
权重在 backend/onyx/tools/tool_implementations/search/constants.py:107-110 中定义为常量:
ORIGINAL_QUERY_WEIGHT = 2.0LLM_SEMANTIC_QUERY_WEIGHT = 1.75LLM_NON_CUSTOM_QUERY_WEIGHT = 1.5LLM_KEYWORD_QUERY_WEIGHT = 1.25
查询去重通过 deduplicate_queries backend/onyx/tools/tool_implementations/search/search_tool.py:135-155 执行,用于合并重复查询(不区分大小写)并累加其权重。
来源:backend/onyx/tools/tool_implementations/search/search_tool.py:432-530,backend/onyx/tools/tool_implementations/search/constants.py:107-110
文档重组与选择
并行搜索后,结果通过 weighted_reciprocal_rank_fusion backend/onyx/tools/tool_implementations/search/search_utils.py:117-119 进行合并。然后使用 merge_individual_chunks backend/onyx/context/search/pipeline.py:151-210 将相邻片段合并为 InferenceSection 对象。
系统随后使用大语言模型(LLM)通过 select_chunks_for_relevance backend/onyx/tools/tool_implementations/search/search_tool.py:83 识别最有前景的片段。对于选定的片段,expand_section_with_context backend/onyx/tools/tool_implementations/search/search_utils.py:102-104 会并行运行,从原始文档中拉取周围的片段。
来源:backend/onyx/tools/tool_implementations/search/search_tool.py:530-720,backend/onyx/context/search/pipeline.py:151-210
引用生成与追踪
引用处理器与映射
DynamicCitationProcessor 处理大语言模型(LLM)输出中的引用标记。它支持多种模式,包括 HYPERLINK(将 [1] 转换为链接格式)、REMOVE(去除标记)和 KEEP_MARKERS backend/onyx/chat/citation_processor.py:12-14。
核心数据结构是 CitationMapping,它将引用编号映射到文档标识符。当工具返回结果时,此映射通过 update_citation_processor_from_tool_response backend/onyx/chat/citation_utils.py:13-14 进行更新。
来源:backend/onyx/chat/citation_processor.py:12-14,backend/onyx/chat/citation_utils.py:13-14
上下文文件提取与引用
上下文文件(来自项目或角色)在集成到大语言模型(LLM)提示之前会经过提取过程。提取过程基于大语言模型(LLM)的 Token 预算执行全有或全无的适配检查。
图:上下文文件提取决策流程
当文件注入到上下文中时,会通过 _build_context_file_citation_mapping backend/onyx/chat/llm_loop.py:185-219 分配引用编号。如果文件超出预算,SearchTool 会配置 project_id_filter 或 persona_id_filter,从向量数据库中检索这些文件 backend/onyx/tools/tool_constructor.py:55-66。
来源:backend/onyx/chat/llm_loop.py:185-219,backend/onyx/tools/tool_constructor.py:55-66
深度研究引用
研究代理引用处理
研究代理流程通过使用 CitationMode.KEEP_MARKERS backend/onyx/tools/fake_tools/research_agent.py:10-11 在中间报告中保留引用标记。这使得中间报告能够维护内部引用,并在最终阶段进行整合。
在生成最终报告时,使用 collapse_citations 对所有研究代理的引用进行重新编号和去重 backend/onyx/tools/fake_tools/research_agent.py:12。
图:深度研究引用保留与重新编号
来源:backend/onyx/tools/fake_tools/research_agent.py:87-143,backend/onyx/deep_research/dr_loop.py:100-151
关键函数与类参考
| 组件 | 位置 | 用途 |
|---|---|---|
SearchTool | backend/onyx/tools/tool_implementations/search/search_tool.py:219 | 多阶段检索管线的主入口。 |
DynamicCitationProcessor | backend/onyx/chat/citation_processor.py:12 | 处理大语言模型(LLM)流中引用标记的逻辑。 |
weighted_reciprocal_rank_fusion | backend/onyx/tools/tool_implementations/search/search_utils.py:108-110 | 合并来自不同查询策略的结果。 |
merge_individual_chunks | backend/onyx/context/search/pipeline.py:151-210 | 将相邻文档片段合并为连贯的片段。 |
run_llm_loop | backend/onyx/chat/llm_loop.py:39 | 编排多轮大语言模型(LLM)推理和工具使用。 |
ChatStateContainer | backend/onyx/chat/chat_state.py:24 | 线程安全的容器,用于存储每轮对话的文档和状态。 |
来源:backend/onyx/tools/tool_implementations/search/search_tool.py:1-1005,backend/onyx/chat/llm_loop.py:1-1204,backend/onyx/context/search/pipeline.py:151-210