Files
ai-agent-admin/backend-fastapi/ai_platform/knowledge/chunking/auto.py
T
2026-06-08 18:14:59 +08:00

91 lines
2.6 KiB
Python

"""
自动分块策略
根据文件类型自动选择最佳分块器。
参考 Dify 的 auto 分块模式。
"""
import logging
from typing import Dict, Any, List, Optional
from .base import BaseChunker, ChunkResult
logger = logging.getLogger(__name__)
# 文件类型 → 推荐分块策略
FILE_TYPE_STRATEGY_MAP = {
# Markdown 文件使用 Markdown 分块器
'md': 'markdown',
'markdown': 'markdown',
# 代码文件使用按句子分块(按行/语句边界)
'py': 'sentence',
'js': 'sentence',
'ts': 'sentence',
'java': 'sentence',
'go': 'sentence',
'rs': 'sentence',
'c': 'sentence',
'cpp': 'sentence',
'h': 'sentence',
# 纯文本使用按句子分块
'txt': 'sentence',
# CSV/Excel 使用固定大小(表格数据按行分割更合理)
'csv': 'fixed',
'xlsx': 'fixed',
'xls': 'fixed',
# HTML 使用 Markdown 分块器(HTML 结构类似)
'html': 'markdown',
'htm': 'markdown',
# 其他文档类型使用递归分块
'pdf': 'recursive',
'docx': 'recursive',
'doc': 'recursive',
'pptx': 'recursive',
'ppt': 'recursive',
}
class AutoChunker(BaseChunker):
"""
自动分块器
根据文档的文件类型自动选择最佳分块策略。
metadata 中需要包含 'file_type' 字段。
"""
def chunk(self, text: str, metadata: Dict[str, Any] = None) -> List[ChunkResult]:
"""自动选择分块策略并执行"""
if not text or not text.strip():
return []
metadata = metadata or {}
file_type = metadata.get('file_type', '').lower().lstrip('.')
# 根据文件类型选择策略
strategy = FILE_TYPE_STRATEGY_MAP.get(file_type, 'recursive')
logger.info(f"AutoChunker: file_type={file_type} → strategy={strategy}")
# 动态创建对应的分块器
chunker = self._get_chunker(strategy)
return chunker.chunk(text, metadata)
def _get_chunker(self, strategy: str) -> BaseChunker:
"""获取对应策略的分块器实例"""
from .recursive import RecursiveChunker
from .markdown import MarkdownChunker
from .fixed import FixedChunker
from .sentence import SentenceChunker
chunkers = {
'recursive': RecursiveChunker,
'markdown': MarkdownChunker,
'fixed': FixedChunker,
'sentence': SentenceChunker,
}
cls = chunkers.get(strategy, RecursiveChunker)
return cls(
chunk_size=self.chunk_size,
chunk_overlap=self.chunk_overlap,
separator=self.separator,
)