spec: add metadata-role-separation module specification [AC-MRS-01~16]
This commit is contained in:
parent
714dc8c480
commit
5ded0c5f75
|
|
@ -0,0 +1,615 @@
|
|||
# 元数据职责分层优化 - 技术设计
|
||||
|
||||
## 1. 系统架构
|
||||
|
||||
### 1.1 整体架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 管理端 (ai-service-admin) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ 元数据字段配置 │ │ 槽位定义配置 │ │ 按角色过滤视图 │ │
|
||||
│ │ (field_roles) │ │ (SlotDefinition) │ │ (RoleFilter) │ │
|
||||
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
|
||||
└───────────┼────────────────────┼────────────────────┼───────────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 后端服务 (ai-service) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ API Layer │ │
|
||||
│ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │
|
||||
│ │ │ MetadataFieldAPI │ │ SlotDefinitionAPI │ │ │
|
||||
│ │ │ - CRUD │ │ - CRUD │ │ │
|
||||
│ │ │ - getByRole │ │ - getByRole │ │ │
|
||||
│ │ └──────────┬───────────┘ └──────────┬───────────┘ │ │
|
||||
│ └─────────────┼────────────────────────┼──────────────────────────┘ │
|
||||
│ │ │ │
|
||||
│ ┌─────────────┼────────────────────────┼──────────────────────────┐ │
|
||||
│ │ │ Service Layer │ │ │
|
||||
│ │ ┌──────────▼───────────┐ ┌────────▼──────────┐ │ │
|
||||
│ │ │ MetadataFieldService │ │ SlotDefinitionSvc │ │ │
|
||||
│ │ │ - create/update │ │ - create/update │ │ │
|
||||
│ │ │ - getByRole │ │ - getByRole │ │ │
|
||||
│ │ │ - validateRoles │ │ - linkToField │ │ │
|
||||
│ │ └──────────┬───────────┘ └────────┬──────────┘ │ │
|
||||
│ └─────────────┼────────────────────────┼──────────────────────────┘ │
|
||||
│ │ │ │
|
||||
│ ┌─────────────┼────────────────────────┼──────────────────────────┐ │
|
||||
│ │ │ Tool Integration │ │ │
|
||||
│ │ ┌──────────▼────────────────────────▼──────────┐ │ │
|
||||
│ │ │ RoleBasedFieldProvider │ │ │
|
||||
│ │ │ - getFieldsByRole(role) │ │ │
|
||||
│ │ │ - getSlotDefinitionsByRole(role) │ │ │
|
||||
│ │ └──────────────────────┬───────────────────────┘ │ │
|
||||
│ └─────────────────────────┼──────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────────────────┼──────────────────────────────────────┐ │
|
||||
│ │ Tool Consumers │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||||
│ │ │kb_search_ │ │memory_recall │ │intent_hint/ │ │ │
|
||||
│ │ │dynamic │ │ │ │high_risk_ │ │ │
|
||||
│ │ │[resource_ │ │[slot] │ │check │ │ │
|
||||
│ │ │filter] │ │ │ │[routing_ │ │ │
|
||||
│ │ └──────────────┘ └──────────────┘ │signal] │ │ │
|
||||
│ │ └──────────────┘ │ │
|
||||
│ │ ┌──────────────┐ │ │
|
||||
│ │ │template_ │ │ │
|
||||
│ │ │engine │ │ │
|
||||
│ │ │[prompt_var] │ │ │
|
||||
│ │ └──────────────┘ │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 数据层 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ metadata_field_ │ │ slot_definitions │ │
|
||||
│ │ definitions │ │ │ │
|
||||
│ │ - id │ │ - id │ │
|
||||
│ │ - field_key │ │ - slot_key │ │
|
||||
│ │ - field_roles[] │ │ - type │ │
|
||||
│ │ - ... │ │ - linked_field_id │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ Redis Cache │ │ PostgreSQL │ │
|
||||
│ │ - field_roles:by_tenant │ - 持久化存储 │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.2 模块依赖关系
|
||||
|
||||
```
|
||||
metadata-role-separation
|
||||
│
|
||||
├── metadata-governance (依赖)
|
||||
│ └── 元数据字段定义基础能力
|
||||
│
|
||||
├── intent-driven-mid-platform (依赖)
|
||||
│ └── 中台运行时工具链
|
||||
│
|
||||
└── ai-service-admin (依赖)
|
||||
└── 管理端配置界面
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 数据模型设计
|
||||
|
||||
### 2.1 MetadataFieldDefinition 扩展
|
||||
|
||||
在现有 `metadata_field_definitions` 表基础上新增字段:
|
||||
|
||||
```sql
|
||||
-- 新增字段:field_roles
|
||||
ALTER TABLE metadata_field_definitions
|
||||
ADD COLUMN field_roles JSONB DEFAULT '[]'::jsonb;
|
||||
|
||||
-- 创建 GIN 索引支持按角色查询
|
||||
CREATE INDEX idx_metadata_field_definitions_roles
|
||||
ON metadata_field_definitions USING GIN (field_roles);
|
||||
|
||||
-- 注释
|
||||
COMMENT ON COLUMN metadata_field_definitions.field_roles IS '字段角色列表:resource_filter, slot, prompt_var, routing_signal';
|
||||
```
|
||||
|
||||
**字段定义**:
|
||||
|
||||
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
||||
|-------|------|-----|-------|------|
|
||||
| `field_roles` | JSONB | 否 | `[]` | 字段角色列表,存储字符串数组 |
|
||||
|
||||
**角色枚举值**:
|
||||
|
||||
```python
|
||||
class FieldRole(str, Enum):
|
||||
RESOURCE_FILTER = "resource_filter" # 资源过滤
|
||||
SLOT = "slot" # 运行时槽位
|
||||
PROMPT_VAR = "prompt_var" # 提示词变量
|
||||
ROUTING_SIGNAL = "routing_signal" # 路由信号
|
||||
```
|
||||
|
||||
### 2.2 SlotDefinition 新增表
|
||||
|
||||
```sql
|
||||
-- 槽位定义表
|
||||
CREATE TABLE slot_definitions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
slot_key VARCHAR(100) NOT NULL,
|
||||
type VARCHAR(20) NOT NULL,
|
||||
required BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
extract_strategy VARCHAR(20),
|
||||
validation_rule TEXT,
|
||||
ask_back_prompt TEXT,
|
||||
default_value JSONB,
|
||||
linked_field_id UUID REFERENCES metadata_field_definitions(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT uk_slot_definitions_tenant_key UNIQUE (tenant_id, slot_key),
|
||||
CONSTRAINT chk_slot_definitions_type CHECK (type IN ('string', 'number', 'boolean', 'enum', 'array_enum')),
|
||||
CONSTRAINT chk_slot_definitions_extract_strategy CHECK (extract_strategy IS NULL OR extract_strategy IN ('rule', 'llm', 'user_input'))
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_slot_definitions_tenant ON slot_definitions(tenant_id);
|
||||
CREATE INDEX idx_slot_definitions_linked_field ON slot_definitions(linked_field_id);
|
||||
|
||||
-- 注释
|
||||
COMMENT ON TABLE slot_definitions IS '槽位定义表';
|
||||
COMMENT ON COLUMN slot_definitions.slot_key IS '槽位键名,可与元数据字段 field_key 关联';
|
||||
COMMENT ON COLUMN slot_definitions.linked_field_id IS '关联的元数据字段 ID';
|
||||
```
|
||||
|
||||
### 2.3 ER 图
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐ ┌─────────────────────────────┐
|
||||
│ metadata_field_definitions │ │ slot_definitions │
|
||||
├─────────────────────────────┤ ├─────────────────────────────┤
|
||||
│ id (PK) │◄──────│ linked_field_id (FK) │
|
||||
│ tenant_id │ │ id (PK) │
|
||||
│ field_key │ │ tenant_id │
|
||||
│ label │ │ slot_key │
|
||||
│ type │ │ type │
|
||||
│ required │ │ required │
|
||||
│ options │ │ extract_strategy │
|
||||
│ default_value │ │ validation_rule │
|
||||
│ scope │ │ ask_back_prompt │
|
||||
│ is_filterable │ │ default_value │
|
||||
│ is_rank_feature │ │ created_at │
|
||||
│ status │ │ updated_at │
|
||||
│ field_roles ◀── NEW │ │ │
|
||||
│ version │ │ │
|
||||
│ created_at │ │ │
|
||||
│ updated_at │ │ │
|
||||
└─────────────────────────────┘ └─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心流程设计
|
||||
|
||||
### 3.1 字段职责配置流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 管理端配置流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. 管理员进入元数据字段配置页面 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 2. 创建/编辑字段定义 │
|
||||
│ │ │
|
||||
│ ├── 填写基本信息 (field_key, label, type, etc.) │
|
||||
│ │ │
|
||||
│ ├── 选择字段角色 (field_roles 多选) │
|
||||
│ │ ├── [ ] resource_filter - 资源过滤 │
|
||||
│ │ ├── [ ] slot - 运行时槽位 │
|
||||
│ │ ├── [ ] prompt_var - 提示词变量 │
|
||||
│ │ └── [ ] routing_signal - 路由信号 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 3. 后端校验 │
|
||||
│ │ │
|
||||
│ ├── field_key 格式校验 (小写字母数字下划线) │
|
||||
│ ├── field_roles 枚举值校验 │
|
||||
│ └── 租户内唯一性校验 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 4. 保存到数据库 │
|
||||
│ │ │
|
||||
│ └── field_roles 以 JSONB 格式存储 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 按角色查询流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 按角色查询流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 工具/模块请求字段 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ RoleBasedFieldProvider.getFieldsByRole(role, tenant_id) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ SELECT * FROM metadata_field_definitions │ │
|
||||
│ │ WHERE tenant_id = :tenant_id │ │
|
||||
│ │ AND status = 'active' │ │
|
||||
│ │ AND field_roles ? :role -- JSONB contains 查询 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 返回字段定义列表 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 工具按需消费字段 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.3 工具协同改造流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 工具协同改造流程 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ kb_search_dynamic [AC-MRS-11] │ │
|
||||
│ │ │ │
|
||||
│ │ 改造前: │ │
|
||||
│ │ filterable_fields = get_filterable_fields(tenant_id) │ │
|
||||
│ │ WHERE is_filterable = true │ │
|
||||
│ │ │ │
|
||||
│ │ 改造后: │ │
|
||||
│ │ filterable_fields = get_fields_by_role( │ │
|
||||
│ │ tenant_id, role='resource_filter' │ │
|
||||
│ │ ) │ │
|
||||
│ └──────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ memory_recall [AC-MRS-12] │ │
|
||||
│ │ │ │
|
||||
│ │ 改造前: │ │
|
||||
│ │ slots = context.get('slots', {}) # 无角色过滤 │ │
|
||||
│ │ │ │
|
||||
│ │ 改造后: │ │
|
||||
│ │ slot_fields = get_fields_by_role( │ │
|
||||
│ │ tenant_id, role='slot' │ │
|
||||
│ │ ) │ │
|
||||
│ │ slots = {k: v for k, v in context.items() │ │
|
||||
│ │ if k in slot_fields} │ │
|
||||
│ └──────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ intent_hint / high_risk_check [AC-MRS-13] │ │
|
||||
│ │ │ │
|
||||
│ │ 改造前: │ │
|
||||
│ │ routing_fields = all_metadata_fields # 全量字段 │ │
|
||||
│ │ │ │
|
||||
│ │ 改造后: │ │
|
||||
│ │ routing_fields = get_fields_by_role( │ │
|
||||
│ │ tenant_id, role='routing_signal' │ │
|
||||
│ │ ) │ │
|
||||
│ └──────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ template_engine [AC-MRS-14] │ │
|
||||
│ │ │ │
|
||||
│ │ 改造前: │ │
|
||||
│ │ variables = extract_all_variables(template) │ │
|
||||
│ │ values = get_all_metadata_values(context) │ │
|
||||
│ │ │ │
|
||||
│ │ 改造后: │ │
|
||||
│ │ prompt_var_fields = get_fields_by_role( │ │
|
||||
│ │ tenant_id, role='prompt_var' │ │
|
||||
│ │ ) │ │
|
||||
│ │ values = {k: v for k, v in context.items() │ │
|
||||
│ │ if k in prompt_var_fields} │ │
|
||||
│ └──────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 接口设计
|
||||
|
||||
### 4.1 后端 API 接口
|
||||
|
||||
| 接口 | 方法 | 说明 | AC |
|
||||
|------|------|------|-----|
|
||||
| `/admin/metadata-schemas` | GET | 获取字段列表(支持 role 过滤) | AC-MRS-06 |
|
||||
| `/admin/metadata-schemas` | POST | 创建字段(含 field_roles) | AC-MRS-01,02,03 |
|
||||
| `/admin/metadata-schemas/{id}` | PUT | 更新字段(含 field_roles) | AC-MRS-01 |
|
||||
| `/admin/metadata-schemas/{id}` | DELETE | 删除字段(无需兼容) | AC-MRS-16 |
|
||||
| `/admin/metadata-schemas/by-role` | GET | 按角色查询字段 | AC-MRS-04,05 |
|
||||
| `/admin/slot-definitions` | GET | 获取槽位定义列表 | - |
|
||||
| `/admin/slot-definitions` | POST | 创建槽位定义 | AC-MRS-07,08 |
|
||||
| `/admin/slot-definitions/{id}` | PUT | 更新槽位定义 | - |
|
||||
| `/admin/slot-definitions/{id}` | DELETE | 删除槽位定义 | AC-MRS-16 |
|
||||
| `/mid/slots/by-role` | GET | 运行时按角色获取槽位 | AC-MRS-10 |
|
||||
| `/mid/slots/{slot_key}` | GET | 获取运行时槽位值 | AC-MRS-09 |
|
||||
|
||||
### 4.2 内部服务接口
|
||||
|
||||
```python
|
||||
class RoleBasedFieldProvider:
|
||||
"""基于角色的字段提供者"""
|
||||
|
||||
async def get_fields_by_role(
|
||||
self,
|
||||
tenant_id: str,
|
||||
role: FieldRole,
|
||||
include_deprecated: bool = False,
|
||||
) -> list[MetadataFieldDefinition]:
|
||||
"""
|
||||
按角色获取字段定义
|
||||
|
||||
Args:
|
||||
tenant_id: 租户ID
|
||||
role: 字段角色
|
||||
include_deprecated: 是否包含已废弃字段
|
||||
|
||||
Returns:
|
||||
字段定义列表
|
||||
"""
|
||||
|
||||
async def get_slot_definitions_by_role(
|
||||
self,
|
||||
tenant_id: str,
|
||||
role: FieldRole,
|
||||
) -> list[SlotDefinition]:
|
||||
"""
|
||||
按角色获取槽位定义(包含关联字段信息)
|
||||
"""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 前端设计
|
||||
|
||||
### 5.1 元数据字段配置页面改造
|
||||
|
||||
**新增组件**:`FieldRolesSelector.vue`
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="field-roles-selector">
|
||||
<label>字段角色</label>
|
||||
<el-checkbox-group v-model="selectedRoles">
|
||||
<el-checkbox
|
||||
v-for="role in availableRoles"
|
||||
:key="role.value"
|
||||
:label="role.value"
|
||||
>
|
||||
<span>{{ role.label }}</span>
|
||||
<el-tooltip :content="role.description">
|
||||
<el-icon><QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const availableRoles = [
|
||||
{
|
||||
value: 'resource_filter',
|
||||
label: '资源过滤',
|
||||
description: '用于 KB 文档检索时的元数据过滤'
|
||||
},
|
||||
{
|
||||
value: 'slot',
|
||||
label: '运行时槽位',
|
||||
description: '对话流程中的结构化槽位,用于信息收集'
|
||||
},
|
||||
{
|
||||
value: 'prompt_var',
|
||||
label: '提示词变量',
|
||||
description: '注入到 LLM Prompt 中的变量'
|
||||
},
|
||||
{
|
||||
value: 'routing_signal',
|
||||
label: '路由信号',
|
||||
description: '用于意图路由和风险判断的信号'
|
||||
},
|
||||
];
|
||||
</script>
|
||||
```
|
||||
|
||||
### 5.2 按角色过滤视图
|
||||
|
||||
**新增过滤器**:在元数据字段列表页面增加角色过滤下拉框
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="filter-bar">
|
||||
<el-select
|
||||
v-model="selectedRole"
|
||||
placeholder="按角色过滤"
|
||||
clearable
|
||||
@change="handleRoleFilter"
|
||||
>
|
||||
<el-option
|
||||
v-for="role in availableRoles"
|
||||
:key="role.value"
|
||||
:label="role.label"
|
||||
:value="role.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 缓存策略
|
||||
|
||||
### 6.1 缓存设计
|
||||
|
||||
```python
|
||||
class FieldRoleCache:
|
||||
"""字段角色缓存"""
|
||||
|
||||
CACHE_KEY_PREFIX = "field_roles"
|
||||
CACHE_TTL = 300 # 5分钟
|
||||
|
||||
async def get_fields_by_role(
|
||||
self,
|
||||
tenant_id: str,
|
||||
role: FieldRole,
|
||||
) -> list[MetadataFieldDefinition]:
|
||||
cache_key = f"{self.CACHE_KEY_PREFIX}:{tenant_id}:{role}"
|
||||
|
||||
# 尝试从缓存获取
|
||||
cached = await self._redis.get(cache_key)
|
||||
if cached:
|
||||
return self._deserialize(cached)
|
||||
|
||||
# 从数据库查询
|
||||
fields = await self._db_query(tenant_id, role)
|
||||
|
||||
# 写入缓存
|
||||
await self._redis.setex(
|
||||
cache_key,
|
||||
self.CACHE_TTL,
|
||||
self._serialize(fields),
|
||||
)
|
||||
|
||||
return fields
|
||||
|
||||
async def invalidate(self, tenant_id: str):
|
||||
"""失效租户所有角色缓存"""
|
||||
pattern = f"{self.CACHE_KEY_PREFIX}:{tenant_id}:*"
|
||||
keys = await self._redis.keys(pattern)
|
||||
if keys:
|
||||
await self._redis.delete(*keys)
|
||||
```
|
||||
|
||||
### 6.2 缓存失效策略
|
||||
|
||||
- 字段创建/更新/删除时失效该租户所有角色缓存
|
||||
- 槽位定义变更时失效相关角色缓存
|
||||
|
||||
---
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
### 7.1 错误码定义
|
||||
|
||||
| 错误码 | 说明 | HTTP 状态码 |
|
||||
|-------|------|------------|
|
||||
| `INVALID_ROLE` | 无效的角色参数 | 400 |
|
||||
| `FIELD_KEY_EXISTS` | field_key 已存在 | 409 |
|
||||
| `SLOT_KEY_EXISTS` | slot_key 已存在 | 409 |
|
||||
| `LINKED_FIELD_NOT_FOUND` | 关联字段不存在 | 404 |
|
||||
|
||||
### 7.2 异常处理示例
|
||||
|
||||
```python
|
||||
class InvalidRoleError(Exception):
|
||||
"""无效角色异常"""
|
||||
def __init__(self, role: str):
|
||||
self.role = role
|
||||
self.valid_roles = [r.value for r in FieldRole]
|
||||
super().__init__(
|
||||
f"Invalid role '{role}'. Valid roles are: {', '.join(self.valid_roles)}"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 测试策略
|
||||
|
||||
### 8.1 单元测试
|
||||
|
||||
- `RoleBasedFieldProvider` 按角色查询测试
|
||||
- `FieldRoleCache` 缓存读写测试
|
||||
- 字段角色校验测试
|
||||
|
||||
### 8.2 集成测试
|
||||
|
||||
- API 端点测试(CRUD + 按角色查询)
|
||||
- 工具协同改造测试(验证各工具只消费对应角色字段)
|
||||
|
||||
### 8.3 契约测试
|
||||
|
||||
- OpenAPI Schema 校验
|
||||
- 响应结构验证
|
||||
|
||||
---
|
||||
|
||||
## 9. 迁移与部署
|
||||
|
||||
### 9.1 数据库迁移
|
||||
|
||||
```sql
|
||||
-- 1. 新增 field_roles 字段
|
||||
ALTER TABLE metadata_field_definitions
|
||||
ADD COLUMN field_roles JSONB DEFAULT '[]'::jsonb;
|
||||
|
||||
-- 2. 创建索引
|
||||
CREATE INDEX idx_metadata_field_definitions_roles
|
||||
ON metadata_field_definitions USING GIN (field_roles);
|
||||
|
||||
-- 3. 创建 slot_definitions 表
|
||||
CREATE TABLE slot_definitions (
|
||||
-- ... 见 2.2 节
|
||||
);
|
||||
|
||||
-- 4. 初始化现有字段的默认角色(可选)
|
||||
-- 根据 is_filterable 推断 resource_filter 角色
|
||||
UPDATE metadata_field_definitions
|
||||
SET field_roles = '["resource_filter"]'::jsonb
|
||||
WHERE is_filterable = true AND status = 'active';
|
||||
```
|
||||
|
||||
### 9.2 部署顺序
|
||||
|
||||
1. 执行数据库迁移脚本
|
||||
2. 部署后端服务(向后兼容,field_roles 可为空)
|
||||
3. 部署前端页面
|
||||
4. 配置字段角色
|
||||
|
||||
---
|
||||
|
||||
## 10. 监控与观测
|
||||
|
||||
### 10.1 关键指标
|
||||
|
||||
| 指标名 | 说明 |
|
||||
|-------|------|
|
||||
| `field_role_query_count` | 按角色查询次数 |
|
||||
| `field_role_query_latency` | 按角色查询延迟 |
|
||||
| `field_role_cache_hit_rate` | 角色缓存命中率 |
|
||||
| `tool_field_consumption` | 工具字段消费统计 |
|
||||
|
||||
### 10.2 日志字段
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "field_role_query",
|
||||
"tenant_id": "xxx",
|
||||
"role": "resource_filter",
|
||||
"field_count": 5,
|
||||
"duration_ms": 12,
|
||||
"cache_hit": true
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
openapi: 3.0.3
|
||||
info:
|
||||
title: 元数据职责分层模块 - 外部依赖
|
||||
description: |
|
||||
本模块依赖的外部 API 契约,用于生成 Mock/SDK。
|
||||
|
||||
## 依赖说明
|
||||
- metadata-governance: 元数据字段定义基础能力
|
||||
- intent-driven-mid-platform: 中台运行时工具链
|
||||
version: 0.1.0
|
||||
x-contract-level: L1
|
||||
contact:
|
||||
name: AI Robot Core Team
|
||||
|
||||
servers:
|
||||
- url: /api
|
||||
description: API Server
|
||||
|
||||
tags:
|
||||
- name: MetadataGovernance
|
||||
description: 元数据治理模块依赖
|
||||
- name: MidPlatform
|
||||
description: 中台模块依赖
|
||||
|
||||
paths:
|
||||
/admin/metadata-schemas:
|
||||
get:
|
||||
summary: 获取元数据字段定义列表(依赖)
|
||||
description: 依赖 metadata-governance 模块的元数据字段列表查询能力
|
||||
operationId: depsListMetadataSchemas
|
||||
tags:
|
||||
- MetadataGovernance
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- draft
|
||||
- active
|
||||
- deprecated
|
||||
- name: scope
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- kb_document
|
||||
- intent_rule
|
||||
- script_flow
|
||||
- prompt_template
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回字段定义列表
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
|
||||
/admin/kb/documents:
|
||||
get:
|
||||
summary: 获取 KB 文档列表(依赖)
|
||||
description: 依赖 KB 文档管理能力,用于验证字段使用情况
|
||||
operationId: depsListKbDocuments
|
||||
tags:
|
||||
- MetadataGovernance
|
||||
parameters:
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: kb_id
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回文档列表
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/KbDocument'
|
||||
|
||||
/mid/dialogue/respond:
|
||||
post:
|
||||
summary: 中台对话响应(依赖)
|
||||
description: 依赖中台对话响应能力,用于工具协同改造验证
|
||||
operationId: depsRespondDialogue
|
||||
tags:
|
||||
- MidPlatform
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DialogueRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回对话响应
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DialogueResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
MetadataFieldStatus:
|
||||
type: string
|
||||
enum:
|
||||
- draft
|
||||
- active
|
||||
- deprecated
|
||||
|
||||
MetadataScope:
|
||||
type: string
|
||||
enum:
|
||||
- kb_document
|
||||
- intent_rule
|
||||
- script_flow
|
||||
- prompt_template
|
||||
|
||||
MetadataFieldType:
|
||||
type: string
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
- enum
|
||||
- array_enum
|
||||
|
||||
MetadataFieldDefinition:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
field_key:
|
||||
type: string
|
||||
label:
|
||||
type: string
|
||||
type:
|
||||
$ref: '#/components/schemas/MetadataFieldType'
|
||||
required:
|
||||
type: boolean
|
||||
options:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default_value:
|
||||
type: object
|
||||
scope:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataScope'
|
||||
is_filterable:
|
||||
type: boolean
|
||||
is_rank_feature:
|
||||
type: boolean
|
||||
status:
|
||||
$ref: '#/components/schemas/MetadataFieldStatus'
|
||||
version:
|
||||
type: integer
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
KbDocument:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
kb_id:
|
||||
type: string
|
||||
format: uuid
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
DialogueRequest:
|
||||
type: object
|
||||
required:
|
||||
- tenant_id
|
||||
- user_id
|
||||
- session_id
|
||||
- user_message
|
||||
properties:
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
user_id:
|
||||
type: string
|
||||
format: uuid
|
||||
session_id:
|
||||
type: string
|
||||
format: uuid
|
||||
user_message:
|
||||
type: string
|
||||
context:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
description: 会话上下文,包含槽位信息
|
||||
|
||||
DialogueResponse:
|
||||
type: object
|
||||
properties:
|
||||
session_id:
|
||||
type: string
|
||||
format: uuid
|
||||
request_id:
|
||||
type: string
|
||||
format: uuid
|
||||
segments:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
segment_id:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
delay_after:
|
||||
type: integer
|
||||
trace:
|
||||
type: object
|
||||
properties:
|
||||
mode:
|
||||
type: string
|
||||
enum:
|
||||
- agent
|
||||
- micro_flow
|
||||
- fixed
|
||||
- transfer
|
||||
intent:
|
||||
type: string
|
||||
tool_calls:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
fallback_reason_code:
|
||||
type: string
|
||||
|
|
@ -0,0 +1,774 @@
|
|||
openapi: 3.0.3
|
||||
info:
|
||||
title: 元数据职责分层 API
|
||||
description: |
|
||||
提供元数据字段职责分层配置、槽位定义管理及按角色查询能力。
|
||||
|
||||
## 字段角色定义
|
||||
- `resource_filter`: 资源过滤角色,用于 KB 文档检索
|
||||
- `slot`: 运行时槽位角色,用于对话信息收集
|
||||
- `prompt_var`: 提示词变量角色,用于 Prompt 注入
|
||||
- `routing_signal`: 路由信号角色,用于意图路由判断
|
||||
version: 0.1.0
|
||||
x-contract-level: L1
|
||||
contact:
|
||||
name: AI Robot Core Team
|
||||
|
||||
servers:
|
||||
- url: /api
|
||||
description: API Server
|
||||
|
||||
tags:
|
||||
- name: MetadataSchema
|
||||
description: 元数据字段定义管理(扩展 field_roles)
|
||||
- name: SlotDefinition
|
||||
description: 槽位定义管理
|
||||
- name: RuntimeSlot
|
||||
description: 运行时槽位查询
|
||||
|
||||
paths:
|
||||
/admin/metadata-schemas:
|
||||
get:
|
||||
summary: 获取元数据字段定义列表
|
||||
description: |-
|
||||
[AC-MRS-06] 支持按状态、范围、角色过滤查询元数据字段定义列表。
|
||||
operationId: listMetadataSchemas
|
||||
tags:
|
||||
- MetadataSchema
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: 字段状态过滤
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataFieldStatus'
|
||||
- name: scope
|
||||
in: query
|
||||
description: 适用范围过滤
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataScope'
|
||||
- name: field_role
|
||||
in: query
|
||||
description: 字段角色过滤
|
||||
schema:
|
||||
$ref: '#/components/schemas/FieldRole'
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回字段定义列表
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
post:
|
||||
summary: 创建元数据字段定义
|
||||
description: |-
|
||||
[AC-MRS-01][AC-MRS-02][AC-MRS-03] 创建新的元数据字段定义,支持 field_roles 多选配置。
|
||||
operationId: createMetadataSchema
|
||||
tags:
|
||||
- MetadataSchema
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinitionCreate'
|
||||
responses:
|
||||
'201':
|
||||
description: 创建成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'409':
|
||||
description: field_key 已存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/admin/metadata-schemas/{id}:
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
get:
|
||||
summary: 获取单个元数据字段定义
|
||||
operationId: getMetadataSchema
|
||||
tags:
|
||||
- MetadataSchema
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回字段定义
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
summary: 更新元数据字段定义
|
||||
description: |-
|
||||
[AC-MRS-01] 更新元数据字段定义,支持修改 field_roles。
|
||||
operationId: updateMetadataSchema
|
||||
tags:
|
||||
- MetadataSchema
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinitionUpdate'
|
||||
responses:
|
||||
'200':
|
||||
description: 更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
summary: 删除元数据字段定义
|
||||
description: |-
|
||||
[AC-MRS-16] 删除元数据字段定义,无需考虑历史数据兼容性。
|
||||
operationId: deleteMetadataSchema
|
||||
tags:
|
||||
- MetadataSchema
|
||||
responses:
|
||||
'204':
|
||||
description: 删除成功
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/admin/metadata-schemas/by-role:
|
||||
get:
|
||||
summary: 按角色查询元数据字段定义
|
||||
description: |-
|
||||
[AC-MRS-04][AC-MRS-05] 按指定角色查询所有包含该角色的活跃字段定义。
|
||||
operationId: getMetadataSchemasByRole
|
||||
tags:
|
||||
- MetadataSchema
|
||||
parameters:
|
||||
- name: role
|
||||
in: query
|
||||
required: true
|
||||
description: 字段角色
|
||||
schema:
|
||||
$ref: '#/components/schemas/FieldRole'
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: include_deprecated
|
||||
in: query
|
||||
description: 是否包含已废弃字段
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回字段定义列表
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
'400':
|
||||
description: 无效的角色参数
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error_code: INVALID_ROLE
|
||||
message: "Invalid role 'invalid_role'. Valid roles are: resource_filter, slot, prompt_var, routing_signal"
|
||||
|
||||
/admin/slot-definitions:
|
||||
get:
|
||||
summary: 获取槽位定义列表
|
||||
operationId: listSlotDefinitions
|
||||
tags:
|
||||
- SlotDefinition
|
||||
parameters:
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: required
|
||||
in: query
|
||||
description: 是否必填槽位过滤
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回槽位定义列表
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SlotDefinition'
|
||||
|
||||
post:
|
||||
summary: 创建槽位定义
|
||||
description: |-
|
||||
[AC-MRS-07][AC-MRS-08] 创建新的槽位定义,可关联已有元数据字段。
|
||||
operationId: createSlotDefinition
|
||||
tags:
|
||||
- SlotDefinition
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SlotDefinitionCreate'
|
||||
responses:
|
||||
'201':
|
||||
description: 创建成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SlotDefinition'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
|
||||
/admin/slot-definitions/{id}:
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
get:
|
||||
summary: 获取单个槽位定义
|
||||
operationId: getSlotDefinition
|
||||
tags:
|
||||
- SlotDefinition
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回槽位定义
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SlotDefinition'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
summary: 更新槽位定义
|
||||
operationId: updateSlotDefinition
|
||||
tags:
|
||||
- SlotDefinition
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SlotDefinitionUpdate'
|
||||
responses:
|
||||
'200':
|
||||
description: 更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SlotDefinition'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
summary: 删除槽位定义
|
||||
description: |-
|
||||
[AC-MRS-16] 删除槽位定义,无需考虑历史数据兼容性。
|
||||
operationId: deleteSlotDefinition
|
||||
tags:
|
||||
- SlotDefinition
|
||||
responses:
|
||||
'204':
|
||||
description: 删除成功
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/mid/slots/by-role:
|
||||
get:
|
||||
summary: 运行时按角色获取槽位定义
|
||||
description: |-
|
||||
[AC-MRS-10] 运行时接口,按角色获取槽位定义及关联的元数据字段信息。
|
||||
operationId: getSlotsByRole
|
||||
tags:
|
||||
- RuntimeSlot
|
||||
parameters:
|
||||
- name: role
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/FieldRole'
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回槽位定义列表
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SlotDefinitionWithField'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
|
||||
/mid/slots/{slot_key}:
|
||||
parameters:
|
||||
- name: slot_key
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
|
||||
get:
|
||||
summary: 获取运行时槽位值
|
||||
description: |-
|
||||
[AC-MRS-09] 获取指定槽位的运行时值,包含来源、置信度、更新时间。
|
||||
operationId: getSlotValue
|
||||
tags:
|
||||
- RuntimeSlot
|
||||
parameters:
|
||||
- name: tenant_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: user_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: session_id
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: 成功返回槽位值
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RuntimeSlotValue'
|
||||
'404':
|
||||
description: 槽位不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
FieldRole:
|
||||
type: string
|
||||
enum:
|
||||
- resource_filter
|
||||
- slot
|
||||
- prompt_var
|
||||
- routing_signal
|
||||
description: |
|
||||
字段角色类型:
|
||||
- resource_filter: 资源过滤角色
|
||||
- slot: 运行时槽位角色
|
||||
- prompt_var: 提示词变量角色
|
||||
- routing_signal: 路由信号角色
|
||||
|
||||
MetadataFieldStatus:
|
||||
type: string
|
||||
enum:
|
||||
- draft
|
||||
- active
|
||||
- deprecated
|
||||
|
||||
MetadataScope:
|
||||
type: string
|
||||
enum:
|
||||
- kb_document
|
||||
- intent_rule
|
||||
- script_flow
|
||||
- prompt_template
|
||||
|
||||
MetadataFieldType:
|
||||
type: string
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
- enum
|
||||
- array_enum
|
||||
|
||||
MetadataFieldDefinition:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- tenant_id
|
||||
- field_key
|
||||
- label
|
||||
- type
|
||||
- status
|
||||
- field_roles
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
field_key:
|
||||
type: string
|
||||
pattern: '^[a-z][a-z0-9_]*$'
|
||||
description: 字段键名,仅允许小写字母数字下划线
|
||||
label:
|
||||
type: string
|
||||
description: 显示名称
|
||||
type:
|
||||
$ref: '#/components/schemas/MetadataFieldType'
|
||||
required:
|
||||
type: boolean
|
||||
default: false
|
||||
options:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: 选项列表(enum/array_enum 类型必填)
|
||||
default_value:
|
||||
description: 默认值
|
||||
scope:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataScope'
|
||||
description: 适用范围
|
||||
is_filterable:
|
||||
type: boolean
|
||||
default: false
|
||||
is_rank_feature:
|
||||
type: boolean
|
||||
default: false
|
||||
field_roles:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FieldRole'
|
||||
description: 字段角色列表
|
||||
status:
|
||||
$ref: '#/components/schemas/MetadataFieldStatus'
|
||||
version:
|
||||
type: integer
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
MetadataFieldDefinitionCreate:
|
||||
type: object
|
||||
required:
|
||||
- tenant_id
|
||||
- field_key
|
||||
- label
|
||||
- type
|
||||
properties:
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
field_key:
|
||||
type: string
|
||||
pattern: '^[a-z][a-z0-9_]*$'
|
||||
label:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 100
|
||||
type:
|
||||
$ref: '#/components/schemas/MetadataFieldType'
|
||||
required:
|
||||
type: boolean
|
||||
default: false
|
||||
options:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default_value:
|
||||
type: object
|
||||
scope:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataScope'
|
||||
is_filterable:
|
||||
type: boolean
|
||||
default: false
|
||||
is_rank_feature:
|
||||
type: boolean
|
||||
default: false
|
||||
field_roles:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FieldRole'
|
||||
description: 字段角色列表,可为空
|
||||
|
||||
MetadataFieldDefinitionUpdate:
|
||||
type: object
|
||||
properties:
|
||||
label:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 100
|
||||
required:
|
||||
type: boolean
|
||||
options:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default_value:
|
||||
type: object
|
||||
scope:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MetadataScope'
|
||||
is_filterable:
|
||||
type: boolean
|
||||
is_rank_feature:
|
||||
type: boolean
|
||||
field_roles:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FieldRole'
|
||||
status:
|
||||
$ref: '#/components/schemas/MetadataFieldStatus'
|
||||
|
||||
ExtractStrategy:
|
||||
type: string
|
||||
enum:
|
||||
- rule
|
||||
- llm
|
||||
- user_input
|
||||
description: |
|
||||
槽位提取策略:
|
||||
- rule: 规则提取
|
||||
- llm: LLM 推断
|
||||
- user_input: 用户输入
|
||||
|
||||
SlotSource:
|
||||
type: string
|
||||
enum:
|
||||
- user_confirmed
|
||||
- rule_extracted
|
||||
- llm_inferred
|
||||
- default
|
||||
|
||||
SlotDefinition:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- tenant_id
|
||||
- slot_key
|
||||
- type
|
||||
- required
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
slot_key:
|
||||
type: string
|
||||
pattern: '^[a-z][a-z0-9_]*$'
|
||||
description: 槽位键名
|
||||
type:
|
||||
$ref: '#/components/schemas/MetadataFieldType'
|
||||
required:
|
||||
type: boolean
|
||||
description: 是否必填槽位
|
||||
extract_strategy:
|
||||
$ref: '#/components/schemas/ExtractStrategy'
|
||||
validation_rule:
|
||||
type: string
|
||||
description: 校验规则(正则或 JSON Schema)
|
||||
ask_back_prompt:
|
||||
type: string
|
||||
description: 追问提示语模板
|
||||
default_value:
|
||||
description: 默认值
|
||||
linked_field_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: 关联的元数据字段 ID
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
SlotDefinitionCreate:
|
||||
type: object
|
||||
required:
|
||||
- tenant_id
|
||||
- slot_key
|
||||
- type
|
||||
- required
|
||||
properties:
|
||||
tenant_id:
|
||||
type: string
|
||||
format: uuid
|
||||
slot_key:
|
||||
type: string
|
||||
pattern: '^[a-z][a-z0-9_]*$'
|
||||
type:
|
||||
$ref: '#/components/schemas/MetadataFieldType'
|
||||
required:
|
||||
type: boolean
|
||||
extract_strategy:
|
||||
$ref: '#/components/schemas/ExtractStrategy'
|
||||
validation_rule:
|
||||
type: string
|
||||
ask_back_prompt:
|
||||
type: string
|
||||
default_value:
|
||||
type: object
|
||||
linked_field_id:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
SlotDefinitionUpdate:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/MetadataFieldType'
|
||||
required:
|
||||
type: boolean
|
||||
extract_strategy:
|
||||
$ref: '#/components/schemas/ExtractStrategy'
|
||||
validation_rule:
|
||||
type: string
|
||||
ask_back_prompt:
|
||||
type: string
|
||||
default_value:
|
||||
type: object
|
||||
linked_field_id:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
SlotDefinitionWithField:
|
||||
type: object
|
||||
description: 槽位定义与关联字段信息
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SlotDefinition'
|
||||
- type: object
|
||||
properties:
|
||||
linked_field:
|
||||
$ref: '#/components/schemas/MetadataFieldDefinition'
|
||||
|
||||
RuntimeSlotValue:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- value
|
||||
- source
|
||||
- confidence
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
description: 槽位键名
|
||||
value:
|
||||
description: 槽位值
|
||||
source:
|
||||
$ref: '#/components/schemas/SlotSource'
|
||||
description: 槽位来源
|
||||
confidence:
|
||||
type: number
|
||||
format: float
|
||||
minimum: 0.0
|
||||
maximum: 1.0
|
||||
description: 置信度
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 最后更新时间
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
required:
|
||||
- error_code
|
||||
- message
|
||||
properties:
|
||||
error_code:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
details:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: 请求参数错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error_code: BAD_REQUEST
|
||||
message: "Invalid request parameters"
|
||||
|
||||
Unauthorized:
|
||||
description: 未授权
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error_code: UNAUTHORIZED
|
||||
message: "Authentication required"
|
||||
|
||||
NotFound:
|
||||
description: 资源不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error_code: NOT_FOUND
|
||||
message: "Resource not found"
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
---
|
||||
feature_id: "MRS"
|
||||
title: "元数据职责分层优化"
|
||||
status: "draft"
|
||||
version: "0.1.0"
|
||||
active_version: "0.1.0"
|
||||
version_history:
|
||||
- version: "0.1.0"
|
||||
ac_range: "AC-MRS-01~16"
|
||||
description: "元数据字段职责分层、槽位模型独立化、工具协同改造与管理端配置能力"
|
||||
owners:
|
||||
- "product"
|
||||
- "backend"
|
||||
- "frontend"
|
||||
last_updated: "2026-03-05"
|
||||
source:
|
||||
type: "conversation"
|
||||
ref: "元数据职责过载问题优化需求"
|
||||
---
|
||||
|
||||
# 元数据职责分层优化(MRS)
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
### 1.1 背景
|
||||
|
||||
当前系统中元数据字段承担了多种隐式职责,导致以下问题:
|
||||
|
||||
1. **职责混淆**:同一字段(如 `grade`)同时用于资源过滤、运行时槽位、提示词变量和路由信号,但系统无法区分其具体用途
|
||||
2. **工具耦合**:`kb_search_dynamic`、`memory_recall`、`intent_hint`、`high_risk_check` 等工具全量消费元数据字段,无法按需筛选
|
||||
3. **槽位语义模糊**:槽位与元数据字段概念混淆,缺少独立的槽位定义模型
|
||||
4. **配置不可视**:管理端无法按职责视角查看和配置字段
|
||||
|
||||
### 1.2 目标
|
||||
|
||||
- 为元数据字段引入显式的 `field_roles` 职责分层
|
||||
- 建立独立的槽位定义模型,与元数据字段解耦但可复用
|
||||
- 改造工具链按职责角色消费字段,实现精准消费
|
||||
- 提供管理端按角色配置和查看的能力
|
||||
|
||||
### 1.3 非目标(Out of Scope)
|
||||
|
||||
- 不处理历史数据迁移,允许删除重建配置
|
||||
- 不新增元数据字段类型(保持 string/number/boolean/enum/array_enum)
|
||||
- 不替换向量引擎或 LLM 供应商
|
||||
- 不覆盖渠道端具体实现
|
||||
|
||||
## 2. 模块边界(Scope)
|
||||
|
||||
- 覆盖:元数据字段职责分层、槽位定义模型、工具协同改造、管理端配置能力
|
||||
- 不覆盖:历史数据迁移、向量引擎替换、模型切换、渠道端实现
|
||||
|
||||
## 3. 依赖盘点(Dependencies)
|
||||
|
||||
- `metadata-governance` 模块:元数据字段定义基础能力
|
||||
- `intent-driven-mid-platform` 模块:中台运行时工具链
|
||||
- `ai-service-admin` 前端:管理端配置界面
|
||||
|
||||
## 4. 用户故事(User Stories)
|
||||
|
||||
- [US-MRS-01] 作为系统架构师,我希望元数据字段有明确的职责角色标记,以便工具能按需消费。
|
||||
- [US-MRS-02] 作为后端开发者,我希望通过接口按角色查询字段定义,以便精准获取所需字段。
|
||||
- [US-MRS-03] 作为运营配置人员,我希望在管理端按角色过滤查看字段,以便快速定位配置。
|
||||
- [US-MRS-04] 作为对话系统开发者,我希望槽位有独立的定义模型,以便管理运行时槽位语义。
|
||||
- [US-MRS-05] 作为工具开发者,我希望 `kb_search_dynamic` 只消费资源过滤角色字段,以便避免无关字段干扰。
|
||||
- [US-MRS-06] 作为工具开发者,我希望 `memory_recall` 只消费槽位角色字段,以便精准管理对话槽位。
|
||||
- [US-MRS-07] 作为工具开发者,我希望 `intent_hint/high_risk_check` 只消费路由信号角色字段,以便精准路由决策。
|
||||
- [US-MRS-08] 作为提示词工程师,我希望 prompt 渲染只消费提示词变量角色字段,以便控制注入范围。
|
||||
|
||||
## 5. 验收标准(Acceptance Criteria, EARS)
|
||||
|
||||
### 5.1 字段职责分层
|
||||
|
||||
- [AC-MRS-01] WHEN 管理员创建或编辑元数据字段 THEN 系统 SHALL 支持 `field_roles` 多选配置,可选值为 `resource_filter`、`slot`、`prompt_var`、`routing_signal`。
|
||||
- [AC-MRS-02] WHEN 保存字段定义时 `field_roles` 为空 THEN 系统 SHALL 允许保存(默认无职责)。
|
||||
- [AC-MRS-03] WHEN 字段定义包含多个 `field_roles` THEN 系统 SHALL 正确存储并返回所有角色。
|
||||
|
||||
### 5.2 分层视图能力
|
||||
|
||||
- [AC-MRS-04] WHEN 调用 `GET /admin/metadata-schemas/by-role?role=resource_filter` THEN 系统 SHALL 返回所有 `field_roles` 包含 `resource_filter` 的活跃字段定义。
|
||||
- [AC-MRS-05] WHEN 调用按角色查询接口且角色参数无效 THEN 系统 SHALL 返回 400 错误并提示有效角色列表。
|
||||
- [AC-MRS-06] WHEN 管理端请求字段列表 THEN 系统 SHALL 支持按 `field_roles` 过滤展示。
|
||||
|
||||
### 5.3 槽位模型
|
||||
|
||||
- [AC-MRS-07] WHEN 管理员创建槽位定义 THEN 系统 SHALL 支持 `slot_key`、`type`、`required`、`extract_strategy`、`validation_rule`、`ask_back_prompt` 属性配置。
|
||||
- [AC-MRS-08] WHEN 槽位定义的 `slot_key` 与已有元数据字段 `field_key` 相同 THEN 系统 SHALL 允许创建并建立关联关系。
|
||||
- [AC-MRS-09] WHEN 运行时读取槽位值 THEN 系统 SHALL 返回 `source`(来源)、`confidence`(置信度)、`updated_at`(更新时间)属性。
|
||||
- [AC-MRS-10] WHEN 调用 `GET /mid/slots/by-role?role=slot` THEN 系统 SHALL 返回所有 `field_roles` 包含 `slot` 的字段定义及关联的槽位定义。
|
||||
|
||||
### 5.4 工具协同改造
|
||||
|
||||
- [AC-MRS-11] WHEN `kb_search_dynamic` 构建过滤器 THEN 系统 SHALL 仅使用 `field_roles` 包含 `resource_filter` 的字段。
|
||||
- [AC-MRS-12] WHEN `memory_recall` 召回槽位 THEN 系统 SHALL 仅使用 `field_roles` 包含 `slot` 的字段。
|
||||
- [AC-MRS-13] WHEN `intent_hint` 或 `high_risk_check` 进行路由判断 THEN 系统 SHALL 仅使用 `field_roles` 包含 `routing_signal` 的字段。
|
||||
- [AC-MRS-14] WHEN 模板引擎渲染 prompt THEN 系统 SHALL 仅使用 `field_roles` 包含 `prompt_var` 的字段。
|
||||
|
||||
### 5.5 管理端可配置能力
|
||||
|
||||
- [AC-MRS-15] WHEN 管理员在元数据字段编辑界面 THEN 系统 SHALL 显示 `field_roles` 多选配置组件。
|
||||
- [AC-MRS-16] WHEN 管理员删除字段或槽位定义 THEN 系统 SHALL 允许删除且无需考虑历史数据兼容性。
|
||||
|
||||
## 6. 追踪映射(Traceability)
|
||||
|
||||
| AC ID | Endpoint | 方法 | operationId | 备注 |
|
||||
|------|----------|------|-------------|------|
|
||||
| AC-MRS-01 | /admin/metadata-schemas | POST | createMetadataSchema | field_roles 配置 |
|
||||
| AC-MRS-01 | /admin/metadata-schemas/{id} | PUT | updateMetadataSchema | field_roles 配置 |
|
||||
| AC-MRS-02 | /admin/metadata-schemas | POST | createMetadataSchema | 空角色允许 |
|
||||
| AC-MRS-03 | /admin/metadata-schemas | POST | createMetadataSchema | 多角色存储 |
|
||||
| AC-MRS-04 | /admin/metadata-schemas/by-role | GET | getMetadataSchemasByRole | 按角色查询 |
|
||||
| AC-MRS-05 | /admin/metadata-schemas/by-role | GET | getMetadataSchemasByRole | 无效角色校验 |
|
||||
| AC-MRS-06 | /admin/metadata-schemas | GET | listMetadataSchemas | 按角色过滤 |
|
||||
| AC-MRS-07 | /admin/slot-definitions | POST | createSlotDefinition | 槽位定义创建 |
|
||||
| AC-MRS-08 | /admin/slot-definitions | POST | createSlotDefinition | 关联元数据字段 |
|
||||
| AC-MRS-09 | /mid/slots/{slot_key} | GET | getSlotValue | 运行时槽位值 |
|
||||
| AC-MRS-10 | /mid/slots/by-role | GET | getSlotsByRole | 按角色获取槽位 |
|
||||
| AC-MRS-11 | 内部调用 | - | kb_search_dynamic | resource_filter 消费 |
|
||||
| AC-MRS-12 | 内部调用 | - | memory_recall | slot 消费 |
|
||||
| AC-MRS-13 | 内部调用 | - | intent_hint/high_risk_check | routing_signal 消费 |
|
||||
| AC-MRS-14 | 内部调用 | - | template_engine | prompt_var 消费 |
|
||||
| AC-MRS-15 | 前端页面 | - | - | field_roles 配置组件 |
|
||||
| AC-MRS-16 | /admin/metadata-schemas/{id} | DELETE | deleteMetadataSchema | 删除无需兼容 |
|
||||
| AC-MRS-16 | /admin/slot-definitions/{id} | DELETE | deleteSlotDefinition | 删除无需兼容 |
|
||||
|
||||
## 7. 字段角色定义
|
||||
|
||||
| 角色标识 | 中文名称 | 用途说明 | 消费工具 |
|
||||
|---------|---------|---------|---------|
|
||||
| `resource_filter` | 资源过滤 | 用于 KB 文档检索时的元数据过滤 | `kb_search_dynamic` |
|
||||
| `slot` | 运行时槽位 | 对话流程中的结构化槽位,用于信息收集 | `memory_recall` |
|
||||
| `prompt_var` | 提示词变量 | 注入到 LLM Prompt 中的变量 | `template_engine` |
|
||||
| `routing_signal` | 路由信号 | 用于意图路由和风险判断的信号 | `intent_hint`, `high_risk_check` |
|
||||
|
||||
## 8. 槽位定义属性
|
||||
|
||||
| 属性 | 类型 | 必填 | 说明 |
|
||||
|-----|------|-----|------|
|
||||
| `slot_key` | string | 是 | 槽位键名,可与 field_key 关联 |
|
||||
| `type` | enum | 是 | 槽位类型:string/number/boolean/enum/array_enum |
|
||||
| `required` | boolean | 是 | 是否必填槽位 |
|
||||
| `extract_strategy` | enum | 否 | 提取策略:rule/llm/user_input |
|
||||
| `validation_rule` | string | 否 | 校验规则(正则或 JSON Schema) |
|
||||
| `ask_back_prompt` | string | 否 | 追问提示语模板 |
|
||||
| `default_value` | any | 否 | 默认值 |
|
||||
| `linked_field_id` | uuid | 否 | 关联的元数据字段 ID |
|
||||
|
||||
## 9. 运行时槽位值属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|-----|------|------|
|
||||
| `key` | string | 槽位键名 |
|
||||
| `value` | any | 槽位值 |
|
||||
| `source` | enum | 来源:user_confirmed/rule_extracted/llm_inferred/default |
|
||||
| `confidence` | float | 置信度 0.0~1.0 |
|
||||
| `updated_at` | datetime | 最后更新时间 |
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
# 元数据职责分层模块边界(Scope)
|
||||
|
||||
## 1. 模块边界说明
|
||||
|
||||
### 1.1 覆盖范围
|
||||
|
||||
本模块聚焦于**元数据字段的职责分层与运行时消费解耦**,具体包括:
|
||||
|
||||
1. **字段职责分层**
|
||||
- 为元数据字段引入 `field_roles` 多选属性
|
||||
- 支持四种职责角色:`resource_filter`、`slot`、`prompt_var`、`routing_signal`
|
||||
- 单个字段可同时承担多种职责
|
||||
|
||||
2. **分层视图能力**
|
||||
- 后端提供按 role 查询字段的能力
|
||||
- 工具与模块按 role 消费,不再全量混用
|
||||
|
||||
3. **槽位模型增强**
|
||||
- 引入独立的槽位定义模型(可复用元数据字段但有独立运行时语义)
|
||||
- 支持 `slot_key/type/required/extract_strategy/validation_rule/ask_back_prompt`
|
||||
- 运行时值包含 `source/confidence/updated_at`
|
||||
|
||||
4. **工具协同改造**
|
||||
- `kb_search_dynamic` 只消费 `resource_filter` 角色
|
||||
- `memory_recall` 只消费 `slot` 角色
|
||||
- `intent_hint/high_risk_check` 只消费 `routing_signal` 角色
|
||||
- prompt 渲染只消费 `prompt_var` 角色
|
||||
|
||||
5. **管理端可配置能力**
|
||||
- 元数据字段编辑界面增加 `field_roles` 配置
|
||||
- 提供"按 role 过滤查看"能力
|
||||
- 允许删除重建配置(无需迁移兼容)
|
||||
|
||||
### 1.2 不覆盖范围
|
||||
|
||||
- **历史数据迁移**:本迭代不负责历史数据的自动迁移,允许删除重建配置
|
||||
- **向量引擎替换**:不涉及 Qdrant 或其他向量引擎的替换
|
||||
- **LLM 模型切换**:不涉及模型供应商或模型选型的变更
|
||||
- **渠道端实现**:不覆盖渠道侧 SegmentDispatcher/InterruptManager 等具体实现
|
||||
- **元数据字段类型扩展**:不新增字段类型(string/number/boolean/enum/array_enum 保持不变)
|
||||
|
||||
---
|
||||
|
||||
## 2. 依赖盘点
|
||||
|
||||
### 2.1 内部依赖
|
||||
|
||||
| 依赖模块 | 用途说明 | 接口 |
|
||||
|---------|---------|------|
|
||||
| `metadata-governance` | 元数据字段定义基础能力 | `/admin/metadata-schemas` |
|
||||
| `intent-driven-mid-platform` | 中台运行时工具链 | `kb_search_dynamic`, `memory_recall`, `intent_hint`, `high_risk_check` |
|
||||
| `ai-service-admin` | 管理端前端页面 | 元数据配置界面 |
|
||||
|
||||
### 2.2 外部依赖
|
||||
|
||||
| 依赖服务 | 用途说明 |
|
||||
|---------|---------|
|
||||
| PostgreSQL | 元数据字段定义、槽位定义存储 |
|
||||
| Redis | 运行时缓存 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 依赖接口清单
|
||||
|
||||
### 3.1 本模块依赖的外部接口(Consumer)
|
||||
|
||||
| 接口 | 来源模块 | 用途 |
|
||||
|------|---------|------|
|
||||
| `GET /admin/metadata-schemas` | metadata-governance | 获取元数据字段列表 |
|
||||
| `POST /admin/metadata-schemas` | metadata-governance | 创建元数据字段 |
|
||||
| `PUT /admin/metadata-schemas/{id}` | metadata-governance | 更新元数据字段 |
|
||||
| `DELETE /admin/metadata-schemas/{id}` | metadata-governance | 删除元数据字段 |
|
||||
|
||||
### 3.2 本模块对外提供的接口(Provider)
|
||||
|
||||
| 接口 | 用途 |
|
||||
|------|------|
|
||||
| `GET /admin/metadata-schemas/by-role` | 按 role 查询字段定义 |
|
||||
| `GET /admin/slot-definitions` | 获取槽位定义列表 |
|
||||
| `POST /admin/slot-definitions` | 创建槽位定义 |
|
||||
| `PUT /admin/slot-definitions/{id}` | 更新槽位定义 |
|
||||
| `DELETE /admin/slot-definitions/{id}` | 删除槽位定义 |
|
||||
| `GET /mid/slots/by-role` | 运行时按 role 获取槽位定义 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据模型边界
|
||||
|
||||
### 4.1 新增模型
|
||||
|
||||
| 模型名 | 说明 |
|
||||
|-------|------|
|
||||
| `SlotDefinition` | 槽位定义表(独立于 MetadataFieldDefinition) |
|
||||
|
||||
### 4.2 扩展模型
|
||||
|
||||
| 模型名 | 扩展字段 |
|
||||
|-------|---------|
|
||||
| `MetadataFieldDefinition` | 新增 `field_roles: list[str]` 字段 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 工具消费关系
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 元数据字段职责分层 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ MetadataFieldDefinition │
|
||||
│ └── field_roles: [resource_filter, slot, prompt_var, │
|
||||
│ routing_signal] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────┼─────────────────────┐
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│resource_filter│ │ slot │ │ prompt_var │
|
||||
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│kb_search_ │ │memory_recall │ │template_engine│
|
||||
│dynamic │ │ │ │ │
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ routing_signal │
|
||||
└───────┬─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
├───────────────┐
|
||||
▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐
|
||||
│intent_hint │ │high_risk_check│
|
||||
└───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 版本与迭代
|
||||
|
||||
- 当前版本:`v0.1.0`
|
||||
- AC 范围:`AC-MRS-01 ~ AC-MRS-16`
|
||||
- 迭代策略:允许删除重建配置,不考虑历史数据迁移
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
# 元数据职责分层优化 - 任务清单
|
||||
|
||||
## 任务概览
|
||||
|
||||
| 阶段 | 任务数 | 状态 |
|
||||
|------|-------|------|
|
||||
| Phase 1: 数据模型扩展 | 4 | ✅ 已完成 |
|
||||
| Phase 2: 后端服务实现 | 6 | ✅ 已完成 |
|
||||
| Phase 3: 工具协同改造 | 4 | ✅ 已完成 |
|
||||
| Phase 4: 前端页面改造 | 3 | ⏳ 待开始 |
|
||||
| Phase 5: 测试与验收 | 3 | ⏳ 待开始 |
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: 数据模型扩展
|
||||
|
||||
### Task 1.1: 扩展 MetadataFieldDefinition 模型
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-01, AC-MRS-02, AC-MRS-03
|
||||
- **描述**: 在现有 `MetadataFieldDefinition` 模型中新增 `field_roles` 字段
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/models/entities.py` 中的 `MetadataFieldDefinition` 类
|
||||
- 新增 `FieldRole` 枚举类
|
||||
- **验收标准**:
|
||||
- `field_roles` 字段类型为 `list[str]`
|
||||
- 支持存储多个角色
|
||||
- 允许空列表
|
||||
|
||||
### Task 1.2: 创建 SlotDefinition 模型
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-07, AC-MRS-08
|
||||
- **描述**: 创建独立的槽位定义模型
|
||||
- **产出**:
|
||||
- 在 `ai-service/app/models/entities.py` 中新增 `SlotDefinition` 类
|
||||
- 新增 `ExtractStrategy` 枚举类
|
||||
- **验收标准**:
|
||||
- 包含所有必需字段:slot_key, type, required, extract_strategy, validation_rule, ask_back_prompt
|
||||
- 支持 linked_field_id 关联元数据字段
|
||||
|
||||
### Task 1.3: 编写数据库迁移脚本
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-01, AC-MRS-07
|
||||
- **描述**: 编写 PostgreSQL 迁移脚本
|
||||
- **产出**:
|
||||
- 创建 `ai-service/scripts/migrations/007_add_field_roles_and_slot_definitions.sql`
|
||||
- **验收标准**:
|
||||
- 为 `metadata_field_definitions` 表新增 `field_roles` 列
|
||||
- 创建 `slot_definitions` 表
|
||||
- 创建必要的索引
|
||||
|
||||
### Task 1.4: 更新 Pydantic Schema
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-01, AC-MRS-07
|
||||
- **描述**: 更新请求/响应 Schema
|
||||
- **产出**:
|
||||
- 创建 `ai-service/app/schemas/metadata.py`
|
||||
- 新增 `SlotDefinitionCreate/Update/Response` Schema
|
||||
- **验收标准**:
|
||||
- Schema 与 OpenAPI 契约一致
|
||||
- 包含完整的字段校验规则
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: 后端服务实现
|
||||
|
||||
### Task 2.1: 实现 RoleBasedFieldProvider 服务
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-04, AC-MRS-05, AC-MRS-10
|
||||
- **描述**: 实现按角色查询字段的核心服务
|
||||
- **产出**:
|
||||
- 创建 `ai-service/app/services/mid/role_based_field_provider.py`
|
||||
- **验收标准**:
|
||||
- `get_fields_by_role()` 方法正确查询指定角色的字段
|
||||
- 无效角色返回 400 错误
|
||||
- 支持缓存机制
|
||||
|
||||
### Task 2.2: 扩展 MetadataFieldDefinitionService
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-01, AC-MRS-02, AC-MRS-03, AC-MRS-06
|
||||
- **描述**: 扩展现有服务支持 field_roles
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/services/metadata_field_definition_service.py`
|
||||
- **验收标准**:
|
||||
- 创建/更新时支持 field_roles 字段
|
||||
- 支持按 role 过滤查询
|
||||
- field_roles 校验正确
|
||||
|
||||
### Task 2.3: 实现 SlotDefinitionService
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-07, AC-MRS-08
|
||||
- **描述**: 实现槽位定义管理服务
|
||||
- **产出**:
|
||||
- 创建 `ai-service/app/services/slot_definition_service.py`
|
||||
- **验收标准**:
|
||||
- CRUD 操作正确
|
||||
- 支持关联元数据字段
|
||||
- slot_key 租户内唯一
|
||||
|
||||
### Task 2.4: 扩展 MetadataFieldDefinition API
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-01, AC-MRS-04, AC-MRS-05, AC-MRS-06, AC-MRS-16
|
||||
- **描述**: 扩展现有 API 端点
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/api/admin/metadata_field_definition.py`
|
||||
- 新增 `/by-role` 端点
|
||||
- **验收标准**:
|
||||
- 所有端点符合 OpenAPI 契约
|
||||
- 包含 AC 注释
|
||||
|
||||
### Task 2.5: 实现 SlotDefinition API
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-07, AC-MRS-08, AC-MRS-16
|
||||
- **描述**: 实现槽位定义管理 API
|
||||
- **产出**:
|
||||
- 创建 `ai-service/app/api/admin/slot_definition.py`
|
||||
- **验收标准**:
|
||||
- CRUD 端点符合 OpenAPI 契约
|
||||
- 包含 AC 注释
|
||||
|
||||
### Task 2.6: 实现运行时槽位 API
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-09, AC-MRS-10
|
||||
- **描述**: 实现运行时槽位查询 API
|
||||
- **产出**:
|
||||
- 创建 `ai-service/app/api/mid/slots.py`
|
||||
- **验收标准**:
|
||||
- `/mid/slots/by-role` 端点正确返回槽位定义
|
||||
- `/mid/slots/{slot_key}` 端点正确返回运行时值
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: 工具协同改造
|
||||
|
||||
### Task 3.1: 改造 kb_search_dynamic 工具
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-11
|
||||
- **描述**: 改造 KB 动态检索工具,只消费 resource_filter 角色
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/services/mid/kb_search_dynamic_tool.py`
|
||||
- 修改 `ai-service/app/services/mid/metadata_filter_builder.py`
|
||||
- **验收标准**:
|
||||
- 只使用 field_roles 包含 resource_filter 的字段
|
||||
- 不影响现有功能
|
||||
|
||||
### Task 3.2: 改造 memory_recall 工具
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-12
|
||||
- **描述**: 改造记忆召回工具,只消费 slot 角色
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/services/mid/memory_recall_tool.py`
|
||||
- **验收标准**:
|
||||
- 只使用 field_roles 包含 slot 的字段
|
||||
- 槽位合并逻辑正确
|
||||
|
||||
### Task 3.3: 改造 intent_hint 和 high_risk_check 工具
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-13
|
||||
- **描述**: 改造意图提示和高风险检测工具,只消费 routing_signal 角色
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/services/mid/intent_hint_tool.py`
|
||||
- 修改 `ai-service/app/services/mid/high_risk_check_tool.py`
|
||||
- **验收标准**:
|
||||
- 只使用 field_roles 包含 routing_signal 的字段
|
||||
- 路由判断逻辑正确
|
||||
|
||||
### Task 3.4: 改造 template_engine
|
||||
- [x] **状态**: ✅ 已完成
|
||||
- **AC**: AC-MRS-14
|
||||
- **描述**: 改造模板引擎,只消费 prompt_var 角色
|
||||
- **产出**:
|
||||
- 修改 `ai-service/app/services/flow/template_engine.py`
|
||||
- **验收标准**:
|
||||
- 只使用 field_roles 包含 prompt_var 的字段
|
||||
- 模板渲染正确
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: 前端页面改造
|
||||
|
||||
### Task 4.1: 元数据字段配置页面增加 field_roles
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-15
|
||||
- **描述**: 在元数据字段编辑表单中增加角色选择组件
|
||||
- **产出**:
|
||||
- 创建 `ai-service-admin/src/components/metadata/FieldRolesSelector.vue`
|
||||
- 修改 `ai-service-admin/src/views/admin/metadata-schema/index.vue`
|
||||
- **验收标准**:
|
||||
- 支持多选角色
|
||||
- 显示角色说明
|
||||
- 保存时正确提交
|
||||
|
||||
### Task 4.2: 增加按角色过滤视图
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-06
|
||||
- **描述**: 在元数据字段列表页面增加角色过滤功能
|
||||
- **产出**:
|
||||
- 修改 `ai-service-admin/src/views/admin/metadata-schema/index.vue`
|
||||
- **验收标准**:
|
||||
- 下拉框选择角色
|
||||
- 过滤结果正确
|
||||
|
||||
### Task 4.3: 槽位定义管理页面
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-07, AC-MRS-08, AC-MRS-16
|
||||
- **描述**: 创建槽位定义管理页面
|
||||
- **产出**:
|
||||
- 创建 `ai-service-admin/src/views/admin/slot-definition/index.vue`
|
||||
- 创建 `ai-service-admin/src/api/slot-definition.ts`
|
||||
- **验收标准**:
|
||||
- 支持 CRUD 操作
|
||||
- 支持关联元数据字段
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: 测试与验收
|
||||
|
||||
### Task 5.1: 单元测试
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-01~16
|
||||
- **描述**: 编写单元测试
|
||||
- **产出**:
|
||||
- `ai-service/tests/test_role_based_field_provider.py`
|
||||
- `ai-service/tests/test_slot_definition_service.py`
|
||||
- `ai-service/tests/test_field_roles.py`
|
||||
- **验收标准**:
|
||||
- 覆盖核心逻辑
|
||||
- 测试通过
|
||||
|
||||
### Task 5.2: 集成测试
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-01~16
|
||||
- **描述**: 编写 API 集成测试
|
||||
- **产出**:
|
||||
- `ai-service/tests/api/test_metadata_field_roles.py`
|
||||
- `ai-service/tests/api/test_slot_definition.py`
|
||||
- **验收标准**:
|
||||
- 覆盖所有 API 端点
|
||||
- 测试通过
|
||||
|
||||
### Task 5.3: 契约测试
|
||||
- [ ] **状态**: ⏳ 待开始
|
||||
- **AC**: AC-MRS-01~16
|
||||
- **描述**: 验证 API 符合 OpenAPI 契约
|
||||
- **产出**:
|
||||
- 运行契约测试
|
||||
- 修复不一致
|
||||
- **验收标准**:
|
||||
- Provider 契约达到 L2 级别
|
||||
- 所有响应符合 Schema
|
||||
|
||||
---
|
||||
|
||||
## 任务依赖关系
|
||||
|
||||
```
|
||||
Phase 1 (数据模型)
|
||||
│
|
||||
├── Task 1.1 (扩展 MetadataFieldDefinition)
|
||||
├── Task 1.2 (创建 SlotDefinition)
|
||||
├── Task 1.3 (迁移脚本) ← 依赖 1.1, 1.2
|
||||
└── Task 1.4 (更新 Schema) ← 依赖 1.1, 1.2
|
||||
│
|
||||
▼
|
||||
Phase 2 (后端服务)
|
||||
│
|
||||
├── Task 2.1 (RoleBasedFieldProvider) ← 依赖 1.4
|
||||
├── Task 2.2 (扩展 MetadataFieldService) ← 依赖 1.4
|
||||
├── Task 2.3 (SlotDefinitionService) ← 依赖 1.4
|
||||
├── Task 2.4 (扩展 MetadataField API) ← 依赖 2.2
|
||||
├── Task 2.5 (SlotDefinition API) ← 依赖 2.3
|
||||
└── Task 2.6 (运行时槽位 API) ← 依赖 2.1, 2.3
|
||||
│
|
||||
▼
|
||||
Phase 3 (工具改造)
|
||||
│
|
||||
├── Task 3.1 (kb_search_dynamic) ← 依赖 2.1
|
||||
├── Task 3.2 (memory_recall) ← 依赖 2.1
|
||||
├── Task 3.3 (intent_hint/high_risk_check) ← 依赖 2.1
|
||||
└── Task 3.4 (template_engine) ← 依赖 2.1
|
||||
│
|
||||
▼
|
||||
Phase 4 (前端改造)
|
||||
│
|
||||
├── Task 4.1 (field_roles 组件) ← 依赖 2.4
|
||||
├── Task 4.2 (角色过滤视图) ← 依赖 2.4
|
||||
└── Task 4.3 (槽位定义页面) ← 依赖 2.5
|
||||
│
|
||||
▼
|
||||
Phase 5 (测试验收)
|
||||
│
|
||||
├── Task 5.1 (单元测试) ← 依赖 Phase 2
|
||||
├── Task 5.2 (集成测试) ← 依赖 Phase 2, 3, 4
|
||||
└── Task 5.3 (契约测试) ← 依赖 5.2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 执行顺序建议
|
||||
|
||||
1. **Phase 1** → **Phase 2** → **Phase 3** → **Phase 4** → **Phase 5**
|
||||
2. Phase 3 和 Phase 4 可并行执行
|
||||
3. 每个 Task 完成后需更新状态并提交
|
||||
|
||||
---
|
||||
|
||||
## 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 |
|
||||
|------|---------|-------|
|
||||
| 2026-03-05 | 初始创建 | AI Agent |
|
||||
| 2026-03-05 | 完成 Phase 3 工具协同改造 (Task 3.1-3.4) [AC-MRS-11~14] | AI Agent |
|
||||
Loading…
Reference in New Issue