建图失败顶多重跑,图建错了却会安静地给出错误答案。这一节讲清两类问题的定位法:建图阶段的失败、和建好后的"图不对"。
这是第五章第二站,生产里绕不开的环节。
import asyncio, cognee async def safe_build(): try: await cognee.add("./资料") await cognee.cognify() except Exception as e: # 记录失败点,便于从检查点续跑 print("建图中断:", type(e).__name__, str(e)[:80]) # 检查点机制让下次 cognify 只补未完成部分 return False return True asyncio.run(safe_build()) # 建图中断: RateLimitError 调用过于频繁
捕获异常后不要整批丢弃——靠第二章讲的检查点,下次 cognify 只补失败片段。这比"报错就全重来"省太多。
当查询结果明显错,按"图→关系→抽取"自底向上查。下面给出排查脚本思路。

# 调试:打印某实体的关系,核对是否抽错 async def inspect(entity: str): triples = await cognee.get_edges(entity) for s, p, o in triples: print(f"{s} --{p}--> {o}") # 若发现 "云图科技 --总部-->> 北京" 但原文写深圳 # 说明抽取阶段把地点搞错,需回抽取模板 asyncio.run(inspect("云图科技")) # (与原文"深圳"不符,定位到抽取错误)
每个三元组都带 source,直接跳回原文坐标核对,比在图里瞎找快得多。这是可追溯性的调试红利。
背景:一批合同是扫描 PDF,建图后这些文档零三元组。
操作:定位到解析层,加 OCR 预处理。
import asyncio, cognee async def ocr_then_build(): # 先 OCR 把扫描件转文字,再 add texts = [ocr_to_text(f) for f in scan_pdfs()] # 示意 OCR for t in texts: await cognee.add(t) await cognee.cognify() print("扫描件经OCR后建图完成") asyncio.run(ocr_then_build()) # [建图] 原零三元组文档现产出 210 条
结果:加一层 OCR 后,原本空白的文档补上了关系。
解读:调试的价值在"定位到正确层"。若没查就怪 Cognee 抽得差,可能永远想不到是 PDF 根本没文字。分层定位省下的不是时间,是方向。
变式:若 OCR 仍漏,可在摄取阶段加"文字长度校验",低于阈值的文档自动标记人工复核,避免静默建出空图。
图出问题分两类,解法完全不同:一类是建图阶段失败(无图或残缺),一类是图建好了但答非所问(图逻辑错)。新手常混着排查,浪费时间。类比到物理——电路不亮,先量"有没有电"再量"元件坏没坏",顺序错了白查。
# 分层定位(示意) async def diagnose(): edges = await cognee.get_edges("云图科技") if not edges: print("病在建图:先修 cognify") # 建不出 else: ans = await cognee.search("云图科技总部") if "杭州" not in str(ans): print("病在图逻辑:关系错或检索权偏") # 答不对
先定性再定量,排查路径短一半。
| 症状 | 病位 | 第一动作 |
|---|---|---|
| 无边 | 建图 | 查抽取/限流 |
| 有边答错 | 图逻辑 | 查关系/权重 |
| 偶发空 | 连接 | 查图库 |
⚠️ 别一报错就全量重跑——先确认是"建不出"还是"答不对",后者重跑图也救不了。
💡 调试时把 search 的中间结果(种子实体、走到的邻居)打印出来,能直接看见图有没有被用、走到哪。
调试的前提是有迹可循。建议建图每一步(切片数、抽取三元组数、写图边数、耗时)都记结构化日志,出问题时一拉就知道哪步异常。类比到物理实验——每一步读数记本上,实验失败才能复盘哪步偏了。
| 步骤 | 记什么 |
|---|---|
| 切片 | 段数 |
| 抽取 | 三元组数 |
| 写图 | 边数/耗时 |
⚠️ 别只记"成功/失败"——失败但不知卡哪步,等于没日志,重跑还是盲猜。
💡 日志结构化(JSON)便于聚合,按文档/批次筛异常,定位从翻日志变查报表。
建图报错别烦,它是系统在告诉你"这批发有问题"。把错误当体检报告读,比当麻烦摁掉更有用。图错比没图危险,报错恰是拦住错误的最后一道闸。
⚠️ 别为跑通而忽略警告——警告常是错的先兆,摁掉它下次就变成失败。
💡 建图日志里的 warning 也归档,定期回看,能提前发现抽取漂移。
两类问题修法天差地别。建图失败是"没图",重跑或修源即可;图逻辑错是"图在建但关系错",要回炉抽取或改模板,重跑救不了逻辑。分不清就乱修,越修越糟。
| 问题 | 修法 |
|---|---|
| 建图失败 | 修源/重跑 |
| 关系错 | 改模板/重抽 |
| 偶发空 | 查连接 |
⚠️ 别图逻辑错时反复 cognify——模板没改,重跑一千遍图还是错的。
💡 改完模板先在小样本验,确认关系对再全量重抽,避免全库跑完发现还错。
source 字段回原文核对是最快定位法。⚠️ 别在抽取报错时整批重来。检查点机制就是为增量续跑设计的,重来是浪费。
💡 给关键文档加"三元组数量下限"断言,建图后自动标出空图,把沉默失败变显式失败。