Skill: zjuzhiyucai/literature-report (version 1.0.4)

--- name: literature-report description: 自动科研文献汇报系统。每天自动检索顶级期刊最新论文，AI辅助筛选，生成双语摘要，推送到飞书。使用方法：1. 用户说"设置文献汇报"或"每天推送论文"时激活；2. 用户要求自定义研究主题时激活；3. 用户要求文献检索和推送时激活。 --- # 自动科研文献汇报系统 自动化的科研文献检索与汇报系统，让科研人员轻松追踪最新研究动态。 --- ## 🔑 所需凭据 ### 必须凭据 **LLM API Key**（必需） - **获取方式：** - OpenAI: https://platform.openai.com - Claude: https://console.anthropic.com - 硅基流动（推荐）: https://cloud.siliconflow.cn - **用途：** 语义理解和内容生成 - **费用：** 约0.01元/篇论文 - **安全提示：** - 请勿将API Key提交到公开仓库 - 确保base_url指向可信的API提供商 - 论文标题和摘要将发送到配置的LLM服务 ### 可选凭据 **飞书用户ID**（可选，用于推送） - **获取方式：** 在飞书中打开个人资料，查看"用户ID"或"open_id" - **用途：** 推送每日文献报告 - **安全提示：** 用户ID不会产生费用，但请勿泄露 --- ## 🚀 快速开始 ### 1. 环境要求 - Python 3.8+ - LLM API Key（OpenAI / Claude / 硅基流动等） - 飞书账号（可选，用于推送） ### 2. 安装 ```bash # 安装 bash install.sh # 验证安装 python3 scripts/verify_install.py ``` ### 3. 配置 1. 复制配置文件模板： ```bash cp config.yaml.example config.yaml ``` 2. 编辑 `config.yaml`，填入你的配置： ```yaml # LLM API配置（必须） api: [REDACTED_SECRET]" # 你的LLM API Key base_url: "https://api.siliconflow.cn/v1" # API基础URL model: "deepseek-ai/DeepSeek-V3.2" # 模型名称 # 推送配置（可选） feishu: enabled: true target: "YOUR_USER_ID" # 你的飞书用户ID # 研究主题 research: topic: "你的研究领域" max_papers: 5 # 每天推送数量 ``` ### 4. 测试 ```bash # 验证配置 python3 scripts/validate_config.py # 测试运行 python3 scripts/fetch_papers.py python3 scripts/generate_summary.py ``` ### 5. 运行 ```bash # 手动执行 python3 scripts/fetch_papers.py # 抓取论文 python3 scripts/generate_summary.py # 生成摘要 python3 scripts/send_to_feishu.py # 推送 # 设置定时任务（每天早上9点） openclaw cron add literature-report --time '0 9 * * *' ``` --- ## 🔧 安装验证 运行验证脚本检查环境： ```bash python3 scripts/verify_install.py ``` **检查项目：** - ✅ Python版本 - ✅ 依赖库安装 - ✅ 配置文件存在 - ✅ API Key格式 - ✅ 网络连接 --- ## ❓ 故障排除 ### 问题1: API Key无效 **错误信息：** `API Key无效或账户余额不足` **解决方案：** 1. 检查API Key是否正确复制 2. 确认账户有余额 3. 确认API Key有权限访问指定模型 4. 确认base_url指向正确的API端点 ### 问题2: 找不到论文 **错误信息：** `未找到符合条件的论文` **解决方案：** 1. 放宽关键词设置 2. 添加更多期刊 3. 调整研究主题描述 4. 检查网络连接 ### 问题3: 推送失败 **错误信息：** `飞书推送失败` **解决方案：** 1. 确认飞书用户ID正确 2. 确认网络连接正常 3. 检查飞书服务状态 4. 注意：当前飞书推送为占位符实现，仅打印消息 --- ## 📚 期刊覆盖 ### RSS期刊（10个） Nature, Nature Biotechnology, Nature Materials, Nature Communications, Nature Nanotechnology, Nature Sustainability, Nature Reviews Drug Discovery, Nature Reviews Materials, Advanced Materials, Advanced Science ### PubMed API期刊（16个） Nature Biomedical Engineering, Nature Electronics, Nature Machine Intelligence, Nature Sensors, Nature Reviews Bioengineering, Science, Science Translational Medicine, Science Advances, Biomaterials, Journal of Controlled Release, ACS Nano, Biosensors and Bioelectronics, Nano Letters, Advanced Healthcare Materials --- ## ⚙️ 自定义配置 ### 修改研究主题 ```yaml research: topic: "你的研究领域" description: | 研究方向包括： - 方向1 - 方向2 ``` ### 添加自定义期刊 ```yaml journals: custom_journals: - name: "Your Journal" type: "pubmed" query: '"Journal Name"[Journal]' ``` --- ## 🔒 安全提示 1. **不要将config.yaml提交到公开仓库** 2. **API Key请妥善保管** 3. **用户ID不要泄露** 4. **建议使用环境变量存储敏感信息** 5. **确保base_url指向可信的API提供商** 6. **论文标题和摘要将发送到配置的LLM服务** --- ## 📞 支持 如有问题或建议，请提交Issue或Pull Request。 --- ## 📜 许可证 MIT License --- *版本: 1.0.4* *更新时间: 2026-03-02*

path: GUIDE.md
content: # 科研文献汇报系统 - 使用指南

## 快速开始

### 1. 安装

```bash
# 克隆或下载项目
cd research/

# 运行安装脚本
bash install.sh
```

### 2. 配置

编辑 `config.yaml` 文件：

```yaml
# 必须配置的项：
api:
  [REDACTED_SECRET]"  # 替换为你的硅基流动API Key

feishu:
  target: "YOUR_FEISHU_USER_ID_HERE"  # 替换为你的飞书用户ID
```

**获取API Key：**
1. 访问 https://cloud.siliconflow.cn
2. 注册并充值（最低10元即可）
3. 复制API Key

**获取飞书用户ID：**
1. 在飞书中打开个人资料
2. 查看"用户ID"或"open_id"

### 3. 测试运行

```bash
# 抓取论文
python3 scripts/fetch_papers.py

# 生成摘要
python3 scripts/generate_summary.py

# 推送到飞书
python3 scripts/send_to_feishu.py
```

### 4. 设置定时任务

**方法1：使用OpenClaw cron**

```bash
openclaw cron add literature-report --time '0 9 * * *' --script 'python3 /path/to/research/scripts/fetch_papers.py'
```

**方法2：使用系统cron**

```bash
crontab -e
# 添加以下行（每天早上9点执行）
0 9 * * * cd /path/to/research && python3 scripts/fetch_papers.py && python3 scripts/generate_summary.py
```

---

## 配置说明

### API配置

支持以下LLM提供商：
- **硅基流动**（推荐）：价格便宜，速度快
- **OpenAI**：需要API Key
- **Claude**：需要API Key

```yaml
api:
  provider: "siliconflow"
  [REDACTED_SECRET]"
  model: "deepseek-ai/DeepSeek-V3.2"
```

### 研究主题配置

修改 `research.topic` 和 `research.description` 来自定义研究主题：

```yaml
research:
  topic: "医疗设备相关研究"
  description: |
    包括但不限于：
    - 可穿戴医疗设备
    - 药物递送设备
    - 生物传感器
```

### 期刊配置

**默认期刊列表：**

RSS期刊（10个）：
- Nature
- Nature Biotechnology
- Nature Materials
- Nature Communications
- Nature Nanotechnology
- Nature Sustainability
- Nature Reviews Drug Discovery
- Nature Reviews Materials
- Advanced Materials
- Advanced Science

PubMed API期刊（16个）：
- Nature Biomedical Engineering
- Nature Electronics
- Nature Machine Intelligence
- Nature Sensors
- Nature Reviews Bioengineering
- Nature Reviews Electrical Engineering
- Science
- Science Translational Medicine
- Science Advances
- Biomaterials
- Journal of Controlled Release
- ACS Nano
- Biosensors and Bioelectronics
- Nano Letters
- Advanced Healthcare Materials

**添加自定义期刊：**

```yaml
journals:
  custom_journals:
    - name: "Your Journal Name"
      type: "pubmed"
      query: '"Journal Name"[Journal]'
```

### 关键词配置

**添加自定义关键词：**

```yaml
keywords:
  custom_core_keywords:
    - "drug-device"
    - "wearable"
    - "biosensor"
  
  custom_exclude_keywords:
    - "review"
    - "editorial"
```

---

## 高级功能

### 1. 修改推送时间

编辑 `config.yaml`：

```yaml
schedule:
  time: "09:00"  # 改为你想要的时间
```

### 2. 修改推送数量

```yaml
research:
  max_papers: 5  # 改为你想要的数量
```

### 3. 关闭某些期刊

编辑 `scripts/fetch_papers.py`，注释掉不需要的期刊。

### 4. 添加新的推送渠道

目前支持：
- ✅ 飞书
- ⏳ 微信（待开发）
- ⏳ 钉钉（待开发）
- ⏳ 邮件（待开发）

---

## 常见问题

### Q1: API Key无效？

**A:** 请检查：
1. API Key是否正确复制
2. 账户是否有余额
3. API Key是否有权限访问指定模型

### Q2: 飞书推送失败？

**A:** 请检查：
1. 飞书用户ID是否正确
2. 是否有权限发送消息

### Q3: 找不到论文？

**A:** 可能原因：
1. 关键词过于严格，尝试放宽
2. 期刊列表需要调整
3. 最近14天没有符合条件的新论文

### Q4: 如何查看日志？

**A:** 查看日志文件：

```bash
tail -f logs/literature.log
```

---

## 文件结构

```
research/
├── README.md              # 项目说明
├── config.yaml            # 配置文件
├── install.sh             # 安装脚本
├── scripts/               # 脚本目录
│   ├── fetch_papers.py    # 论文抓取
│   ├── ai_filter.py       # AI筛选
│   ├── generate_summary.py # 生成摘要
│   └── send_to_feishu.py  # 推送飞书
├── data/                  # 数据目录
└── logs/                  # 日志目录
```

---

## 联系支持

如有问题，请联系：[你的联系方式]

---

*更新时间: 2026-03-02*

path: README.md
content: # literature-report

自动科研文献汇报系统

## 功能特点

- 双重数据源（RSS + PubMed API）
- AI辅助检索
- 双语输出
- 自动推送
- 定时任务

## 安装

```bash
bash install.sh
```

## 配置

1. 复制配置文件模板：
```bash
cp config.yaml.example config.yaml
```

2. 编辑 `config.yaml`，填入你的配置：
   - LLM API Key
   - 飞书用户ID（可选）
   - 研究主题

## 使用

```bash
python3 scripts/fetch_papers.py
python3 scripts/generate_summary.py
python3 scripts/send_to_feishu.py
```

## 许可证

MIT License

path: install.sh
content: #!/bin/bash
# 科研文献汇报系统一键安装脚本

echo "=========================================="
echo "科研文献汇报系统 - 一键安装"
echo "=========================================="

# 检查Python版本
echo ""
echo "[1/5] 检查Python版本..."
python_version=$(python3 --version 2>&1 | awk '{print $2}')
if [ -z "$python_version" ]; then
    echo "❌ 未找到Python3，请先安装Python 3.8+"
    exit 1
fi
echo "✅ Python版本: $python_version"

# 安装依赖
echo ""
echo "[2/5] 安装Python依赖..."
echo "安装核心依赖..."
pip3 install -q feedparser requests pyyaml 2>&1 | grep -v "WARNING\|DEPRECATION" || true

echo "安装可选依赖（PDF生成）..."
pip3 install -q markdown weasyprint 2>&1 | grep -v "WARNING\|DEPRECATION" || true

echo "✅ 依赖安装完成"

# 创建目录
echo ""
echo "[3/5] 创建目录结构..."
mkdir -p data logs
echo "✅ 目录创建完成"

# 检查配置文件
echo ""
echo "[4/5] 检查配置文件..."
if [ ! -f "config.yaml" ]; then
    if [ -f "config.yaml.example" ]; then
        echo "⚠️  未找到config.yaml，正在从config.yaml.example创建..."
        cp config.yaml.example config.yaml
        echo "✅ 已创建config.yaml，请修改其中的API Key和用户ID"
    else
        echo "❌ 未找到config.yaml.example，请手动创建config.yaml"
    fi
else
    echo "✅ 配置文件已存在"
fi

# 验证安装
echo ""
echo "[5/5] 验证安装..."
if [ -f "scripts/verify_install.py" ]; then
    python3 scripts/verify_install.py
else
    echo "⚠️  verify_install.py不存在，跳过验证"
fi

echo ""
echo "=========================================="
echo "安装完成！"
echo "=========================================="
echo ""
echo "下一步："
echo "  1. 编辑config.yaml，填入你的API Key和用户ID"
echo "  2. 运行: python3 scripts/fetch_papers.py"
echo "  3. 设置定时任务: openclaw cron add literature-report --time '0 9 * * *'"
echo ""

path: package.json
content: {
  "name": "literature-report",
  "version": "1.0.4",
  "description": "自动科研文献汇报系统，每天自动检索顶级期刊最新论文，AI辅助筛选，生成双语摘要，推送到飞书",
  "keywords": [
    "literature",
    "research",
    "papers",
    "AI",
    "automation",
    "RSS",
    "PubMed"
  ],
  "author": "ClawHub Community",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/clawhub-community/literature-report"
  },
  "credentials": {
    "required": [
      {
        "name": "LLM_API_KEY",
        "description": "LLM API Key for semantic understanding and content generation",
        "how_to_get": "https://platform.openai.com or https://cloud.siliconflow.cn",
        "stored_in": "config.yaml (api.api_key)"
      }
    ],
    "optional": [
      {
        "name": "FEISHU_USER_ID",
        "description": "Feishu user ID for push notifications",
        "how_to_get": "Open Feishu profile, view 'User ID'",
        "stored_in": "config.yaml (feishu.target)"
      }
    ]
  },
  "python": {
    "dependencies": [
      "feedparser>=6.0.0",
      "requests>=2.25.0",
      "pyyaml>=5.4.0",
      "markdown>=3.3.0",
      "weasyprint>=52.0"
    ]
  },
  "files": [
    "SKILL.md",
    "README.md",
    "GUIDE.md",
    "install.sh",
    "config.yaml.example",
    "scripts/*.py"
  ]
}

path: scripts/ai_filter.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI辅助检索脚本
使用LLM进行语义理解，判断论文是否相关
"""

import requests
import json
from pathlib import Path
import sys

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from scripts.config_loader import get_api_config

def call_llm(prompt, max_tokens=500):
    """调用LLM API"""
    
    # 从配置文件读取API配置
    try:
        api_config = get_api_config()
        [REDACTED_SECRET]'api_key']
        base_url = api_config['base_url']
        model = api_config['model']
    except Exception as e:
        print(f"❌ API配置加载失败: {e}")
        return None
    
    # 检查API Key是否已配置
    if api_key == "YOUR_API_KEY_HERE":
        print("❌ 请先在config.yaml中配置API Key")
        return None
    
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    data = {
        "model": model,
        "messages": [
            {"role": "user", "content": prompt}
        ],
        "max_tokens": max_tokens,
        "temperature": 0.3
    }
    
    try:
        response = requests.post(
            f"{base_url}/chat/completions",
            headers=headers,
            json=data,
            timeout=60
        )
        
        if response.status_code == 200:
            result = response.json()
            return result['choices'][0]['message']['content']
        else:
            print(f"API调用失败: {response.status_code} - {response.text}")
            return None
            
    except Exception as e:
        print(f"API调用异常: {e}")
        return None

def check_paper_relevance(title, abstract, research_focus="医疗设备相关研究"):
    """使用LLM判断论文是否与研究主题相关"""
    
    prompt = f"""你是一个科研文献筛选专家。请判断以下论文是否与"{research_focus}"相关。

研究主题包括：
- 可穿戴医疗设备（如：智能手表、健康监测贴片、可穿戴传感器等）
- 药物递送设备（如：微针贴片、胰岛素泵、植入式给药系统等）
- 生物传感器（用于疾病诊断、健康监测、生物标志物检测等）
- 植入式医疗设备（如：心脏起搏器、神经刺激器、人工关节等）
- 监测+治疗闭环系统
- AI在医疗设备中的应用
- 柔性电子器件（用于医疗健康）
- 微流控芯片（用于诊断或治疗）

论文标题：{title}

论文摘要：{abstract if abstract else "无摘要"}

请回答：
1. 是否相关（是/否）
2. 相关程度（高/中/低）
3. 简要说明理由（1句话）

请严格按照以下格式回复：
是否相关：是/否
相关程度：高/中/低
理由：XXX
"""
    
    result = call_llm(prompt, max_tokens=200)
    
    if result:
        # 解析结果
        is_relevant = "是" in result.split("是否相关")[1].split("\n")[0] if "是否相关" in result else False
        relevance_level = "高" if "高" in result else ("中" if "中" in result else "低")
        
        return {
            'is_relevant': is_relevant,
            'relevance_level': relevance_level,
            'reason': result
        }
    
    return {
        'is_relevant': False,
        'relevance_level': '低',
        'reason': 'AI判断失败'
    }

def filter_papers_with_ai(papers, research_focus="医疗设备相关研究"):
    """使用AI筛选论文"""
    
    print(f"\n使用AI筛选论文（研究主题：{research_focus}）...")
    
    filtered_papers = []
    
    for i, paper in enumerate(papers):
        title = paper.get('title', '')
        abstract = paper.get('abstract', '')
        
        print(f"  [{i+1}/{len(papers)}] 分析: {title[:60]}...")
        
        # 使用AI判断相关性
        result = check_paper_relevance(title, abstract, research_focus)
        
        if result['is_relevant']:
            paper['ai_relevance'] = result['relevance_level']
            paper['ai_reason'] = result['reason']
            filtered_papers.append(paper)
            print(f"    ✅ 相关程度：{result['relevance_level']}")
        else:
            print(f"    ❌ 不相关")
    
    # 按相关程度排序
    relevance_order = {'高': 3, '中': 2, '低': 1}
    filtered_papers.sort(key=lambda x: relevance_order.get(x.get('ai_relevance', '低'), 0), reverse=True)
    
    return filtered_papers

if __name__ == '__main__':
    # 测试
    test_title = "A wireless patch for the continuous monitoring of C-reactive protein in sweat"
    test_abstract = "This study presents a wireless wearable patch for continuous monitoring of biomarkers in sweat."
    
    print("测试AI相关性判断...")
    result = check_paper_relevance(test_title, test_abstract)
    print(f"\n结果：{result}")

path: scripts/config_loader.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置加载模块
从config.yaml读取配置
"""

import yaml
from pathlib import Path

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent

def load_config():
    """加载配置文件"""
    config_file = PROJECT_ROOT / 'config.yaml'
    
    if not config_file.exists():
        raise FileNotFoundError(
            f"配置文件不存在: {config_file}\n"
            f"请复制 config.yaml.example 并修改配置"
        )
    
    with open(config_file, 'r', encoding='utf-8') as f:
        config = yaml.safe_load(f)
    
    return config

def get_api_config():
    """获取API配置"""
    config = load_config()
    return {
        'api_key': config['api']['api_key'],
        'base_url': config['api']['base_url'],
        'model': config['api']['model'],
    }

def get_feishu_config():
    """获取飞书配置"""
    config = load_config()
    return {
        'enabled': config['feishu']['enabled'],
        'target': config['feishu']['target'],
    }

def get_research_config():
    """获取研究配置"""
    config = load_config()
    return {
        'topic': config['research']['topic'],
        'description': config['research']['description'],
        'max_papers': config['research']['max_papers'],
    }

def get_journal_config():
    """获取期刊配置"""
    config = load_config()
    return {
        'use_rss': config['journals']['use_rss'],
        'use_pubmed': config['journals']['use_pubmed'],
        'custom_journals': config['journals']['custom_journals'],
    }

def get_keyword_config():
    """获取关键词配置"""
    config = load_config()
    return {
        'custom_core_keywords': config['keywords']['custom_core_keywords'],
        'custom_exclude_keywords': config['keywords']['custom_exclude_keywords'],
    }

if __name__ == '__main__':
    # 测试配置加载
    print("测试配置加载...")
    
    try:
        api_config = get_api_config()
        print(f"✅ API配置: {api_config['model']}")
        
        feishu_config = get_feishu_config()
        print(f"✅ 飞书配置: {feishu_config['target']}")
        
        research_config = get_research_config()
        print(f"✅ 研究主题: {research_config['topic']}")
        
    except FileNotFoundError as e:
        print(f"❌ {e}")
    except Exception as e:
        print(f"❌ 配置加载失败: {e}")

path: scripts/fetch_papers.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RSS抓取脚本 + PubMed API搜索
从各期刊RSS源抓取最新论文，并使用PubMed API补充缺失的期刊
"""

import feedparser
import json
import requests
import time
from datetime import datetime, timedelta
from pathlib import Path

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent

# 期刊RSS列表（可用）
JOURNALS_RSS = {
    'Nature': 'https://www.nature.com/nature.rss',
    'Nature Biotechnology': 'https://www.nature.com/nbt.rss',
    'Nature Materials': 'https://www.nature.com/nmat.rss',
    'Nature Communications': 'https://www.nature.com/ncomms.rss',
    'Nature Nanotechnology': 'https://www.nature.com/nnano.rss',
    'Nature Sustainability': 'https://www.nature.com/s41893.rss',
    'Nature Reviews Drug Discovery': 'https://www.nature.com/nrd.rss',
    'Nature Reviews Materials': 'https://www.nature.com/natrevmats.rss',
    'Advanced Materials': 'https://onlinelibrary.wiley.com/feed/15214095/most-recent',
    'Advanced Science': 'https://onlinelibrary.wiley.com/feed/21983844/most-recent',
}

# 期刊PubMed搜索列表（补充无法用RSS的期刊）
JOURNALS_PUBMED = {
    # Nature子刊
    'Nature Biomedical Engineering': '"Nature Biomedical Engineering"[Journal]',
    'Nature Electronics': '"Nature Electronics"[Journal]',
    'Nature Machine Intelligence': '"Nature Machine Intelligence"[Journal]',
    'Nature Sensors': '"Nature Sensors"[Journal]',
    
    # Nature Reviews系列
    'Nature Reviews Bioengineering': '"Nature Reviews Bioengineering"[Journal]',
    'Nature Reviews Electrical Engineering': '"Nature Reviews Electrical Engineering"[Journal]',
    
    # Science系列
    'Science': '"Science"[Journal]',
    'Science Translational Medicine': '"Science Translational Medicine"[Journal]',
    'Science Advances': '"Science Advances"[Journal]',
    
    # 专业期刊（新增）
    'Biomaterials': '"Biomaterials"[Journal]',
    'Journal of Controlled Release': '"Journal of Controlled Release"[Journal]',
    'ACS Nano': '"ACS Nano"[Journal]',
    'Biosensors and Bioelectronics': '"Biosensors and Bioelectronics"[Journal]',
    'Nano Letters': '"Nano Letters"[Journal]',
    'Advanced Healthcare Materials': '"Advanced Healthcare Materials"[Journal]',
}

# 核心关键词（宽松匹配，只检查标题）
CORE_KEYWORDS = [
    'drug delivery',
    'drug-device',
    'microneedle',
    'transdermal',
    'insulin pump',
    'infusion pump',
    'theranostic',
    'biosensor',
    'patch',
    'wearable',
    'implantable',
    'sensor',
    'microfluidic',
]

# 排除关键词（标题中包含这些词的跳过）
EXCLUDE_KEYWORDS = [
    # 文献类型
    'editorial', 'comment', 'news', 'perspective', 
    'correspondence', 'letter', 'highlight', 'book review',
    'nature news', 'news and views', 'breaking news',
    'review', 'perspective', 'opinion', 'editorial',
    'correction', 'retraction', 'erratum',
    
    # 不相关主题
    'tree', 'forest', 'climate', 'policy', 'politics',
    'counting', 'together', 'eu', 'europe',
    'coral', 'microbiome', 'electrodeposition', 'window',
    'plant', 'agriculture', 'soil', 'water treatment',
    
    # 过于基础的研究
    'theoretical', 'simulation', 'modeling only',
]

def fetch_journal_papers_rss(journal_name, rss_url, days=14):
    """通过RSS抓取期刊最新论文"""
    papers = []
    
    try:
        print(f"正在抓取 {journal_name}...")
        feed = feedparser.parse(rss_url)
        
        if feed.bozo:
            print(f"  ⚠️ RSS解析警告: {feed.bozo_exception}")
        
        for entry in feed.entries:
            # 解析发布时间
            published = entry.get('published_parsed') or entry.get('updated_parsed')
            if published:
                pub_date = datetime(*published[:6])
                # 只抓取最近N天的论文
                if (datetime.now() - pub_date).days > days:
                    continue
            else:
                pub_date = None
            
            paper = {
                'title': entry.get('title', ''),
                'authors': entry.get('author', ''),
                'abstract': entry.get('summary', ''),
                'journal': journal_name,
                'link': entry.get('link', ''),
                'published': pub_date.strftime('%Y-%m-%d') if pub_date else '',
                'doi': entry.get('dc_identifier', '').replace('doi:', '') if entry.get('dc_identifier') else '',
            }
            
            papers.append(paper)
        
        print(f"  ✅ 抓取到 {len(papers)} 篇论文")
        
    except Exception as e:
        print(f"  ❌ 抓取失败: {e}")
    
    return papers

def fetch_journal_papers_pubmed(journal_query, journal_name, days=14):
    """通过PubMed API搜索期刊最新论文"""
    papers = []
    
    try:
        print(f"正在PubMed搜索 {journal_name}...")
        
        # 计算日期范围
        end_date = datetime.now()
        start_date = end_date - timedelta(days=days)
        date_range = f"{start_date.strftime('%Y/%m/%d')}:{end_date.strftime('%Y/%m/%d')}[PDAT]"
        
        # 构建搜索查询
        search_query = f"{journal_query} AND {date_range}"
        
        # PubMed API搜索
        search_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
        params = {
            'db': 'pubmed',
            'term': search_query,
            'retmax': 50,
            'retmode': 'json',
            'sort': 'pub_date',
        }
        
        response = requests.get(search_url, params=params, timeout=30)
        data = response.json()
        
        if 'esearchresult' not in data:
            print(f"  ⚠️ 无搜索结果")
            return papers
        
        pmids = data['esearchresult'].get('idlist', [])
        
        if not pmids:
            print(f"  ⚠️ 未找到论文")
            return papers
        
        # 获取论文详情
        fetch_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
        params = {
            'db': 'pubmed',
            'id': ','.join(pmids[:20]),  # 限制20篇
            'retmode': 'xml',
        }
        
        response = requests.get(fetch_url, params=params, timeout=30)
        
        # 简单解析XML（只提取标题和摘要）
        import xml.etree.ElementTree as ET
        root = ET.fromstring(response.content)
        
        for article in root.findall('.//PubmedArticle'):
            try:
                title_elem = article.find('.//ArticleTitle')
                title = title_elem.text if title_elem is not None else ''
                
                abstract_elem = article.find('.//Abstract/AbstractText')
                abstract = abstract_elem.text if abstract_elem is not None else ''
                
                authors_elem = article.findall('.//Author')
                authors = []
                for author in authors_elem[:5]:  # 只取前5个作者
                    lastname = author.find('LastName')
                    if lastname is not None:
                        authors.append(lastname.text)
                authors_str = ', '.join(authors)
                
                pub_date_elem = article.find('.//PubDate/Year')
                pub_date = pub_date_elem.text if pub_date_elem is not None else ''
                
                pmid_elem = article.find('.//PMID')
                pmid = pmid_elem.text if pmid_elem is not None else ''
                
                paper = {
                    'title': title,
                    'authors': authors_str,
                    'abstract': abstract,
                    'journal': journal_name,
                    'link': f"https://pubmed.ncbi.nlm.nih.gov/{pmid}/",
                    'published': pub_date,
                    'doi': '',
                }
                
                papers.append(paper)
                
            except Exception as e:
                continue
        
        print(f"  ✅ 抓取到 {len(papers)} 篇论文")
        
        # 避免API限流
        time.sleep(0.5)
        
    except Exception as e:
        print(f"  ❌ PubMed搜索失败: {e}")
    
    return papers

def filter_papers_by_keywords(papers):
    """根据关键词进行宽松筛选（第一轮）"""
    filtered_papers = []
    
    for paper in papers:
        # 过滤文献类型：只保留article和review
        title = paper.get('title', '')
        if not title or title is None:
            continue
        
        title_lower = title.lower()
        
        # 排除非article/review类型
        if any(exclude in title_lower for exclude in EXCLUDE_KEYWORDS):
            continue
        
        # 宽松匹配：标题中包含任意核心关键词
        for keyword in CORE_KEYWORDS:
            if keyword.lower() in title_lower:
                filtered_papers.append(paper)
                break
    
    return filtered_papers

def main():
    """主函数"""
    print("=" * 60)
    print("开始抓取最新论文")
    print("=" * 60)
    
    all_papers = []
    
    # 通过RSS抓取期刊
    print("\n【通过RSS抓取期刊】")
    for journal_name, rss_url in JOURNALS_RSS.items():
        papers = fetch_journal_papers_rss(journal_name, rss_url, days=14)
        all_papers.extend(papers)
    
    # 通过PubMed API补充期刊
    print("\n【通过PubMed API补充期刊】")
    for journal_name, journal_query in JOURNALS_PUBMED.items():
        papers = fetch_journal_papers_pubmed(journal_query, journal_name, days=14)
        all_papers.extend(papers)
    
    print(f"\n总共抓取到 {len(all_papers)} 篇论文")
    
    # 第一轮：关键词筛选（宽松）
    print("\n【第一轮】关键词筛选...")
    filtered_papers = filter_papers_by_keywords(all_papers)
    print(f"筛选后剩余 {len(filtered_papers)} 篇候选论文")
    
    # 第二轮：AI语义理解（如果候选论文较多，限制数量）
    max_ai_papers = 20  # 限制AI判断的论文数量
    if len(filtered_papers) > max_ai_papers:
        print(f"\n候选论文较多，限制AI判断数量为 {max_ai_papers} 篇")
        # 随机选择或按期刊分布选择
        filtered_papers = filtered_papers[:max_ai_papers]
    
    # 使用AI筛选
    from ai_filter import filter_papers_with_ai
    ai_filtered_papers = filter_papers_with_ai(filtered_papers, research_focus="医疗设备相关研究")
    print(f"AI筛选后剩余 {len(ai_filtered_papers)} 篇相关论文")
    
    # 去重（根据标题）
    seen_titles = set()
    unique_papers = []
    for paper in ai_filtered_papers:
        title_key = paper['title'].lower().strip()
        if title_key not in seen_titles:
            seen_titles.add(title_key)
            unique_papers.append(paper)
    
    print(f"去重后剩余 {len(unique_papers)} 篇论文")
    
    # 按发布时间排序
    unique_papers.sort(key=lambda x: x['published'], reverse=True)
    
    # 限制数量
    max_papers = 5
    final_papers = unique_papers[:max_papers]
    
    print(f"\n最终选择 {len(final_papers)} 篇论文")
    
    # 保存数据
    output_file = PROJECT_ROOT / 'data' / 'latest_papers.json'
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(final_papers, f, ensure_ascii=False, indent=2)
    
    print(f"\n数据已保存到: {output_file}")
    print("=" * 60)
    
    return final_papers

if __name__ == '__main__':
    main()

path: scripts/generate_summary.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
生成摘要和关键发现
使用硅基流动API调用Step-3.5-Flash模型
"""

import json
from pathlib import Path
import sys

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

# 导入LLM模块
from llm_client import generate_chinese_title, generate_english_summary, generate_key_findings

def process_papers():
    """处理所有论文"""
    
    # 读取数据
    input_file = PROJECT_ROOT / 'data' / 'latest_papers.json'
    with open(input_file, 'r', encoding='utf-8') as f:
        papers = json.load(f)
    
    print(f"读取到 {len(papers)} 篇论文")
    
    # 生成摘要
    for paper in papers:
        title = paper.get('title', '')
        abstract = paper.get('abstract', '')
        
        print(f"\n处理: {title[:60]}...")
        
        # 生成中文标题
        title_cn = generate_chinese_title(title)
        paper['title_cn'] = title_cn if title_cn else title
        print(f"  ✅ 中文标题: {paper['title_cn'][:50]}...")
        
        # 生成英文摘要
        summary_en = generate_english_summary(title, abstract)
        paper['summary_en'] = summary_en if summary_en else abstract[:200] if abstract else "Please refer to the original article."
        print(f"  ✅ 英文摘要已生成 ({len(paper['summary_en'])} chars)")
        
        # 生成关键发现
        key_findings = generate_key_findings(title, abstract)
        paper['key_findings'] = key_findings
        print(f"  ✅ 关键发现: {len(key_findings)} 条")
    
    # 保存数据
    output_file = PROJECT_ROOT / 'data' / 'papers_with_summary.json'
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(papers, f, ensure_ascii=False, indent=2)
    
    print(f"\n数据已保存到: {output_file}")
    
    return papers

if __name__ == '__main__':
    process_papers()

path: scripts/llm_client.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
LLM调用脚本
使用配置文件中的API配置
"""

import requests
import json
from pathlib import Path
import sys

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from scripts.config_loader import get_api_config

def call_llm(prompt, max_tokens=500):
    """调用LLM API"""
    
    # 从配置文件读取API配置
    try:
        api_config = get_api_config()
        [REDACTED_SECRET]'api_key']
        base_url = api_config['base_url']
        model = api_config['model']
    except Exception as e:
        print(f"❌ API配置加载失败: {e}")
        return None
    
    # 检查API Key是否已配置
    if api_key == "YOUR_API_KEY_HERE":
        print("❌ 请先在config.yaml中配置API Key")
        return None
    
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    data = {
        "model": model,
        "messages": [
            {"role": "user", "content": prompt}
        ],
        "max_tokens": max_tokens,
        "temperature": 0.3
    }
    
    try:
        response = requests.post(
            f"{base_url}/chat/completions",
            headers=headers,
            json=data,
            timeout=60
        )
        
        if response.status_code == 200:
            result = response.json()
            return result['choices'][0]['message']['content']
        else:
            print(f"API调用失败: {response.status_code} - {response.text}")
            return None
            
    except Exception as e:
        print(f"API调用异常: {e}")
        return None

def generate_chinese_title(english_title):
    """生成中文标题"""
    
    prompt = f"""请将以下英文论文标题翻译成中文，要求：
1. 准确传达原文含义
2. 符合中文学术表达习惯
3. 不要添加任何解释或说明，只输出翻译后的中文标题

英文标题：{english_title}

中文标题："""
    
    return call_llm(prompt, max_tokens=200)

def generate_english_summary(title, abstract):
    """生成100词英文摘要"""
    
    # 如果摘要太短，用标题生成
    if len(abstract) < 100 or 'EarlyView' in abstract or 'Volume' in abstract:
        prompt = f"""请根据以下论文标题生成一段约100词的英文摘要，要求：
1. 简明扼要地概述研究内容
2. 突出创新点和应用价值
3. 使用学术写作风格
4. 控制在80-120词之间

标题：{title}

摘要："""
    else:
        prompt = f"""请将以下论文摘要压缩成约100词的简洁版本，要求：
1. 保留核心研究内容和创新点
2. 突出应用价值
3. 控制在80-120词之间

标题：{title}

原始摘要：{abstract}

精简摘要："""
    
    return call_llm(prompt, max_tokens=300)

def generate_key_findings(title, abstract):
    """生成关键发现"""
    
    prompt = f"""请根据以下论文信息提取3个关键发现，要求：
1. 每个发现用一句话概括
2. 突出创新性和应用价值
3. 使用简洁的学术表达

标题：{title}
摘要：{abstract}

关键发现（3条）："""
    
    result = call_llm(prompt, max_tokens=300)
    
    if result:
        # 解析关键发现
        findings = []
        for line in result.split('\n'):
            line = line.strip()
            if line and (line[0].isdigit() or line.startswith('-') or line.startswith('•')):
                # 移除编号
                if line[0].isdigit():
                    line = line.split('.', 1)[-1].strip()
                elif line.startswith('-') or line.startswith('•'):
                    line = line[1:].strip()
                findings.append(line)
        
        return findings[:3] if findings else ["请查看原文获取详细信息"]
    
    return ["请查看原文获取详细信息"]

def process_paper(paper):
    """处理单篇论文，生成中文标题、英文摘要和关键发现"""
    
    title = paper.get('title', '')
    abstract = paper.get('abstract', '')
    
    print(f"  处理: {title[:50]}...")
    
    # 生成中文标题
    title_cn = generate_chinese_title(title)
    if not title_cn:
        title_cn = title
    
    # 生成英文摘要
    summary_en = generate_english_summary(title, abstract)
    if not summary_en:
        summary_en = abstract[:200] if abstract else "Please refer to the original article for details."
    
    # 生成关键发现
    key_findings = generate_key_findings(title, abstract)
    
    return {
        'title_cn': title_cn,
        'summary_en': summary_en,
        'key_findings': key_findings
    }

if __name__ == '__main__':
    # 测试
    test_title = "Machine Learning‐Informed Nano Co‐Assembly Inhibits Fibroblast Activation Protein and Improves Drug Delivery in Fibrotic Tissue"
    test_abstract = "This study presents a novel approach using machine learning to optimize nano co-assembly for improved drug delivery."
    
    print("测试LLM调用...")
    print("\n生成中文标题...")
    title_cn = generate_chinese_title(test_title)
    print(f"中文标题: {title_cn}")
    
    print("\n生成英文摘要...")
    summary_en = generate_english_summary(test_title, test_abstract)
    print(f"英文摘要: {summary_en}")

path: scripts/main.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
主程序：自动科研文献汇报系统
整合所有步骤：抓取、过滤、生成摘要、推送
"""

import json
from pathlib import Path
from datetime import datetime
import sys

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent

def run():
    """主流程"""
    
    print("=" * 60)
    print("🚀 开始执行自动科研文献汇报任务")
    print("=" * 60)
    
    # 步骤1：抓取论文
    print("\n【步骤1】抓取论文...")
    from fetch_papers import main as fetch_papers
    papers = fetch_papers()
    
    if not papers:
        print("❌ 没有找到符合条件的论文")
        return False
    
    # 步骤2：生成摘要
    print("\n【步骤2】生成摘要...")
    from generate_summary import process_papers
    papers_with_summary = process_papers()
    
    # 步骤3：格式化消息
    print("\n【步骤3】格式化消息...")
    from send_to_feishu import format_daily_report
    message = format_daily_report(papers_with_summary)
    
    # 保存消息
    output_file = PROJECT_ROOT / 'data' / 'daily_report.txt'
    with open(output_file, 'w', encoding='utf-8') as f:
        f.write(message)
    
    print(f"✅ 消息已保存: {output_file}")
    
    # 步骤4：推送到飞书（通过OpenClaw）
    print("\n【步骤4】推送到飞书...")
    print("✅ 任务完成！")
    
    return True

if __name__ == '__main__':
    success = run()
    sys.exit(0 if success else 1)

path: scripts/md_to_pdf.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Markdown to PDF converter
"""

from pathlib import Path
import markdown
from weasyprint import HTML, CSS

def md_to_pdf(md_file, pdf_file):
    """Convert Markdown to PDF"""
    
    # Read markdown
    with open(md_file, 'r', encoding='utf-8') as f:
        md_content = f.read()
    
    # Convert to HTML
    html_content = markdown.markdown(md_content, extensions=['tables', 'fenced_code'])
    
    # Add CSS styling
    html_with_style = f"""
    <html>
    <head>
        <meta charset="utf-8">
        <style>
            body {{
                font-family: 'Noto Sans SC', 'SimHei', sans-serif;
                font-size: 12pt;
                line-height: 1.6;
                margin: 40px;
                color: #333;
            }}
            h1 {{
                font-size: 24pt;
                color: #2c3e50;
                border-bottom: 2px solid #3498db;
                padding-bottom: 10px;
            }}
            h2 {{
                font-size: 18pt;
                color: #34495e;
                margin-top: 30px;
            }}
            h3 {{
                font-size: 14pt;
                color: #7f8c8d;
            }}
            code {{
                background: #f4f4f4;
                padding: 2px 6px;
                border-radius: 3px;
                font-family: 'Courier New', monospace;
            }}
            pre {{
                background: #f4f4f4;
                padding: 15px;
                border-radius: 5px;
                overflow-x: auto;
            }}
            table {{
                border-collapse: collapse;
                width: 100%;
                margin: 20px 0;
            }}
            th, td {{
                border: 1px solid #ddd;
                padding: 8px;
                text-align: left;
            }}
            th {{
                background: #3498db;
                color: white;
            }}
            tr:nth-child(even) {{
                background: #f9f9f9;
            }}
        </style>
    </head>
    <body>
        {html_content}
    </body>
    </html>
    """
    
    # Convert to PDF
    HTML(string=html_with_style).write_pdf(pdf_file)
    
    print(f"✅ PDF已生成: {pdf_file}")

if __name__ == '__main__':
    # 项目根目录
    PROJECT_ROOT = Path(__file__).parent.parent
    
    md_file = PROJECT_ROOT / 'TECH_FLOW.md'
    pdf_file = PROJECT_ROOT / 'TECH_FLOW.pdf'
    
    md_to_pdf(md_file, pdf_file)

path: scripts/send_message.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
消息发送脚本
从配置文件读取用户ID
"""

import sys
from pathlib import Path

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from scripts.config_loader import get_feishu_config

def send_message(message, target=None):
    """发送消息"""
    
    # 从配置文件读取飞书配置
    try:
        feishu_config = get_feishu_config()
        if target is None:
            target = feishu_config['target']
    except Exception as e:
        print(f"配置加载失败: {e}")
        return False
    
    print(f"发送消息到: {target}")
    print(f"消息: {message}")
    
    return True

if __name__ == '__main__':
    # 测试
    test_message = "测试消息"
    send_message(test_message)

path: scripts/send_to_feishu.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
飞书推送脚本
从配置文件读取用户ID
"""

import requests
import json
from pathlib import Path
import sys

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from scripts.config_loader import get_feishu_config

def send_to_feishu(message, target=None):
    """发送消息到飞书"""
    
    # 从配置文件读取飞书配置
    try:
        feishu_config = get_feishu_config()
        if not feishu_config['enabled']:
            print("飞书推送未启用")
            return False
        
        if target is None:
            target = feishu_config['target']
    except Exception as e:
        print(f"飞书配置加载失败: {e}")
        return False
    
    # 检查用户ID是否已配置
    if target == "YOUR_USER_ID_HERE":
        print("请先在config.yaml中配置飞书用户ID")
        return False
    
    # 发送消息
    # 注意：这里需要替换为实际的飞书API调用
    print(f"发送消息到飞书: {target}")
    print(f"消息内容: {message[:100]}...")
    
    return True

if __name__ == '__main__':
    # 测试
    test_message = "这是一条测试消息"
    send_to_feishu(test_message)

path: scripts/validate_config.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置验证脚本
检查配置文件格式和必填字段
"""

import sys
import yaml
from pathlib import Path

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent

def validate_config():
    """验证配置文件"""
    print("=" * 50)
    print("配置文件验证")
    print("=" * 50)
    
    config_file = PROJECT_ROOT / 'config.yaml'
    
    # 检查文件是否存在
    if not config_file.exists():
        print("❌ 配置文件不存在: config.yaml")
        print("请复制 config.yaml.example 并修改：")
        print("  cp config.yaml.example config.yaml")
        return False
    
    print(f"✅ 配置文件存在: {config_file}")
    
    # 读取配置
    try:
        with open(config_file, 'r', encoding='utf-8') as f:
            config = yaml.safe_load(f)
        print("✅ 配置文件格式正确")
    except Exception as e:
        print(f"❌ 配置文件格式错误: {e}")
        return False
    
    # 验证必填字段
    print("\n验证必填字段：")
    all_valid = True
    
    # API配置
    print("\n1. API配置：")
    api_config = config.get('api', {})
    
    [REDACTED_SECRET]'api_key', '')
    if api_key == 'YOUR_API_KEY_HERE' or not [REDACTED_SECRET]"  ❌ api_key: 未配置")
        all_valid = False
    elif len(api_key) < 10:
        print("  ⚠️  [REDACTED_SECRET]")
        all_valid = False
    else:
        print("  ✅ api_key: 已配置")
    
    base_url = api_config.get('base_url', '')
    if base_url:
        print(f"  ✅ base_url: {base_url}")
    else:
        print("  ⚠️  base_url: 使用默认值")
    
    model = api_config.get('model', '')
    if model:
        print(f"  ✅ model: {model}")
    else:
        print("  ⚠️  model: 使用默认值")
    
    # 飞书配置（可选）
    print("\n2. 飞书配置（可选）：")
    feishu_config = config.get('feishu', {})
    
    feishu_enabled = feishu_config.get('enabled', False)
    if feishu_enabled:
        print(f"  ✅ enabled: {feishu_enabled}")
        
        feishu_target = feishu_config.get('target', '')
        if feishu_target == 'YOUR_USER_ID_HERE' or not feishu_target:
            print("  ⚠️  target: 未配置，推送功能将不可用")
        else:
            print(f"  ✅ target: 已配置")
    else:
        print(f"  ℹ️  飞书推送未启用")
    
    # 研究配置
    print("\n3. 研究配置：")
    research_config = config.get('research', {})
    
    topic = research_config.get('topic', '')
    if topic and topic != '你的研究领域':
        print(f"  ✅ topic: {topic}")
    else:
        print("  ⚠️  topic: 未配置或使用默认值")
    
    max_papers = research_config.get('max_papers', 5)
    print(f"  ✅ max_papers: {max_papers}")
    
    # 总结
    print("\n" + "=" * 50)
    if all_valid:
        print("✅ 配置验证通过！")
        print("\n下一步：")
        print("  python3 scripts/fetch_papers.py")
    else:
        print("⚠️  配置验证未完全通过，请检查上述警告。")
        print("\n必需配置：")
        print("  - api.api_key: 你的LLM API Key")
        print("\n可选配置：")
        print("  - feishu.target: 你的飞书用户ID")
    
    return all_valid

if __name__ == '__main__':
    success = validate_config()
    sys.exit(0 if success else 1)

path: scripts/verify_install.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
安装验证脚本
检查环境、依赖、配置
"""

import sys
import subprocess
from pathlib import Path

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent

def check_python_version():
    """检查Python版本"""
    print("检查Python版本...")
    version = sys.version_info
    
    if version.major < 3 or (version.major == 3 and version.minor < 8):
        print(f"  ❌ Python版本过低: {version.major}.{version.minor}")
        print(f"  需要Python 3.8+")
        return False
    
    print(f"  ✅ Python版本: {version.major}.{version.minor}.{version.micro}")
    return True

def check_dependencies():
    """检查依赖库"""
    print("\n检查依赖库...")
    
    required = ['feedparser', 'requests', 'yaml']
    all_installed = True
    
    for dep in required:
        try:
            __import__(dep)
            print(f"  ✅ {dep} 已安装")
        except ImportError:
            print(f"  ❌ {dep} 未安装")
            all_installed = False
    
    if not all_installed:
        print("\n  运行以下命令安装依赖：")
        print("  pip install feedparser requests pyyaml")
    
    return all_installed

def check_config_file():
    """检查配置文件"""
    print("\n检查配置文件...")
    
    config_file = PROJECT_ROOT / 'config.yaml'
    example_file = PROJECT_ROOT / 'config.yaml.example'
    
    if config_file.exists():
        print(f"  ✅ config.yaml 存在")
        return True
    else:
        if example_file.exists():
            print(f"  ⚠️  config.yaml 不存在")
            print(f"  请复制 config.yaml.example 并修改：")
            print(f"  cp config.yaml.example config.yaml")
        else:
            print(f"  ❌ config.yaml.example 不存在")
        return False

def check_api_key():
    """检查API Key配置"""
    print("\n检查API Key配置...")
    
    try:
        import yaml
        config_file = PROJECT_ROOT / 'config.yaml'
        
        if not config_file.exists():
            print(f"  ⚠️  配置文件不存在")
            return False
        
        with open(config_file, 'r', encoding='utf-8') as f:
            config = yaml.safe_load(f)
        
        [REDACTED_SECRET]'api', {}).get('api_key', '')
        
        if api_key == 'YOUR_API_KEY_HERE' or not [REDACTED_SECRET]"  ⚠️  API Key未配置")
            print(f"  请在config.yaml中设置api_key")
            return False
        else:
            # 检查API Key格式（简单验证）
            if len(api_key) < 10:
                print(f"  ⚠️  API Key格式可能不正确")
                return False
            print(f"  ✅ API Key已配置")
            return True
    
    except Exception as e:
        print(f"  ❌ 配置读取失败: {e}")
        return False

def check_network():
    """检查网络连接"""
    print("\n检查网络连接...")
    
    try:
        import requests
        response = requests.get('https://www.google.com', timeout=5)
        if response.status_code == 200:
            print(f"  ✅ 网络连接正常")
            return True
    except:
        pass
    
    try:
        import requests
        response = requests.get('https://www.baidu.com', timeout=5)
        if response.status_code == 200:
            print(f"  ✅ 网络连接正常（国内）")
            return True
    except:
        print(f"  ❌ 网络连接失败")
        print(f"  请检查网络设置")
        return False
    
    return False

def main():
    """主函数"""
    print("=" * 50)
    print("literature-report 安装验证")
    print("=" * 50)
    
    results = {
        'Python版本': check_python_version(),
        '依赖库': check_dependencies(),
        '配置文件': check_config_file(),
        'API Key': check_api_key(),
        '网络连接': check_network(),
    }
    
    print("\n" + "=" * 50)
    print("验证结果：")
    print("=" * 50)
    
    all_passed = True
    for item, result in results.items():
        status = "✅" if result else "❌"
        print(f"{status} {item}")
        if not result:
            all_passed = False
    
    print("=" * 50)
    
    if all_passed:
        print("\n🎉 所有检查通过！系统已准备就绪。")
        print("\n下一步：")
        print("  python3 scripts/fetch_papers.py")
    else:
        print("\n⚠️  部分检查未通过，请按上述提示修复。")
    
    return all_passed

if __name__ == '__main__':
    success = main()
    sys.exit(0 if success else 1)

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)