"""加载 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)