AI 搜索(RAG)与 LLM 集成概述

概述

Fess 支持利用大型语言模型(LLM)的 AI 搜索模式(RAG:Retrieval-Augmented Generation)功能。 通过此功能,用户可以以与 AI 助手对话的形式,基于搜索结果获取信息,直接从您的企业搜索索引中回答自然语言问题,并引用信息来源。

LLM 集成功能以 fess-llm-* 插件的形式提供。请安装与所用 LLM 提供商对应的插件。

AI 搜索模式并非通过专用的向量索引,而是通过标准的 Fess 搜索流水线(Rank Fusion)获取文档,默认使用关键词(BM25)检索。 由于该功能重用了这一标准流水线,启用核心集成的语义搜索(内容分块 + 向量搜索)后,其语义搜索器会参与所有搜索(包括 AI 搜索模式的检索步骤)中的 Rank Fusion,无需为了让语义搜索器参与其中而进行 AI 搜索模式专属的配置。不过,传递给回答生成的分块数量 可以通过 content_chunker.chat.top_k 进行调整。详情请参阅 混合搜索与 Rank Fusion(语义 + 关键词)语义搜索(内容分块 + 向量搜索)

支持的提供商

Fess 支持以下 LLM 提供商。

提供商 配置值 插件 说明
Ollama ollama fess-llm-ollama 在本地环境运行的开源 LLM 服务器。可运行 Llama、Mistral、Gemma 等模型。默认配置。
OpenAI openai fess-llm-openai OpenAI 公司的云 API。可使用 GPT-5 等模型。
Google Gemini gemini fess-llm-gemini Google 公司的云 API。可使用 Gemini 模型。

提供商比较

提供商( rag.llm.name 默认模型 端点 认证 数据存储位置
Ollama( ollama gemma4:e4b http://localhost:11434 无(本地) 本地 / 自托管 — 问题和文档保留在主机内
OpenAI( openai gpt-5-mini https://api.openai.com/v1 Authorization: Bearerrag.llm.openai.api.key 云端 — 问题及检索到的文档会被发送至 OpenAI
Google Gemini( gemini gemini-3.1-flash-lite-preview https://generativelanguage.googleapis.com/v1beta x-goog-api-keyrag.llm.gemini.api.key 云端 — 问题及检索到的文档会被发送至 Google

Note

rag.llm.name 的默认值为 ollama 。该值用于确定要加载的 DI 组件名称( {rag.llm.name}LlmClient )。因此,如果将 rag.llm.name 保持为默认值,而仅安装了 fess-llm-ollama 以外的插件,则不会启用任何 LLM 客户端。此时,日志中会输出警告 [LLM] LlmClient not found. componentName=ollamaLlmClient ,AI 搜索模式将无法使用。请务必根据所安装的插件设置 rag.llm.name 。指定 none 可明确禁用 LLM 集成。

插件安装

LLM 功能以插件形式提供。请安装与所用提供商对应的 fess-llm-{provider} 插件。

可从管理界面「系统 > 插件」页面进行安装。 fess-llm-* 插件会显示在可安装插件列表中。

如需手动安装,请将对应的 JAR 文件(例如 OpenAI 提供商对应的 fess-llm-openai-15.8.0.jar )放置到以下目录。

app/WEB-INF/plugin/

无论采用哪种方式,安装后重启 Fess 即可加载插件。

架构

AI 搜索模式功能按以下流程运作。

  1. 用户输入: 用户在聊天界面输入问题

  2. 意图解析(intent): LLM 分析用户问题,提取搜索关键词

  3. 执行搜索(search): Fess 搜索引擎搜索相关文档

  4. 结果评估(evaluate): LLM 评估搜索结果的相关性,选择最优文档

  5. 查询再生成(根据需要): 当没有搜索结果,或评估未找到相关文档时,LLM 重新生成查询并重新搜索

  6. 内容获取(fetch): 获取所选文档的正文内容

  7. 回答生成(answer): LLM 基于获取的文档生成回答(支持 Markdown 渲染)

  8. 来源引用: 回答中包含参考文档的链接

Note

内部处理由 intentsearchevaluatefetchanswer 五个阶段构成,各阶段的进度通过流式传输(SSE)通知客户端。查询再生成并非独立的阶段,而是作为 search 阶段的回退(fallback)进行通知,之后会重新执行 search

Note

上述流程是在流式 API 中意图被判定为”搜索”时的情况,实际路径会因意图判定结果而变化。当问题被判定为不明确时,将不经过搜索直接生成响应;当被要求对 URL 进行摘要时,将执行 URL 搜索但不执行评估阶段。此外,非流式的 POST /api/v2/chat 不执行评估阶段,也不进行按阶段的进度通知。

基本配置

LLM 功能的配置在以下两处进行。

管理界面的通用设置 / system.properties

在管理界面的通用设置或 system.properties 中进行配置。用于选择 LLM 提供商。

# 指定LLM提供商(ollama, openai, gemini)
rag.llm.name=ollama

fess_config.properties

app/WEB-INF/classes/fess_config.properties (软件包版中为 /etc/fess/fess_config.properties )中进行配置。除启用 AI 搜索模式、配置会话及历史记录相关设置外,提供商专属配置(连接 URL、API 密钥、生成参数等)也记录在此文件中。

# 启用AI搜索模式功能(默认为false)
rag.chat.enabled=true

# 提供商专属配置示例(以OpenAI为例)
rag.llm.openai.api.key=sk-...
rag.llm.openai.answer.temperature=0.7

有关各提供商的详细配置,请参阅以下文档。

通用配置

所有 LLM 提供商通用的配置项。这些在 fess_config.properties 中进行设置。

上下文配置

属性 说明 默认值
rag.chat.context.max.documents 上下文中包含的最大文档数 5
rag.chat.content.fields 从文档获取的字段 title,url,content,doc_id,content_title,content_description

Note

上下文最大字符数( context.max.chars )已更改为按提供商和提示类型分别配置。请在 fess_config.properties 中以 rag.llm.{provider}.{promptType}.context.max.chars 的形式进行设置。

系统提示

系统提示在各插件的 DI XML 文件中进行管理,而非属性文件。

fess-llm-* 插件的 JAR 文件内包含的 fess_llm++.xml 文件中定义了系统提示。 无需解压 JAR 文件重新编辑即可自定义提示词。借助 LastaDi 的组件重定义机制,在 app/WEB-INF/classes/ 下放置名为 fess_llm+{组件名}.xml 的文件,即可替换插件侧的组件定义。

各提供商对应的组件名称如下。

提供商 组件名称
Ollama ollamaLlmClient
OpenAI openaiLlmClient
Google Gemini geminiLlmClient

例如,若要修改 OpenAI 提供商的回答生成提示词,请创建 app/WEB-INF/classes/fess_llm+openaiLlmClient.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//DBFLUTE//DTD LastaDi 1.0//EN"
    "http://dbflute.org/meta/lastadi10.dtd">
<components>
    <component name="openaiLlmClient" class="org.codelibs.fess.llm.openai.OpenAiLlmClient">
        <postConstruct name="register"/>
        <postConstruct name="init"/>
        <preDestroy name="destroy"/>
        <property name="answerGenerationSystemPrompt">"自定义回答生成提示词"</property>
        <!-- 未修改的提示属性也需要全部写出 -->
    </component>
</components>

Warning

重定义文件会替换组件定义。因此,请务必包含原始 fess_llm++.xml 中记述的全部内容(类名、 postConstructpreDestroy ,以及未修改的提示属性)。未记述的属性将恢复为未设置状态。

Warning

请勿直接复制 fess_llm++.xml 本身并放置到 app/WEB-INF/classes/ 下。 文件名以 ++ 结尾的 DI XML 会将类路径上所有同名文件都作为”追加”加载,因此同名组件会被重复注册, 导致抛出 TooManyRegistrationComponentException ,使 Fess 无法启动。

可用性检查

属性 说明 默认值
rag.llm.{provider}.availability.check.interval 定期检查 LLM 可用性的间隔(秒) 60

此配置在 fess_config.properties 中进行。 Fess 会定期检查 LLM 提供商的连接状态。

Note

如果为该属性指定 0 以下的值或非数值,则该值将被忽略,转而使用默认值( 60 )。无法通过该属性禁用可用性检查。此外,当 rag.chat.enabledfalse 时,以及未在 rag.llm.name 中选中的提供商,均不会执行可用性检查。

会话管理

聊天会话相关配置。这些在 fess_config.properties 中进行设置。

属性 说明 默认值
rag.chat.session.timeout.minutes 会话超时时间(分钟) 30
rag.chat.session.max.size 最大会话数 10000
rag.chat.history.max.messages 对话历史中保留的最大消息数 30

并发控制

控制对 LLM 请求并发数的配置。在 fess_config.properties 中进行设置。

属性 说明 默认值
rag.llm.{provider}.max.concurrent.requests 对提供商的最大并发请求数 5
rag.llm.{provider}.concurrency.wait.timeout 并发数达到上限时,等待空闲的最长时间(毫秒)。在此时间内未获得空闲时将返回速率限制错误 30000

例如,设置 OpenAI 提供商的并发数时如下所示。

rag.llm.openai.max.concurrent.requests=10

评估配置

搜索结果评估相关配置。在 fess_config.properties 中进行设置。

属性 说明 默认值
rag.llm.{provider}.chat.evaluation.max.relevant.docs 评估阶段选择的最大相关文档数 3

按提示类型配置

可以按提示类型分别设置生成参数。这样可以根据用途进行精细调整。配置在 fess_config.properties 中进行。

提示类型一览

提示类型 配置值 说明
意图解析 intent 分析用户问题,提取搜索关键词
评估 evaluation 评估搜索结果的相关性
问题不明确 unclear 当问题不明确时生成响应
无搜索结果 noresults 当未找到搜索结果时生成响应
文档不存在 docnotfound 当对应文档不存在时生成响应
回答生成 answer 基于搜索结果生成回答
摘要 summary 生成文档摘要
FAQ faq 生成 FAQ 形式的回答
直接回答 direct 不经过搜索直接生成回答(当前版本不会被调用)
查询再生成 queryregeneration 当没有搜索结果时重新生成查询

配置模式

按提示类型的配置以如下模式指定。

rag.llm.{provider}.{promptType}.temperature
rag.llm.{provider}.{promptType}.max.tokens
rag.llm.{provider}.{promptType}.context.max.chars

配置示例(以 OpenAI 提供商为例):

# 将回答生成的temperature设低
rag.llm.openai.answer.temperature=0.5
# 回答生成的最大token数
rag.llm.openai.answer.max.tokens=4096
# 意图解析只需短回答,设置较低值
rag.llm.openai.intent.max.tokens=256
# 摘要的上下文最大字符数
rag.llm.openai.summary.context.max.chars=8000

Note

temperaturemax.tokenscontext.max.chars 可在所有提供商中通用。不过,这些参数的默认值因提供商和提示类型而异。

此外,各提供商还支持各自专属的参数。支持情况如下。

参数 Ollama OpenAI Gemini
thinking.budget 支持 不支持 支持
thinking.level 支持 不支持 不支持
top.p 支持 支持 不支持
top.knum.ctx 支持 不支持 不支持
reasoning.effort 不支持 支持 不支持
frequency.penaltypresence.penalty 不支持 支持 不支持

Note

即使指定了”不支持”的参数,也不会报错,只是会被忽略。有关各参数的含义及可设置的值,详情请参阅各提供商的文档。

Note

仅 Ollama 提供商在不存在按提示类型分别设置的情况下,具有回退到 rag.llm.ollama.default.{参数} 的机制 ( context.max.chars 除外)。OpenAI 提供商和 Gemini 提供商没有此回退机制, 若不存在按提示类型的设置,则使用插件内置的默认值。

后续步骤