LLMBundle 与模型类型
LLMBundle 与模型类型
相关源文件
本章引用的主要源码文件:
api/apps/llm_app.pyapi/db/services/tenant_llm_service.pyconf/llm_factories.jsonrag/llm/__init__.pyrag/llm/chat_model.pyrag/llm/cv_model.pyrag/llm/embedding_model.pyrag/llm/ocr_model.pyrag/llm/rerank_model.pyrag/llm/sequence2txt_model.pyrag/llm/tts_model.pyweb/src/components/layout-recognize-form-field.tsxweb/src/components/svg-icon.tsxweb/src/constants/llm.tsweb/src/hooks/use-llm-request.tsxweb/src/pages/user-setting/setting-model/constant.tsweb/src/pages/user-setting/setting-model/hooks.tsxweb/src/pages/user-setting/setting-model/modal/mineru-modal/index.tsxweb/src/pages/user-setting/setting-model/modal/ollama-modal/index.tsxweb/src/utils/common-util.tsweb/tsconfig.json
本文档记录了 RAGFlow 中的 LLMBundle 抽象层,它为各种大语言模型(LLM)提供了统一的接口层。同时,本文也涵盖了系统的模型类型分类(例如 CHAT、EMBEDDING、RERANK、TTS)以及基于工厂模式的动态注册和实例化机制。
概述
LLMBundle 是一个核心包装类,定义在 api/db/services/llm_service.py:85-456 中,它封装了针对每个租户和模型配置的底层模型实现。它构建在 LLM4Tenant(api/db/services/tenant_llm_service.py:27-82)之上,后者负责从工厂映射和租户凭证中初始化具体的提供商模型实例。
LLMBundle 的主要职责:
- 将请求方法委托给底层的提供商实例(
self.mdl)。 - 在多种模型类型之间提供一致的接口。
- 跟踪 Token 使用量,通过
TenantLLMService持久化使用数据,用于配额和计费。 - 集成可选的 Langfuse 追踪功能,实现对模型调用的可观测性。
- 支持多种模型类型,适用于各种 AI 任务(聊天、嵌入向量、重排序、文本转语音、视觉等)。
- 通过绑定租户特定的 API 密钥和模型名称,管理租户隔离。
因此,LLMBundle 充当了 RAGFlow 业务逻辑与异构大语言模型(LLM)后端之间的网关,集中处理横切关注点并简化使用。
LLMBundle 数据流与实体映射
来源:api/db/services/llm_service.py:85-456、api/db/services/tenant_llm_service.py:27-82、rag/llm/__init__.py:141-147、api/db/db_models.py:27
模型类型
RAGFlow 支持七种不同的大语言模型(LLM)模型类型。每种模型类型在 rag/llm/__init__.py:141-147 中都有一个对应的全局字典用于工厂注册(保存具体的提供商类),并与 LLMType 枚举(common/constants.py:26)中的条目对应。
| 模型类型 | 工厂字典 | LLMType 枚举 | 用途 | 基类模块 |
|---|---|---|---|---|
| Chat | ChatModel | LLMType.CHAT | 对话/文本生成 | rag/llm/chat_model.py:113-126 |
| Embedding | EmbeddingModel | LLMType.EMBEDDING | 文本转向量嵌入 | rag/llm/embedding_model.py:36-50 |
| Rerank | RerankModel | LLMType.RERANK | 文档相关性评分 | rag/llm/rerank_model.py:29-55 |
| 视觉(CV) | CvModel | LLMType.IMAGE2TEXT | 图像描述/提取 | rag/llm/cv_model.py:42-68 |
| 语音转文本 | Seq2txtModel | LLMType.SPEECH2TEXT | 音频转录 | rag/llm/sequence2txt_model.py:31-49 |
| TTS | TTSModel | LLMType.TTS | 文本转语音合成 | rag/llm/tts_model.py:67-80 |
| OCR | OcrModel | LLMType.OCR | 视觉文本识别 | rag/llm/__init__.py:147 |
动态提供商注册
提供商实现模型基类的子类,并声明一个唯一的 _FACTORY_NAME 属性。在初始化期间,RAGFlow 通过反射在 rag/llm/ 子模块中动态发现这些类,并将它们按工厂名称分配到相应的模型类型字典中。
来自 rag/llm/__init__.py:172-181 的关键代码片段:
elif name == "LiteLLMBase":
lite_llm_base_class = obj
assert hasattr(obj, "_FACTORY_NAME"), "LiteLLMbase should have _FACTORY_NAME field."
if isinstance(obj._FACTORY_NAME, list):
for factory_name in obj._FACTORY_NAME:
mapping_dict[factory_name] = obj
else:
mapping_dict[obj._FACTORY_NAME] = obj
这种方法使得添加新的提供商变得灵活,无需更改核心逻辑,只需放置命名和标记正确的新类即可。
来源:rag/llm/__init__.py:141-181、rag/llm/chat_model.py:113-126、rag/llm/embedding_model.py:36-50、rag/llm/rerank_model.py:29-55、rag/llm/cv_model.py:42-68、rag/llm/sequence2txt_model.py:31-49、rag/llm/tts_model.py:67-80
LLMBundle 架构与实现
LLMBundle 继承自 LLM4Tenant(api/db/services/tenant_llm_service.py:27-82),后者负责解析租户特定的配置、模型选择以及底层提供商模型类的实例化。
类结构与实例化流程
LLM4Tenant类从数据库查询租户模型配置,并使用ChatModel[factory](用于聊天)或EmbeddingModel[factory](用于嵌入向量)等映射来实例化适当的提供商类。LLMBundle通过添加使用量跟踪和更高级的逻辑来扩展此类。它将方法调用转发给self.mdl(具体的提供商实例)。
来自 api/db/services/llm_service.py:85-87 的构造示例:
class LLMBundle(LLM4Tenant):
def __init__(self, tenant_id: str, model_config: dict, lang="Chinese", **kwargs):
super().__init__(tenant_id, model_config, lang, **kwargs)
# self.mdl 在父类 LLM4Tenant.__init__ 中创建
来源:api/db/services/llm_service.py:85-100、api/db/services/tenant_llm_service.py:27-82、rag/llm/chat_model.py:113-126、rag/llm/embedding_model.py:123-157
使用量跟踪
LLMBundle 在对大语言模型(LLM)提供商的调用周围添加了自动的 Token 使用量跟踪。在调用 API(例如 encode、similarity、async_chat)之后,它会从响应中提取 Token 消耗量,并通过 TenantLLMService.increase_usage_by_id() 更新数据库中的使用记录。
使用量跟踪示例
嵌入向量调用示例(api/db/services/llm_service.py:95-118):
def encode(self, texts: list):
# 如果文本超过 max_length,则进行截断
safe_texts = [t[: self.max_length] if len(t) > self.max_length else t for t in texts]
# 调用底层提供商
embeddings, used_tokens = self.mdl.encode(safe_texts)
# 记录 Token 使用量,除非模型工厂是 "Builtin"
if self.model_config["llm_factory"] != "Builtin":
if not TenantLLMService.increase_usage_by_id(self.model_config["id"], used_tokens):
logging.error("Failed to update token usage")
return embeddings, used_tokens
重排序调用示例(api/db/services/llm_service.py:136-148):
def similarity(self, query: str, texts: list):
sim, used_tokens = self.mdl.similarity(query, texts)
if not TenantLLMService.increase_usage_by_id(self.model_config["id"], used_tokens):
logging.error("Failed to update token usage")
return sim, used_tokens
这种系统化的跟踪确保了基于使用量的计费和租户配额执行。
来源:api/db/services/llm_service.py:95-148、api/db/services/tenant_llm_service.py:27-82
工厂配置与数据库模式
RAGFlow 将其大语言模型(LLM)提供商和模型元数据维护在一个 JSON 文件(conf/llm_factories.json)中,并在初始化期间镜像到关系表中。
llm_factories.json 结构
- 根对象包含
factory_llm_infos,这是一个提供商工厂数组。 - 每个工厂条目包含以下属性:
name(字符串):工厂名称,例如 "OpenAI"。tags(字符串):逗号分隔的支持能力,例如 "LLM,TEXT EMBEDDING,TTS"。status、rank(元数据)。url:基础 API 端点。llm:模型定义数组,包含:llm_name:提供商模型 ID 字符串。tags:模型标签(例如 "LLM,CHAT,400k")。max_tokens:整数,上下文窗口限制。model_type:例如 "chat"、"embedding"。is_tools:布尔标志,表示是否支持工具调用。
此 JSON 在系统启动时被加载到 LLMFactories 和 LLM 表中。
加载到数据库
- 清除旧的工厂/模型记录。
- 使用工厂信息和关联的模型条目创建新记录。
- 此结构用于驱动:
- 可用工厂和模型的 API 暴露(
api/apps/llm_app.py:49-54)。 - 前端 UI 模型选择。
- 用于模型实例化的工厂键类查找。
- 可用工厂和模型的 API 暴露(
来源:conf/llm_factories.json:1-170、api/apps/llm_app.py:49-54
LLMBundle 中的模型类型接口
LLMBundle 定义了特定于模型类型的方法。这些方法调用底层提供商模型并执行使用量跟踪。
聊天模型
- 接口方法:
async_chat、async_chat_streamly。 - 如果模型支持,通过
bind_tools支持可选的工具函数绑定。 - 模型特定的行为由提供商基类处理。
- 策略调整(例如,在某些 qwen3 模型上禁用"思考"模式)在
_apply_model_family_policies中完成。
来自 api/db/services/llm_service.py:290-320 的示例片段:
async def async_chat(self, system, history, gen_conf, **kwargs):
if self.is_tools:
# 绑定工具或准备工具调用会话
pass
response, token_count = await self.mdl.async_chat(system, history, gen_conf, **kwargs)
TenantLLMService.increase_usage_by_id(self.model_config["id"], token_count)
return response, token_count
嵌入向量模型
encode执行批量编码,并带有智能截断功能。encode_queries处理单个查询编码。- 每次调用后跟踪使用量。
- 通过
self.max_length应用截断限制。
重排序模型
- 方法:
similarity。 - 通过基类方法对相关性分数进行归一化。
- 调用后记录使用量。
视觉(CV)模型
- 方法:
describe、describe_with_prompt。 - 图像透明地归一化为数据 URL。
- 调用后跟踪使用量。
语音转文本 / TTS 模型
transcription及其流式变体用于语音识别。tts用于文本转语音合成。- 根据需要处理文本归一化和片段切分。
来源:api/db/services/llm_service.py:85-456、rag/llm/chat_model.py:64-110、rag/llm/embedding_model.py:95-134、rag/llm/rerank_model.py:41-54、rag/llm/cv_model.py:88-123、rag/llm/tts_model.py:130-180
总结图:将自然语言 AI 类型连接到代码实体
总结图:高层工厂与租户模型集成
结论
LLMBundle是在 RAGFlow 中与大语言模型(LLM)交互的主要抽象层,提供了一致的多模型类型 API。- 支持多种模型类型,每种类型都有专用的提供商注册字典。
- 提供商通过
_FACTORY_NAME动态注册实现。 - 使用量跟踪、租户感知的模型选择和可观测性关注点被透明地处理。
- 工厂 JSON 配置集中管理提供商和模型元数据,与数据库表同步以用于运行时使用。
这种架构使 RAGFlow 能够在统一接口下灵活地集成多样化的 AI 提供商和模型能力。
参考资料
api/db/services/llm_service.py:85-456api/db/services/tenant_llm_service.py:27-82rag/llm/__init__.py:141-181rag/llm/chat_model.py:113-126rag/llm/embedding_model.py:36-50rag/llm/rerank_model.py:29-55rag/llm/cv_model.py:42-68rag/llm/sequence2txt_model.py:31-49rag/llm/tts_model.py:67-80conf/llm_factories.json:1-170api/apps/llm_app.py:49-54
来源:请参见页面中上述文件引用