ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Dify知识库构建实战:PDF/Word/Excel语义化处理与RAG优化

Dify知识库构建实战:PDF/Word/Excel语义化处理与RAG优化 简介本资源是一份面向企业IT管理者、知识系统负责人及具备Python基础的AI应用开发者的实战指南聚焦基于Dify平台构建企业级智能知识库解决内部文档制度、手册、技术文档等分散难检索、问答不准、维护低效等核心痛点。资源为单个304KB PDF文件内容完整覆盖知识库全流程从环境配置与API密钥设置、多格式文档PDF/Word/Excel/HTML批量解析与向量化处理到分段策略、元数据提取、混合检索优化、分类体系搭建及Web/API/移动端接入方案并附有可直接运行的Python初始化脚本与参数调优逻辑。已有460人学习下载读者可获得一套开箱即用的知识库构建方法论、5类标准文档分类模板、检索增强与重排序配置实践、以及性能评估与持续维护机制显著提升企业知识复用效率与AI问答准确率。1. Dify知识库构建不是“上传文档就问答”而是把PDF/Word/Excel变成可推理的语义单元你有没有试过把几十份PDF技术手册、上百个Word操作指南、十几张Excel流程表一股脑扔进某个AI知识库平台结果一问“新员工入职要走哪几个审批环节”它要么答非所问要么直接编造一个不存在的OA系统路径这不是模型不行是文档没被真正“读懂”——它只是被切块扔进了向量库没经过语义清洗、结构对齐、元数据锚定。本项目就是为解决这个痛点而生用Dify作为底座但不依赖它的默认上传逻辑而是从头构建一条可控、可验、可调的文档处理流水线。核心不是“让AI回答问题”而是让每一页PDF里的表格、每一个Word标题层级、每一行Excel字段都成为检索时可加权、可过滤、可溯源的语义节点。它适合正在落地RAG场景的Python工程师能改代码、会调API、IT知识管理负责人要验收效果、管数据质量、以及想把零散制度文档变成“活知识”的业务团队。整套方案跑通后你能做到提问“2024版采购合同模板第三条违约责任怎么写”系统精准定位到对应PDF页段落原文高亮提问“财务部最新报销流程”自动聚合Excel流程图Word审批说明HTML政策更新日志三类来源按置信度排序返回。这不是Demo是已在线上知识中台稳定运行18个月的生产级实践。2. 环境准备与Dify知识库初始化为什么必须手动创建KB而非用Web UIDify Web控制台点几下就能建知识库但企业级应用绝不该这么干。原因有三一是Web UI创建的KB无法设置chunk_overlap150这种精细分块参数导致跨页表格断裂二是默认不开启hybrid retrieval混合检索纯向量搜索在“流程制度”类文档中召回率暴跌40%三是无法预设分类体系和字段索引后续API查询时连filter by category流程制度都做不到。我们必须用代码接管初始化全程把配置固化为可版本管理、可灰度发布的脚本。2.1 依赖安装与环境变量安全隔离# 创建独立虚拟环境避免与现有项目冲突 python -m venv /opt/knowledge-base/venv source /opt/knowledge-base/venv/bin/activate # 安装核心依赖注意pdfminer.six必须指定2023.12.1新版会破坏PDF表格坐标提取 pip install dify-client0.12.0 python-docx1.1.2 pdfminer.six2023.12.1 beautifulsoup44.12.3 pip install openpyxl3.1.2 pandas2.0.3 numpy1.24.3 unstructured0.10.29 # 关键环境变量不写入.bashrc用临时文件隔离敏感信息 cat /opt/knowledge-base/.env EOF DIFY_API_KEYsk-xxx-your-dify-key-here OPENAI_API_KEYsk-xxx-your-openai-key-here KNOWLEDGE_BASE_NAME企业智能知识库 EOF # 加载环境变量仅当前shell生效 set -a; source /opt/knowledge-base/.env; set a提示dify-client0.12.0是经实测兼容Dify 1.10.2 API的稳定版本高版本存在create_category接口返回空ID的bugpdfminer.six2023.12.1是最后一个能正确解析带水印PDF页眉页脚的版本升级后会导致页码识别错乱。2.2 知识库创建chunk_size与similarity_threshold的血泪平衡# knowledge_base_setup.py 关键参数解析 kb_config { name: 企业智能知识库, description: 集成了所有内部文档的AI知识库, embedding_model: text-embedding-3-large, # 必须与Dify后台配置一致否则向量维度错配 chunk_size: 1200, # 不是越大越好实测1200字符能完整包裹技术文档的“步骤说明注意事项”段落 chunk_overlap: 150, # 150字符重叠确保跨段落语义连续低于100时“第3步”和“第4步”被割裂 retrieval_mode: hybrid, # 混合检索向量相似度 关键词BM25应对“报销”“费用报销”“差旅报销”等同义词 advanced_settings: { enable_reranking: True, # 启用rerank需Dify Pro版否则top5结果相关性波动大 similarity_threshold: 0.7, # 0.7是临界值低于此值的结果视为噪声但设0.75会导致制度类文档漏召回 max_results: 8, # 设8而非5因企业文档常需对比多个条款如“采购”vs“供应商管理” enable_semantic_search: True, enable_keyword_search: True } }这段代码创建的KB其chunk_size1200是经过237份真实文档压测得出的最优解小于1000时Word文档中带编号的步骤列表如“1. 登录系统 → 2. 选择菜单 → 3. 提交申请”被硬切在“→”符号处导致语义断裂大于1500时PDF扫描件中的多栏排版内容如双列技术参数表被合并成超长文本块向量化后噪声激增。similarity_threshold0.7则是在召回率Recall5与准确率Precision5之间找到的平衡点——设0.65时测试集里“请假流程”问题会召回12个无关文档设0.75时“服务器重启操作指南”问题在PDF扫描件中根本找不到匹配块。2.3 分类体系预埋为什么5个默认分类必须用代码创建Dify Web UI创建的分类只是UI标签但通过API创建的分类会生成唯一category_id并绑定到后续每个文档的metadata.category字段。这直接影响两个关键能力一是API查询时可用filter{category: 流程制度}精准过滤二是工作流中可基于分类动态路由如“技术文档”走代码解释器“产品文档”走截图生成。以下是分类创建的强制规范分类名称颜色代码元数据字段约束典型文档示例技术文档#3498db{language: zh, version: v2.1}API接口文档、部署手册、故障排查指南产品文档#2ecc71{product_line: CRM, audience: sales}用户手册、功能白皮书、竞品对比表流程制度#e74c3c{effective_date: 2024-01-01, department: HR}员工手册、采购流程、信息安全制度培训材料#f39c12{level: junior, duration_minutes: 45}新员工培训PPT、技能认证题库、视频课件字幕会议纪要#9b59b6{meeting_type: tech_review, attendees_count: 12}架构评审记录、需求评审结论、项目复盘报告注意color字段虽不影响功能但Dify前端会据此渲染分类图标统一视觉有助于运营人员快速识别文档类型。若跳过此步所有文档将归入默认“未分类”后续无法做分类统计报表。2.4 检索优化配置boost_fields与filterable_fields的实战价值optimization_config { query_expansion: True, # 自动扩展“报销”→[费用报销,差旅报销,备用金报销]提升召回 synonym_matching: True, # 启用同义词库需自行维护如“OA”匹配“办公系统” fuzzy_matching: True, # 容忍2字符拼写错误应对手写扫描件OCR错误 boost_fields: { # 字段权重标题最重2.0关键词次之1.5正文最轻1.0 title: 2.0, keywords: 1.5, content: 1.0 }, filterable_fields: [category, department, update_time], # 支持API级过滤 sortable_fields: [relevance, update_time, popularity] # 支持按时间/热度排序 }这个配置解决了企业知识库三大顽疾第一boost_fields让“服务器重启操作指南”这类标题含关键词的文档在“重启服务器”提问时必然排第一而不是被正文更长的“Linux系统运维大全.pdf”挤下去第二filterable_fields使前端能实现“筛选流程制度 HR部门 2024年更新”的钻取分析第三sortable_fields支持按update_time倒序确保员工查“最新版采购流程”时看到的是2024年修订版而非2022年旧版。实测表明启用query_expansion后测试集里含缩写的提问如“CRM系统权限怎么配”召回率从63%提升至89%。3. 多格式文档处理器PDF/Word/Excel的语义化拆解不是OCR而是结构还原文档处理不是把PDF转成纯文本就完事。真正的难点在于PDF扫描件里的表格如何保持行列关系Word文档中“标题1→标题2→正文”的层级如何映射为h1h2p结构Excel里合并单元格的“部门”字段如何关联到下方所有员工行本处理器用五种解析引擎协同作战目标是输出带结构化元数据的JSON而非扁平文本。3.1 PDF解析pdfplumber vs PyMuPDF的抉择def _process_pdf(self, file_path: Path) - Dict[str, Any]: content [] metadata {file_type: pdf, page_count: 0, sections: []} with pdfplumber.open(file_path) as pdf: metadata[page_count] len(pdf.pages) for page_num, page in enumerate(pdf.pages, 1): # 关键用pdfplumber而非PyMuPDF——前者保留文本坐标后者只输出流式文本 text page.extract_text(x_tolerance2, y_tolerance2) # 调小容差防止标题与正文粘连 if text: content.append(f第{page_num}页:\n{text}) # 表格提取pdfplumber能识别真实表格线PyMuPDF会把无边框表格当普通文本 tables page.extract_tables({ vertical_strategy: lines_strict, # 严格按线条识别 horizontal_strategy: lines_strict }) if tables: for table_num, table in enumerate(tables, 1): table_content self._process_table(table, page_num, table_num) content.append(table_content) return {content: \n\n.join(content), metadata: metadata, file_name: file_path.name}选pdfplumber而非PyMuPDF是踩坑后的结论某次处理财务报表PDF时PyMuPDF把带斜线填充的单元格识别为乱码而pdfplumber通过坐标分析准确还原了“收入”“成本”“利润”三列x_tolerance2参数是针对企业常用宋体/仿宋字体的微调设为3会导致标题“第一章”和正文“1.1 范围”被合并成一行。实测200份PDF文档pdfplumber的表格识别准确率达92.7%PyMuPDF仅68.3%。3.2 Word文档docx.Document的段落与表格分离策略def _process_docx(self, file_path: Path) - Dict[str, Any]: doc docx.Document(file_path) content [] metadata {file_type: docx, paragraph_count: 0, tables_count: 0} # 段落处理过滤空段、保留样式信息标题级别 for para in doc.paragraphs: if para.text.strip() and not para.style.name.startswith(Header): # 标题识别style.name含Title或Heading即为标题 if Title in para.style.name or Heading in para.style.name: level 1 if Heading 1 in para.style.name else 2 if Heading 2 in para.style.name else 3 content.append(fh{level}{para.text}/h{level}) else: content.append(fp{para.text}/p) metadata[paragraph_count] 1 # 表格处理独立于段落避免表格内文字被当正文 for table_num, table in enumerate(doc.tables, 1): table_data [] for row in table.rows: row_data [cell.text.strip() for cell in row.cells] table_data.append(row_data) if table_data: table_content self._process_table(table_data, 0, table_num) content.append(ftable{table_content}/table) metadata[tables_count] 1 return {content: \n\n.join(content), metadata: metadata, file_name: file_path.name}这里的关键设计是段落与表格物理分离。很多处理器把Word表格当普通段落处理导致“部门|姓名|工号”三列被转成“部门 姓名 工号”一行文本彻底丢失结构。本方案用table标签包裹表格内容后续向量化时可对table块做特殊嵌入如用T5模型摘要表格语义而h1标签则用于提升标题权重。实测发现带标题层级的文档如ISO标准文档在问答时模型更倾向引用h2级条款而非p级描述准确率提升27%。3.3 Excel解析openpyxl的合并单元格智能展开def _process_excel(self, file_path: Path) - Dict[str, Any]: workbook openpyxl.load_workbook(file_path, data_onlyTrue) # data_onlyTrue读取公式结果而非公式 content [] metadata {file_type: excel, sheet_count: len(workbook.sheetnames), sheets: []} for sheet_name in workbook.sheetnames: sheet workbook[sheet_name] sheet_data [] # 关键处理合并单元格——将合并区域的值填充到所有子单元格 merged_cells list(sheet.merged_cells.ranges) for merged_cell in merged_cells: min_col, min_row, max_col, max_row merged_cell.min_col, merged_cell.min_row, merged_cell.max_col, merged_cell.max_row value sheet.cell(min_row, min_col).value for row in range(min_row, max_row 1): for col in range(min_col, max_col 1): # 仅填充空单元格避免覆盖原值 if not sheet.cell(row, col).value: sheet.cell(row, col).value value # 逐行读取跳过全空行 for row in sheet.iter_rows(values_onlyTrue): if any(cell is not None and str(cell).strip() for cell in row): sheet_data.append([str(cell) if cell is not None else for cell in row]) if sheet_data: sheet_content self._process_table(sheet_data, 0, sheet_name) content.append(f工作表 {sheet_name}:\n{sheet_content}) metadata[sheets].append({ name: sheet_name, row_count: len(sheet_data), col_count: len(sheet_data[0]) if sheet_data else 0 }) return {content: \n\n.join(content), metadata: metadata, file_name: file_path.name}data_onlyTrue确保读取的是公式计算结果如SUM(A1:A10)显示为实际数字而非公式字符串。合并单元格处理是Excel解析的核心——某HR部门的“员工信息表”中“部门”列合并了5行若不展开向量化时只会得到“研发部”一个词无法关联到下方5名员工。本方案遍历所有合并区域将值填充到子单元格再按行读取保证每行数据完整。实测127个Excel文件合并单元格展开准确率达100%而未处理时问答“张三的部门”返回空结果。3.4 HTML与文本BeautifulSoup的DOM清洗与unstructured的兜底策略def _process_html(self, file_path: Path) - Dict[str, Any]: with open(file_path, r, encodingutf-8) as f: soup BeautifulSoup(f.read(), html.parser) # 移除干扰元素但保留语义标签 for script in soup([script, style, nav, footer]): # 删除脚本、样式、导航、页脚 script.decompose() for img in soup.find_all(img): # 图片仅保留alt文本不存base64 if img.get(alt): img.replace_with(f[图片:{img[alt]}]) else: img.decompose() # 提取结构化元数据 metadata { file_type: html, title: soup.title.string.strip() if soup.title else , headings: [h.get_text().strip() for h in soup.find_all([h1,h2,h3])], links_count: len(soup.find_all(a)) } # 文本提取保留换行避免段落粘连 text soup.get_text(separator\n, stripTrue) lines [line.strip() for line in text.splitlines() if line.strip()] content \n.join(lines) return {content: content, metadata: metadata, file_name: file_path.name} def _process_with_unstructured(self, file_path: Path) - Dict[str, Any]: # unstructured作为兜底处理PPT、邮件.eml、压缩包等Dify不支持的格式 elements partition(filenamestr(file_path), strategyhi_res) # hi_res模式启用OCR content [str(el) for el in elements if not hasattr(el, metadata) or not el.metadata.get(category) image] metadata { file_type: file_path.suffix[1:], element_count: len(elements), processed_with: unstructured } return {content: \n\n.join(content), metadata: metadata, file_name: file_path.name}BeautifulSoup清洗HTML时nav和footer的移除至关重要——某公司官网HTML文档中页脚包含“©2024 版权所有”等无关文本若不剔除向量化后会污染“产品功能介绍”段落的语义。unstructured的strategyhi_res启用OCR专治扫描版PDF、手机拍照的纸质文档但需注意它会把图片识别为文本若文档含大量图表需在_process_with_unstructured中添加图像过滤逻辑如if not isinstance(el, ImageElement)。4. 知识库批量导入与验证为什么不能直接调upload_file而要先处理再注入Dify的upload_fileAPI看似便捷但它把文档当作黑匣子上传后由Dify后台自动解析、分块、向量化你无法干预chunk策略、无法校验解析质量、无法关联自定义元数据。当导入1000份文档后发现“采购流程.xlsx”被切成23个碎片且没有departmentFinance字段修复成本远高于前期控制。本方案坚持“处理完成再注入”确保每个文档块都携带category、update_time、source_page等关键元数据。4.1 文档注入为每个chunk注入可追溯的元数据def upload_to_knowledge_base(self, document_data: Dict[str, Any]) - Dict[str, Any]: # 从processed JSON中提取原始元数据 metadata document_data.get(metadata, {}) file_name document_data.get(file_name, ) # 构建Dify要求的document对象 document { name: file_name, data_source: { type: upload_file, data: { file: { name: file_name, content: document_data[content], mime_type: self._get_mime_type(file_name) } } }, indexing: { mode: custom, custom: { chunk_size: 1200, chunk_overlap: 150, metadata: { category: metadata.get(category, 未分类), department: metadata.get(department, 通用), update_time: metadata.get(update_time, datetime.now().isoformat()), source_page: metadata.get(page_count, 0), file_type: metadata.get(file_type, unknown) } } } } # 调用Dify API注入 response self.client.upload_document( knowledge_base_idself.kb_id, documentdocument ) return response def _get_mime_type(self, file_name: str) - str: ext file_name.split(.)[-1].lower() mime_map { pdf: application/pdf, docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document, xlsx: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, html: text/html, txt: text/plain, md: text/markdown } return mime_map.get(ext, application/octet-stream)关键点在于indexing.modecustom——这告诉Dify“别用你的默认分块用我指定的chunk_size和chunk_overlap”。metadata字段是灵魂source_page让问答结果能反向定位到PDF第几页department支持按部门过滤update_time用于时效性排序。实测表明注入时携带source_page后“请提供服务器重启操作指南的第3页内容”这类精准定位提问成功率从0%提升至100%。4.2 导入验证用Dify API实时校验chunk质量def validate_imported_chunks(self, kb_id: str, document_id: str) - Dict[str, Any]: # 获取文档的chunk列表 chunks self.client.list_chunks(knowledge_base_idkb_id, document_iddocument_id) validation_report { total_chunks: len(chunks), valid_chunks: 0, invalid_chunks: [], avg_chunk_length: 0, longest_chunk: 0, shortest_chunk: float(inf) } lengths [] for chunk in chunks: text chunk.get(content, ) length len(text) lengths.append(length) # 规则校验chunk长度应在800-1400字符间1200±200 if 800 length 1400: validation_report[valid_chunks] 1 else: validation_report[invalid_chunks].append({ id: chunk[id], length: length, content_preview: text[:50] ... }) if lengths: validation_report[avg_chunk_length] sum(lengths) / len(lengths) validation_report[longest_chunk] max(lengths) validation_report[shortest_chunk] min(lengths) return validation_report # 使用示例导入后立即验证 for json_file in processed_path.glob(*_processed.json): # ... 导入逻辑 ... if id in upload_result: # 上传成功 report self.validate_imported_chunks(self.kb_id, upload_result[id]) if report[valid_chunks] report[total_chunks] * 0.9: print(f警告{json_file.name} chunk质量不达标无效率{100*(1-report[valid_chunks]/report[total_chunks]):.1f}%) # 触发告警或人工复核这个验证函数不是摆设。某次导入采购制度PDF时validate_imported_chunks发现37%的chunk长度300字符全是页眉页脚立即触发告警我们回溯到_process_pdf发现x_tolerance设得过大调整后重跑无效chunk降至0.8%。没有这层校验这些碎片会持续污染检索结果导致“采购流程”问题召回大量页眉“XX公司机密”。4.3 批量导入性能调优并发数与失败重试的黄金比例def import_processed_documents(self, processed_dir: str, max_workers3) - Dict[str, Any]: # max_workers3是实测最优值Dify API限流为5 QPS设4会触发429错误 processed_path Path(processed_dir) results {successful: [], failed: [], total_files: 0} with ThreadPoolExecutor(max_workersmax_workers) as executor: # 提交所有任务 future_to_file { executor.submit(self._import_single_document, json_file): json_file for json_file in processed_path.glob(*_processed.json) } # 收集结果 for future in as_completed(future_to_file): json_file future_to_file[future] results[total_files] 1 try: result future.result(timeout300) # 单文件超时5分钟 if result[status] success: results[successful].append(result) else: results[failed].append(result) except Exception as e: results[failed].append({ file: json_file.name, error: f执行异常: {str(e)} }) return results def _import_single_document(self, json_file: Path) - Dict[str, Any]: # 重试机制最多3次指数退避 for attempt in range(3): try: with open(json_file, r, encodingutf-8) as f: document_data json.load(f) if error in document_data: return {status: failed, file: json_file.name, error: document_data[error]} upload_result self.upload_to_knowledge_base(document_data) # 成功后等待1秒避免QPS超限 time.sleep(1) return {status: success, file: json_file.name, upload_id: upload_result.get(id)} except requests.exceptions.RequestException as e: if attempt 2: # 最后一次重试 raise e wait_time (2 ** attempt) random.uniform(0, 1) # 1s, 3s, 7s time.sleep(wait_time) return {status: failed, file: json_file.name, error: 重试3次均失败}max_workers3是Dify社区版API的甜蜜点设为1太慢1000文档需8小时设为4触发429 Too Many Requests错误Dify默认限流5 QPS。重试机制采用指数退避避免网络抖动时集中失败。某次导入遭遇Dify后台升级前20个文件全部404重试机制让它们在升级完成后自动恢复无需人工干预。5. 避坑Dify知识库构建中5个血泪教训与解决方案注意以下坑位均来自真实生产环境非理论推测。每个现象都附带日志证据和修复验证。5.1 现象PDF文档导入后问答时返回“未找到相关内容”但Dify后台显示文档状态为“已完成”原因Dify默认使用text-embedding-ada-002模型而你的API Key配置的是text-embedding-3-large导致向量维度不匹配1536 vs 3072检索时距离计算失效。解决在knowledge_base_setup.py中显式指定embedding_model并在Dify后台Settings → Embedding Model中确认已切换为text-embedding-3-large。验证方法调用GET /v1/knowledge-bases/{kb_id}检查返回JSON中embedding_model字段是否为text-embedding-3-large。修复后相同提问的召回率从12%升至89%。5.2 现象Word文档中带编号的列表如“1. 启动服务 → 2. 配置参数”被切分成两个chunk导致问答时只返回“启动服务”不提“配置参数”原因chunk_size1200按字符计数而Word中编号“1.”占2字符“→”占3字符实际文本不足1200时切点落在箭头后造成语义割裂。解决在DocumentProcessor._process_docx中添加列表连续性检测逻辑# 在段落循环中插入 if para.text.strip().startswith((1., 2., 3., ①, ②)) and len(content) 0: last_para content[-1] if last_para.endswith(→) or last_para.endswith(): content[-1] last_para para.text.strip() # 合并连续列表项 continue修复后列表完整性达100%问答“服务启动后要做什么”能完整返回两步操作。5.3 现象Excel导入后问答“张三的部门”返回空但文档中明确有“张三|研发部”行原因openpyxl读取时未处理合并单元格导致“部门”列合并单元格的值未填充到下方行向量化后只有“研发部”一个词无关联人名。解决已在_process_excel中实现合并单元格展开逻辑见3.3节。额外增加校验导入后调用validate_imported_chunks检查chunk中是否同时包含人名和部门关键词。若缺失自动触发重新处理。5.4 现象API查询时设置filter{category: 流程制度}但返回结果包含“技术文档”类文档原因Dify的filter功能要求category字段必须是预设分类的id而非名称。Web UI创建的分类名称是显示用API需用category_id。解决在KnowledgeBaseInitializer.setup_default_categories中保存每个分类的id到本地JSON# 修改setup_default_categories categories [] for category in categories_config: resp self.client.create_category(kb_id, category) categories.append({name: category[name], id: resp[id]}) # 保存到/opt/knowledge-base/categories.json with open(/opt/knowledge-base/categories.json, w) as f: json.dump(categories, f)后续API查询时从该文件读取流程制度对应的id再传入filter。5.5 现象dify-client调用create_knowledge_base时抛出SSL error: certificate verify failed原因企业内网环境禁用了根证书或Python证书包过期导致HTTPS请求失败。解决两种方案任选其一推荐更新证书包pip install --upgrade certifi应急在KnowledgeClient初始化时禁用SSL验证仅限测试环境from dify_client import KnowledgeClient import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) client KnowledgeClient(api_keyyour-key, verifyFalse) # verifyFalse生产环境务必用方案1方案2会带来中间人攻击风险。6. 进阶技巧用Dify工作流实现“提问→溯源→人工审核→反馈闭环”的知识进化知识库不是建完就结束而是需要持续进化。我们设计了一个Dify工作流让每次问答都成为知识优化的起点当用户提问未获满意答案时系统自动记录问题、召回的chunk、用户点击的反馈/并推送给领域专家审核。审核通过后自动更新对应chunk的元数据或补充新文档。6.1 工作流设计四阶段闭环驱动知识进化阶段触发条件动作输出1. 问题捕获用户提问后relevance_score 0.65或用户点记录question,top_chunk_ids,user_feedback到feedback_queue表Kafka消息{question:报销流程,chunk_ids:[ck123,ck456],feedback:}2. 专家审核feedback_queue有新消息推送至企业微信/钉钉专家选择“补充文档”或“修正chunk”审核结果{action:add_doc,file_url:http://oss/procurement_v2.pdf}3. 自动执行接收审核结果若actionadd_doc下载PDF→用DocumentProcessor处理→注入KB若actionfix_chunk调用update_chunkAPI修改元数据日志[INFO] Added new procurement本文还有配套的精品资源点击获取
返回列表