# 数据模型 ## 文档维护规范 0. **先改文档,再动代码** - 新功能或重大修改需先完成文档更新、并完成审阅后,再进行代码实现;除非改动较小、不被文档涵盖 1. **文档分层,链接代码** - 重要或复杂设计可以另有详细文档;关键实现需标注代码文件路径;格式:`module/file.py:function_name` 2. **简洁快照,日志分离** - 只记录最重要的、与代码准确对应的或者明确的已完成的设计的信息,避免推测、建议、决策历史、修改日志、大量代码;决策依据或修改日志若有必要,可在 `knowhub/docs/decisions.md` 另行记录 --- ## 存储架构 PostgreSQL (阿里云 AnalyticDB for PostgreSQL)。所有向量字段为 float4[](1536维),使用余弦距离(`<=>`)检索。 Embedding 模型:`google/gemini-2.5-flash-lite`(通过 OpenRouter)。实现:`knowhub/embeddings.py`。 数据库名:`knowhub` ## 多租户版本字段(version) 6 张实体表中除 tool 外(tool.version 早已存在,指工具自身发布版本),另外 5 张都有 `version VARCHAR(32) NOT NULL DEFAULT 'v0'` 列:`knowledge`, `resource`, `requirement`, `capability`, `strategy`。 - 用途:隔离算法测试数据(tao_dev_1 等)与生产数据(v0),共用一套入库/查询/可视化管道 - 规则:独立 ID 跨版本唯一(`CAP-v0-001` 和 `CAP-tao_dev_1-00-01` 是两个不同实体) - junction 表**不带 version**——自动继承两端实体的 version(通过 JOIN 实现过滤) - 批量清除某版本:`cascade.purge_version(cursor, 'tao_dev_1')` 一次清 5 张实体表 + 它们所有 junction 行 - 默认查询不过滤版本(返回所有数据);过滤时显式传 `version` 参数 --- ## 设计原则 - **knowledge 是基础层**,其余实体是组织/提炼知识的维度 - 每个维度的目标是**收敛到最优知识**,不是关联尽可能多的知识 - 实体字段(description、criterion、match_result)是提炼结果,知识链是提炼来源——两者都需要 - 所有实体间关系通过**关联表**存储,不使用 JSONB 数组软关联 - 工具库和知识库共用同一套工具 ID,不做 ID 映射 - Provider(运行环境)不作为知识库实体,由执行 Agent(Craftsman)内部管理;`tool_provider` 仅提供工具可用性索引 --- ## 表间关系 ``` requirement ──── requirement_strategy ──── strategy ╱ ╲ ╲ ╱ │ ╲ capability_ids knowledge_ids resource_ids capability │ knowledge / resource ╱ ╲ ╲ compose capability knowledge ← knowledge_resource → resource │ ╲ ╱ ╲ ↑ │ tool_ids knowledge_ids knowledge_relation │ │ ╲ ╱ (知识间关系) │ │ tool ... ← capability_resource ┤ capability_resource ← requirement_resource ← strategy_resource tool_provider (执行层索引) ``` 所有 `*_knowledge` / `knowledge_relation` / `strategy_capability` / `strategy_knowledge` 边带 `relation_type` 语义标签: - `source` — 知识/资料是该实体的构建来源 - `case` — 知识是该实体的应用实例 - `compose` — 组合关系(strategy → capability) - `related` — 默认/未分类 --- ## 实体表(6) ### knowledge — 知识表 基础层。用例、方法、经验、评论都是 knowledge。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | VARCHAR PK | `"knowledge-{timestamp}-{random}"` | | `task_embedding` | float4[] | task 的向量 | | `content_embedding` | float4[] | content 的向量 | | `message_id` | VARCHAR | 来源 Agent 消息 ID | | `task` | VARCHAR | 任务场景描述 | | `content` | TEXT | 知识正文 | | `types` | TEXT[] | 知识类型:tool / strategy / case / experience / definition | | `tags` | JSONB | 标签键值对 | | `tag_keys` | TEXT[] | tags 中的键列表(用于过滤) | | `scopes` | TEXT[] | 作用域,如 `["org:cybertogether"]` | | `owner` | VARCHAR | 所有者 | | `source` | JSONB | 来源信息(agent_id, category, urls, submitted_by, timestamp) | | `eval` | JSONB | 评估(score, helpful, harmful, confidence) | | `created_at` | BIGINT | 创建时间戳(秒) | | `updated_at` | BIGINT | 更新时间戳(秒) | | `status` | VARCHAR | pending → approved / rejected / checked | 关联(通过关联表,API 返回时聚合为 `{entity}_ids` 扁平列表 + `{entity}_links` 带 relation_type): - `requirement_ids` / `requirement_links` ← requirement_knowledge - `capability_ids` / `capability_links` ← capability_knowledge - `tool_ids` / `tool_links` ← tool_knowledge - `resource_ids` ← knowledge_resource - `relations` ← knowledge_relation ### resource — 资源表 知识的原始来源。文档、代码、凭证等。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | TEXT PK | 路径格式,如 `"tools/selenium/login"` | | `title` | TEXT | 标题 | | `body` | TEXT | 公开内容 | | `secure_body` | TEXT | 敏感内容(AES-256-GCM 加密) | | `content_type` | TEXT | text / code / credential / cookie | | `metadata` | JSONB | 附加元数据 | | `images` | JSONB | 图片 URL 列表 `[url1, url2, ...]`,用于 dashboard 缩略图展示(v5 新增)| | `sort_order` | INTEGER | 同级排序 | | `submitted_by` | TEXT | 提交者 | | `created_at` | BIGINT | 创建时间戳 | | `updated_at` | BIGINT | 更新时间戳 | | `version` | VARCHAR(32) | 多租户版本标签,DEFAULT `'v0'` | ### requirement — 需求表 业务目标。分解为能力的组合,以保持稳定性。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | VARCHAR PK | `"REQ_XXX"` | | `description` | TEXT | 需求描述 | | `source_nodes` | JSONB | 来源节点 `[{node_name, posts}]` | | `status` | VARCHAR | 已满足 / 未满足 | | `match_result` | TEXT | 满足方案描述(提炼结果) | | `embedding` | float4[] | description 的向量 | 关联: - `capability_ids` ← requirement_capability - `knowledge_ids` / `knowledge_links` ← requirement_knowledge - `resource_ids` ← requirement_resource - `strategy_ids` ← requirement_strategy(满足该需求的 strategy) ### capability — 原子能力表 需求的稳定分解锚点。从知识中提炼,连接需求与工具。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | VARCHAR PK | `"CAP-XXX"` | | `name` | VARCHAR | 能力名称 | | `criterion` | TEXT | 评估标准(提炼结果) | | `description` | TEXT | 能力描述(提炼结果) | | `embedding` | float4[] | name + description 的向量 | 关联: - `requirement_ids` ← requirement_capability - `tool_ids` ← capability_tool - `knowledge_ids` / `knowledge_links` ← capability_knowledge - `resource_ids` ← capability_resource ### tool — 工具表 具体的技术/模型/软件。工具库和知识库共用同一套 ID。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | VARCHAR PK | 路径格式,如 `"tools/image_gen/controlnet_openpose"` | | `name` | VARCHAR | 工具名称 | | `version` | VARCHAR | 版本号 | | `introduction` | TEXT | 功能介绍 | | `tutorial` | TEXT | 使用指南 | | `input` | JSONB | 输入规格 | | `output` | JSONB | 输出规格 | | `updated_time` | BIGINT | 更新时间戳 | | `status` | VARCHAR | 未接入 / 可用 / 异常 | | `embedding` | float4[] | name + introduction 的向量 | 关联: - `capability_ids` ← capability_tool - `knowledge_ids` / `knowledge_links` ← tool_knowledge - `provider_ids` ← tool_provider ### strategy — 制作策略表 一组原子 capability 的组合,附带自身的可执行 `body`(如工作流脚本、流程描述)与 source 知识。strategy 设计用来满足 requirement。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | VARCHAR PK | `"strategy-{...}"` | | `name` | VARCHAR | 策略名称 | | `description` | TEXT | 策略描述 | | `body` | TEXT | 可执行正文(工作流/脚本/流程步骤) | | `status` | VARCHAR | draft / approved / deprecated 等 | | `created_at` | BIGINT | 创建时间戳(秒) | | `updated_at` | BIGINT | 更新时间戳(秒) | | `embedding` | float4[] | name + description 的向量 | 关联: - `requirement_ids` ← requirement_strategy(这个 strategy 被设计用来满足哪些 requirement) - `capability_ids` / `capability_links` ← strategy_capability(compose 组合) - `knowledge_ids` / `knowledge_links` ← strategy_knowledge(source / case 等) - `resource_ids` ← strategy_resource(直接原始素材) --- ## 关联表(14) ### 实体链(3) **requirement_capability** — 需求分解为能力 | 字段 | 类型 | 说明 | |------|------|------| | `requirement_id` | VARCHAR | → requirement.id | | `capability_id` | VARCHAR | → capability.id | PK: (requirement_id, capability_id) **capability_tool** — 能力由工具实现 | 字段 | 类型 | 说明 | |------|------|------| | `capability_id` | VARCHAR | → capability.id | | `tool_id` | VARCHAR | → tool.id | | `description` | TEXT | 该工具如何实现此能力 | PK: (capability_id, tool_id) **requirement_strategy** — 需求由 strategy 满足 | 字段 | 类型 | 说明 | |------|------|------| | `requirement_id` | VARCHAR | → requirement.id | | `strategy_id` | VARCHAR | → strategy.id | PK: (requirement_id, strategy_id) ### 知识链(4) 所有 `*_knowledge` 表及 `strategy_knowledge` 都带 `relation_type VARCHAR(32)` 列,值 ∈ {`source`, `case`, `related`}。DEFAULT `'related'`(历史数据)。 **requirement_knowledge** — 需求的方案策略、完成方法 | 字段 | 类型 | 说明 | |------|------|------| | `requirement_id` | VARCHAR | → requirement.id | | `knowledge_id` | VARCHAR | → knowledge.id | | `relation_type` | VARCHAR(32) | source / case / related(默认) | PK: (requirement_id, knowledge_id) **capability_knowledge** — 能力的原理依据、评判来源 | 字段 | 类型 | 说明 | |------|------|------| | `capability_id` | VARCHAR | → capability.id | | `knowledge_id` | VARCHAR | → knowledge.id | | `relation_type` | VARCHAR(32) | source / case / related(默认) | PK: (capability_id, knowledge_id) **tool_knowledge** — 工具的用法、案例、经验 | 字段 | 类型 | 说明 | |------|------|------| | `tool_id` | VARCHAR | → tool.id | | `knowledge_id` | VARCHAR | → knowledge.id | | `relation_type` | VARCHAR(32) | source / case / related(默认) | PK: (tool_id, knowledge_id) **strategy_knowledge** — strategy 的知识来源 | 字段 | 类型 | 说明 | |------|------|------| | `strategy_id` | VARCHAR | → strategy.id | | `knowledge_id` | VARCHAR | → knowledge.id | | `relation_type` | VARCHAR(32) | 默认 `source`;可为 `case` 等 | PK: (strategy_id, knowledge_id) ### 组合关系(1) **strategy_capability** — strategy 组合哪些原子能力 | 字段 | 类型 | 说明 | |------|------|------| | `strategy_id` | VARCHAR | → strategy.id | | `capability_id` | VARCHAR | → capability.id | | `relation_type` | VARCHAR(32) | 默认 `compose` | PK: (strategy_id, capability_id) ### 来源链(5) **knowledge_resource** — 知识的原始来源 | 字段 | 类型 | 说明 | |------|------|------| | `knowledge_id` | VARCHAR | → knowledge.id | | `resource_id` | VARCHAR | → resource.id | PK: (knowledge_id, resource_id) **requirement_resource** — 需求直接来自的原始素材(绕过 knowledge 整理层) PK: (requirement_id, resource_id) **capability_resource** — capability 直接来自的原始素材 PK: (capability_id, resource_id) **strategy_resource** — strategy 直接来自的原始素材 PK: (strategy_id, resource_id) `*_resource` 边**无 relation_type**——存在本身即"source"语义,不需额外标签。 ### 知识间关系(1) **knowledge_relation** — 知识之间的关系(替代、扩展、矛盾等) | 字段 | 类型 | 说明 | |------|------|------| | `source_id` | VARCHAR | → knowledge.id | | `target_id` | VARCHAR | → knowledge.id | | `relation_type` | VARCHAR | supersedes / extends / contradicts / ... | PK: (source_id, target_id, relation_type) ### 执行层索引(1) **tool_provider** — 工具在哪些运行环境可用(供 Craftsman 查询) | 字段 | 类型 | 说明 | |------|------|------| | `tool_id` | VARCHAR | → tool.id | | `provider_id` | VARCHAR | 运行环境标识(如 "comfyui"、"liblib") | PK: (tool_id, provider_id) --- ## Embedding 策略 | 表 | 向量字段 | Embedding 内容 | |---|---|---| | knowledge | `task_embedding` | task | | knowledge | `content_embedding` | content | | tool | `embedding` | name + introduction | | capability | `embedding` | name + description | | requirement | `embedding` | description | | strategy | `embedding` | name + description |