跳转至

元数据与标签

元数据和标签是组织和检索文档的强大工具。本教程讲解如何利用它们实现精细化管理和过滤搜索。

元数据 vs 标签

元数据 (metadata):键值对形式,支持复杂结构
├── 适合:结构化属性(部门、版本、日期)
├── 支持:过滤查询、范围查询
└── 示例:{"department": "HR", "version": "2.0"}

标签 (tags):字符串数组
├── 适合:分类标记
├── 支持:简单过滤
└── 示例:["重要", "待审核", "2024"]

文件级元数据

上传时设置

from unifiles import UnifilesClient

client = UnifilesClient(api_key="sk_...")

file = client.files.upload(
    path="contract.pdf",
    metadata={
        "department": "法务部",
        "project": "合同管理系统",
        "contract_type": "服务合同",
        "party_a": "甲公司",
        "party_b": "乙公司",
        "sign_date": "2024-01-15",
        "expire_date": "2025-01-14",
        "value": 100000
    },
    tags=["合同", "重要", "2024"]
)

查询使用元数据

# 按标签过滤
files = client.files.list(tags=["合同"])

# 按元数据过滤(如果API支持)
files = client.files.list(
    metadata_filter={"department": "法务部"}
)

# 获取文件时查看元数据
file = client.files.get(file_id)
print(file.metadata)
print(file.tags)

文档级元数据

在知识库中添加文档时可以设置额外元数据:

# 创建知识库
kb = client.knowledge_bases.create(name="company-docs")

# 添加文档时设置元数据
doc = client.knowledge_bases.documents.create(
    kb_id=kb.id,
    file_id=file.id,
    title="采购合同模板 v2.0",
    metadata={
        "category": "模板",
        "sub_category": "采购类",
        "author": "法务部",
        "status": "已审核",
        "applicable_scope": "全公司",
        "revision": 2
    }
)

元数据过滤搜索

基本过滤

# 只搜索特定类别的文档
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="付款条款",
    filter={
        "metadata.category": "合同"
    }
)

多条件过滤

# 多个条件(AND)
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="审批流程",
    filter={
        "metadata.department": "HR",
        "metadata.status": "已发布"
    }
)

范围查询

# 数值范围
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="合同条款",
    filter={
        "metadata.value": {"$gte": 100000}  # >= 10万
    }
)

# 日期范围
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="有效合同",
    filter={
        "metadata.expire_date": {"$gte": "2024-01-01"}
    }
)

列表包含

# 部门在列表中
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="政策",
    filter={
        "metadata.department": {"$in": ["HR", "财务", "行政"]}
    }
)

过滤操作符

操作符 说明 示例
$eq 等于(默认) {"field": "value"}
$ne 不等于 {"field": {"$ne": "value"}}
$gt 大于 {"field": {"$gt": 10}}
$gte 大于等于 {"field": {"$gte": 10}}
$lt 小于 {"field": {"$lt": 10}}
$lte 小于等于 {"field": {"$lte": 10}}
$in 在列表中 {"field": {"$in": ["a", "b"]}}
$nin 不在列表中 {"field": {"$nin": ["a", "b"]}}

实战示例

示例1:多租户文档管理

# 上传时标记租户
def upload_tenant_document(tenant_id: str, file_path: str):
    return client.files.upload(
        path=file_path,
        metadata={
            "tenant_id": tenant_id,
            "uploaded_by": "system"
        }
    )

# 添加到知识库
def add_to_tenant_kb(kb_id: str, file_id: str, tenant_id: str):
    return client.knowledge_bases.documents.create(
        kb_id=kb_id,
        file_id=file_id,
        metadata={"tenant_id": tenant_id}
    )

# 搜索时限制租户
def search_tenant_docs(kb_id: str, tenant_id: str, query: str):
    return client.knowledge_bases.search(
        kb_id=kb_id,
        query=query,
        filter={"metadata.tenant_id": tenant_id}
    )

示例2:文档版本管理

# 上传新版本
def upload_new_version(doc_name: str, file_path: str, version: int):
    return client.files.upload(
        path=file_path,
        metadata={
            "doc_name": doc_name,
            "version": version,
            "is_latest": True,
            "uploaded_at": datetime.now().isoformat()
        }
    )

# 搜索最新版本
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="操作指南",
    filter={"metadata.is_latest": True}
)

示例3:按文档类型检索

# 文档类型分类
DOCUMENT_TYPES = {
    "policy": "政策制度",
    "manual": "操作手册",
    "template": "模板文档",
    "report": "报告文档",
    "contract": "合同协议"
}

# 上传时分类
file = client.files.upload(
    path="hr_policy.pdf",
    metadata={
        "doc_type": "policy",
        "department": "HR"
    }
)

# 按类型搜索
def search_by_type(kb_id: str, doc_type: str, query: str):
    return client.knowledge_bases.search(
        kb_id=kb_id,
        query=query,
        filter={"metadata.doc_type": doc_type}
    )

# 使用
results = search_by_type(kb.id, "policy", "年假规定")

示例4:权限控制

# 文档权限级别
PERMISSION_LEVELS = {
    "public": 0,
    "internal": 1,
    "confidential": 2,
    "secret": 3
}

# 上传时设置权限
file = client.files.upload(
    path="salary_report.xlsx",
    metadata={
        "permission_level": "confidential",
        "allowed_departments": ["HR", "财务"],
        "allowed_roles": ["manager", "hr_admin"]
    }
)

# 搜索时检查权限
def search_with_permission(kb_id: str, query: str, user_role: str, user_dept: str):
    # 确定用户可访问的权限级别
    accessible_levels = ["public", "internal"]
    if user_role in ["manager", "hr_admin"]:
        accessible_levels.append("confidential")

    return client.knowledge_bases.search(
        kb_id=kb_id,
        query=query,
        filter={
            "metadata.permission_level": {"$in": accessible_levels}
        }
    )

元数据设计最佳实践

1. 规划元数据架构

# 定义元数据 Schema
DOCUMENT_METADATA_SCHEMA = {
    # 基础属性
    "doc_type": str,        # policy, manual, template, etc.
    "department": str,       # 所属部门
    "author": str,           # 作者

    # 状态属性
    "status": str,           # draft, review, published, archived
    "version": int,          # 版本号
    "is_latest": bool,       # 是否最新版

    # 时间属性
    "created_at": str,       # ISO 日期
    "updated_at": str,
    "effective_date": str,   # 生效日期
    "expire_date": str,      # 失效日期

    # 权限属性
    "permission_level": str,
    "allowed_roles": list,

    # 业务属性(可选)
    "project_id": str,
    "customer_id": str,
    "tags": list
}

def validate_metadata(metadata: dict) -> bool:
    """验证元数据是否符合 Schema"""
    required_fields = ["doc_type", "department", "status"]
    return all(field in metadata for field in required_fields)

2. 使用一致的命名

# 好的命名
metadata = {
    "department": "HR",           # 清晰
    "created_at": "2024-01-15",   # ISO 格式
    "is_active": True             # 布尔值
}

# 避免的命名
metadata = {
    "dept": "HR",                  # 缩写不清晰
    "date": "15/01/2024",          # 格式不一致
    "active": "yes"                # 字符串代替布尔值
}

3. 避免过度嵌套

# 推荐:扁平结构
metadata = {
    "author_name": "张三",
    "author_department": "HR",
    "author_email": "zhangsan@company.com"
}

# 避免:深度嵌套
metadata = {
    "author": {
        "info": {
            "name": "张三",
            "contact": {
                "email": "..."
            }
        }
    }
}

4. 预留扩展字段

metadata = {
    # 核心字段
    "doc_type": "policy",
    "department": "HR",

    # 扩展字段
    "custom_fields": {
        "field1": "value1",
        "field2": "value2"
    }
}

标签使用建议

标签分类

# 按类型组织标签
TAGS = {
    "status": ["待审核", "已发布", "已归档"],
    "priority": ["紧急", "重要", "普通"],
    "category": ["政策", "指南", "模板"],
    "year": ["2023", "2024", "2025"]
}

# 使用
file = client.files.upload(
    path="document.pdf",
    tags=["已发布", "重要", "政策", "2024"]
)

标签搜索

# 按标签筛选文件
files = client.files.list(tags=["重要", "2024"])

# 搜索带特定标签的内容
results = client.knowledge_bases.search(
    kb_id=kb.id,
    query="审批流程",
    filter={"tags": {"$in": ["政策"]}}  # 如果支持
)

下一步