zhehelima / backend /knowledge_loader.py
占禹轩
init: 这合礼吗
74a4482
Raw
History Blame Contribute Delete
3.44 kB
"""加载 skus 和 skills 知识库 + 周礼原文,构建周礼知识上下文。"""
import json
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent
SKUS_DIR = PROJECT_ROOT / "skus"
SKILLS_DIR = PROJECT_ROOT / "generated_skills"
RAW_TEXT_FILE = PROJECT_ROOT / "zhouli_raw_texts.json"
# 原文分块:相邻短段合并,目标每块 300-500 字
RAW_CHUNK_TARGET = 400
def load_all_skus() -> list[dict]:
"""读取 skus/ 下所有 JSON 文件并返回列表。"""
skus = []
for f in sorted(SKUS_DIR.glob("*.json")):
with open(f, "r", encoding="utf-8") as fh:
skus.append(json.load(fh))
return skus
def load_all_skills() -> list[dict]:
"""读取 generated_skills/ 下所有 SKILL.md,返回 {name, content} 列表。"""
skills = []
for skill_dir in sorted(SKILLS_DIR.iterdir()):
skill_file = skill_dir / "SKILL.md"
if skill_file.is_file():
content = skill_file.read_text(encoding="utf-8")
skills.append({"name": skill_dir.name, "content": content})
return skills
def _merge_paragraphs(paragraphs: list[str], target: int = RAW_CHUNK_TARGET) -> list[str]:
"""将短段落合并为接近 target 字数的块。"""
merged = []
buf = ""
for p in paragraphs:
if buf and len(buf) + len(p) > target:
merged.append(buf)
buf = p
else:
buf = buf + p if not buf else buf + "\n" + p
if buf:
merged.append(buf)
return merged
def load_raw_text_chunks() -> list[dict]:
"""读取周礼原文 JSON,按章节合并短段落后返回 chunk 列表。"""
if not RAW_TEXT_FILE.exists():
return []
with open(RAW_TEXT_FILE, "r", encoding="utf-8") as f:
data = json.load(f)
chunks = []
for chapter, paragraphs in data.items():
merged = _merge_paragraphs(paragraphs)
for i, text in enumerate(merged):
chunks.append({
"id": f"raw:{chapter}:{i}",
"title": f"《周礼·{chapter}》原文({i+1})",
"text": f"《周礼·{chapter}》原文:\n{text}",
})
return chunks
def build_chunks() -> list[dict]:
"""将 SKU、Skill 和原文拆分为检索用的 chunk 列表。
返回: [{"id": str, "title": str, "text": str}, ...]
"""
chunks = []
for sku in load_all_skus():
uid = sku.get("metadata", {}).get("uuid", "")
name = sku.get("metadata", {}).get("name", "未命名")
logic = sku.get("core_logic", {}).get("execution_body", "")
schema = sku.get("schema_explanation", "")
tags = ", ".join(sku.get("custom_attributes", {}).get("domain_tags", []))
trigger = sku.get("trigger", {}).get("condition_logic", "")
text = f"【{name}】\n领域: {tags}\n触发条件: {trigger}\n{logic}\n{schema}"
chunks.append({"id": f"sku:{uid}", "title": name, "text": text})
for skill in load_all_skills():
chunks.append({
"id": f"skill:{skill['name']}",
"title": skill["name"],
"text": skill["content"],
})
chunks.extend(load_raw_text_chunks())
return chunks
def build_knowledge_text() -> str:
"""(保留兼容)将所有知识拼接为全量文本。"""
parts = []
for chunk in build_chunks():
parts.append(chunk["text"])
return "\n\n---\n\n".join(parts)