Base URL:
http://127.0.0.1:8800全部接口返回 JSON;FastAPI 自动生成交互式文档:http://127.0.0.1:8800/docs
{ "detail": "错误描述" }| HTTP | 含义 | 典型场景 |
|---|---|---|
| 400 | 参数/业务校验失败 | 类型已存在、类型在使用中、格式错误 |
| 404 | 资源不存在 | 实体/关系 ID 无效 |
| 409 | 乐观锁冲突 | 提交的 if_version 不等于当前 version |
| 422 | 请求体校验失败 | 缺字段、字段类型错误 |
获取实体类型、关系类型、颜色映射与数据版本号。
响应
{
"entity_types": ["Person", "Skill"],
"relation_types": ["HAS_SKILL", "KNOWS"],
"relation_type_labels": { "HAS_SKILL": "掌握技能" },
"entity_colors": { "Person": "#ff6b6b" },
"version": 17
}列出全部实体类型(名称 → 颜色)。
{ "Person": "#ff6b6b", "Skill": "#4ecdc4" }新增类型。
请求
{ "name": "Language", "color": "#54a0ff" }失败:400 {"detail": "类型已存在: Language"}
改色 / 改名(可同时)。
请求
{ "color": "#eb4d4b" }{ "new_name": "Language" }改名会级联更新所有使用该类型的实体。
name需 URL 编码。
删除类型。
失败:400 {"detail": "类型正在被 3 个实体使用,无法删除"}(有实体在使用时拒绝)
{ "HAS_SKILL": "掌握技能" }请求
{ "name": "OWNS", "label": "拥有" }改标签 / 改名。
请求
{ "label": "掌握" }有关系的类型在使用时拒绝(400)。
列出全部实体,?type= 可选过滤。
获取单个实体。
创建实体。
请求
{
"name": "Python",
"type": "Skill",
"properties": { "level": "advanced" },
"color": "#4ecdc4"
}properties/color可选color留空 = 使用类型默认色
更新实体。
请求
{
"name": "Python 3",
"type": "Skill",
"properties": { "level": "advanced", "logo": "http://127.0.0.1:8800/uploads/xx.png" },
"color": "",
"if_version": 16
}- 所有字段可选;
color: ""清除自定义色 properties为整体替换(非合并)if_version可选,不匹配返回 409
409 示例
{ "detail": "数据已被其他页面或程序修改,请刷新后重试" }删除实体,级联删除所有关联关系。
列出全部关系,?type= 可选过滤。
获取单个关系。
请求
{
"source": "1e2b0a7e-...",
"target": "3f5c...",
"type": "HAS_SKILL",
"properties": {}
}失败:400 {"detail": "源实体或目标实体不存在"} 或 {"detail": "未注册的关系类型: XXX"}
请求
{
"source": "新源id",
"target": "新目标id",
"type": "USES",
"properties": {},
"if_version": 16
}端点变化时后端会重建图边。
删除关系。
返回完整图谱(3D 渲染用):
{
"entities": [ { "id": "...", "name": "...", "type": "...", "color": "...", "size": null } ],
"relations": [ { "id": "...", "source": "...", "target": "...", "type": "..." } ]
}邻居子图。degree 默认 1(直接邻居),2 = 二度邻居。
{
"entities": [],
"relations": []
}查询两实体间关联路径(无向视角,按跳数从短到长)。
响应
{
"source": "A-id",
"target": "B-id",
"paths": [
{
"nodes": ["A-id", "C-id", "B-id"],
"relations": ["r1", "r2"],
"length": 2,
"node_names": ["A", "C", "B"],
"relation_types": ["USES", "PART_OF"]
}
]
}max_hops范围 1~4(超出会被钳制)- 失败:400
{"detail": "起点或终点实体不存在"}/{"detail": "起点和终点不能相同"}
共同邻居。
响应
{
"a": { "...": "实体A" },
"b": { "...": "实体B" },
"common": [ { "...": "实体C" } ],
"common_count": 1
}搜索实体(名称 + 属性值模糊匹配)。
[ { "id": "...", "name": "Python", "type": "Skill" } ]{
"total_entities": 26,
"total_relations": 41,
"entity_types": { "Person": 3 },
"relation_types": { "HAS_SKILL": 5 }
}文本 → LLM 抽取三元组 → 查重/类型白名单 → 写入图谱。内置五道防噪闸,
闲聊/寒暄文本零写入;建议先 dry_run 预览再正式写入。
模型配置见 TECHNICAL.md 8.3 节(默认 DASHSCOPE_API_KEY + qwen-flash)。
curl -X POST http://127.0.0.1:8800/api/ingest -H "Content-Type: application/json" \
-d "{\"text\": \"小明掌握 Python,正在参与 AceFelix 项目。\", \"dry_run\": true}"请求体
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
text |
string | 必填 | 待抽取文本 |
dry_run |
bool | false | true 只返回预览,不写入 |
source |
string | text | 来源标记(写入实体属性溯源) |
as_session |
bool | false | true 时把 text 按会话 JSON(messages 数组)解析 |
响应(写入与预览同构)
{
"dry_run": true,
"gate": "passed",
"created_entities": [ { "name": "小明", "type": "Person" } ],
"created_relations": [ { "source": "小明", "target": "Python", "type": "HAS_SKILL" } ],
"skipped_duplicate_entities": ["Python"],
"skipped_duplicate_relations": [],
"pending_review": [],
"skipped_relations": [],
"version": 75
}gate:闸门判定,被拦截时为rejected: 原因(如文本过短/纯疑问句/价值预判为空)pending_review:类型不在白名单的实体,不写入,由人工裁决(可手动建实体后重新抽取)skipped_relations:含拒绝原因(类型不在白名单/端点未入库/自环)
失败:400 会话 JSON 解析失败;502 抽取模型未配置或调用失败(detail 含原因)
上传 .txt / .md / .json 文件抽取(multipart,上限 2MB,UTF-8)。 .json 文件优先按 jarvis 会话记录(messages 数组)解析,失败退回纯文本。
curl -X POST http://127.0.0.1:8800/api/ingest/file \
-F "file=@./notes.md" -F "dry_run=true"响应结构同 POST /api/ingest。失败:400 文件类型/大小/编码不合法。
上传图片(multipart/form-data,字段名 file)。
curl -X POST http://127.0.0.1:8800/api/upload \
-F "file=@./logo.png"响应
{ "url": "/uploads/3f2a9c1e8b7d4f5e9a1b2c3d4e5f6a7b.png" }访问图片:http://127.0.0.1:8800/uploads/{filename}
失败:400 {"detail": "仅支持图片文件"}(MIME 非图片类型)
上传文档(multipart/form-data,字段名 file),供实体属性引用。
- 允许扩展名:
.pdf/.md/.txt/.docx/.xmind(按扩展名白名单校验,浏览器上报的文档 MIME 不可靠) - 大小上限:20MB
- 文件名:保留原始名称(清洗路径分隔符/非法字符,防路径穿越),拼接短 UUID 前缀防冲突
curl -X POST http://127.0.0.1:8800/api/upload/doc \
-F "file=@./简历.pdf"响应
{
"url": "/doc-uploads/3f2a9c1e_简历.pdf",
"name": "简历.pdf",
"size": 102400
}访问文档:http://127.0.0.1:8800/doc-uploads/{filename}(浏览器预览或下载)
失败:
- 400
{"detail": "仅支持 .pdf/.md/.txt/.docx/.xmind 文档文件"}(扩展名不在白名单) - 400
{"detail": "文档大小超过 20MB 限制"}(超过大小上限)
| 路径 | 说明 |
|---|---|
/uploads/{filename} |
上传的图片文件 |
/doc-uploads/{filename} |
上传的文档文件(pdf/md/txt/docx/xmind) |
/docs |
FastAPI Swagger UI |
/redoc |
ReDoc 文档 |