Langchain-Chatchat 嵌入模型关键词定制指南:深入解析 add_embedding_keywords 的实现原理与实战流程
【免费下载链接】Langchain-ChatchatLangchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM, Qwen 与 Llama 等语言模型的 RAG 与 Agent 应用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain项目地址: https://gitcode.com/GitHub_Trending/la/Langchain-Chatchat
导读
在 RAG(检索增强生成)应用中,嵌入模型(Embedding Model)的"词表"决定了一个文本片段能否被精确、无歧义地表征。当知识库里频繁出现模型预训练词表之外的专有名词、领域术语或中英文混合词(例如"Chatchat""RAG""知识库检索")时,默认分词器可能将其切成碎片,导致语义检索召回效果下降。Langchain-Chatchat 文档中保留了一套为嵌入模型追加自定义关键词的完整方案:通过读取一个每行一个关键词的文本文件,生成这些关键词的嵌入表示,扩展 BERT 嵌入层词表并把改动后的模型落盘保存。本文将基于 markdown_docs/embeddings/add_embedding_keywords.md 详细拆解这一机制的三个核心函数、它们的调用链与参数细节,并结合 settings.py 中的真实配置常量说明如何在项目中串联这套流程。读完后,你将掌握"为领域场景定制嵌入模型词表"的完整方法,并理解其背后的 Token 化、词嵌入层扩展与模型持久化原理。
说明:本文所述三个函数属于 Langchain-Chatchat 演进过程中沉淀下来的嵌入模型定制方案;当前仓库保留了完整的接口文档与配置项常量(见下文
EMBEDDING_KEYWORD_FILE),实际使用时应结合当前版本代码确认函数入口,原理与配置用法完全一致。
一、为什么需要给嵌入模型"加关键词"?
1.1 RAG 检索链路中的嵌入模型
在 Langchain-Chatchat 中,知识库问答的典型链路是:文档切片 → Embedding 向量化 → 向量库召回 → 重排 → LLM 生成。其中第一步文本向量化的质量直接决定召回精度。系统通过DEFAULT_EMBEDDING_MODEL指定默认嵌入模型(默认值为bge-m3,见 settings.py),嵌入模型本身来自预训练权重。
1.2 词表缺失带来的问题
基于 BERT 架构的嵌入模型依赖WordPiece等分词算法,词表中没有的词会被切分为子词(subword)。例如中文领域词可能被拆成毫无语义的偏旁级别 token,英文专有名词可能被切得面目全非。这样即使添加关键词后文本相似度计算正常,这些词的向量表征也失去了整体语义,最终体现为知识库问答时"明明库里有答案却召不回"。
本文方案的核心思路是:既然预训练词表缺词,那就把关键词当作新 token 加入模型词表,为其单独生成词嵌入向量并冻结在模型权重里,之后分词器见到这些词即可整体切分、整体表征。
二、整体架构与调用链
整套定制流程由三个函数协作完成,呈清晰的逐级调用关系:
add_keyword_to_embedding_model(path) # 顶层入口:读取配置、拼装模型名与保存路径 │ ▼ add_keyword_to_model(model_name, keyword_file, output_model_path) │ 读取每行一个关键词的文件,加载 SentenceTransformer,取出其中的 BERT 词嵌入模块 ▼ get_keyword_embedding(bert_model, tokenizer, key_words) │ 分词 → 取 input_ids → 去特殊标记 → 查 word_embeddings → 平均 ▼ 扩展 tokenizer 词表 → resize 嵌入层 → 写入关键词向量 → 保存新模型从源码结构看,该调用链的设计意图非常明确:底层函数只负责"从词到向量"的纯计算(get_keyword_embedding),中间函数负责"加载模型 + 扩展词表 + 保存"的模型手术(add_keyword_to_model),顶层函数负责"对接项目配置"的用户入口(add_keyword_to_embedding_model),三层解耦,便于在不同场景下复用。
三、底层计算:get_keyword_embedding(bert_model, tokenizer, key_words)
3.1 函数职责
该函数负责把自然语言关键词转换成词嵌入向量,是整个定制流程的计算核心。
参数说明:
| 参数 | 类型 | 含义 |
|---|---|---|
bert_model | 预训练 BERT 模型 | 用于生成嵌入表示的模型对象 |
tokenizer | 与 BERT 匹配的分词器 | 把关键词字符串转换为模型能理解的输入格式 |
key_words | List[str] | 需要获取嵌入表示的关键词列表 |
3.2 执行步骤拆解
- 分词与编码:调用
tokenizer将关键词列表转换成模型可处理的输入格式,包括把每个词映射为input_ids,并按模型要求完成 padding(填充)与 truncation(截断)。 - 去除特殊标记:从编码结果中取出
input_ids,剔除序列首尾的[CLS]/[SEP]等特殊 token——这些标记服务于"句子级"任务,对"关键词级"的向量表示并非必需。 - 查表取向量:通过
bert_model.embeddings.word_embeddings属性(BERT 最底层的 token 嵌入查表层)按input_ids取出对应词向量。 - 池化平均:对单个关键词内部的多个 token 向量做平均,得到该关键词唯一的、整体化的向量表示。
3.3 原理与注意事项
这一实现本质上是一种轻量级"平均池化"策略:把切分后的子词向量取均值作为整个词组的向量。该方法无需额外训练即可快速为新词兜底,工程代价小。
注意点:
- 模型与分词器必须同源匹配:
bert_model与tokenizer应来自同一个预训练模型,否则 id 空间与词表不一致会直接取到错乱的向量。 - 关键词质量直接决定效果:这些向量会被写入模型并长期复用,选择不当会劣化模型在相关文本上的表征。
- 输出形状:假设传入两个关键词
["AI", "机器学习"],若词向量维度为embedding_size,函数可能返回形状为(2, embedding_size)的张量,对应两个关键词各自的平均嵌入表示。
四、核心模型扩展:add_keyword_to_model(model_name, keyword_file, output_model_path)
4.1 函数职责
该函数完成**"把关键词文件里的词真正加进预训练嵌入模型"**的完整手术,是整个流程的中枢。
参数说明:
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
model_name | str | EMBEDDING_MODEL | 要使用的预训练嵌入模型名称 |
keyword_file | str | ""(空字符串) | 自定义关键词文件路径,每行一个词 |
output_model_path | str | None | 添加关键词后的模型保存路径 |
4.2 执行步骤拆解
- 读取关键词文件:逐行读取
keyword_file,把每一行作为一个关键词追加进key_words列表。 - 加载模型并抽取词嵌入模块:按
model_name加载 SentenceTransformer 模型(sentence_transformers.SentenceTransformer),随后取该模型第一个模块作为词嵌入模型,从中进一步获取 BERT 骨干模型及其分词器。 - 生成关键词向量:调用
get_keyword_embedding(bert_model, tokenizer, key_words),得到所有关键词的嵌入表示。 - 扩展嵌入层:
- 扩展分词器词表,使新关键词成为可被独立切分的 token;
- 调用嵌入层大小调整机制(对应 BERT 的
resize_token_embeddings类 API),让模型嵌入层适配新增词的数量; - 把上一步算好的关键词向量直接赋值给新扩展出的嵌入层权重行。
- 保存模型:若传入
output_model_path,则先创建目标目录,再把更新后的词嵌入模型与 BERT 模型写入磁盘;其中 BERT 模型使用safetensors格式保存,兼顾兼容性与安全性。
4.3 关键技术点说明
- "直方图右侧补行"式的权重注入:扩展后的嵌入层在原有权重矩阵基础上追加新行,关键词向量被精确定位到新 token 的 id 上,原有 token 的向量完全不受影响——这正是该方案可逆、安全的原因。
- 保存路径为空则只改内存不落盘:当
output_model_path为None时,扩展只发生在当前进程的模型对象上,用于临时验证;只有传入保存路径才会持久化。 - 模型体积变化:因为嵌入层行数随词条增加,保存后的模型文件会略大于原模型。
五、顶层入口:add_keyword_to_embedding_model(path)
5.1 函数职责
该函数是对接 Langchain-Chatchat 项目配置的对外入口,把关键词文件与项目中的模型配置衔接起来,实现"一键定制"。
参数说明:
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
path | str | EMBEDDING_KEYWORD_FILE | 关键词文件路径 |
其中EMBEDDING_KEYWORD_FILE正是项目配置中定义的词表文件名。在 settings.py 中可以找到它的真实定义:
EMBEDDING_KEYWORD_FILE: str = "embedding_keywords.txt" """Embedding模型定制词语的词表文件"""即:项目默认的关键词词表文件名为embedding_keywords.txt,放在配置指定的数据根目录下;path未显式传参时,函数会自动定位该文件。
5.2 执行步骤拆解
- 解析关键词文件路径:通过
os.path.join(path)拼出关键词文件的完整路径。 - 读取模型配置:从配置的
MODEL_PATH["embed_model"][EMBEDDING_MODEL]中取出当前使用的嵌入模型名称与本地路径。 - 构造输出路径与唯一模型名:计算模型所在父目录,生成形如
{EMBEDDING_MODEL}_Merge_Keywords_{当前时间戳}的新模型名——时间戳保证每次产出的模型版本唯一,便于追溯"哪一批关键词在什么时间合入"。 - 调用核心函数:以当前模型名、关键词文件路径、新模型保存路径为入参调用
add_keyword_to_model,由它完成加载、扩展、保存全流程。
六、实战落地:一份可操作的配置指南
6.1 准备关键词文件
在工作目录下创建embedding_keywords.txt,格式约定为每行一个关键词,例如:
Langchain-Chatchat 知识库问答 大模型应用 bge-m3 向量检索建议把词表与模型一起纳入版本管理,方便复现与团队共享。
6.2 串联配置并触发定制
- 确认嵌入模型配置:
MODEL_PATH["embed_model"][EMBEDDING_MODEL]指向本地已下载的模型目录,且默认名称为项目使用的EMBEDDING_MODEL(Langchain-Chatchat 默认嵌入模型为bge-m3,见 settings.py)。 - 调用顶层入口
add_keyword_to_embedding_model(path="embedding_keywords.txt")。 - 程序将按前文调用链自动完成全部步骤,最终在模型父目录下产出带时间戳后缀的合并模型,例如
bge-m3_Merge_Keywords_20260908180000/。 - 把新模型目录配回
MODEL_PATH["embed_model"],重启服务,即可让知识库检索使用定制词表后的嵌入模型。
6.3 使用注意
- 关键词文件必须存在且格式正确(每行一词),否则读取阶段会失败或引入错误词条。
- 合并后模型体积增大、加载耗时略升,属正常现象;应在模型加载与运行时性能间做权衡。
- 添加关键词是影响模型整体性能的操作,应结合具体任务的实际应用价值谨慎选词,避免把随机词灌进词表稀释模型表达能力。
- 该能力解决的是"词被拆碎"问题,无法替代向量检索中的重排(rerank)等上层优化;关键词的选择与
DEFAULT_EMBEDDING_MODEL的分词特性相关,建议针对不同嵌入模型分别维护词表。
七、小结
Langchain-Chatchat 的嵌入模型关键词定制能力,用"三函数递进调用"的方式给出了一个工程上非常干净的解法:get_keyword_embedding负责把词变成平均化向量,add_keyword_to_model负责把词安全地写进模型词表并落盘,add_keyword_to_embedding_model负责对接项目配置(词表文件名EMBEDDING_KEYWORD_FILE = "embedding_keywords.txt"、默认模型名、时间戳命名的输出目录)。配合 settings.py 中已有的配置常量,开发者可以低成本地为垂直领域知识库定制嵌入模型的词表,从根上缓解专有名词被错误切分导致的召回率问题。文中三个函数的详细说明文档保存在 add_embedding_keywords.md,可作为实现细节的权威参照。
【免费下载链接】Langchain-ChatchatLangchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM, Qwen 与 Llama 等语言模型的 RAG 与 Agent 应用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain项目地址: https://gitcode.com/GitHub_Trending/la/Langchain-Chatchat
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考