CoolFace
Apppublic

LiSiyi13146413708/Baseline_Agent

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
llm_analyzer.py107 linesDownload Raw Back to root
1# -*- coding: utf-8 -*-2"""3LLM 分析模块:调用 DeepSeek API 动态解析论文结构并返回 Roadmap。4"""5 6import re7import json8from typing import Optional9 10from secure_api import load_api_key11from schemas import Roadmap12from pydantic import ValidationError13from fallback import build_fallback_roadmap14 15 16LLM_SYSTEM_PROMPT = (17    "你是一名科研架构师。请阅读论文,设计一个结构化的技术路线图。请将研究过程划分为 3-5 个主要阶段(如:研究背景与问题、理论框架构建、核心模型设计、实验验证与应用等)。"18    "为了满足‘四列层级布局’要求,你需要生成以下四类节点:\n"19    "1. 'stage_label': 阶段名称(第1列)。\n"20    "2. 'task': 核心任务(第2列),动词+核心对象(如‘构建双螺旋耦合模型’)。\n"21    "3. 'sub_content': 细分内容(第3列),列出具体指标、变量或执行点(如‘输入:R&D经费’)。\n"22    "4. 'method': 方法与工具(第4列),该阶段涉及的方法。\n"23    "输出必须严格符合 JSON Schema:\n"24    "{\n"25    "  \"title\": string,\n"26    "  \"clusters\": [ { \"id\": string, \"label\": string } ],\n"27    "  \"nodes\": [ { \"id\": string, \"label\": string, \"type\": \"stage_label\"|\"task\"|\"sub_content\"|\"method\", \"parent_cluster\": string } ],\n"28    "  \"edges\": [ { \"source\": string, \"target\": string, \"label\"?: string } ]\n"29    "}\n"30    "要求:\n"31    "1. 每个 cluster 代表图中的一行(横向区域)。\n"32    "2. 每个 cluster 内必须有一个 'stage_label' 类型的节点(放在左侧)。\n"33    "3. 核心逻辑流向主要体现在 'task' 之间(垂直向下),'task' 指向其对应的 'sub_content'(水平向右)。\n"34    "4. 'sub_content' 内容要具体(拒绝空泛),提取具体指标或变量名。\n"35    "5. 节点文字要精简(不超过 15 个字,允许换行),避免长句。\n"36    "6. 不要输出任何非 JSON 的附加说明。"37)38 39 40def _extract_json_block(text: str) -> Optional[str]:41    # 从回答中提取 JSON 代码块或最外层 JSON42    code_block = re.search(r"```\s*json\s*([\s\S]*?)```", text, flags=re.IGNORECASE)43    if code_block:44        return code_block.group(1).strip()45    start = text.find("{")46    end = text.rfind("}")47    if start != -1 and end != -1 and end > start:48        return text[start : end + 1]49    return None50 51 52def analyze_structure(text: str, model: str = "deepseek-chat", api_key_env: str = "DEEPSEEK_API_KEY", key_file: Optional[str] = None, pass_env: str = "DEEPSEEK_KEY_PASSPHRASE", env_file: Optional[str] = None, key_name: str = "DEEPSEEK_API_KEY") -> Roadmap:53    # 加载 API Key(优先 .env,其次加密文件,最后环境变量)54    api_key = load_api_key(api_key_env=api_key_env, encrypted_file=key_file, pass_env=pass_env, env_file=env_file, key_name=key_name)55 56    content = None57    # 优先使用 OpenAI SDK 兼容模式(设置 base_url 指向 DeepSeek)58    try:59        from openai import OpenAI60 61        client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com/v1")62        resp = client.chat.completions.create(63            model=model,64            messages=[65                {"role": "system", "content": LLM_SYSTEM_PROMPT},66                {"role": "user", "content": text},67            ],68            temperature=0.2,69        )70        content = resp.choices[0].message.content71    except Exception:72        # 回退到 requests 直连 DeepSeek REST API73        try:74            import requests75 76            headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}77            payload = {78                "model": model,79                "messages": [80                    {"role": "system", "content": LLM_SYSTEM_PROMPT},81                    {"role": "user", "content": text},82                ],83                "temperature": 0.2,84            }85            r = requests.post("https://api.deepseek.com/v1/chat/completions", headers=headers, json=payload, timeout=60)86            r.raise_for_status()87            data_resp = r.json()88            content = data_resp["choices"][0]["message"]["content"]89        except Exception as e:90            # 无法获取内容,降级91            return build_fallback_roadmap(text, error=str(e))92 93    raw_json = _extract_json_block(content) or content94    try:95        data = json.loads(raw_json)96    except Exception:97        cleaned = raw_json.replace("'", '"')98        cleaned = re.sub(r",\s*}\s*$", "}", cleaned)99        data = json.loads(cleaned)100 101    try:102        roadmap = Roadmap(**data)103        roadmap.ensure_consistency()104        return roadmap105    except (ValidationError, ValueError) as e:106        return build_fallback_roadmap(text, error=str(e))107