---
title: 笔记关系与图视图：从候选发现到可验证扩展
description: 按 ChatCrystal 当前关系 API、候选筛选与图投影说明自动发现、手动关系和标签图的实际边界。
image: "https://zengliangyi.com/og/blog/note-relations-and-graph.png"
---

ChatCrystal 的“关系图”由两类数据组成：笔记之间的有向关系，以及当前界面默认展示的标签共现图。不要把图上的一条边直接当成事实或证明；它只是从候选、模型输出或标签共现规则得到的可检查线索。

本文依据固定提交 [`7642768`](https://github.com/ZengLiangYi/ChatCrystal/tree/764276814e5c5a33ecbfeae63754f74b9261a3a8) 的 [关系服务](https://github.com/ZengLiangYi/ChatCrystal/blob/764276814e5c5a33ecbfeae63754f74b9261a3a8/server/src/services/relations.ts) 与 [关系路由](https://github.com/ZengLiangYi/ChatCrystal/blob/764276814e5c5a33ecbfeae63754f74b9261a3a8/server/src/routes/relations.ts)。

## 两种图不要混为一谈

笔记关系表记录 source、target、类型、confidence、description 和 `created_by`。自动发现允许 `CAUSED_BY`、`LEADS_TO`、`RESOLVED_BY`、`SIMILAR_TO`、`CONTRADICTS`、`DEPENDS_ON`、`EXTENDS`、`REFERENCES` 八种枚举；同一方向、同一类型只能保留一条。手动关系的 confidence 固定设为 1，来源由 `created_by` 记录；这个数值不是经过测量的概率。

当前 Web 图页面调用 `GET /api/graph/projection?level=tag`，默认展示标签节点和共现边，最多 120 个节点；强度筛选对应 `minScore`。点击标签后，页面再按该标签加载最多 20 条笔记。`GET /api/relations/graph` 仍可返回笔记节点和关系边，但它是另一个接口，不代表首页当前一定使用它。

## 自动发现如何挑选候选

`POST /api/notes/<note-id>/discover-relations` 先用源笔记标题做语义搜索，最多取 20 个候选并排除自己；搜索失败或没有候选时，退回按创建时间取最近 20 条。候选的摘要最多截取 200 个字符，源笔记摘要最多放入 500 个字符的提示。候选集合有限，发现结果不代表扫描了整个库。

模型输出使用结构化数组和上述关系枚举。应用随后只保留候选 ID、confidence 至少 `0.5` 的项，并截取最多 5 条；描述字段有“简短说明”的提示，但 schema 没有把 20 字做成硬性长度校验。写入使用 `INSERT OR IGNORE`，重复关系不会产生第二条。

执行前将 `<note-id>` 和 `<relation-id>` 替换为实际 ID；手动示例中的 42、58 也须替换为库中存在的笔记。



```bash
curl   --request   POST   \  
    'http://localhost:3721/api/notes/<note-id>/discover-relations'  
  curl   'http://localhost:3721/api/notes/<note-id>/relations'
```



接口是同步发现流程，模型不可用时会返回错误；它不是后台保证完成的任务。手动创建关系则显式指定目标 ID、类型和说明：



```bash
curl   --request   POST   http://localhost:3721/api/notes/42/relations   \  
    --header   'Content-Type: application/json'   \  
    --data   '{"target_note_id":58,"relation_type":"RESOLVED_BY","description":"按测试结果复核"}'  
  curl   --request   DELETE   'http://localhost:3721/api/relations/<relation-id>'
```



服务会校验两条笔记存在、禁止自引用和未知类型；手动重复插入会返回 HTTP 400 错误。

## 用关系扩展搜索，但保留来源

语义搜索可以用 `expand=true` 加一跳关系：只扩展 confidence 至少 `0.5` 的边，关联分数按“直接分数 × 0.7 × confidence”折扣。已在结果中的笔记会跳过，扩展不是多跳路径搜索，也不能保证每个关联结果都来自最强路径。阅读结果时回到笔记正文和原始会话，不把 `via_relation` 当成事实验证。

批量发现接口会为没有出边的笔记入队；队列按应用的任务机制执行，响应里的 `queued` 只是提交数量。它不承诺每条关系生成成功，也不应替代逐条结果核验。

## 让图成为可复查的线索

先记录关系的 source、target、类型、confidence 和创建来源，再用一个具体问题验证：这条关系是否能在两条笔记的摘要或原文中找到依据？若结论冲突，保留反例并检查当前项目条件。标签共现图只能说明标签出现在相同笔记中，不能自动升级为因果关系。

关系接口、语义检索和图投影的边界见 [语义搜索流程](/blog/semantic-search-workflow)；数据写回的质量约束见 [Agent 知识记忆闭环](/blog/agent-knowledge-memory-loop)。

分享：

##  相关文章

[##  语义搜索与关系上下文：发现隐藏依赖但保留验证

用构造的重构场景组合直接检索和一跳关系扩展，解释分数、候选和来源字段，不把关联线索写成依赖证明。          曾亮懿       2026年10月3日      阅读约 3 分钟

#ChatCrystal

#语义搜索

#知识图谱](/blog/semantic-search-relation-context)    [##  从 RAG 到知识图谱：让个人知识检索保留关系

区分关键词检索、向量搜索、RAG 与笔记关系图，结合 ChatCrystal 的候选召回和一跳扩展实现，说明关系能补充什么、不能证明什么。          曾亮懿       2026年6月5日      阅读约 6 分钟

#ChatCrystal

#RAG

#知识图谱

#检索](/blog/rag-and-knowledge-graphs)    [##  AI 对话格式差异：事件、快照与跨库消息定位

对照五个固定适配器，区分 JSONL 容器、事件语义与 SQLite 键布局，用两个内存数据库观察消息索引、孤立数据和未知版本。          曾亮懿       2026年10月7日      阅读约 4 分钟

#ChatCrystal

#Node.js

#SQLite](/blog/ai-conversation-format-divergence)

##  从文章到代码

到我的 GitHub 看看 ChatCrystal、开发者工具和日常学习记录，欢迎交流实现细节。

[访问我的 GitHub](https://github.com/ZengLiangYi)

```json
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "ZengLiangYi Blog",
  "alternateName": [
    "Zeng Liangyi",
    "ZengLiangYi",
    "zengliangyi.com"
  ],
  "url": "https://zengliangyi.com",
  "description": "曾亮懿的个人网站。记录 AI Native 探索、开发者工具与全栈产品实践。"
}
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "笔记关系与图视图：从候选发现到可验证扩展",
  "description": "按 ChatCrystal 当前关系 API、候选筛选与图投影说明自动发现、手动关系和标签图的实际边界。",
  "url": "https://zengliangyi.com/blog/note-relations-and-graph/",
  "image": "https://zengliangyi.com/images/blog/note-relations-and-graph.svg",
  "datePublished": "2026-10-03T00:00:00.000Z",
  "dateModified": "2026-10-03T00:00:00.000Z",
  "author": {
    "@type": "Person",
    "name": "曾亮懿",
    "url": "https://zengliangyi.com/about"
  },
  "publisher": {
    "@type": "Organization",
    "name": "ZengLiangYi Blog",
    "logo": {
      "@type": "ImageObject",
      "url": "https://zengliangyi.com/favicon-96x96.png"
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://zengliangyi.com/blog/note-relations-and-graph/"
  }
}
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "首页",
      "item": "https://zengliangyi.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "文章",
      "item": "https://zengliangyi.com/blog"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "笔记关系与图视图：从候选发现到可验证扩展",
      "item": "https://zengliangyi.com/blog/note-relations-and-graph/"
    }
  ]
}
```
