完成和大模型的通信

This commit is contained in:
wandering
2026-06-04 09:58:45 +08:00
parent 37199970c9
commit 580fe4ad6e
13 changed files with 2117 additions and 1820 deletions

View File

@@ -1,115 +1,93 @@
# ---------------------------------------------------------------------------
# 辅助函数
# ---------------------------------------------------------------------------
"""
Unified entry point.
Re-exports from sub-modules for backward compatibility.
"""
import logging
from prompt import build_analysis_prompt, language_rule
from llm import query_analysis
__all__ = ["language_rule", "build_analysis_prompt", "query_analysis"]
logger = logging.getLogger(__name__)
def language_rule(source_content: str, configured_language: str | None = None) -> str:
"""
生成语言规则提示。
def _setup_logging() -> None:
"""配置日志格式和级别,同时输出到终端和文件。"""
from pathlib import Path
参数
----------
source_content : str
用于语言检测回退的源文档文本。
configured_language : str | None
明确配置的输出语言(如 "Chinese""English""auto")。
传入 ``None`` 或 ``"auto"`` 以自动检测。
log_path = Path(__file__).parent.parent / "llmwiki.log"
返回
-------
str
语言规则提示字符串。
"""
if configured_language and configured_language.lower() != "auto":
return f"使用 {configured_language} 语言输出分析报告。"
formatter = logging.Formatter(
"%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
# 简单的语言检测回退
if source_content and any("\u4e00" <= char <= "\u9fff" for char in source_content[:500]):
return "源文档包含中文内容,使用简体中文输出分析报告。"
file_handler = logging.FileHandler(log_path, encoding="utf-8")
file_handler.setFormatter(formatter)
return "使用与源文档相同的语言输出分析报告。"
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
handlers=[file_handler, stream_handler],
)
# ---------------------------------------------------------------------------
# 主函数build_analysis_prompt
# ---------------------------------------------------------------------------
def main() -> None:
"""执行入口:遍历 raw 目录,对每个源文件进行分析。"""
import sys
from pathlib import Path
_setup_logging()
from config import load_config
config = load_config()
raw_dir = Path(config.get("raw_dir", "raw"))
wiki_dir = Path(config.get("wiki_dir", "wiki"))
# 读取 wiki 上下文
purpose_path = wiki_dir / "purpose.md"
index_path = wiki_dir / "index.md"
purpose = purpose_path.read_text(encoding="utf-8") if purpose_path.exists() else ""
index = index_path.read_text(encoding="utf-8") if index_path.exists() else ""
logger.info("purpose.md: %s", "已加载" if purpose else "未找到")
logger.info("index.md: %s", "已加载" if index else "未找到")
# 收集 raw 目录下的 .md 文件
md_files = sorted(raw_dir.rglob("*.md"))
if not md_files:
logger.info("未找到 %s 下的 .md 文件", raw_dir)
sys.exit(0)
logger.info("共发现 %d 个源文件", len(md_files))
for fp in md_files:
source_content = fp.read_text(encoding="utf-8")
logger.info("=" * 60)
logger.info("分析: %s", fp.relative_to(raw_dir.parent))
logger.info("=" * 60)
try:
result = query_analysis(
purpose=purpose,
index=index,
source_content=source_content,
)
logger.info("分析完成,结果长度: %d 字符", len(result))
logger.info("结果: %s", result)
except Exception as e:
logger.error("分析失败: %s", e, exc_info=True)
sys.exit(1)
def build_analysis_prompt(
purpose: str,
index: str,
source_content: str = "",
configured_language: str | None = None,
) -> str:
"""
第一步提示AI 阅读源文档并生成结构化分析报告。
这是「讨论」步骤——AI 在撰写 wiki 页面之前先对源文档进行推理。
参数
----------
purpose : str
wiki/purpose.md 的内容(可能为空)。
index : str
wiki/index.md 的内容(可能为空)。
source_content : str
用于语言检测回退的源文档文本。
configured_language : str | None
显式覆盖语言设置。传入 ``None`` 时从配置文件读取。
返回
-------
str
完整的系统提示字符串。
"""
from config import get_language
if configured_language is None:
configured_language = get_language()
parts: list[str] = [
"你是一位专业研究分析师。阅读源文档并产出一份结构化的分析报告。",
"不要输出思维链、隐藏推理或思考过程。在内部进行推理,只撰写简洁的最终分析。",
"",
language_rule(source_content, configured_language),
"",
"你的分析需要包含:",
"",
"## 关键实体",
"列出文档中提到的人物、组织、产品、数据集、工具、芯片、算法等。对于每一项:",
"- 名称和类型",
"- 在源文档中的角色(核心还是边缘)",
"- 是否可能已存在于 wiki 中(查阅索引)",
"",
"## 关键概念",
"列出理论、方法、技术、现象。对于每一项:",
"- 名称和简要定义",
"- 为什么在源文档中重要",
"- 是否可能已存在于 wiki 中",
"",
"## 主要论点与发现",
"- 核心主张或结果是什么?",
"- 有什么证据支持这些主张?",
"- 证据的强度如何?",
"",
"## 与现有 Wiki 的关联",
"- 源文档与哪些现有页面相关?",
"- 它是否强化、挑战或扩展了现有知识?",
"",
"## 矛盾与张力",
"- 源文档中是否有任何内容与现有 wiki 内容冲突?",
"- 是否存在内部矛盾或注意事项?",
"",
"## 建议",
"- 应该创建或更新哪些 wiki 页面?",
"- 应该强调什么,弱化什么?",
"- 是否有任何需要向用户指出的开放性问题?",
"",
"分析要全面但简洁,专注于真正重要的内容。",
"",
"如果提供了文件夹上下文,请将其作为分类的提示——文件夹结构通常反映了用户的组织意图(例如,'papers/energy' 表示该文件是与能源相关的论文)。",
"",
f"## Wiki 目的(供参考)\n{purpose}" if purpose else "",
(f"## 当前 Wiki 索引(用于检查现有内容)\n{index}" if index else ""),
]
# 过滤空字符串并用换行符连接
return "\n".join(part for part in parts if part)
if __name__ == "__main__":
main()