知识图谱面试题
知识图谱面试题
Qdrant / 向量检索、Neo4j / 知识图谱各三档,每档 20 题。★ 是高频题。入门讲概念,中等讲实现,高难按「现象→定位→方案→取舍→验证」练口述。没有标「项目」的架构方案不代表项目已经采用。
知识图谱 入门(20 题)
1. ★ 属性图是什么?
用节点表示实体,关系表示联系,节点和关系都可带属性。Neo4j 属于属性图;标签用来归类节点。它适合有关系遍历需求的数据,不是把所有业务表都换成圆圈和箭头。
2. 节点、标签、关系类型分别是什么?
例如「张三」是节点,Person 是标签,WORKS_ON 是关系类型。节点可有多个标签;关系有方向和类型,也能存角色、有效期。业务 ID 应自己维护,别依赖内部存储 ID 长期稳定。
3. ★ Cypher 和 SQL 有什么不同?
Cypher 用图模式表达节点和关系匹配,SQL 用表与连接表达关系。两者都需要索引、约束和执行计划;图查询写着短,不代表执行一定快或没有笛卡尔积。
4. MATCH 和 WHERE 怎么用?
MATCH 描述要找的模式,WHERE 给匹配加条件。先用带标签和索引字段定位起点,再展开关系,通常比从所有节点出发扫描便宜。租户条件同样要写进受控查询。
5. CREATE 和 MERGE 的区别?
CREATE 总是新建指定模式;MERGE 尝试匹配整个模式,不匹配才创建。MERGE 不自动猜哪个字段是身份,应该用稳定 ID 匹配,把会变的摘要等属性放进 SET。
6. ★ MERGE 能保证并发不重复吗?
不能单独保证。并发下还需要对业务唯一键建立唯一约束,遇到冲突按策略重试。关系身份也要设计清楚,避免一次模式 MERGE 因部分不匹配而创建多余节点。
7. SET、REMOVE、DELETE 有什么区别?
SET 更新属性或标签;REMOVE 移除属性或标签;DELETE 删除节点或关系。节点还有关系时普通 DELETE 会失败;DETACH DELETE 会连关系一起删,范围必须严格限制。
8. ★ 为什么要用查询参数?
参数绑定避免把用户值拼进 Cypher,便于复用计划。动态标签/类型等结构部分要按服务版本能力处理,无法参数化时做白名单映射;参数化不代替权限检查和查询限额。
9. 什么是度数?
节点连接的关系数量。少数高频实体可能成为超级节点,遍历时造成候选爆炸;「公司」「所有文档」这类泛化节点尤其要控制扩展范围,不能只看全图平均度。
10. ★ 一跳和多跳查询是什么?
一跳沿一个关系到邻居,多跳经过多个关系。跳数不是业务可信度;两个项目都连到同一部门,不等于项目之间存在合作。返回路径时要解释每条边的含义和出处。
11. OPTIONAL MATCH 有什么用?
类似可选关联,模式未匹配时保留原行,相应值为 null。WHERE 的归属会影响结果;把条件放错位置可能把本想保留的行过滤掉,需要用「无关系」样本验证。
12. UNWIND 是什么?
把列表展开成多行,适合批量写入或处理参数列表。展开会放大行数;两个列表连续 UNWIND 可能形成乘积,批量写要控制批次并用稳定键保持幂等。
13. ★ 知识图谱比向量检索强在哪里?
明确的实体、类型和关系支持可解释的结构查询,比如某人负责的项目及其依赖。前提是抽取和实体对齐足够可靠;图谱不是天然事实库,错误关系会被查询稳定放大。
14. 实体消歧是什么?
区分同名实体是不是同一个,例如两位「王伟」不能仅凭名字合并。结合组织、外部 ID、时间、上下文判断,保留候选和证据;误合并通常比暂时分成两个节点更难修。
15. 本体或 schema 有什么作用?
限定实体类型、关系类型、必要属性和允许的起终点,减少「负责人」「负责者」等散乱表达。它应随业务演进并有版本;过度僵硬会丢信息,完全自由则难以查询与治理。
16. ★ 事实和推断为什么分开?
原文明确写出的关系,与模型根据线索猜出的关系可信程度不同。分别记录层级、来源和置信信息,回答时说明推断;不能让多跳组合自动升级成原始材料明确陈述的事实。
17. 为什么边也要记录来源?
同一对实体可能在不同时间、材料里有不同关系。记录来源文档、片段、提取版本和时间,有利于追溯、重抽和撤销;只存一句关系文本,之后无法解释为何得到这个结论。
18. ★ 项目图谱和向量库怎么分工?(项目)
Neo4j 存结构关系,Qdrant 存节点名称/摘要表示帮助语义定位。图节点 ID 用来串起两边;两库更新不是天然原子,要考虑索引残留、缺失和重试。
19. 图谱的读取和修改由谁做?(项目)
当前图只读工具向主 Agent 开放,三个图写工具限制给 ariadne。不要照旧文档说「读图也必须委派」;子 Agent 合并仍是计划,不改变当前工具注册事实。
20. Neo4j 可以替代业务 PG 吗?
能存属性不等于适合所有业务。订单、成员权限和事务型状态放关系数据库更自然;复杂关系遍历放图谱。跨库边界要明确,避免两个库都声称自己是同一权限事实的最终来源。
知识图谱 中等(20 题)
1. ★ 图索引和唯一约束怎么选?
索引帮助按标签及属性定位节点;唯一约束保证业务键不重复,并有相应索引支持。多租户实体可用租户加业务键作为组合身份;具体约束能力按 Neo4j 版本和版本类型核对。
2. MERGE 为什么只放身份字段?
把名称、摘要等可变属性都写进 MERGE,任一属性变化就可能匹配不到旧节点。先按稳定 ID MERGE,再 SET 可变属性;更新空字段时明确是删除、保持旧值还是写入空字符串。
3. ★ 怎么批量写图?
用参数列表加 UNWIND,每批一个短事务,控制批次和并发。先建所需索引/唯一约束再灌数据;重试整个事务时必须幂等,事务回调里别顺带调用会重复扣费的外部接口。
4. 如何避免无界遍历?
给起点、关系类型、方向、最大跳数和返回量设限制。只在末尾 LIMIT 不能保证中间枚举少;高阶路径查询还要设超时,必要时按业务限定路径或预聚合。
5. ★ EXPLAIN 和 PROFILE 有什么区别?
EXPLAIN 展示计划而不真正执行;PROFILE 执行并给出实际行数、DB hits 等。检查起点是否走索引、行数在哪个算子激增;写查询的 PROFILE 也会写数据,不能当只读分析。
6. 为什么会出现笛卡尔积?
独立模式没有关联约束,例如分别匹配全体人员和项目后才处理。检查变量是否真正连起来,先缩小起点再匹配;看计划中的估计/实际行数,不因返回只十条就认为代价小。
7. DISTINCT 为什么不能随便加?
它能消除多路径造成的重复结果,但需要额外去重内存与计算,也可能掩盖错误模式。先确认返回单位是节点、边还是路径,再在正确层级去重,不把不同来源关系误合并。
8. ★ 实体对齐怎么做得稳?
先用租户内外部 ID、规范化名称等确定性规则,再用向量召回候选,最后结合类型和上下文判别。低把握保留待核对;记录合并历史和别名,支持拆回,别让模型一句话直接合并。
9. 图里如何表示时间变化?
区分业务有效时间和系统记录时间;对「某人负责某项目」可存有效区间或单独关系事件。查询要明确问当前还是历史,不要覆盖旧属性后还声称可以回答过去的状态。
10. 图谱更正为什么适合软废弃?
废弃能保留审计、来源和历史回答解释,再在默认查询排除。物理删除更省存储但难追溯;对法规或业务要求必须删除的情况,还需同步清理向量索引、缓存和原始材料。
11. ★ 文档更新后怎么重抽关系?
给每次抽取带文档版本和任务 ID,先生成新证据,验证后替换该来源的贡献。不能直接删节点所有边,因为还有别的材料也支持这些关系;实体身份与证据生命周期要分开。
12. 多来源支持同一个关系怎么存?
可把关系断言/证据建成独立记录,汇总视图再返回实体之间的关系。这样撤回一份材料不必删除其他支持;权威程度、时间和来源独立保存,不只把置信分数简单相加。
13. ★ 图查询怎么做租户隔离?
从可信 scope 限定起点,每一步扩展的节点与关系也符合允许范围;尤其防跨租户的脏边。结构化查询模板统一注入条件,结果再复核,不能只在返回的第一个节点检查组织。
14. Text2Cypher 的危险在哪里?
模型可能生成写语句、无界遍历或遗漏权限。应使用只读数据库身份、允许的查询结构、硬超时和结果上限;参数值来自用户但 scope 来自服务端。提示词写「只读」不形成权限边界。
15. 图向量命中后怎么扩展?
先核对命中节点是否仍存在、可读,再按关系白名单做少量跳数扩展,保留路径和出处。按上下文预算截断并说明未展开部分;不能把所有邻居全部塞进 prompt。
16. 图查询结果怎么排序?
按问题选择时间、业务权重或相关性,不默认内部 ID 排序。多条路径可根据证据质量和长度排序,但最短不一定最可信;稳定分页还要加唯一键作为并列排序条件。
17. ★ 超级节点怎么建模?
把无差别聚合关系按时间、业务域分组,查询先筛子类;高频统计可预计算。不随意复制实体来消除度数,否则身份与更新会漂移;先测真实遍历模式再改模型。
18. 图事务失败怎么重试?
对驱动判断为可重试的瞬时错误进行有限退避,业务唯一键保证幂等;语法和授权错误不能盲重试。驱动事务回调可能被多次执行,外部副作用应放事务外并单独幂等。
19. 怎么测试抽取效果?
人工标注实体、关系、来源位置和否定/时间范围,分别看精确率、召回率、误合并、无来源断言。最终再测业务问答的证据支持率,不能用「节点变多」证明知识质量提高。
20. ★ 图 schema 改版怎么兼容?
新旧关系类型并存过渡,读取层明确兼容规则,分批回填并校验数量和典型路径。切换后观察旧查询命中情况再清理;prompt、本体校验、索引与图查询模板要一起升级。
知识图谱 高难(20 题)
1. ★ 两个来源对负责人说法冲突怎么答?
同时保存来源、有效时间和权威级别,先判断是时序变化还是同一时点冲突。返回有出处的差异或请求确认,不能简单选最新写入或最高模型分数;业务裁决后留更正历史。
2. ★ 文档权限撤回后,图关系会泄密吗?
会,摘要和路径也可能暴露原文事实。按证据来源维护可见范围,查询阶段及输出阶段都过滤;一个关系仍被公开来源支持时可保留该公开证据,不能把私有来源一起带出。
3. PG、Neo4j、Qdrant 三库怎么保持一致?
权威业务事件带版本写入 outbox,各存储消费时幂等更新并记录版本;读时校验业务有效性,后台对账补偿。跨库不强装成一笔 ACID 事务,要定义短暂不一致时可接受与必须拒绝的行为。
4. ★ 图查询突然占满 CPU 怎么查?
从慢查询和参数复现,PROFILE 看实际展开量、全图扫描、路径枚举和去重。先终止异常查询、限并发,再限制起点和路径;不要先给所有关系建索引却不看瓶颈。
5. 千万节点做全图多跳为什么危险?
候选量随分支数和跳数快速放大,路径数还可能远多于节点数。先把业务问题改写成有限关系模式,必要时离线预计算;「最多返回 20 条」无法证明中间过程便宜。
6. 如何安全合并两个实体?
先核对 scope、类型和证据,事务内重连边并处理重复断言,保留旧 ID 到新 ID 的映射。向量索引异步更新并对账;设计反向拆分需要的记录,否则一次误合并很难恢复。
7. ★ 图查询有路径但答案不成立?
路径连通只说明存了这些关系,关系组合是否能推出结论还需业务规则。检查方向、时间交集、否定和关系含义;展示证据链,并把模型补出的推断与原始事实区分。
8. 同一个名字在多个组织都存在怎么办?
身份键带 scope,先在有权范围内做候选检索;跨组织同名不自动合并。确有全局身份时另外维护受控映射和授权规则,避免查询内部图时无意返回其他组织的存在信息。
9. 图抽取任务重试导致关系越来越多?
检查关系身份是否包含不断变化的属性、是否缺少唯一业务键,以及每次抽取是否清理同来源旧版本。以来源断言 ID/抽取版本做幂等,做重复关系检测,不能定期全库去重代替修写入逻辑。
10. ★ LLM 生成了合法但昂贵的只读查询?
只读不代表安全。实施跳数、起点规模、允许算子、超时、行数及并发预算,复杂模式转受控工具。分析无害小样本与真实图规模下的代价,不能仅靠解析成功就执行。
11. 怎么设计图谱灾难恢复?
备份图数据、schema、本体和抽取版本,保存重建所需原文与事件水位。恢复后检查约束、代表性路径、权限隔离及向量映射;重放增量前按版本防止旧事件覆盖新修正。
12. Neo4j page cache 命中低怎么办?
先看工作集、内存预算和查询随机访问,区分堆、page cache 与 OS 缓存。优化起点和返回属性,确认磁盘延迟,再调缓存或扩容;不能把所有 RAM 分给堆导致页缓存饥饿。
13. ★ 多人同时改同一关系怎么防覆盖?
更新附带版本或预期旧值,事务内检查影响结果;冲突时重读给出差异。对聚合边要小心不同来源贡献被整体 SET 覆盖,尽量按独立证据修改,保留审计与操作者。
14. 图模型演进后历史问答还能解释吗?
答案记录证据 ID、图/抽取版本和查询时点;实体重定向保留历史映射。只保留最终自然语言答案无法追查旧推断;对真正需要复现的场景还需保留当时证据快照。
15. 为什么不让主 Agent 直接改图?(项目)
当前共享图写入权限集中给 ariadne,控制领域规则和修改入口。仍须在写工具执行时验证 scope、身份和目标,委派本身不等于授权;只读开放不代表写入边界也已开放。
16. 多来源关系的置信度能直接累加吗?
不能,多篇转载可能只有同一个原始来源,模型错误也可能相关。先做来源去重并区分独立证据、权威性和冲突;若输出概率需要校准,别把任意加权分数叫正确概率。
17. ★ 图谱删掉原文后还保留摘要吗?
先按数据保留规则决定,而不是为了检索效果默认保留。摘要可能同样含敏感信息;删除事件应覆盖节点、断言、向量、缓存和产物。合法审计保留需限定权限和期限。
18. GraphRAG 比普通 RAG 一定更好吗?
不是。结构关系密集、需要多跳的问题可能受益;单段原文查找可能增加抽取错误和延迟。用同一题集比较增益与维护成本,只有明确收益再扩图,不把架构复杂度当技术成果。
19. 图写入中途失败,哪些地方必须原子?
单个图事务内的节点与关系修改要么一起成功要么回滚;外部 embedding 和 PG 状态另有补偿。不要在 Neo4j 长事务里等模型;先得到候选再用短事务提交,失败能按抽取 ID 重试。
20. ★ 怎么向面试官讲项目图谱的现状和后续?
现状讲 Neo4j 关系、Qdrant 双向量定位、图只读开放与 ariadne 写权限。后续可讲证据治理、实体消歧评测、跨库对账;DELEGATION_PLAN.md 的子 Agent 合并仍是方案,不能当成当前实现。
可运行练习
verify_16.py提供独立 RRF 自检与本机 Qdrant / Neo4j 练习。RRF 名次从 1 开始,同一榜单同一 ID 只计一次;常数 60 用来演示项目图融合,未假定服务端默认也是 60。
Qdrant 练习使用临时 collection 并在 finally 删除;Neo4j 练习只在一个回滚事务中创建带随机标记的节点与边,不做 schema 变更。具体运行结果见 验证记录.md。
项目事实与源码入口
核对日期:2026-10-21,路径相对 ../xknow-ai/。
| 事实 | 依据 |
|---|---|
| 文档稠密向量 + BM25 稀疏向量,两路 Prefetch,服务端 Fusion.RRF | app/extended/ext_vector.py 的 hybrid_search;BM25 使用 Qdrant/bm25 |
| 图节点 name-embedding / summary-embedding 分别检索,再在 Python 按排名融合,常数 60 | app/core/graph/graph_store.py 的 search_nodes_semantic(融合常数见 _RRF_K) |
| 检索参数可带 payload filter;授权不能只信 payload | app/extended/ext_vector.py、app/services/agent_read_scope.py、app/core/agent/tools/vector_tools.py;源码要求命中文档按 PG 归属复核 |
| 图写工具 update_node / update_relation / deprecate_node 仅 ariadne 可用,图只读工具已向主 Agent 放开 | app/core/agent/tools/__init__.py、graph_edit_tools.py |
| qwen3-vl-rerank 有模型迁移记录和历史 rerank profile 配置 | app/migrations/versions/f2a3b4c5d6e7_dashscope_model_pricing.py、app/scripts/legacy_config/models.yaml;实际当前模型由配置中心/数据库决定,不能仅据此断言运行时永远是它 |
官方核对入口:Qdrant 混合检索、Qdrant 过滤、Neo4j MERGE、Neo4j 执行计划。API 与可用功能要按实际服务版本核对。
第一部分:Qdrant 与向量检索
七、Neo4j(知识图谱)
入门
- 图数据库适合什么? 关系多跳查询(朋友的朋友、A 到 B 的路径、谁负责什么)。关系型数据库多次 JOIN 越来越慢,图数据库沿着边走,复杂度和总数据量无关,只和走过的部分有关(index-free adjacency)。
- Cypher 基本语法?
MATCH (p:Person)-[:WORKS_ON]->(proj:Project {name: '荔枝'}) RETURN p.name MERGE (p:Person {name: '张三'}) // 有就匹配,没有就创建 - CREATE 和 MERGE 区别? CREATE 必定新建;MERGE 先找、找不到才建(整个模式匹配)。
中等
- 索引和约束? 范围索引(等值和范围)、文本索引(
CONTAINS)、全文索引(Lucene,分词搜索)、向量索引(5.x 起);唯一约束CREATE CONSTRAINT FOR (p:Person) REQUIRE p.id IS UNIQUE(同时自带索引)。 - 怎么看查询计划?
EXPLAIN(不执行)/PROFILE(执行并统计每步的 db hits)。看有没有AllNodesScan(全图扫描)、NodeByLabelScan(按标签扫),理想是NodeIndexSeek。 - 批量写入怎么快?一次传几千行,比一条条写快几十倍;超大批量用
UNWIND $rows AS row MERGE (n:Entity {id: row.id}) SET n += row.propsCALL { ... } IN TRANSACTIONS OF 1000 ROWS分批提交,或离线用neo4j-admin import。 - 我们怎么用的? 从文档和对话里用模型抽取实体和关系写入;节点同时在 Qdrant 存名字和摘要的向量,语义找节点(双向量 RRF);关系问题用 text2cypher 或从已知节点展开邻居。
高难(场景模拟)
场景 1:超级节点(super node)
- 比如「公司」节点连了 100 万条边,任何经过它的查询都要遍历 100 万条边,直接卡死。
- 方案:
- 查询时指定关系类型和方向(Neo4j 对同一节点的边按类型和方向分组存储,指定后只扫对应的组);
- 建模时拆分:按时间 / 类别引入中间节点(公司 → 2026年10月 → 事件),而不是所有事件直接连公司;
- 业务上设上限,结果分页;
- 遍历时避开超级节点(路径查询里加条件跳过度数过高的节点)。
场景 2:变长路径查询爆炸
MATCH (a)-[*]-(b)不限深度,路径数随深度指数增长。- 方案:一律限制深度
[*1..3];用shortestPath();用 APOC 的apoc.path.expandConfig控制遍历(唯一性、黑白名单标签);加LIMIT;设查询超时db.transaction.timeout。
场景 3:并发 MERGE 产生重复节点
- MERGE 不是原子的「查 + 建」,两个事务同时 MERGE 同一个不存在的节点,可能各建一个。
- 方案:在 MERGE 的键上建唯一约束,这样并发时一个会失败(重试即可),而不是产生重复。
场景 4:实体去重(同一个人「张总」「张三」「Zhang San」)
- 这是知识图谱最难的问题,不是数据库能解决的。
- 方案:抽取时就规范化(统一全称);写入前先在向量库里按名字 + 摘要的语义相似度找候选,再让模型判断是否同一实体;保留别名属性;低置信度的进人工审核队列。我们的图谱写入带置信度,可以被重新抽取推翻。
场景 5:Text2Cypher 的安全和准确性
- 安全:只读事务执行(
session.execute_read);账号只给读权限;强制 LIMIT;查询超时;禁止CALL危险过程。我们的图谱写操作只给特定子 agent,主 agent 拒绝「直接改 Neo4j」的请求。 - 准确:prompt 里给 schema(标签、关系类型、属性);few-shot 示例;生成后先
EXPLAIN校验语法;失败把错误回喂给模型重试。
场景 6:多租户
- 社区版只有一个数据库 → 所有节点带
org_id属性并建索引,每条查询都必须带租户条件(在代码层统一注入,不依赖模型生成的 Cypher 记得加)。 - 企业版可以每个租户一个数据库(多数据库特性)。
场景 7:上亿节点 Neo4j 的容量和性能
- 内存:page cache 尽量装下整个图数据文件(节点、关系、属性存储),heap 用于查询执行;
- 社区版不支持集群,扩展读能力要企业版(读副本);
- 超大规模分析型图计算(PageRank、社区发现)用 GDS 库或导出到专门的图计算引擎,别在在线库上跑。
- 我们的取舍(加分点):图谱只存「需要关系查询」的事实,偏好、记忆这类不需要遍历的东西放 PG,控制图的规模。
