Ingest 数据导入
1201 字约 4 分钟
2026-05-11
让 agent 通过对话往 KB / DB / Graph 写数据。这一层把 DataMind 从纯只读检索 agent 变成可读可写的工作助手。
工具目录
| 工具 | 说明 |
|---|---|
kb_add_file | 单文件 → chunk → embed → upsert 进 Chroma,立刻可被 kb_search 检索到 |
kb_add_path | 目录递归扫描或单文件,批量导入 |
db_import_csv | CSV → 推断 schema → CREATE TABLE → INSERT,支持 append / replace / fail 模式 |
graph_add_triples_from_text | 自然语言 → LLM 抽取 (subject, relation, object) → upsert 进图谱,并立即持久化 |
所有工具属于 ingest 组,注册到 ToolRegistry 后会出现在 system prompt 的"数据导入"分组里。enable={"kb","db","graph",…} 中加上 "ingest"(或不传 enable)即可启用。
所有工具属于 ingest 或 workspace 组,注册到 ToolRegistry 后会按 StoreAgent / RetrieveAgent 的权限边界暴露。写入工具只给 StoreAgent,读取和构建检查工具也可给 RetrieveAgent 使用。
工作区统一构建
对于包含文档、表格、代码和图片的工作区,推荐使用下面的流程:
| 工具 | 作用 |
|---|---|
workspace_inspect | 只读盘点文件类型、大小、hash 和候选数据面 |
surface_ingest_path | 自动把文档送入 KB、表格送入 SQL、文件关系送入 Lineage Graph |
raw_file_read | 分页读取原始文件或解析后的文档证据,并返回 SHA-256 |
graph_build_lineage | 建立 contains、mentions、version_of、shared_artifact、depends_on 等文件关系 |
build_start | 创建构建运行并保存源文件清单 |
build_status | 查看构建状态,冻结后自动校验 |
build_freeze | 固化 DataMind 产物的 hash |
build_verify | 检查冻结产物是否被修改 |
build_export | 导出已验证的 KB、SQL 和 Graph 产物 |
推荐顺序:
build_start → workspace_inspect → surface_ingest_path → build_freeze
↓
build_status / build_verify / build_export支持的文档格式包括 PDF、DOCX、PPTX、DOC、PPT、Markdown、TXT、HTML、JSON、XML、Python 和 Java;CSV、TSV、XLSX 进入 SQL。PDF 默认优先调用 MinerU Hosted API,API 不可用、超时或返回空结果时回退到 pypdf。通过 DATAMIND_MINERU=off 可以强制只使用 pypdf。
使用方式
1. 直接对话(推荐)
[你] 帮我把 /Users/foo/policy.md 加进知识库
[agent] 调用 kb_add_file(path="/Users/foo/policy.md")
✓ 1 chunk 已导入,现在可以搜索
[你] 把 /Users/foo/sales-q2.csv 导入成数据表 sales_q2
[agent] 调用 db_import_csv(path=..., table="sales_q2", if_exists="append")
✓ 18 行已写入,可立刻 SQL 查询
[你] 陈诚晋升 Tech Lead,向 Ann 汇报,主要负责 Project Kepler
[agent] 调用 graph_add_triples_from_text(text="...")
✓ 抽出 3 条 triples 并写入图谱2. 浏览器拖拽上传
打开 http://127.0.0.1:8000,输入框上方有一块"📎 拖拽文件到这里上传"的区域:
- 拖入任意
.md/.txt/.csv文件 - 后端
POST /api/upload把文件存到data/profiles/<profile>/uploads/<filename> - 文件出现在 dropzone 下方列表,每行有「导入」按钮
- 点击后前端按扩展名构造 prompt(
.csv→ "导入成数据表",.md/.txt→ "加进知识库"),自动发给 agent - agent 自主选 ingest 工具完成导入
后端会做内容 hash 去重,重复同名上传不会污染。
3. 直接走 service 层(程序化)
agent = await build_agent(settings)
res = await agent.ingest.kb_add_file(path="/path/to/file.md")
res = await agent.ingest.db_import_csv(
path="/path/to/data.csv", table="customers", if_exists="replace"
)
res = await agent.ingest.graph_add_triples_from_text(
text="Alice leads the Search team."
)适合在脚本 / 后台任务里批量灌数据。
路径安全
IngestService 维护一个 allow-list,默认包含:
- 当前 profile 的
data_dir - 当前 cwd
- cwd 的父目录(让用户能用
~/Desktop/DataMind/demo-uploads/这样的相邻目录) - 系统临时目录(
tempfile.gettempdir()) - macOS 下的
/tmp与/private/tmp
所有路径会先 Path.resolve(),再做前缀检查,所以软链接不能绕过。需要更宽的白名单时通过 IngestService(..., allowed_roots=[...]) 显式注入。
工具还支持 basename fallback:如果用户只说 "把刚上传的 foo.md 加进去",service 会去 <profile>/uploads/foo.md 找。这让前端拖拽 + 自动发 prompt 的流程不需要前端记住完整路径。
内容去重
KB 的 chunk id 是 _hash(text, source) 的 SHA1。同一文件再次导入产生相同 id,Chroma upsert 等价 no-op,不会重复占空间。
失败处理
- 单文件批量导入时(
kb_add_path),其中一个文件出错不会中断其他文件 - CSV 导入失败(表名非法、文件空、SQL 错)会抛
CapabilityError("ingest", ...),agent 看到友好错误并向用户反馈 - LLM 抽取 triples 失败(返回空数组、JSON 格式不对)会返回
{"triples_added": 0, "raw_response": "..."}而不是异常
跟其他能力的协作
你:把 /tmp/customers.csv 导入成 customers 表
agent → db_import_csv → ✓ 已建表
你:customers 表里 Enterprise 套餐客户的 ARR 加起来是多少?
agent → db_query_nl → db_query_sql → 返回结果
你:再问"鼎元金融"对应的负责人是哪位 CSM?
agent → db_query_sql → "Leo"
agent → graph_search_entities("Leo") → "属于 Operations 部门"ingest 出来的数据立刻被同一个 ToolRegistry 暴露给后续问答,完全无缝。