基于大众点评文本与Qwen大模型 LangExtract+RAG演示案例
本篇是继续【大型语言模型(LLM)文本中提取结构化信息:LangExtract(一)】,根据github的开源项目【LangExtract-RAG】改编,放在我自己的github当中:
LangExtract-RAG-ch

1 引言
本项目改编自:https://github.com/PromtEngineer/LangExtract-RAG 。该类 RAG(Retrieval-Augmented Generation)示例可以抽象为以下五个连续步骤:
- LangExtract:使用结构化抽取工具(示例为 langextract),从原始文本中提取结构化字段(metadata)。
- Metadata + Chunks:将抽取出的 metadata 与文本块(chunks,若实现)建立关联,用作后续索引的附带信息。
- Vector DB:将文本块(或整文档)向量化并写入向量数据库,支持语义相似度检索。
- Filter:对用户 query 做结构化解析,抽取可用的 metadata 过滤条件(如店名、评分、关注点等)。
- Search Subset:根据 filters 与语义检索结果,筛选最相关的候选(subset),作为生成模型的上下文进行回答。
需注意:原仓库提供的是简化的概念验证(proof-of-concept)实现:优先使用 LangExtract,失败回退正则;
索引层用 SmartVectorStore 模拟(内存列表 + 子串/元数据匹配);
未实现 chunking、embedding 或真实向量数据库。
2 本项目介绍:中文点评场景的改写
我将原示例改写为面向中文大众点评评论的演示脚本(langextract_rag_cn.py),并配套 README 与 requirements。下文按子项说明关键实现与设计思想。
2.1 项目流程
整体流程沿用原始项目,但字段与抽取逻辑针对中文点评定制,核心流程如下:
- Documents:
get_sample_documents()返回静态样本(id、title、content)。生产环境应替换为从数据库/API 拉取。 - LangExtract 优先:
FixedLangExtractProcessor尝试导入langextract并用中文 prompt 抽取以下字段:- shop_name(店名)
- rating(评分,仅数字)
- review_date(YYYY-MM-DD)
- review_focus(主要关注:口味/环境/服务/价格)
- tags(标签列表)
- sentiment(情感:positive/negative/neutral)
抽取后通过_process_and_normalize映射并规范化成统一 metadata(shop/rating/date/focus/tags/sentiment)。
- 正则回退:若未安装
langextract或抽取失败,使用_enhanced_regex_extraction回退。正则规则包括:- 从 content 中提取“店名:XXX”或 title 的前缀;
- 匹配“5星”、“评分:5”等表示评分的表达;
- 匹配 YYYY-MM-DD 日期;
- 识别“标签:…”或关键词构建 tags;
- 基于关键词判断关注点(口味/环境/服务/价格);
- 以关键词表做粗略情感判断。
- 规范化与回退融合:即便使用 LangExtract,也会在关键字段缺失时回退使用正则结果进行补齐,保证 metadata 的可用性。
2.2 如何通过 SmartVectorStore 进行文档索引
在示例中,SmartVectorStore 是一个内存级“索引器”,主要职责:
add_documents(docs):把带 metadata 的文档列表保存到内存(self.documents = docs)。search(query, filters):实现检索逻辑(模拟),返回满足条件的文档列表。该实现没有向量或 embedding,仅依赖字符串匹配与 metadata 过滤。
索引过程非常简单:把带 metadata 的对象存入列表。示例的意图是演示“metadata 驱动的检索”概念而不是提供高性能检索引擎。
2.3 SmartVectorStore 的工作原理(基于元数据模糊匹配 + 子串匹配)
虽然名为 SmartVectorStore,但该示例未使用任何向量化技术。检索逻辑要点如下:
- 无 filters(filters=None)时:对 query 按空白拆词,只要文档 content 含任一词即认为命中并返回。
- 有 filters 时:逐条文档判断以下字段是否匹配(示例支持 shop、rating、focus、sentiment):
- shop(店名)模糊匹配:
- 首先 lowercase 后做包含判断(filter_shop in doc_shop 或反向);
- 若失败,移除常见词(“店/餐厅/馆/面馆/烧烤”等)并拆词,做集合交集判定;
- 若无交集视为不匹配。该策略对短名与带后缀的店名有一定鲁棒性,但仍会出现假阳性/假阴性。
- rating(评分)匹配:
- 尝试将 filters[‘rating’] 转为整数,判定文档评分是否 >= 目标(示例采用“至少 X 星”语义);若非数字则回退为字符串包含匹配。
- focus 与 sentiment:
- 以精确匹配为主(filters 的值必须等于文档 metadata 对应字段)。
- shop(店名)模糊匹配:
- 最后一步:即便 metadata 匹配成功,仍要求文档 content 包含 query 的某个关键词(子串匹配),以避免仅靠 metadata 返回与 query 无关的文档。
该检索逻辑在小样本下较易理解,但缺乏语义召回能力与细粒度定位(因为未做 chunking)。
2.4 如何通过 extract_smart_filters 从 query 提取 filters
extract_smart_filters 用规则与正则从中文查询中提取结构化过滤条件:
- 评分提取:匹配“5星”“评分5”“至少4分”等表达,将数字写入 filters[‘rating’]。
- 店名识别:示例使用样本内的关键词映射(如“老王”→“老王烧烤”),生产应使用通用实体识别或别名库。
- 关注点识别:基于 query 中是否包含“口味/味道/好吃/难吃”等关键词设置 focus=‘口味’,同理识别“环境”“服务”“价格”等。
- 情感识别:若 query 含“好评/推荐/满意”标记 positive,含“差评/失望”标记 negative。
提取的 filters 作为 SmartVectorStore.search(query, filters) 的参数,实现 metadata + 文本的混合检索。
3 该项目的弊端:技术限制与工程化挑战
虽然示例清晰地演示了 metadata 驱动检索的思想,但为教学/演示而做出的简化带来若干明显局限,以下为主要弊端、影响与改进建议。
3.1 过度依赖正则与硬编码规则
- 问题:正则和关键词对自然语言变体极度脆弱(如“五星好评”“给他打5分”等多种表达会被漏掉);否定句或复杂句会导致情感误判。
- 影响:抽取召回率低、误抽或漏抽,干扰统计与检索结果。
- 建议:短期扩展正则与同义词库并做文本预处理;长期用 NER/分类模型或 LangExtract 替代单纯正则,并为抽取结果附带置信度。
3.2 没有分块(chunking),metadata 仅文档级
- 问题:一条评论常同时包含正负两方面观点(“环境好但菜太咸”),文档级标签无法反映细粒度。
- 影响:检索难以精确匹配用户关注的片段,上下文噪声影响生成质量。
- 建议:实现 chunking(基于句子或固定 token 长度),为每个 chunk 抽取 chunk 级 metadata 并单独索引。
3.3 未使用 embedding/向量化,检索基于子串匹配
- 问题:无法处理同义替换或隐式表达(例如“赞”“味道一级棒”与“好吃”语义相似)。
- 影响:语义召回能力差,召回率低。
- 建议:引入 embedding(OpenAI/Cohere/HF),配合向量数据库(FAISS/Chroma/Pinecone/Weaviate)做语义检索,并与 metadata 过滤结合。
3.4 extract_smart_filters 规则化不足、覆盖面窄
- 问题:演示中对店名和意图做硬编码,泛化能力弱。
- 影响:多数真实查询不能被正确解析为 filters。
- 建议:使用中文 NER/意图识别模型,维护店名别名库与模糊匹配表。
3.5 缺少置信度、审计与可追溯性
- 问题:抽取字段没有置信度或来源注记(langextract vs regex),难以回溯错误。
- 建议:为每字段返回置信度、原始匹配片段与抽取来源,低置信度触发人工审核或二次抽取。
3.6 可扩展性与性能问题
- 问题:
SmartVectorStore线性扫描内存列表,不适合大规模评论(万级以上)。 - 建议:使用持久化索引(向量 DB 或倒排索引),实现分段检索(metadata 过滤 → 向量检索 → rerank),并增加缓存与并发处理支持。
3.7 情感与评分判定脆弱(否定/复合句处理不足)
- 问题:关键词法无法正确处理“并不推荐”“不是很好”等否定/复合表达。
- 建议:使用面向中文的情感分类器或基于 aspect 的情感分析,并加入否定检测与上下文依赖判定。
4 结语与后续方向
本文基于原始 LangExtract-RAG 的流程,介绍了我对中文大众点评评论场景的改写实现(langextract_rag_cn.py),并详细阐述了实现思路:优先调用 LangExtract、回退到中文正则、metadata 规范化、以及内存级 SmartVectorStore 的 metadata 驱动检索流程。
同时列举了该示例的主要工程与算法局限(如未做 chunking、未使用 embedding、过度依赖正则等),并提出了短期与长期的改进建议。
我已将该示例整理为单文件脚本并配套 README 与 requirements,便于本地快速验证抽取与检索逻辑。后续若要工程化推进,建议优先做:文本预处理与正则扩充、chunking + chunk 级 metadata、embedding 验证与向量 DB 迁移、以及基于小模型的 query→filters 解析与情感分类。
这些改进将在提升召回与精确度、提高系统鲁棒性及可扩展性方面带来显著收益。
更多推荐
所有评论(0)