Files

63 lines
2.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""RAG 管道:标题感知的连续窗口分块。"""
import re
TARGET = 500
MIN_CHUNK = 120
OVERLAP_RATIO = 0.15
def chunk_texts(units: list[dict], target: int = TARGET) -> list[dict]:
"""连续合并相同元数据的相邻单元,避免字幕类文件被切成大量细碎向量。"""
target = max(MIN_CHUNK, int(target or TARGET))
chunks = []
buf: list[str] = []
buf_len = 0
active_meta: dict | None = None
def flush() -> None:
nonlocal buf, buf_len
if buf:
text = "".join(buf)
if len(text) >= 30:
chunks.append({"text": text, "meta": dict(active_meta or {})})
buf, buf_len = [], 0
for u in units:
text = str(u.get("text") or "")
meta = dict(u.get("meta") or {})
if not text:
continue
if active_meta is not None and meta != active_meta:
flush()
if active_meta is None or meta != active_meta:
active_meta = meta
# 按句子/标点切候选段
parts = _split_sentences(text)
for p in parts:
if buf_len + len(p) > target * 1.15 and buf:
chunks.append({"text": "".join(buf), "meta": dict(active_meta)})
# 重叠:保留最后 15% 字符
overlap = "".join(buf)
cut = int(len(overlap) * OVERLAP_RATIO)
keep = overlap[-cut:] if cut > 30 else ""
buf = [keep] if keep else []
buf_len = len(keep)
buf.append(p)
buf_len += len(p)
flush()
return chunks
def _split_sentences(text: str) -> list[str]:
# 在句号/问号/感叹号/换行后切分,保持小段不小于 30 字
parts = re.split(r"(?<=[。!?!?;;])\s*|\n+", text)
merged, cur = [], ""
for p in parts:
if not p:
continue
cur += p
if len(cur) >= 30:
merged.append(cur)
cur = ""
if cur:
merged.append(cur)
return merged or [text]