
这个系列写到第二十五篇了。之前聊过不少DeepSeek的提示词技巧、API调用和流程搭建但后台被反复问到的一个问题始终绕不开知识图谱、向量数据库、embedding这几个词到底和大模型是什么关系为什么现在做知识库问答、企业智能助手这类应用大家都要把它们放到一起讨论。正好在最近的模拟项目X里完整用过这套组合我把三者之间的分工、一条完整的实战链路、以及过程中踩过的坑一次性写清楚。这篇文章不是纯理论科普更像是一份实践记录。我会以“某公司内部资料智能问答系统”为例从信息抽取、图谱构建、向量化入库到最终的检索生成把每一步怎么做、为什么这么做讲透。适合正在做RAG、知识库问答、企业AI应用或者只是被各种概念绕晕的读者。无论你是自己搭过向量库还是完全新手按照文中的思路都能跑通一条从零到可用的链路。1. 先用一张“地图”看清三者分工很多人一上来就把知识图谱和向量数据库对立起来这是最大的误区。它们不是替代关系而是负责解决两类完全不同的问题。1.1 知识图谱给数据装上关系骨架知识图谱的核心是“实体—关系—实体”的三元组结构。比如“张三任职某部门某部门负责项目X”就是一个典型的图谱表达。它把信息从一堆文字中抽离出来变成带语义的节点再用边表示关系。这种结构的最大优势是精确、可推理。问“某部门负责的所有项目有哪些”向量检索很难一次答清楚但图查询可以沿着边直接遍历出来。代价也很明显构建图谱需要抽取、清洗、消歧维护成本比单纯做索引高得多。在实战里图谱更像一个“企业架构图”。大模型回答问题时能从里面拿到确定的关系和上下文减少自由发挥的空间。1.2 向量数据库给数据建一个语义索引向量数据库存的不是原始文本而是经过embedding模型转换后的高维向量。它的工作方式特别像一个超级搜索引擎只不过检索的是“意思相近”而不是“字面相同”。比如用户问“项目延期了怎么办”库里有一句话是“项目进度落后时可以考虑调整排期”这两句话没有共同关键词但语义相似向量检索可以把它找出来。这正是知识图谱做不到的地方因为图谱只回答确定的关系不擅长模糊匹配。实际生产环境一般不会因为几百份文档就上向量数据库但文档量一大比如上万份合同、几十万条工单靠关键词搜索和人工翻文档就完全不现实了。向量数据库的价值是把“模糊的语义”变成“可计算的距离”。1.3 Embedding连接语言世界和数学世界的翻译层embedding本质上是把文本、图片、音视频都映射成一组数组。两个文本的语义相似度就变成了两个数组的距离。没有embedding向量数据库就是空壳。这里有个容易混淆的点embedding模型不是只有一个不同模型训练目标和能力差异很大。比如通用中文embedding模型处理金融领域术语效果往往不如在领域语料上微调过的模型。所以选好embedding模型比换一个更贵的向量数据库重要得多。表格可以很好地说明三者定位差异维度知识图谱向量数据库Embedding数据结构节点和边高维向量一组浮点数擅长任务多跳关系推理、精确查询语义相似度匹配语义空间表达典型查询查询某实体的所有关联对象找与某段内容意思相近的段落计算两句子的相似度成本瓶颈人工/模型抽取成本高索引存储和检索延迟模型推理算力适合场景实体关系固定的领域大量非结构化文档检索所有需要语义表示的任务2. DeepSeek在这条链路里到底扮演什么角色2.1 大模型更像“推理器”而不是“资料库”很多人的第一反应是有了DeepSeek是不是就不需要知识库、图谱和向量库了。这是个非常危险的理解。大模型虽然训练数据非常庞大但它对私有领域知识一无所知也无法保证信息的时效性。更关键的是它擅长“从已有上下文里归纳总结”而不是“凭空记住一个具体项目的所有细节”。所以DeepSeek在这条链路里的角色更像是拿到检索结果之后负责组织语言、给出最终答复的人。它也从两个环节往前参与一个是知识抽取根据非结构化文本生成三元组一个是查询改写把用户模糊的问题转成适合检索和图查询的表达。2.2 从普通RAG到知识图谱增强的GraphRAG普通RAG的流程已经被人说烂了文档切分、embedding入库、向量召回、拼给大模型。这个流程解决“资料如同大海捞针”的问题但解决不了“多个资料之间的关联问题”。举个例子用户问“某部门最近三个月所有延期项目的共同风险因素是什么”。纯向量召回会找到几段相关文本但大模型只能基于碎片信息猜测。如果有一个知识图谱能查到这些项目是否属于同一个人负责、是否依赖同一个外部供应商、是否集中在一个时间段启动回答质量会完全不同。这种把图谱作为额外上下文喂给大模型的方案行业内叫GraphRAG。它的本质是用向量召回保证覆盖度用图查询保证精确关系再用大模型把两者统一成自然语言答案。2.3 为什么“向量图谱”双通道比单通道更稳实际项目里我很少单独用一个通道。原因很简单向量召回的结果有噪声可能召回了语义相似但无关的信息图查询的结果虽然准确但覆盖不全很多知识没有建到图里。双通道的策略是并行执行。向量通道负责从大量文档里找回候选段落图谱通道负责定位实体及其关系。最终由一层逻辑把两部分内容合并再交给DeepSeek生成答案。这样做的好处很直观。即使图谱缺失了一部分实体向量通道仍然能覆盖即使向量召回结果不理想图谱通道也能兜住关系问题。两条腿走路比单腿稳得多。3. 一个具备的实战公司知识问答系统怎么做这一章我会按五个环来写完整的构建流程所有代码只保留核心逻辑方便你迁移到自己的场景。3.1 场景定义与数据准备模拟项目X的背景设定是某公司要搭建一个内部知识问答系统资料包括产品文档、项目周报、组织架构说明、会议纪要等大概几千份非结构化文档。需要支持的问题类型有三种一是事实型问题例如“某产品的发布版本是什么”二是关系型问题例如“某项目的项目经理是谁当前状态如何”三是总结型问题例如“最近一个季度的共性问题有哪些”。数据准备的要点是先明确边界。哪些资料可以入库哪些涉敏资料不能进系统哪些实体类型需要重点关注。我建议先用一个最小的子集跑通流程再逐步扩充不要一上来就全量导入。3.2 第一环用DeepSeek做实体和关系抽取从文档中抽取三元组是构建知识图谱最累的一步。人工标注太慢纯规则又覆盖不了复杂表达。用DeepSeek做抽取成本低而且效果好。提示词的设计很关键。一个稳定可复用的抽取模板长这样from openai import OpenAI client OpenAI( api_keyyour_api_key, base_urlhttps://api.deepseek.com ) def extract_triples(text: str) - list: prompt 你是知识抽取助手。请从文本中提取所有(主体, 关系, 客体)三元组。 规则 1. 只输出JSON数组不要有任何额外文字。 2. 每个三元组格式为{subject: , relation: , object: }。 3. 主体和客体必须是具体实体而不是抽象概念。 4. 关系用尽量简洁的动词或名词表示例如“负责”、“属于”、“发布于”。 5. 只抽取与业务相关的信息忽略无关细节。 文本 text resp client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: prompt}], response_format{type: json_object} ) # 这里假设返回结构为 {triples: [...]} data json.loads(resp.choices[0].message.content) return data.get(triples, [])实际跑下来的经验是DeepSeek对中文长文本的抽取比较稳定但一次不要喂超过2000字否则容易漏掉细节。文档比较长时先按段落切分再分别抽取最后汇总去重。3.3 第二环构建知识图谱抽取出来的三元组还不能直接上图。需要做几轮清洗先对实体做归一化。比如“小王”、“王某”、“王经理”很可能指向同一个人需要通过规则或模型判断后合并。再过滤掉低置信关系。批量抽出来的时候会有很多噪音比如“文档中提到项目X项目X很重要”这种语义空泛的关系不保留。清洗完的四元组加上来源文档ID可以写入图数据库。以Cypher为例MERGE (s:Entity {name: $subject}) MERGE (o:Entity {name: $object}) MERGE (s)-[:REL {type: $relation, source: $source}]-(o)图数据库的价值不是存完就完了而是可以灵活查询。比如“查项目X的所有关联人”可以写MATCH (e:Entity {name: 项目X})-[r]-(related) RETURN related.name, r.type注意不要一开始就建太多实体类型。宁可先只保留“人员、项目、部门、供应商、产品”五类核心实体把关系限定在“负责、参与、属于、供应商提供、关联”几种把骨架做干净再逐步扩充。3.4 第三环文本切分与Embedding入库知识图谱解决关系但非结构化的细节内容仍然要靠向量检索。文档入库前需要切分。切分策略上我建议从300到500个token一个块开始重叠50个token左右。切太碎导致上下文不完整切太大向量检索不够精确而且拼给大模型时容易超长。embedding生成后写入向量数据库。一个简化示意import requests def get_embedding(text: str) - list: # 假设使用某个embedding服务接口形式可能不同 resp requests.post( http://your-embedding-service/encode, json{text: text} ) return resp.json()[embedding] chunks split_text(doc_text) for i, chunk in enumerate(chunks): vec get_embedding(chunk) vector_store.add( idfdoc_{doc_id}_chunk_{i}, vectorvec, metadata{ doc_id: doc_id, chunk_index: i, content: chunk } )这里有个坑像DeepSeek这类对话大模型一般不是专门为embedding训练的业界更建议用单独的中文embedding模型来生成向量。DeepSeek在抽取、生成、改写上发挥价值向量化交给专用embedding服务两个各司其职。3.5 第四环双通道检索与答案生成用户输入一个问题后系统并行做两件事第一件是向量检索。把问题也向量化在向量库里召回top10相关块。第二件是图谱查询。先用实体识别从问题中提取关键实体再到图数据库里查这个实体的一跳或两跳邻居关系。然后把两条结果合并组装成上下文喂给DeepSeek。提示词是这样设计的prompt 你是企业知识助手请基于提供的资料片段回答问题。 要求 1. 优先采用资料片段和知识图谱查询结果。 2. 如果资料与图谱结果冲突明确说明哪里冲突。 3. 无法从资料中得出答案时直接回答“资料不足”不要编造。 知识图谱结果 {graph_context} 资料片段 {vector_context} 用户问题 {question} 组装上下文时图谱结果用紧凑的表格或列表形式呈现比如“项目X - 负责人 - 张三项目X - 状态 - 已延期”。向量片段按相关性从高到低排序。两部分的长度加起来建议控制在模型上下文的50%以内留足生成空间。3.6 第五环实测效果与调优方向我在模拟项目X上跑完这套流程后对比了三组设置纯向量检索、纯图谱查询、双通道融合。结果大致是这样场景纯向量纯图谱双通道融合事实型问题较好一般好关系型问题偏差较好好总结型问题中差较好幻觉发生率较高低低实现复杂度低高中高双通道不是每一步都最优但它把关系型问题这个大短板补上了。尤其对“谁负责什么、哪个项目依赖什么”这类问题效果是肉眼可见的提升。4. 关键参数、工具选型与调参经验4.1 分块策略块大小、重叠、切分单位向量库里最容易被忽略的参数是分块策略。实践中我总结出的经验是先考虑文档类型再决定切分单位。如果你处理的是产品说明书、合同条款建议按语义段落或标题分块中间插入重叠部分。如果是会议纪要、聊天记录这种结构不够清晰的文本固定token切分更省心。块大小可以先用400token重叠50token然后再按检索效果微调。块太大召回颗粒度粗回答容易东拉西扯块太小上下文破碎DeepSeek拼不出完整逻辑。具体做法是每次抽20到30个测试问题人工检查召回是否命中目标段落再调整参数。不要凭感觉决定。4.2 Embedding模型怎么选维度、语境与性价比embedding模型的维度决定了向量库的存储和检索成本。常见的有256维、768维、1024维、1536维等。维度越高不一定效果越好尤其在垂直领域一个在通用语料上训练的1536维模型可能不如一个在领域语料上微调的512维模型。中文场景我建议优先测试bge系列和m3e这类开源模型。注意看模型是否支持长文本有的模型单次输入上限只有512token遇到长文本要提前切分。更重要的是embedding模型和下游检索器要配套测试。同一份文档用不同embedding模型召回结果差异可能非常大。4.3 向量库与图数据库选型参考市面上向量数据库很多选型时主要看三点索引类型、部署方式和生态成熟度。常见的HNSW索引适合中大规模数据brute force适合数据量小的场景。对比维度主流开源向量库图数据库数据模型向量加metadata节点和边查询能力近似最近邻检索图遍历、路径查询扩展难点数据量大后索引构建慢关系复杂后查询深度受限适合规模千万级向量百万级节点以内维护成本中中高如果只是个人项目或小团队知识库用轻量级方案能跑就够。当数据量到了百万级以上才需要考虑分布式部署和分片策略。图数据库同理实体关系超过几十万甚至上百万之后盲目加深查询跳数会明显拖慢响应。4.4 距离算法与召回数量怎么定向量相似度常用余弦、点积、欧氏距离。如果embedding模型做过归一化余弦和点积结果等价。文本场景我一般直接用余弦相似度。召回数量top_k从10开始然后根据效果调整。top_k太小容易漏top_k太大噪声多上下文过长影响回答质量。可以在召回后加一道轻量级rerank用交叉编码器或规则过滤掉明显不相关的片段。这一步在正式系统里很值得做能让最终喂给大模型的内容干净不少。4.5 混合检索权重调优的思路双通道检索必然涉及权重分配哪些结果优先哪些结果要降权。我的思路不是给向量和图各设一个固定权重而是按问题类型决定通道优先级。如果用户问题里出现了明显的实体名以图谱通道为主向量通道作为补充。如果问题是描述性、总结性以向量通道为主图谱结果只提供背景。最简单的方式是在系统里加一个“是否包含实体”的规则判断再为两类问题写不同的组装模板。权重调优没有绝对标准完全依赖业务场景和测试集。我建议把历史问答维护成一个评测集每次调参后跑一遍对比正确率和漏检率。5. 实战中经常踩的坑与排查方法5.1 向量检索召回一堆“看起来很像其实无关”的结果这是最常碰到的坑。明明用了embedding用户问题也很清晰但召回结果就是不着调。先查分块。如果块太大语义被稀释。再查embedding模型。中文领域尤其明显通用模型对专业术语不敏感换成领域微调模型经常立竿见影。还有一个隐藏因素查询端没有做改写。用户口语化表达和文档书面化表达差距很大直接用原始问题去检索效果容易差。可以在检索前加一个“问题改写”步骤让DeepSeek把用户问题转成更适合检索的短句。5.2 实体抽取不准或者抽出一堆垃圾关系DeepSeek抽取三元组时经常出现实体不对齐、关系冗余、虚指对象一堆的情况。比如“公司认为这个产品很好”会抽出“公司 - 认为 - 产品很好”这种信息没有业务价值。应对方法是在抽取阶段就限定实体类型和关系类型而不是让模型自由发挥。把业务关注的对象明确告诉模型。其次是清洗阶段做一次“黑名单关系”过滤把“包含、提到、涉及”这类低价值关系剔除。每次清洗规则调整后保留一份人工review样本验证规则没有误伤。5.3 大模型答错了却引用正确资料矛盾何来有几次我遇到一个诡异场景检索回来的资料完全正确但DeepSeek生成的答案跑偏了。问题出在提示词。如果提示词里没有明确“优先采用资料内容”模型会默认“自由发挥”。还有可能是资料太多上下文里信息互相冲突模型选择了一条不重要的信息进行展开。解决办法是在提示词里加入“回答只能基于资料内容不要补充资料外信息”这类约束并设置矛盾检测规则。当图谱结果和向量结果冲突时可以在prompt中要求模型明确指出冲突而不是强行融合。长期来看建立答案溯源机制非常有用让每条回答后面带上来源文档ID和图谱路径。5.4 响应延迟偏高混合检索要做好哪些优化双通道并行是基础。很多实现是把向量检索和图查询串行执行延迟自然高。两条路分别跑再合并结果能省一半时间。图查询的深度也要限制。以一跳和二跳为主超过三跳基本无法接受。向量检索的top_k不要无脑设50除非后面有强大的rerank兜底。缓存机制值得做遇到相似的历史问题直接命中缓存结果大幅降低重复计算压力。再就是批量处理。离线阶段提前把高频问题的检索结果预计算好在线只需要匹配提问模板。6. 这套链路后续还能怎么扩展6.1 从静态图谱到动态图谱模拟项目X跑完我的最大感受是“静态图谱只能撑起一半”。文档更新后图谱里的实体关系需要同步更新否则会出现旧关系误导新问题的现象。更合理的方案是给三元组加时间戳比如“负责人”关系要标明生效周期。这样查询时可以优先取最新关系。如果你的系统处理的是持续变动的业务数据建议把图数据库和其他业务系统打通用事件驱动更新图谱。比如项目状态变更时自动触发关系更新而不是定期全量重建。6.2 把多轮对话和答案溯源做进去目前很多知识问答系统只支持单轮提问体验不够好。结合DeepSeek的上下文能力完全可以把历史对话信息引入图谱检索。当用户追问“那它为什么延期”系统需要从上一轮提到的项目中提取关联原因这一能力比重建所有问题要自然得多。同时我强烈建议把答案溯源做成产品的一部分。每条回答不仅给用户结论还要展示引用了哪些资料片段、经过了哪些图谱路径。这既提升可信度也方便排查错误。至少在当前阶段用户对AI生成内容的信任还比较脆弱有溯源会好很多。写在最后的实操心得这个项目做完我最想分享的不是某个参数怎么调而是一个工作顺序先用纯向量检索把知识库问答跑通再逐步叠加知识图谱增强。一上来就追求“图谱RAG完全体”容易陷入实体抽取和关系清洗的泥潭。第二个心得是DeepSeek这类模型最值钱的地方不是“答问题”而是“结构化信息抽取”和“上下文组织”。很多知识库项目把精力全花在检索调参上忽略了抽取质量对最终效果的决定性影响。抽取出问题后面的图谱和检索都是白费。最后分享一个小技巧做实体链接时让DeepSeek输出JSON数组远比输出自然语言稳定。你在提示词里给出明确的Schema并让它只输出纯JSON哪怕内容有一点缺失也能通过后处理兜住。这个习惯能省掉80%的解析烦恼。