Langchain-Chatchat结合关键词提取实现重点内容标注
在企业知识管理日益复杂的今天,员工每天面对海量的制度文件、合同条款和技术文档,如何快速从冗长文本中定位关键信息,已成为提升工作效率的核心挑战。尤其是在金融、医疗和法律等高合规性行业,一个被忽略的时间节点或责任人名称,可能带来严重的运营风险。
正是在这种背景下,Langchain-Chatchat作为一款开源的本地化知识库问答系统,正逐步成为构建私有智能助手的重要工具。它不仅能基于企业内部PDF、Word等非结构化文档提供精准问答,更重要的是——所有数据处理均在内网完成,彻底规避了公有云API带来的数据泄露隐患。
但仅仅“回答问题”已经不够了。用户真正需要的是:不仅知道答案,还能一眼看出答案里的重点是什么。比如,“谁负责审批?”、“截止日期是哪天?”、“涉及金额多少?”这些问题的答案,应该在输出时就被自动标亮出来。
这就引出了我们今天要探讨的技术增强方案:在 Langchain-Chatchat 中集成关键词提取机制,实现对问答结果的重点内容自动标注。
这套方案的本质,是在不改变原有 RAG(检索增强生成)流程的前提下,在输出层增加一层“语义精炼”能力。具体来说,当大模型生成回答后,系统会立即对该回答及其来源上下文进行分析,识别出其中的关键实体与核心术语,并通过前端高亮展示,让使用者无需逐字阅读即可抓住要点。
这种设计思路看似简单,实则解决了多个实际痛点:
- 新员工查阅《项目管理制度》时,不再需要反复扫描全文来找“延期审批权限”;
- 法务人员审核合同时,能迅速锁定“违约责任”“生效条件”等关键词段落;
- 客服支持团队查询产品手册,关键参数如“保修期”“适配型号”一目了然。
更重要的是,整个过程完全运行于本地环境,无需调用任何外部服务,真正实现了安全可控 + 智能可用的双重目标。
要理解这一增强机制是如何工作的,我们得先看看 Langchain-Chatchat 的底层逻辑。
这个系统本质上是一个典型的 RAG 架构:文档先被切分成小块,再通过嵌入模型转为向量存入 FAISS 或 Chroma 这类向量数据库;用户提问时,问题也会被编码成向量并检索最相关的几个文本片段;这些片段连同问题一起送入本地部署的大语言模型(如 ChatGLM3、Qwen 或 Llama3),最终生成自然语言回答。
from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import FAISS from langchain.chains import RetrievalQA from langchain.llms import HuggingFacePipeline # 加载文档 loader = PyPDFLoader("company_policy.pdf") pages = loader.load_and_split() # 分块处理 text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) docs = text_splitter.split_documents(pages) # 向量化 embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5") db = FAISS.from_documents(docs, embeddings) # 检索器 retriever = db.as_retriever(search_kwargs={"k": 3}) # 本地大模型接入 llm = HuggingFacePipeline.from_model_id( model_id="THUDM/chatglm3-6b", task="text-generation", device=0 ) # 构建问答链 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True ) # 提问测试 query = "年假是如何规定的?" result = qa_chain({"query": query}) print("回答:", result["result"])这段代码展示了完整的问答流程。但它输出的结果是一段纯文本——虽然准确,但缺乏视觉引导。如果能把“年假”、“工作年限”、“最多可休15天”这类信息自动标出来,体验将大幅提升。
于是我们在其基础上加入关键词提取模块,形成一个新的输出增强层。
这里的关键技术点在于:不能依赖大模型自己去“加粗重点”,因为这种方式不可控、难审计,且容易受 prompt 变化影响。更可靠的做法是采用独立的后处理算法,确保每处高亮都有明确依据。
目前主流的中文关键词提取方法有几种:
- TF-IDF:基于词频统计,适合通用场景;
- TextRank:图排序算法,能捕捉语义重要性;
- jieba.analyse.textrank:专为中文优化,支持指定词性过滤;
- 正则匹配 + NER:针对结构化信息(日期、金额、电话)特别有效。
我们可以组合使用这些策略,实现多维度覆盖。
例如,以下函数利用 jieba 的 TextRank 算法提取中文关键词,并限定只保留名词、人名、地名、动词等有意义的词性:
import jieba.analyse from bs4 import BeautifulSoup def extract_keywords(text, topK=5): """ 使用 TextRank 提取中文关键词,限制词性以提高质量 """ keywords = jieba.analyse.textrank( text, topK=topK, allowPOS=('ns', 'n', 'vn', 'v', 'nr') # 地名、普通名词、动名词、动词、人名 ) return keywords接着,我们将这些关键词回插到原文中,用 HTML 标签包裹实现高亮:
def highlight_text(text, keywords): """ 对文本中的关键词添加高亮标签 注意:先替换长关键词,避免嵌套冲突 """ highlighted = text for kw in sorted(keywords, key=len, reverse=True): if kw in highlighted: highlighted = highlighted.replace( kw, f'<mark style="background-color: yellow;">{kw}</mark>' ) return highlighted然后将其应用于问答系统的输出:
# 获取原始输出 source_text = result["source_documents"][0].page_content answer_text = result["result"] # 提取关键词 keywords_in_context = extract_keywords(source_text, topK=8) keywords_in_answer = extract_keywords(answer_text, topK=5) # 生成高亮文本 highlighted_answer = highlight_text(answer_text, keywords_in_answer) highlighted_context = highlight_text(source_text, keywords_in_context) print("高亮回答:") print(highlighted_answer)这样,原本平淡的回答就变成了带有视觉焦点的信息摘要。前端只需支持渲染 HTML 内容,就能让用户立刻注意到核心要素。
为了进一步提升实用性,还可以引入规则引擎来识别特定类型的结构化信息。比如财务文档中的金额、人事制度中的日期、技术支持文档中的版本号等:
import re def extract_structured_entities(text): """ 使用正则提取结构化实体 """ patterns = { "日期": r'\d{4}年\d{1,2}月\d{1,2}日', "金额": r'¥?\d+(,\d+)*\.?\d*元?', "电话": r'1[3-9]\d{9}', "邮箱": r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', "条款编号": r'第[零一二三四五六七八九十百千]+条|Article\s+\d+' } entities = {} for name, pattern in patterns.items(): matches = re.findall(pattern, text) if matches: entities[name] = list(set(matches)) return entities这类规则虽简单,但在专业场景下召回率极高,且解释性强,非常适合用于合规审查或审计辅助。
整个增强架构可以归纳为如下流程:
+------------------+ +---------------------+ | 用户提问 | --> | Langchain-Chatchat | +------------------+ | (RAG问答引擎) | +----------+-----------+ | v +----------------------------------+ | 向量检索:从FAISS中获取top-k chunk | +----------------------------------+ | v +---------------------------------------------------------+ | 大语言模型生成回答 | | 输入:问题 + 上下文 → 输出:自然语言回答 | +---------------------------------------------------------+ | +--------------------------+---------------------------+ | | v v +----------------------+ +-----------------------+ | 来源文本关键词提取 | | 回答文本关键词提取 | | (TextRank + 正则) | | (TextRank + NER) | +----------------------+ +-----------------------+ | | +--------------------------+---------------------------+ | v +----------------------------------+ | 生成高亮HTML/Mardown输出 | | 并返回至前端界面 | +----------------------------------+这是一个典型的“非侵入式增强”设计:原有问答逻辑不变,仅在输出阶段叠加一层语义解析与可视化处理。这种轻量级改造方式,既能快速落地,又便于后期维护和迭代。
在实际部署中,还需注意几个工程细节:
- 关键词去重与优先级排序:避免同一词汇多次高亮造成视觉干扰,建议按长度或频率降序处理;
- 性能控制:关键词提取应控制在毫秒级,必要时可缓存高频文档的关键词结果;
- 前端兼容性:确保
<mark>标签在移动端和不同浏览器中正常显示,提供纯文本切换选项; - 安全性防护:对用户输入做严格校验,防止恶意正则触发 ReDoS 攻击;
- 可配置性:允许管理员动态开关某些规则、调整高亮颜色主题、导入领域词典(如公司职级表、产品型号库);
此外,若系统需支持多语言文档,也可灵活切换算法。例如英文场景下改用 YAKE 或 KeyBERT,避免过度依赖中文分词工具。
从应用价值来看,这套“精准问答 + 智能标注”的组合拳,已在多个场景展现出显著优势:
- 在企业制度查询中,新员工可通过高亮快速掌握考勤、报销、晋升等政策要点;
- 在法律合同审查中,律师能迅速识别“签署方”“违约金比例”“争议解决方式”等关键条款;
- 在客户技术支持中,客服人员无需记忆全部产品参数,系统自动标出适用型号与配置要求;
- 在教育培训材料中,学员可聚焦考点与核心概念,提升学习效率。
尤为关键的是,这一切都在本地完成。没有数据上传、没有第三方依赖,完全满足金融、军工、医疗等行业的安全合规要求。
未来,这条技术路径还有更大的演进空间。例如,可以将提取出的关键词反馈给检索模块,实现“优先召回含‘责任人’‘截止时间’的段落”;也可以在 prompt 中提示模型:“请特别强调时间和审批角色”,从而形成闭环优化。
甚至可以设想一种“交互式标注”模式:用户点击某个高亮词,系统自动展开相关联的其他条款或历史案例,构建起一张动态的知识网络。
这种高度集成的设计思路,正在引领企业级智能问答系统向更可靠、更高效的方向演进。它不只是让机器“会说话”,更是让它“说清楚”。而 Langchain-Chatchat 与关键词提取的结合,正是这一趋势下的一个务实而有力的实践范例。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考