Metadata-Version: 2.4
Name: paper-talent
Version: 0.1.2
Summary: 从学术论文中发现企业人才,自动搜索脉脉并加入招聘项目
Author-email: Chandler <275737875@qq.com>
License-Expression: MIT
Keywords: arxiv,recruitment,maimai,talent,AI
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: arxiv>=2.0.0
Requires-Dist: llmdog
Requires-Dist: maimai-cat
Requires-Dist: PyMuPDF
Requires-Dist: requests
Requires-Dist: typer
Requires-Dist: rich
Requires-Dist: schedule
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: mypy; extra == "dev"

# Paper Talent - 学术论文人才发现系统

> 从学术论文中发现企业人才，自动搜索脉脉并加入招聘项目

## 项目概述

**Paper Talent** 是一个智能化的技术人才招聘辅助工具，通过自动化流程从学术论文平台（arxiv）中发现潜在的优秀技术人才。

### 核心功能

1. **论文搜索**：基于关键词在 arxiv 上搜索相关学术论文
2. **智能识别**：使用 LLM（大语言模型）识别论文中的企业作者
3. **人才搜索**：在脉脉平台搜索并验证候选人身份
4. **自动入库**：将符合条件的技术人才自动加入招聘项目
5. **定时执行**：支持每日定时任务，持续发现新人才

### 应用场景

- **技术招聘**：从前沿论文中发现活跃在企业界的研究人员
- **人才储备**：构建特定技术领域的人才库
- **竞对分析**：了解竞争对手在哪些技术领域有研究布局
- **引用挖掘**：通过论文引用关系发现更多相关人才

---

## 设计思路

### 核心设计理念

Paper Talent 采用 **"论文→作者→人才"** 的三步发现模型：

```
学术论文 (arxiv)
    ↓ 提取第一页内容
企业作者 (LLM 识别)
    ↓ 多策略搜索
脉脉候选人 (验证评估)
    ↓ 符合条件
招聘项目 (自动入库)
```

### 1. arxiv 论文搜索策略

系统采用**多策略搜索**确保全面性：

- **全字段搜索**：在标题、摘要、作者中搜索关键词
- **标题搜索**：仅搜索标题中包含关键词的论文（更精准）
- **摘要搜索**：仅搜索摘要中包含关键词的论文（更广泛）
- **去重机制**：通过 arxiv ID 自动去重，避免重复处理

### 2. LLM 企业作者识别

使用大语言模型从论文第一页文本中智能识别企业作者：

**识别流程：**
1. 使用 PyMuPDF 提取论文第一页文本（包含作者、单位、邮箱）
2. 构造 Prompt 发送给 LLM，要求识别在企业工作的作者
3. LLM 返回结构化数据：作者姓名、邮箱、企业全称、企业简称
4. 解析 LLM 输出，生成 `EnterpriseAuthor` 对象

**优势：**
- 无需维护企业列表，LLM 自动识别
- 支持各种企业表述形式（公司、研究院、实验室等）
- 可同时提取企业全称和简称，便于后续搜索

### 3. 脉脉候选人搜索与验证

采用**多策略搜索 + LLM 验证**的双重保障机制：

**搜索策略（按优先级）：**
1. 名字 + 公司全称（最精准）
2. 名字 + 公司简称（较精准）
3. 仅名字搜索（兜底策略）

**验证流程：**
1. **公司验证**：使用 LLM 验证候选人当前/历史公司是否与论文作者公司匹配
2. **技术人员判断**：使用 LLM 判断候选人是否为技术人员（研发、算法、工程等）
3. **置信度评分**：综合公司和职位信息给出匹配置信度（0-1）
4. **阈值过滤**：只保留置信度高于设定阈值的候选人

### 4. 三个核心场景

#### 场景 1：关键词搜索

```
用户输入关键词 → arxiv 搜索 → 领域判断 → 下载 PDF → 识别企业作者 → 脉脉搜索 → 加入项目
```

**适用场景：** 快速搜索某个技术领域的人才

#### 场景 2：引用论文挖掘

```
本地已有论文 → 提取引用 → 搜索引用论文 → 领域判断 → 识别企业作者 → 脉脉搜索 → 加入项目
```

**适用场景：** 从已有论文的引用关系中发现更多相关人才

#### 场景 3：每日定时执行

```
定时触发 → 搜索最新论文（按提交日期排序） → 查重 → 执行场景 1 → 执行场景 2
```

**适用场景：** 持续监控某个技术领域，自动发现新人才

---

## 架构说明

### 项目目录结构

```
paper-talent/
├── paper_talent/                 # Python 包
│   ├── __init__.py              # 包初始化（版本信息）
│   ├── config.py                # 配置管理模块
│   ├── paper_search.py          # arxiv 论文搜索模块
│   ├── author_identify.py       # 企业作者识别模块
│   ├── maimai_search.py         # 脉脉搜索与评估模块
│   ├── pipeline.py              # 场景流程编排模块
│   └── cli.py                   # 命令行接口模块
├── papers/                      # 论文存储目录（自动生成）
│   ├── pdf/                     # PDF 文件
│   └── *.json                   # 论文元数据
├── results/                     # 结果存储目录（自动生成）
│   ├── *.json                   # 作者识别结果
│   └── maimai/                  # 脉脉搜索结果
├── pyproject.toml               # 项目配置与依赖
├── requirements.txt             # 依赖清单
└── README.md                    # 项目文档
```

### 核心模块职责

#### 1. `config.py` - 配置管理

**功能：**
- 定义 `Settings` 数据类，集中管理所有配置项
- 支持从环境变量加载配置
- 自动创建必要的目录

**核心配置项：**
- `papers_dir`: 论文存储根目录
- `results_dir`: 识别结果存储目录
- `maimai_project_name`: 脉脉项目名称
- `maimai_cookies_file`: 脉脉 cookies 文件路径
- `domain_keywords`: 论文领域关键词列表
- `confidence_threshold`: 置信度阈值
- `max_search_results`: arxiv 最大搜索结果数
- `max_citation_papers`: 引用论文最大处理数
- `schedule_time`: 定时任务执行时间

**使用方式：**
```python
from paper_talent.config import Settings

# 从环境变量加载
settings = Settings.from_env()

# 或直接实例化
settings = Settings(
    papers_dir=Path("papers"),
    maimai_project_name="Agent人才",
    confidence_threshold=0.7,
)
```

#### 2. `paper_search.py` - 论文搜索模块

**功能：**
- arxiv 论文搜索（多策略）
- PDF 下载与管理
- 论文第一页文本提取
- LLM 领域判断
- 引用论文提取
- 论文持久化（JSON 存储）

**核心函数：**
- `search_papers()`: 多策略搜索 arxiv 论文
- `download_paper_pdf()`: 下载 PDF 到本地
- `extract_first_page_text()`: 提取第一页文本（PyMuPDF）
- `is_target_domain_paper()`: LLM 判断是否属于目标领域
- `extract_citations_from_pdf()`: LLM 提取引用论文列表
- `search_paper_by_title()`: 按标题搜索论文
- `save_paper_info()` / `load_paper_info()`: 论文信息序列化
- `load_all_papers()`: 加载本地所有论文
- `check_paper_exists()`: 检查论文是否已存在

**数据流：**
```
用户关键词 → arxiv API → PaperInfo 对象 → 下载 PDF → 提取文本 → LLM 判断 → 保存 JSON
```

#### 3. `author_identify.py` - 企业作者识别

**功能：**
- 使用 LLM 从论文第一页识别企业作者
- 提取作者姓名、邮箱、企业全称/简称
- 识别结果持久化

**核心函数：**
- `identify_enterprise_authors()`: LLM 识别企业作者
- `save_identification_result()`: 保存识别结果
- `load_identification_results()`: 加载识别结果

**LLM Prompt 设计：**
```
请从以下论文第一页内容中，识别出在企业或公司工作的作者。
要求：
1. 只识别明确标注了企业/公司/研究院 affiliation 的作者
2. 排除纯高校/大学的作者
3. 返回 JSON 格式：[{name, email, company_full, company_short}]
```

#### 4. `maimai_search.py` - 脉脉搜索与评估

**功能：**
- 多策略脉脉搜索
- LLM 公司验证
- LLM 技术人员判断
- 加入脉脉项目
- 搜索结果持久化

**核心函数：**
- `search_person_on_maimai()`: 多策略搜索候选人
- `verify_candidate_company()`: LLM 验证公司匹配度
- `judge_tech_person()`: LLM 判断是否为技术人员
- `add_to_maimai_project()`: 加入脉脉项目
- `search_and_evaluate_author()`: 完整搜索评估流程
- `save_maimai_results()`: 保存脉脉结果

**搜索策略实现：**
```python
# 策略 1: 名字 + 公司全称
search = Search()
results = search.search_by_keyword(f"{author.name} {author.company_full}")

# 策略 2: 名字 + 公司简称（策略 1 无结果时）
results = search.search_by_keyword(f"{author.name} {author.company_short}")

# 策略 3: 仅名字（前两者无结果时）
results = search.search_by_keyword(author.name)
```

#### 5. `pipeline.py` - 场景流程编排

**功能：**
- 实现三个核心场景的完整流程
- 进度条显示（Rich）
- 结果统计与汇总
- 定时任务调度（schedule 库）

**核心函数：**
- `run_scenario1()`: 场景 1（关键词搜索）
- `run_scenario2()`: 场景 2（引用论文挖掘）
- `run_scenario3()`: 场景 3（每日定时执行）
- `start_scheduled_task()`: 启动定时任务
- `_print_result_summary()`: 打印结果汇总

**数据流（场景 1）：**
```
query → search_papers() → [PaperInfo]
    ↓ for each paper
is_target_domain_paper() → 领域判断
    ↓ if True
download_paper_pdf() → PDF 下载
extract_first_page_text() → 文本提取
identify_enterprise_authors() → [EnterpriseAuthor]
    ↓ for each author
search_and_evaluate_author() → [MaimaiCandidate]
    ↓ for each candidate
add_to_maimai_project() → 加入项目
```

#### 6. `cli.py` - 命令行接口

**功能：**
- 基于 Typer 构建现代化 CLI
- 四个命令：search、citations、daily、run-now
- Rich 控制台输出
- 参数验证与默认值

**命令列表：**
- `paper init`: 初始化项目配置
- `paper search`: 场景 1
- `paper citations`: 场景 2
- `paper daily`: 场景 3（定时）
- `paper run-now`: 场景 3（立即执行）
- `paper process-pdf-folder`: 处理本地 PDF 文件夹

### 模块交互关系

```
cli.py (用户入口)
    ↓ 调用
pipeline.py (流程编排)
    ↓ 协调
┌──────────────────┬──────────────────┬──────────────────┐
│ paper_search.py  │author_identify.py│ maimai_search.py │
│ (论文搜索)       │ (作者识别)       │ (脉脉搜索)       │
└──────────────────┴──────────────────┴──────────────────┘
    ↓ 使用              ↓ 使用              ↓ 使用
┌──────────────────┬──────────────────┬──────────────────┐
│ arxiv API        │ llmdog (LLM)     │ maimai-cat API   │
│ PyMuPDF          │                  │                  │
└──────────────────┴──────────────────┴──────────────────┘
    ↓ 数据存储          ↓ 数据存储          ↓ 数据存储
┌──────────────────────────────────────────────────────┐
│ config.py (配置管理) + JSON 文件持久化               │
└──────────────────────────────────────────────────────┘
```

---

## 快速开始

### 环境要求

- **Python 版本**：≥ 3.9（推荐 3.10+）
- **操作系统**：macOS / Linux / Windows
- **系统依赖**：无特殊要求
- **LLM API**：需要配置 llmdog（大语言模型接口）
- **脉脉账号**：需要有效的脉脉 cookies

### 安装步骤

#### 1. 克隆项目

```bash
git clone <your-repo-url>
cd paper-talent
```

#### 2. 创建虚拟环境

```bash
# macOS / Linux
python -m venv venv
source venv/bin/activate

# Windows
python -m venv venv
venv\Scripts\activate
```

#### 3. 安装依赖

```bash
# 升级 pip
pip install --upgrade pip

# 安装项目依赖
pip install -e .
```

#### 4. 验证安装

```bash
# 查看帮助
paper --help

# 查看版本
python -c "import paper_talent; print(paper_talent.__version__)"
```

### 配置说明

#### 方式 1：命令行参数（推荐新手）

直接在命令中指定所有参数：

```bash
paper search "agent" \
  --project "Agent人才" \
  --max-results 50 \
  --threshold 0.6 \
  --papers-dir papers \
  --results-dir results \
  --cookies cookies.json
```

#### 方式 2：环境变量

```bash
# 脉脉配置
export MAIMAI_PROJECT_NAME="Agent人才"
export MAIMAI_COOKIES_FILE="cookies.json"

# 论文配置
export PAPERS_DIR="papers"
export RESULTS_DIR="results"
export MAX_SEARCH_RESULTS=50
export CONFIDENCE_THRESHOLD=0.6

# LLM 配置（根据 llmdog 要求）
export LLMDOG_API_KEY="your-api-key"
export LLMDOG_BASE_URL="https://your-llm-api.com"
```

然后运行：

```bash
paper search "agent" --project "Agent人才"
```

#### 方式 3：配置文件

创建 `.env` 文件：

```bash
# .env
MAIMAI_PROJECT_NAME="Agent人才"
MAIMAI_COOKIES_FILE="cookies.json"
PAPERS_DIR="papers"
RESULTS_DIR="results"
MAX_SEARCH_RESULTS=50
CONFIDENCE_THRESHOLD=0.6
```

### 获取脉脉 Cookies

1. 登录脉脉网页版（https://maimai.cn）
2. 打开浏览器开发者工具（F12）
3. 进入 Application/存储 → Cookies
4. 复制所有 cookies 并保存为 `cookies.json` 文件

**cookies.json 格式示例：**
```json
{
  "name": "your-cookie-name",
  "value": "your-cookie-value",
  "domain": ".maimai.cn"
}
```

### 使用示例

#### 示例 1：搜索 Agent 领域人才

```bash
# 基本用法
paper search "agent" --project "Agent人才"

# 指定搜索数量和阈值
paper search "LLM agent" --project "Agent人才" --max-results 30 --threshold 0.7

# 自定义目录
paper search "multi-agent" \
  --project "Agent人才" \
  --papers-dir my_papers \
  --results-dir my_results
```

#### 示例 2：挖掘引用论文人才

```bash
# 先运行一次搜索，建立本地论文库
paper search "agent" --project "Agent人才" --max-results 20

# 然后挖掘这些论文的引用
paper citations --project "Agent人才" --max-citations 30
```

#### 示例 3：每日定时执行

```bash
# 每天 9:00 自动执行
paper daily "agent" --project "Agent人才" --time "09:00"

# 立即执行一次（不启动定时）
paper run-now "agent" --project "Agent人才"
```

#### 示例 4：查看帮助

```bash
# 查看所有命令
paper --help

# 查看具体命令帮助
paper search --help
paper citations --help
paper daily --help
paper run-now --help
```

---

## 扩展指南

### 1. 添加新的搜索策略

#### 在 paper_search.py 中添加 arxiv 搜索策略

```python
def search_papers_by_author(
    author_name: str,
    max_results: int = 50,
) -> list[PaperInfo]:
    """按作者名搜索论文"""
    search = arxiv.Search(
        query=f"au:{author_name}",
        max_results=max_results,
        sort_by=arxiv.SortCriterion.Relevance,
    )
    results = _client.results(search)
    return [_to_paper_info(r) for r in results]
```

#### 在 maimai_search.py 中添加脉脉搜索策略

```python
def search_by_email_on_maimai(
    author: EnterpriseAuthor,
    cookies_file: str = "cookies.json",
) -> list[MaimaiCandidate]:
    """通过邮箱搜索脉脉候选人"""
    # 实现基于邮箱的搜索逻辑
    pass
```

### 2. 集成其他招聘平台

#### 添加新的平台模块（如 LinkedIn）

创建 `linkedin_search.py`：

```python
"""LinkedIn 搜索与评估模块"""

from dataclasses import dataclass
from typing import Optional

@dataclass
class LinkedInCandidate:
    """LinkedIn 候选人信息"""
    profile_url: str
    name: str
    company: str
    position: str
    is_tech_person: bool = False

def search_person_on_linkedin(
    author: EnterpriseAuthor,
    api_key: str,
) -> list[LinkedInCandidate]:
    """在 LinkedIn 上搜索候选人"""
    # 调用 LinkedIn API
    pass

def verify_candidate_on_linkedin(
    candidate: LinkedInCandidate,
    author: EnterpriseAuthor,
) -> float:
    """验证候选人公司匹配度"""
    # LLM 验证逻辑
    pass
```

#### 在 pipeline.py 中集成

```python
from .linkedin_search import search_person_on_linkedin

def run_scenario1_with_linkedin(query: str, settings: Settings):
    # ... 原有逻辑 ...
    
    # 添加 LinkedIn 搜索
    linkedin_candidates = search_person_on_linkedin(author, settings.linkedin_api_key)
    
    # 合并结果
    all_candidates = maimai_candidates + linkedin_candidates
```

### 3. 自定义 LLM 提示词

#### 修改企业作者识别 Prompt

编辑 `author_identify.py` 中的 `identify_enterprise_authors()` 函数：

```python
def identify_enterprise_authors(
    first_page_text: str,
    paper_title: str = "",
    paper_arxiv_id: str = "",
) -> list[EnterpriseAuthor]:
    
    prompt = f"""你是一个专业的学术论文分析助手。

请从以下论文第一页内容中识别企业作者。

**识别标准：**
1. 作者单位包含：公司、企业、研究院、实验室等
2. 排除纯高校/大学作者
3. 如果作者同时在高校和企业任职，只保留企业身份

**输出格式：**
```json
[
  {{
    "name": "作者姓名",
    "email": "邮箱",
    "company_full": "企业全称",
    "company_short": "企业简称"
  }}
]
```

论文标题：{paper_title}
论文第一页内容：
{first_page_text}
"""
    # ... 后续逻辑 ...
```

#### 修改领域判断 Prompt

编辑 `paper_search.py` 中的 `is_target_domain_paper()` 函数：

```python
def is_target_domain_paper(
    paper: PaperInfo,
    domain_keywords: list[str] = None,
) -> bool:
    prompt = f"""请判断以下论文是否属于目标研究领域。

**目标领域关键词：**
{', '.join(domain_keywords or [])}

**判断标准：**
1. 论文主题与关键词直接相关
2. 论文方法可应用于该领域
3. 宁可漏判，不可误判（保守策略）

**输出：** 只回答 "是" 或 "否"

论文标题：{paper.title}
论文摘要：{paper.abstract}
"""
    # ... 后续逻辑 ...
```

### 4. 模块化设计的优势与扩展点

#### 优势

1. **职责分离**：每个模块独立负责一个功能域
2. **易于测试**：模块间通过明确的数据结构交互
3. **可替换性**：可轻松替换某个模块（如更换 LLM 提供商）
4. **可扩展性**：新功能只需添加新模块或扩展现有模块

#### 扩展点

| 模块 | 扩展方向 | 示例 |
|------|---------|------|
| `config.py` | 添加新配置项 | 新平台 API Key、新阈值参数 |
| `paper_search.py` | 新论文源 | Google Scholar、Semantic Scholar |
| `author_identify.py` | 新识别策略 | 基于规则的企业作者识别 |
| `maimai_search.py` | 新招聘平台 | LinkedIn、Boss 直聘、拉勾 |
| `pipeline.py` | 新场景 | 批量导入论文、人才去重 |
| `cli.py` | 新命令 | 查看统计、导出报告 |

#### 扩展示例：添加 Google Scholar 支持

```python
# 创建 google_scholar_search.py
from scholarly import scholarly

def search_scholar_papers(query: str) -> list[PaperInfo]:
    """搜索 Google Scholar"""
    search_results = scholarly.search_pubs(query)
    return [_scholar_to_paper_info(r) for r in search_results]
```

```python
# 在 pipeline.py 中使用
from .paper_search import search_papers
from .google_scholar_search import search_scholar_papers

def run_scenario1_multi_source(query: str, settings: Settings):
    # 从多个来源搜索
    arxiv_papers = search_papers(query)
    scholar_papers = search_scholar_papers(query)
    
    # 合并并去重
    all_papers = merge_and_deduplicate(arxiv_papers, scholar_papers)
    
    # 继续后续流程...
```

---

## 命令行使用说明

### 全局选项

```bash
paper [OPTIONS] COMMAND [ARGS]...
```

### 命令 1：search（场景 1）

在 arxiv 搜索论文，识别企业作者，搜索脉脉并加入项目。

```bash
paper search QUERY [OPTIONS]
```

**参数：**

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `QUERY` | str | ✅ | - | 搜索关键词（如 "agent"） |
| `--project`, `-p` | str | ❌ | "" | 脉脉项目名称 |
| `--max-results`, `-n` | int | ❌ | 50 | 最大搜索结果数 |
| `--threshold`, `-t` | float | ❌ | 0.6 | 置信度阈值（0-1） |
| `--papers-dir` | str | ❌ | "papers" | 论文存储目录 |
| `--results-dir` | str | ❌ | "results" | 结果存储目录 |
| `--cookies` | str | ❌ | "cookies.json" | 脉脉 cookies 文件路径 |

**示例：**

```bash
# 基本搜索
paper search "agent" --project "Agent人才"

# 精确搜索（高阈值）
paper search "LLM agent" -p "Agent人才" -t 0.8

# 限制结果数
paper search "multi-agent" -p "Agent人才" -n 20

# 完整参数
paper search "autonomous agent" \
  -p "Agent人才" \
  -n 30 \
  -t 0.7 \
  --papers-dir my_papers \
  --results-dir my_results \
  --cookies my_cookies.json
```

### 命令 2：citations（场景 2）

读取本地论文，提取引用论文，搜索并处理。

```bash
paper citations [OPTIONS]
```

**参数：**

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `--project`, `-p` | str | ❌ | "" | 脉脉项目名称 |
| `--max-citations`, `-n` | int | ❌ | 50 | 最大处理引用论文数 |
| `--threshold`, `-t` | float | ❌ | 0.6 | 置信度阈值 |
| `--papers-dir` | str | ❌ | "papers" | 论文存储目录 |
| `--results-dir` | str | ❌ | "results" | 结果存储目录 |
| `--cookies` | str | ❌ | "cookies.json" | 脉脉 cookies 文件路径 |

**示例：**

```bash
# 处理所有引用
paper citations --project "Agent人才"

# 限制处理数量
paper citations -p "Agent人才" -n 20

# 高阈值过滤
paper citations -p "Agent人才" -n 30 -t 0.75
```

**前置条件：**
- 必须先运行 `paper search` 建立本地论文库
- 本地 `papers/` 目录下需要有已下载的论文

### 命令 3：daily（场景 3 - 定时）

每日定时执行，搜索新论文，查重后执行场景 1 和场景 2。

```bash
paper daily QUERY [OPTIONS]
```

**参数：**

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `QUERY` | str | ✅ | - | 搜索关键词 |
| `--project`, `-p` | str | ❌ | "" | 脉脉项目名称 |
| `--time` | str | ❌ | "09:00" | 定时执行时间（HH:MM） |
| `--threshold`, `-t` | float | ❌ | 0.6 | 置信度阈值 |
| `--papers-dir` | str | ❌ | "papers" | 论文存储目录 |
| `--results-dir` | str | ❌ | "results" | 结果存储目录 |
| `--cookies` | str | ❌ | "cookies.json" | 脉脉 cookies 文件路径 |

**示例：**

```bash
# 每天 9:00 执行
paper daily "agent" --project "Agent人才" --time "09:00"

# 每天凌晨 2:00 执行
paper daily "LLM agent" -p "Agent人才" --time "02:00"

# 使用默认时间（09:00）
paper daily "multi-agent" -p "Agent人才"
```

**注意事项：**
- 程序会持续运行，直到按 `Ctrl+C` 停止
- 建议使用 `nohup` 或 `tmux` 后台运行
- 示例：`nohup paper daily "agent" -p "Agent人才" &`

### 命令 4：run-now（场景 3 - 立即）

立即执行一次场景 3（不启动定时任务）。

```bash
paper run-now QUERY [OPTIONS]
```

**参数：**

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `QUERY` | str | ✅ | - | 搜索关键词 |
| `--project`, `-p` | str | ❌ | "" | 脉脉项目名称 |
| `--threshold`, `-t` | float | ❌ | 0.6 | 置信度阈值 |
| `--papers-dir` | str | ❌ | "papers" | 论文存储目录 |
| `--results-dir` | str | ❌ | "results" | 结果存储目录 |
| `--cookies` | str | ❌ | "cookies.json" | 脉脉 cookies 文件路径 |

**示例：**

```bash
# 立即执行一次
paper run-now "agent" --project "Agent人才"

# 立即执行（高阈值）
paper run-now "LLM agent" -p "Agent人才" -t 0.75
```

**与 `daily` 的区别：**
- `daily`: 启动定时任务，持续运行，每天定时执行
- `run-now`: 立即执行一次，执行完毕后退出

### 命令 5：init（初始化）

初始化项目配置，创建目录结构和示例 cookies.json 文件。

```bash
paper init [OPTIONS]
```

**参数：**

| 参数 | 简写 | 默认值 | 说明 |
|------|------|--------|------|
| `--force`, `-f` | - | `False` | 强制覆盖现有配置文件 |
| `--papers-dir` | - | `"papers"` | 论文存储目录 |
| `--results-dir` | - | `"results"` | 结果存储目录 |

**示例：**

```bash
# 基本初始化
paper init

# 强制覆盖
paper init --force

# 自定义目录
paper init --papers-dir ./my-papers --results-dir ./my-results
```

**初始化内容：**
1. 创建目录结构：`papers/pdf/`, `results/identify/`, `results/maimai/`
2. 生成 `cookies.json` 示例文件（包含配置指引）
3. 提供获取脉脉 cookies 的详细步骤

**自动检测机制：**
运行其他命令时自动检查 cookies 文件状态：
- ❌ 文件不存在 → 提示运行 `paper init`
- ❌ 文件为空 → 提示填写数据
- ❌ 仍为示例格式 → 提示替换为真实 cookies
- ❌ 格式错误 → 提示修正 JSON

### 命令 6：process-pdf-folder（处理本地 PDF）

批量处理本地 PDF 文件夹，对每个 PDF 执行企业作者识别和脉脉搜索。

```bash
paper process-pdf-folder PDF_FOLDER_PATH [OPTIONS]
```

**参数：**

| 参数 | 简写 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `PDF_FOLDER_PATH` | - | ✅ | - | 包含 PDF 文件的文件夹路径 |
| `--project`, `-p` | - | ❌ | `""` | 脉脉项目名称 |
| `--threshold`, `-t` | - | ❌ | `0.6` | 置信度阈值（0.0-1.0） |
| `--papers-dir` | - | ❌ | `"papers"` | 论文存储目录 |
| `--results-dir` | - | ❌ | `"results"` | 结果存储目录 |
| `--cookies` | - | ❌ | `"cookies.json"` | 脉脉 cookies 文件路径 |

**示例：**

```bash
# 基本用法
paper process-pdf-folder ./papers/pdf --project "Agent人才"

# 设置置信度阈值
paper process-pdf-folder ./pdfs -p "Agent人才" -t 0.7

# 完整参数
paper process-pdf-folder ./my-pdfs \
  --project "AI Talent" \
  --threshold 0.8 \
  --papers-dir ./my-papers \
  --results-dir ./my-results \
  --cookies ./my-cookies.json
```

**处理流程：**
1. 提取 PDF 第一页文本（性能优化：仅读取第一页）
2. 识别企业作者（LLM 智能分析）
3. 脉脉搜索与评估（多策略搜索 + LLM 验证）
4. 加入脉脉项目（如指定了 `--project`）

**与场景 1 的区别：**

| 特性 | 场景 1 (search) | process-pdf-folder |
|------|----------------|---------------------|
| 论文来源 | arxiv 在线搜索 | 本地 PDF 文件夹 |
| 领域判断 | ✅ LLM 判断 | ❌ 跳过（假设都是目标领域） |
| PDF 下载 | ✅ 自动下载 | ❌ 使用本地文件 |
| 企业作者识别 | ✅ | ✅ |
| 脉脉搜索 | ✅ | ✅ |
| 项目添加 | ✅ | ✅ |

**注意事项：**
- 只处理 `.pdf` 扩展名的文件
- 空文件夹会显示警告并退出
- 单个 PDF 处理失败不影响其他文件
- 需要正确配置 LLM API 和脉脉 cookies

---

## 高级功能

### 1. Verbose 详细模式

所有命令支持 `--verbose` 或 `-v` 参数，显示详细的处理过程和中间结果。

**使用示例：**

```bash
# 显示详细的搜索过程
paper search "agent" --project "Agent人才" -v

# 显示详细的引用处理过程
paper citations -p "Agent人才" -v

# 显示详细的 PDF 文件夹处理过程
paper process-pdf-folder ./papers/pdf -p "Agent人才" -v
```

**详细输出内容：**
- 🔍 搜索参数和配置
- 📄 每篇论文的标题和 arxiv_id
- ✔️ 领域判断结果
- 📥 PDF 下载状态
- 🏢 企业作者识别详情（公司全称、简称、邮箱）
- 👥 脉脉搜索结果数量

**使用建议：**
- 生产环境：不使用 `-v` 参数（简洁输出）
- 调试/测试：使用 `-v` 参数（详细输出）
- 只查看最终统计：不使用 `-v`，查看命令末尾的汇总输出

### 2. 性能优化：仅读取 PDF 第一页

系统采用智能优化策略，**仅读取 PDF 第一页**进行作者识别：

**优化原理：**
- 第一页（标题页）包含所有必要信息：作者姓名、邮箱、机构
- 大幅减少 PDF 解析时间（~80% 提升）
- 显著降低 LLM 处理文本量（~90% 减少）
- 降低 API 调用成本，提升处理速度

**技术实现：**
```python
# 仅提取第一页文本
first_page_text = extract_first_page_text(pdf_path)

# 传递给 LLM 识别企业作者
authors = identify_enterprise_authors(first_page_text, paper.title, paper.arxiv_id)
```

### 3. 企业作者识别优化

**识别标准：**
1. ✅ 邮箱域名判断（企业域名 vs 学术域名）
2. ✅ 单位标注识别（公司名称）
3. ✅ 混合单位处理（多个单位中只要有一个是企业）

**排除规则：**
- ❌ 纯学术机构（大学、研究所）
- ❌ 纯实验室/研究中心（除非明确属于企业）
- ❌ 无法确定工作单位的作者

**示例输出：**
```json
[
  {
    "name": "John Smith",
    "email": "john.smith@google.com",
    "company_full": "Google LLC",
    "company_short": "Google"
  },
  {
    "name": "张三",
    "email": "zhangsan@tencent.com",
    "company_full": "腾讯科技(深圳)有限公司",
    "company_short": "腾讯"
  }
]
```

**提高识别率建议：**
1. 使用包含完整作者信息的 PDF
2. 确保论文第一页有邮箱和单位信息
3. 优先选择企业参与的合作论文
4. 检查 LLM API 配置是否正确
5. 使用 `-v` 参数查看识别过程，检查 `results/identify/` 目录下的识别结果

---

## 故障排除

### 1. 安装问题

#### 问题：`pip install` 报错 "Could not find a version that satisfies the requirement"

**原因：** Python 版本过低或 pip 版本过旧

**解决方案：**
```bash
# 检查 Python 版本
python --version  # 需要 ≥ 3.9

# 升级 pip
pip install --upgrade pip

# 如果 Python 版本过低，请升级 Python
# macOS 使用 Homebrew:
brew install python@3.10
```

#### 问题：`PyMuPDF` 安装失败

**原因：** 缺少系统依赖

**解决方案：**
```bash
# macOS
brew install pkg-config

# Ubuntu/Debian
sudo apt-get install python3-dev build-essential

# 然后重新安装
pip install PyMuPDF
```

### 2. LLM 相关问题

#### 问题：`llmdog` 调用失败，报错 "API key not found"

**原因：** 未配置 LLM API 密钥

**解决方案：**
```bash
# 设置环境变量
export LLMDOG_API_KEY="your-api-key"
export LLMDOG_BASE_URL="https://your-llm-api.com"

# 或在使用命令时指定
LLMDOG_API_KEY="your-key" paper search "agent" -p "Agent人才"
```

#### 问题：LLM 返回格式错误，无法解析 JSON

**原因：** LLM 输出格式不稳定

**解决方案：**
1. 在 Prompt 中加强格式要求
2. 使用更强大的模型（如 GPT-4）
3. 添加重试机制：

```python
# 在 author_identify.py 中添加重试
from tenacity import retry, stop_after_attempt

@retry(stop=stop_after_attempt(3))
def identify_enterprise_authors(first_page_text: str, ...):
    # ... 原有逻辑 ...
```

### 3. 脉脉相关问题

#### 问题：脉脉搜索返回空结果

**原因：** Cookies 过期或无效

**解决方案：**
1. 重新登录脉脉网页版
2. 重新获取 cookies 并更新 `cookies.json`
3. 检查 cookies 格式是否正确

#### 问题：加入脉脉项目失败

**原因：** 项目名称不存在或无权限

**解决方案：**
```bash
# 检查项目名称是否正确
# 在脉脉网页版确认项目是否存在
# 确保你有权限向该项目添加候选人
```

#### 问题：脉脉 API 频率限制

**原因：** 短时间内请求过多

**解决方案：**
1. 降低 `--max-results` 参数
2. 在代码中添加延迟：

```python
import time

# 在 maimai_search.py 中添加
time.sleep(2)  # 每次请求间隔 2 秒
```

### 4. 论文搜索问题

#### 问题：arxiv 搜索返回结果过少

**原因：** 关键词过于具体

**解决方案：**
```bash
# 使用更宽泛的关键词
paper search "agent" --project "Agent人才"

# 而不是
paper search "large language model based autonomous agent" --project "Agent人才"
```

#### 问题：PDF 下载失败

**原因：** 网络问题或 arxiv 服务器不可用

**解决方案：**
```bash
# 检查网络连接
ping export.arxiv.org

# 稍后重试，或手动下载 PDF 到 papers/pdf/ 目录
```

### 5. 运行问题

#### 问题：定时任务意外停止

**原因：** 终端关闭或进程被杀死

**解决方案：**
```bash
# 使用 nohup 后台运行
nohup paper daily "agent" -p "Agent人才" --time "09:00" > daily.log 2>&1 &

# 或使用 tmux
tmux new -s paper-talent
paper daily "agent" -p "Agent人才" --time "09:00"
# 按 Ctrl+B 然后按 D 退出 tmux（程序继续运行）
```

#### 问题：程序运行缓慢

**原因：** 处理论文数量过多或 LLM 响应慢

**解决方案：**
```bash
# 减少处理数量
paper search "agent" -p "Agent人才" -n 20  # 而不是默认的 50

# 降低引用论文处理数量
paper citations -p "Agent人才" -n 20  # 而不是默认的 50
```

### 6. 数据问题

#### 问题：重复处理同一篇论文

**原因：** 论文 ID 判断逻辑有问题

**解决方案：**
```bash
# 清理重复数据
rm -rf papers/ results/

# 重新开始
paper search "agent" -p "Agent人才"
```

#### 问题：识别结果为空

**原因：** 论文作者都是高校研究人员

**解决方案：**
- 这是正常现象，不是所有论文都有企业作者
- 尝试搜索更偏应用的领域（如 "LLM application"）

---

## 依赖项清单

### 核心依赖

| 依赖 | 版本 | 用途 |
|------|------|------|
| `arxiv` | ≥ 2.0.0 | arxiv 论文搜索与元数据获取 |
| `llmdog` | latest | 大语言模型接口调用 |
| `maimai-cat` | latest | 脉脉平台 API 封装 |
| `PyMuPDF` | latest | PDF 文本提取 |
| `requests` | latest | HTTP 请求（下载 PDF） |
| `typer` | latest | 命令行框架 |
| `rich` | latest | 终端美化和进度条 |
| `schedule` | latest | 定时任务调度 |

### 开发依赖（可选）

| 依赖 | 用途 |
|------|------|
| `pytest` | 单元测试 |
| `pytest-cov` | 测试覆盖率 |
| `black` | 代码格式化 |
| `flake8` | 代码风格检查 |
| `mypy` | 类型检查 |

安装开发依赖：
```bash
pip install -e ".[dev]"
```

---

## 贡献指南

### 开发环境搭建

```bash
# 1. Fork 并克隆项目
git clone <your-fork-url>
cd paper-talent

# 2. 创建虚拟环境
python -m venv venv
source venv/bin/activate

# 3. 安装开发依赖
pip install -e ".[dev]"

# 4. 运行测试
pytest

# 5. 代码格式化
black paper_talent/

# 6. 类型检查
mypy paper_talent/
```

### 提交 PR

1. 创建特性分支：`git checkout -b feature/amazing-feature`
2. 提交更改：`git commit -m 'Add amazing feature'`
3. 推送分支：`git push origin feature/amazing-feature`
4. 在 GitHub 上提交 Pull Request

### 代码规范

- 遵循 PEP 8 风格指南
- 使用 Black 格式化代码
- 添加类型注解
- 编写单元测试
- 更新文档

---

## 许可证

本项目采用 **MIT License** 开源协议。

详见 [LICENSE](LICENSE) 文件。


---

## 更新日志

### v0.1.0 (2026)

- ✨ 初始版本发布
- ✨ 支持 arxiv 论文搜索
- ✨ LLM 企业作者识别
- ✨ 脉脉候选人搜索与验证
- ✨ 三个核心场景（关键词搜索、引用挖掘、定时执行）
- ✨ 命令行接口（Typer + Rich）

### v0.2.0 (2026-05-28)

- ✨ 添加 `init` 命令用于项目初始化
- ✨ 添加 `process-pdf-folder` 命令处理本地 PDF
- ✨ 所有命令支持 `--verbose/-v` 详细模式
- ✨ 优化企业作者识别 LLM 提示词
- ✨ 添加 cookies 文件自动检测机制
- ⚡ 性能优化：仅读取 PDF 第一页内容（处理速度提升 ~80%）
- 🐛 修复数据验证逻辑
- 📝 完善文档和使用说明

---

## 免责声明

**重要提示：在使用本软件之前，请仔细阅读以下声明。**

### 1. 使用风险

本软件（Paper Talent）按“现状”提供，不提供任何形式的明示或暗示的保证。使用本软件的风险完全由用户自行承担。

### 2. 责任限制

在适用法律允许的最大范围内，本软件的作者和贡献者对因使用或无法使用本软件而导致的任何直接、间接、偶然、特殊或后果性损害不承担任何责任，包括但不限于：

- 数据丢失或损坏
- 利润损失
- 业务中断
- 计算机故障或其他商业损害

即使已被告知可能发生此类损害。

### 3. 合规性要求

用户在使用本软件时，必须遵守所有适用的法律法规，包括但不限于：

- **数据保护法律**：遵守《中华人民共和国个人信息保护法》、《通用数据保护条例》（GDPR）等适用的数据保护法规
- **平台服务条款**：遵守 arxiv、脉脉等第三方平台的服务条款和使用政策
- **隐私权保护**：尊重他人的隐私权，不得非法收集、使用或披露个人信息
- **知识产权**：尊重他人的知识产权，不得侵犯他人的著作权、商标权等

### 4. 第三方服务

本软件可能依赖第三方服务（如 arxiv API、脉脉 API、LLM 服务等）。用户应：

- 自行了解并遵守这些第三方服务的使用条款
- 自行承担使用这些第三方服务的风险
- 理解本软件作者不对第三方服务的可用性、安全性或准确性负责

### 5. Cookies 使用

本软件需要用户使用脉脉平台的 cookies 进行身份验证。用户应：

- 确保获取 cookies 的方式合法合规
- 妥善保管 cookies 文件，防止泄露
- 理解 cookies 可能包含敏感信息，应承担相应的安全责任
- 不得使用本软件进行任何违反脉脉平台规定的行为

### 6. 自动化操作

本软件提供自动化搜索和处理功能。用户应：

- 确保自动化操作符合相关法律法规
- 避免对第三方服务造成过度负担或干扰
- 自行承担因自动化操作导致的任何后果

### 7. 适用范围

本免责声明适用于本软件的所有功能、文档和相关材料。如果本免责声明的任何部分被认定为无效或不可执行，其余部分仍然有效。

### 8. 最终解释

本免责声明的最终解释权归本软件作者所有。软件作者保留随时更新本免责声明的权利。

**通过使用本软件，您表示已阅读、理解并同意接受本免责声明的所有条款。如果您不同意这些条款，请不要使用本软件。**
