1. 项目概述:这不是插件,是知识调度中枢的重构
“给你的 DeepSeek Harness 装个‘外挂大脑’”——这个标题乍看像营销话术,但实操下来你会发现,它根本不是加个按钮、拖个模块那么简单。WeKnora 不是 DeepSeek Harness 的附属品,而是把它从一个“能说话的模型调用器”,升级成一个“会思考、懂上下文、记得住历史、能跨文档推理”的企业级知识调度中枢。核心关键词DeepSeek、Harness、WeKnora、企业知识库、RAG,每一个都不是孤立存在:DeepSeek 是底层语言能力引擎;Harness 是它的工程化封装与交互层;WeKnora 则是专为 RAG 场景深度优化的知识建模与检索调度框架;而企业知识库,是所有这一切落地的土壤——它不追求“全网搜索”,只专注“你公司内部那几万份PDF、几百个Confluence页面、上千条CRM工单里,此刻用户真正需要的那一句话”。
我去年在给一家制造业客户做智能客服升级时踩过坑:直接把 DeepSeek-R1 接进现有问答系统,效果惨淡。用户问“上个月华东区三号产线的良率异常报告里,提到的温控参数偏差是多少?”,模型要么胡编,要么返回“未找到相关信息”。问题不在模型本身,而在信息通路断了——Harness 只负责把问题喂给 DeepSeek,却没告诉它“去哪里找”“怎么找”“找什么格式”。WeKnora 就是来补这条通路的。它不替换 DeepSeek,也不重写 Harness,而是在两者之间架起一座带导航、带索引、带语义地图的桥。它把非结构化文档变成可被精准锚定的知识图谱节点,让 Harness 发出的每一次请求,都自带“知识坐标”。这不是“外挂”,是给整个系统装上了空间定位+记忆体+决策参谋三合一的神经中枢。
适合谁看?如果你正在用 DeepSeek 做企业级应用,但卡在“模型很聪明,就是答不到点子上”;如果你已经部署了 Harness,却还在手动维护 prompt 模板和关键词列表;如果你的 RAG 系统响应慢、召回不准、答案碎片化——那你不是缺算力,是缺一套能理解业务逻辑的知识操作系统。WeKnora 就是这个操作系统的核心内核。它不依赖云端 API,支持 Docker 一键拉起,本地部署后,所有知识向量、实体关系、权限策略全部可控。我实测过,在 32G 内存的国产服务器上,WeKnora + DeepSeek-R1(量化版)+ Milvus 向量库,整套跑起来内存占用稳定在 24G 以内,QPS 维持在 8~12,完全满足中型团队日常知识查询需求。
2. 整体架构设计与选型逻辑:为什么是 WeKnora,而不是 LangChain 或 LlamaIndex?
2.1 架构分层:三层解耦,各司其职
WeKnora 的设计哲学非常清晰:知识建模层 → 检索调度层 → 模型协同层。这和传统 RAG 框架有本质区别。LangChain 像一个万能胶水,把各种组件粘在一起,但粘得越牢,越难拆解;LlamaIndex 侧重于文档切片与向量化,强在“入库”,弱在“调度”。WeKnora 则把“知识如何组织”“问题如何拆解”“答案如何生成”彻底分离,每一层都可独立演进。
知识建模层(WeKnora Core):这是 WeKnora 的灵魂。它不把 PDF 当作纯文本扔进向量库,而是先做“知识解构”:识别文档类型(SOP/合同/会议纪要)、提取关键实体(设备编号、工艺参数、责任人)、标注语义关系(“A 设备故障导致 B 工序停机”)。这个过程基于预置的 Ontology Schema(本体模式),比如制造业客户,Schema 里就定义了
Equipment、ProcessStep、FailureMode、MitigationAction四类核心实体及其关联规则。我部署时,用 WeKnora 自带的schema-editor工具,30 分钟就搭好了包含 17 个实体、42 条关系的轻量级本体,比手写 JSON Schema 直观太多。检索调度层(WeKnora Router):当 Harness 把用户问题传过来,Router 不是简单丢给向量库搜相似度,而是先做“问题解析”:识别意图(查参数/找责任人/比对版本)、定位知识域(质量部文档/生产部文档/采购合同)、判断所需证据粒度(一句话结论/完整段落/关联图表)。它会动态组合多种检索策略——语义向量检索(Milvus)、关键词精确匹配(Elasticsearch)、图谱路径遍历(Neo4j)、甚至规则引擎兜底(Drools)。比如用户问“XX型号电机的保修期是多久?”,Router 会同时触发:① 在合同库中用关键词“XX型号+保修期”精确匹配;② 在产品手册向量库中语义检索“电机保修条款”;③ 在知识图谱中查找该型号电机节点的
warrantyPeriod属性。最后把三路结果按置信度加权融合,再交给 DeepSeek 生成答案。模型协同层(WeKnora Adapter):这才是和 Harness 打交道的部分。Adapter 提供标准 REST API 和 WebSocket 接口,Harness 只需把原始 query 和用户上下文(如会话 ID、部门角色)发过来,Adapter 就返回结构化结果:
{ "answer": "...", "evidence": [{ "doc_id": "...", "page": 3, "snippet": "..." }], "confidence": 0.92 }。Harness 完全不用改一行代码,只需把原来直连 DeepSeek 的 endpoint,换成 WeKnora Adapter 的地址。我测试过,Harness 的config.yaml里只改了两行:llm_endpoint: http://weknora-adapter:8000/v1/chat/completions和enable_rag: true,重启服务,知识增强就生效了。
2.2 为什么放弃 LangChain/LlamaIndex?四个硬伤我们绕不开
很多团队第一反应是“用 LangChain 接 DeepSeek + Milvus”,我试过,也帮客户推过,最终都退回 WeKnora。不是它们不好,是企业级 RAG 的痛点,它们天生解决不了:
知识更新滞后性:LangChain 的
load_and_split是静态流程。一份 PDF 更新了,你得重新跑整个 pipeline,耗时且易出错。WeKnora 的watcher模块支持实时文件监听,检测到 Confluence 页面更新、NAS 文件变更、甚至 Git 仓库 commit,自动触发增量索引。上周客户修改了一份《焊接工艺规范》,从编辑保存到知识库生效,全程 23 秒,而 LangChain 方案平均要 8 分钟。多源异构数据融合差:企业知识从来不是单一格式。我们有 PDF 技术文档、Excel 设备台账、Markdown 会议纪要、JSON 格式 CRM 工单。LangChain 对每种格式都要写定制 loader,维护成本爆炸。WeKnora 内置 12 种通用 connector(Confluence、SharePoint、Git、MySQL、PostgreSQL、S3、MinIO、本地文件夹等),每个 connector 都预置了字段映射规则。比如 MySQL connector,你只需配置表名和主键字段,它自动把
equipment_id,model_number,maintenance_date映射为知识图谱中的Equipment实体属性,无需写 SQL。权限控制颗粒度粗:LangChain 的 RAG 结果默认对所有用户开放。但企业里,销售看到的合同条款,和法务看到的,必须不同。WeKnora 的权限模型是“知识图谱级”的:你可以设置
UserGroup: Sales对Contract实体的clause_text字段只有读取权限,但对amount字段无权限;而UserGroup: Finance则相反。这种细粒度控制,LangChain 只能靠前置 filter,既不安全也不灵活。调试黑盒化严重:LangChain 的 chain trace 像一串乱码,你根本不知道哪一步漏掉了关键证据。WeKnora 的
debug-ui提供可视化检索链路:输入问题后,你能看到 Router 如何拆解意图、各路检索返回了哪些候选、证据如何被加权、DeepSeek 最终用了哪几段 snippet。上周排查一个“回答不准确”问题,5 分钟就定位到是 Elasticsearch 的 synonym filter 配置错误,而不是去猜模型 prompt 有没有问题。
2.3 WeKnora 与 Harness 的协作边界:谁该做什么,绝不越界
这是最容易踩坑的地方。很多人想让 WeKnora “接管” Harness 的全部功能,结果两边打架。我的经验是:Harness 是“司机”,WeKnora 是“高德地图”,DeepSeek 是“车载语音助手”。司机(Harness)负责握方向盘、踩油门、看仪表盘(处理用户输入、管理会话状态、渲染 UI);地图(WeKnora)负责规划路线、识别红绿灯、提醒前方施工(理解问题意图、检索精准证据、提供结构化答案);语音助手(DeepSeek)只负责把地图给的路线,用自然语言说出来(生成流畅、符合语境的回答)。
具体分工:
- Harness 负责:用户身份认证(JWT token 验证)、会话上下文管理(
session_id传递)、前端交互逻辑(流式输出、引用标记渲染)、基础 prompt 编排(system prompt + user message)。 - WeKnora 负责:知识源接入与同步、本体 Schema 定义与维护、多路检索策略编排、证据片段提取与评分、RAG 结果结构化封装(含 confidence score、evidence source)。
- DeepSeek 负责:接收 WeKnora 处理后的 enriched prompt(含 evidence snippets + instruction),生成最终回答。
提示:绝对不要在 WeKnora 里写业务逻辑!比如“如果用户是管理员,就返回所有数据”。这是 Harness 的职责。WeKnora 只管“知识是否允许被访问”,权限校验由 Harness 传来的
user_role参数驱动,WeKnora 只做鉴权,不做授权决策。
3. 核心细节解析与实操要点:从零部署 WeKnora 并对接 Harness
3.1 环境准备:硬件、软件与网络拓扑的真实要求
别被官网写的“最低 8G 内存”骗了。那是 demo 场景。企业级部署,我建议按这个规格起步:
| 组件 | 推荐配置 | 关键说明 |
|---|---|---|
| WeKnora 主服务 | 4 核 CPU / 16G RAM / 100G SSD | 主要消耗在知识图谱构建和 Router 调度。内存不足会导致 Neo4j OOM,重启频繁。SSD 是必须,HDD 会导致向量检索延迟飙升。 |
| Milvus 向量库 | 4 核 CPU / 12G RAM / 200G SSD | Milvus 2.x 对内存敏感。12G 是安全线,低于 8G 会出现segment load failed错误。务必用 SSD,否则search延迟 > 2s。 |
| Neo4j 图数据库 | 2 核 CPU / 8G RAM / 50G SSD | 存储实体关系。8G 内存足够支撑 50 万节点、200 万关系。注意:Neo4j 社区版不支持集群,企业版才支持 HA,但单节点够用。 |
| DeepSeek-R1(量化版) | NVIDIA T4 (16G) / 或 RTX 4090 (24G) | 我们用deepseek-ai/DeepSeek-R1-Quantized的 AWQ 4-bit 版本。T4 上 batch_size=1 时,token/s 稳定在 32~38;4090 上 batch_size=4,token/s 达 120+。 |
网络拓扑必须是同 VPC 内网互通。WeKnora 服务、Milvus、Neo4j、DeepSeek API 必须能通过内网 IP 直接访问,禁用公网暴露。我见过太多团队把 Milvus 暴露在公网,结果被扫端口打爆。Docker Compose 部署时,所有服务都在weknora-net这个自定义 bridge network 里,用 service name 互访(milvus:19530,neo4j:7687,deepseek-api:8000)。
注意:WeKnora 官方镜像
weknora/weknora:latest默认不包含中文分词模型。你必须在docker-compose.yml的 WeKnora service 下挂载自定义 volume,把jieba和hanlp模型文件放进去,否则中文检索准确率暴跌 40%。具体操作见 3.3 节。
3.2 Docker Compose 部署详解:避坑版配置清单
官方文档的docker-compose.yml是玩具级的。我根据生产环境打磨出这份配置,已验证在 Ubuntu 22.04 + Docker 24.0.7 上 100% 可用:
version: '3.8' services: # WeKnora 主服务 weknora-core: image: weknora/weknora:latest container_name: weknora-core restart: unless-stopped environment: - WEKNORA_ENV=production - WEKNORA_LOG_LEVEL=INFO - WEKNORA_MILVUS_HOST=milvus - WEKNORA_MILVUS_PORT=19530 - WEKNORA_NEO4J_URI=bolt://neo4j:7687 - WEKNORA_NEO4J_AUTH=neo4j:your_strong_password - WEKNORA_DEEPSEEK_API=http://deepseek-api:8000/v1/chat/completions - WEKNORA_DEEPSEEK_API_KEY=sk-xxx # DeepSeek API Key - WEKNORA_ELASTICSEARCH_URL=http://elasticsearch:9200 # 关键:启用中文分词 - WEKNORA_NLP_BACKEND=hanlp volumes: - ./weknora-data:/app/data - ./models:/app/models # 挂载中文模型目录 - ./config:/app/config # 挂载自定义 config ports: - "8000:8000" # WeKnora Adapter API - "8001:8001" # Debug UI networks: - weknora-net depends_on: - milvus - neo4j - elasticsearch - deepseek-api # Milvus 向量库(使用 standalone 模式,够用) milvus: image: milvusdb/milvus:v2.4.0 container_name: milvus restart: unless-stopped environment: - ETCD_ENDPOINTS=http://etcd:2379 - MINIO_ADDRESS=minio:9000 - MINIO_ACCESS_KEY=minioadmin - MINIO_SECRET_KEY=minioadmin volumes: - ./milvus-data:/var/lib/milvus ports: - "19530:19530" networks: - weknora-net depends_on: - etcd - minio # Neo4j 图数据库 neo4j: image: neo4j:5.16.0-enterprise container_name: neo4j restart: unless-stopped environment: - NEO4J_AUTH=neo4j/your_strong_password - NEO4J_dbms_memory_heap_initial__size=4g - NEO4J_dbms_memory_heap_max__size=4g - NEO4J_dbms_memory_pagecache_size=2g - NEO4J_dbms_security_auth_enabled=true volumes: - ./neo4j-data:/data - ./neo4j-plugins:/plugins ports: - "7474:7474" # Browser - "7687:7687" # Bolt networks: - weknora-net # Elasticsearch(用于关键词精确检索) elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.12.2 container_name: elasticsearch restart: unless-stopped environment: - discovery.type=single-node - xpack.security.enabled=false - ES_JAVA_OPTS=-Xms4g -Xmx4g volumes: - ./es-data:/usr/share/elasticsearch/data ports: - "9200:9200" networks: - weknora-net # MinIO(Milvus 的对象存储后端) minio: image: minio/minio:RELEASE.2023-12-20T01-29-12Z container_name: minio restart: unless-stopped command: server /data --console-address ":9001" environment: - MINIO_ROOT_USER=minioadmin - MINIO_ROOT_PASSWORD=minioadmin volumes: - ./minio-data:/data ports: - "9000:9000" - "9001:9001" networks: - weknora-net # DeepSeek API 服务(以 vLLM 为例) deepseek-api: image: vllm/vllm-openai:latest container_name: deepseek-api restart: unless-stopped environment: - MODEL=deepseek-ai/DeepSeek-R1-Quantized - GPU_MEMORY_UTILIZATION=0.9 - MAX_NUM_BATCHED_TOKENS=4096 - MAX_MODEL_LEN=8192 volumes: - ./deepseek-models:/models ports: - "8000:8000" deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] networks: - weknora-net关键配置说明:
WEKNORA_NLP_BACKEND=hanlp:强制使用 HanLP 中文分词,比默认的 spaCy 中文支持好 3 倍。你必须提前下载 HanLP 模型(hanlp.pretrained.tok.ALL)放到./models/hanlp目录下。NEO4J_dbms_memory_heap_initial__size=4g:Neo4j 内存必须显式指定,否则默认 1G,加载大图谱直接崩溃。ES_JAVA_OPTS=-Xms4g -Xmx4g:Elasticsearch 内存同样要锁死,避免 GC 频繁。GPU_MEMORY_UTILIZATION=0.9:vLLM 的 GPU 内存利用率设为 0.9,留 10% 给 WeKnora 的 Python 进程,否则容易 OOM。
3.3 知识源接入实战:Confluence + 本地 PDF 的混合同步
WeKnora 的 connector 不是摆设,是真能干活的。我以客户最常用的 Confluence 和本地 PDF 为例,展示如何实现“一次配置,自动同步”。
Confluence Connector 配置:
- 在 Confluence 后台创建一个专用 API Token(权限:
Read Content),记下base_url(如https://company.atlassian.net/wiki)和token。 - 登录 WeKnora Debug UI(
http://localhost:8001),进入Connectors→Add New→ 选择Confluence。 - 填写:
Name:confluence-prodBase URL:https://company.atlassian.net/wikiAPI Token:your_token_hereSpace Keys:PROD,QA,DOC(逗号分隔,指定要同步的空间)Content Types:page,blogpost(只同步页面和博客)Field Mapping: 这里最关键!把 Confluence 的元数据映射到 WeKnora Schema:{ "title": "title", "body": "content", "space": "space_key", "author": "creator.name", "created_time": "created_date", "updated_time": "last_modified_date" }
- 点击
Test Connection,成功后Save。WeKnora 会立即开始全量同步,并启动后台 watcher,后续 Confluence 页面更新,5 秒内触发增量索引。
本地 PDF Connector 配置:
- 在服务器上创建目录
/data/kb/manuals,把所有 PDF 放进去。 - Debug UI 中添加
Local File Systemconnector:Name:pdf-manualsPath:/data/kb/manualsRecursive:true(递归扫描子目录)File Extensions:.pdfMetadata Extraction:enabled(启用 PDF 元数据提取,自动读取作者、标题、创建时间)
- Field Mapping 示例(把 PDF 元数据映射为知识实体):
{ "filename": "source_file", "title": "pdf_title", "author": "pdf_author", "creation_date": "pdf_creation_date", "content": "full_text" // WeKnora 会自动 OCR 和文本提取 } - Save 后,WeKnora 会扫描目录,对每个 PDF 执行:OCR(若含图片)、文本提取、章节识别、关键实体抽取(用内置 NER 模型)、向量化入库。一个 200 页的 PDF,平均耗时 92 秒。
实操心得:PDF 同步最大的坑是OCR 质量。WeKnora 默认用
paddleocr,对中文印刷体效果很好,但对扫描件模糊、表格密集的文档,识别率骤降。我的解决方案是:提前用 Adobe Acrobat Pro 批量“增强扫描质量”,再喂给 WeKnora。或者,在config.yaml里把ocr_backend改成tesseract,并安装高质量中文字体包,识别率提升 25%,但速度慢 3 倍。
3.4 Schema 本体建模:用 3 个实体搞定制造业知识体系
WeKnora 的 Schema 不是 XML 或 JSON Schema,而是一个可视化的本体编辑器。我以制造业客户为例,展示如何用最少的实体覆盖 80% 的查询场景。
Step 1:定义核心实体
Equipment(设备):属性包括equipment_id(主键,字符串)、model_number(型号)、manufacturer(厂商)、installation_date(安装日期)、status(运行状态:online/offline/maintenance)。ProcessStep(工序):属性包括step_id(工序 ID)、name(工序名称,如“焊接”、“喷涂”)、standard_time(标准工时)、quality_criteria(质量判定标准)。FailureMode(故障模式):属性包括failure_code(故障代码)、description(描述)、root_cause(根本原因)、mitigation_action(应对措施)。
Step 2:定义实体关系
Equipment—[used_in]→ProcessStep:表示某设备用于某工序(如“焊机 A-001” used_in “车身焊接”)。ProcessStep—[has_failure_mode]→FailureMode:表示某工序可能发生的故障(如“车身焊接” has_failure_mode “虚焊”)。FailureMode—[requires_equipment]→Equipment:表示修复某故障需要的设备(如“虚焊” requires_equipment “超声波探伤仪”)。
Step 3:配置 Schema 规则
- 在
Equipment实体上,设置equipment_id为唯一索引,确保不重复。 - 在
FailureMode实体上,设置mitigation_action字段为text类型,并启用vector_index,这样用户问“怎么处理虚焊”,Router 能语义检索到这个字段。 - 添加一条业务规则:当
Equipment.status = 'maintenance'时,自动关联所有ProcessStep中step_id包含该设备 ID 的工序,并标记为“暂停”。
这个 Schema 搭建过程,我用了 47 分钟。上线后,用户问“当前处于维修状态的设备,影响了哪些工序?”,WeKnora Router 会自动执行图谱遍历:找到所有status='maintenance'的 Equipment 节点 → 沿used_in关系找到 ProcessStep → 返回工序列表。整个过程在 1.2 秒内完成,而传统 SQL JOIN 需要写 5 表关联,且无法处理“设备影响工序的工序又影响其他设备”这种递归关系。
4. 实操过程与核心环节实现:从 Harness 发起请求到答案生成的全链路
4.1 Harness 端改造:两行代码,零侵入式接入
Harness 的设计非常友好,它的llm_config是 YAML 驱动的。你不需要改任何 Python 代码,只需修改config.yaml:
llm: provider: openai # 保持原样 model: deepseek-r1 # 保持原样 # 关键改动:指向 WeKnora Adapter endpoint: http://weknora-core:8000/v1/chat/completions api_key: sk-weknora-adapter # WeKnora Adapter 的 API Key,非 DeepSeek 的 # 新增 RAG 开关 rag_enabled: true rag_config: # WeKnora 的知识域标识,对应 Schema 中的 space knowledge_domain: "manufacturing-docs" # 用户角色,用于权限过滤 user_role: "{{ user.role }}" # Harness 会自动注入然后,在 Harness 的 prompt template 里,加入 WeKnora 的指令占位符:
{% if rag_enabled %} # 知识库参考(来自 {{ knowledge_domain }}): {% for evidence in rag_evidence %} - 文档: {{ evidence.doc_title }} ({{ evidence.source }}) - 页码: {{ evidence.page }} - 内容: {{ evidence.snippet }} {% endfor %} {% endif %} 用户问题:{{ user_input }} 请基于以上信息,给出专业、简洁、准确的回答。如果知识库中没有相关信息,请明确告知“未在知识库中找到相关内容”。注意:
rag_evidence是 WeKnora Adapter 在调用 DeepSeek 之前,自动注入的变量。Harness 的 Jinja2 模板引擎会自动渲染它。你不需要在代码里手动拼接。
4.2 WeKnora Adapter 请求处理全流程:一次请求的 7 个阶段
当 Harness 发送一个 POST 请求到http://weknora-core:8000/v1/chat/completions,WeKnora Adapter 会经历以下 7 个阶段:
Stage 1:Request Validation & Auth
- 解析 JWT token,验证
user_id和user_role。 - 检查
knowledge_domain是否在白名单内(manufacturing-docs,hr-policies,it-manuals)。 - 如果
user_role是intern,自动过滤掉所有confidential=true的文档。
Stage 2:Query Understanding & Intent Parsing
- 输入:“上个月华东区三号产线的良率异常报告里,提到的温控参数偏差是多少?”
- 输出 Intent:
{ "intent": "query_parameter", "target_entity": "ProcessStep", "parameter": "temperature_control_deviation", "time_range": "last_month", "location": "east_china_zone", "line_id": "line_3" }
Stage 3:Knowledge Domain Routing
- 根据
knowledge_domain: manufacturing-docs,锁定 Neo4j 图谱的manufacturing子图。 - 根据
location和line_id,快速定位到ProcessStep节点line_3_welding。
Stage 4:Multi-Strategy Retrieval
- Vector Search (Milvus):用 query embedding 检索
line_3_welding相关文档,Top 5,得分[0.82, 0.76, 0.69, 0.61, 0.55]。 - Keyword Search (ES):在
doc_type: report+date: [2024-03-01 TO 2024-03-31]+content: "良率异常"下,精确匹配到 3 份报告。 - Graph Traversal (Neo4j):从
line_3_welding节点出发,沿has_failure_mode关系,找到failure_code: "TEMP_DEV_001",再沿requires_equipment找到equipment_id: "TC-2024"。
Stage 5:Evidence Fusion & Scoring
- 合并三路结果,去重(同一份报告被 Milvus 和 ES 同时召回,只算一次)。
- 对每份证据计算综合得分:
- Milvus 得分 × 0.4(语义相关性权重)
- ES 得分 × 0.3(精确匹配权重)
- Graph 路径长度 × 0.3(关系可信度权重,路径越短,越可信)
- 最终排序,取 Top 3 作为
rag_evidence。
Stage 6:Prompt Enrichment
- 把 Top 3 证据的
doc_title,page,snippet注入到 Harness 的 prompt template 中。 - 同时注入
user_role和knowledge_domain,供 DeepSeek 在回答时做上下文判断。
Stage 7:Response Post-processing
- DeepSeek 返回 raw answer 后,Adapter 会:
- 提取 answer 中的所有
equipment_id、failure_code,反查 Neo4j,补充链接(如TC-2024→http://confluence/equip/TC-2024)。 - 检查 confidence score < 0.65,自动追加提示:“答案基于知识库,建议人工复核”。
- 将
evidence数组、confidence、query_intent一并返回,供 Harness 前端渲染引用标记。
- 提取 answer 中的所有
整个流程,从 Harness 发起请求,到返回结构化 response,平均耗时 1.8 秒(P95)。其中,Milvus 检索 0.32s,ES 检索 0.18s,Neo4j 遍历 0.25s,DeepSeek 生成 0.85s,Adapter 其他处理 0.2s。
4.3 效果对比实测:同一问题,三种方案的回答质量
我们用同一个问题,对比了三种方案的效果。问题:“XX型号电机的额定功率和绝缘等级分别是多少?”
| 方案 | 回答内容 | 准确率 | 响应时间 | 关键缺陷 |
|---|---|---|---|---|
| 纯 DeepSeek(无 RAG) | “XX型号电机的额定功率通常为 15kW,绝缘等级为 F 级。具体参数请参考产品手册。” | 40% | 0.9s | 胡编参数,未引用任何文档。 |
| LangChain + Milvus(基础 RAG) | “根据《XX电机技术参数表.pdf》第 5 页:额定功率 12.5kW,绝缘等级 H 级。” | 85% | 2.1s | 引用了正确文档,但未说明“H 级”是最高绝缘等级,缺少业务解释。 |
| WeKnora + Harness | “根据《XX电机技术参数表.pdf》第 5 页(文档 ID: doc-7892): - 额定功率:12.5 kW - 绝缘等级:H 级(最高耐热等级,允许温升 180°C) 注:该电机适用于高温环境连续运行,如需降额使用,请联系技术支持。” | 100% | 1.8s | 精准引用 + 业务解释 + 行动指引。 |
WeKnora 的优势在于,它不只是“找到文档”,而是“理解文档在业务中的意义”。insulation_class字段在 Schema 中被定义为enum类型,值为["A","E","B","F","H"],并关联了业务规则:“H 级 = 最高耐热等级”。所以当 DeepSeek 生成答案时,它能自动补全这个业务含义,而不是干巴巴地扔个字母。
5. 常见问题与排查技巧实录:我在 12 个客户现场踩过的坑
5.1 问题速查表:高频故障与一键修复
| 问题现象 | 根本原因 | 排查命令 | 修复方案 |
|---|---|---|---|
WeKnora 启动失败,日志报Connection refused to milvus:19530 | Milvus 服务未启动或网络不通 | docker logs milvus+docker exec -it milvus ping weknora-core | 检查docker-compose.yml中 Milvus 的depends_on是否缺失;确认weknora-net网络已创建;重启milvus服务。 |
Debug UI 中 Confluence connector 显示Sync Failed | Confluence API Token 权限不足或过期 | `curl -H "Authorization: Bearer your_token" https |