Skip to main content

GitHub 人才触达工具:获取 GitHub 信息 → 总结技术方向 → 生成触达邮件 → 发送

Project description

github-reachout

GitHub 人才触达自动化工具 — 从 GitHub 信息采集到个性化邮件发送,全流程 LLM 驱动智能编排。

PyPI Python License


目录


项目简介

github-reachout 是一款面向技术招聘场景的自动化工具,帮助招聘人员高效触达 GitHub 上的技术人才。

核心价值:将原本需要人工逐一完成的「信息采集 → 背景分析 → 邮件撰写 → 校验发送」流程,通过 LLM 驱动的状态图自动编排,实现端到端自动化。

工作流程

GitHub 用户列表
      │
      ▼
┌──────────┐    ┌──────────┐    ┌───────────┐    ┌──────────┐
│  获取     │───▶│  丰富     │───▶│  总结      │───▶│  生成     │
│ GitHub   │    │ 网页信息  │    │ 技术方向   │    │ 触达邮件  │
│ 用户信息  │    │          │    │           │    │          │
└──────────┘    └──────────┘    └───────────┘    └──────────┘
                                                       │
      ┌────────────────────────────────────────────────┘
      ▼
┌──────────┐    ┌──────────┐    ┌───────────┐
│  校验     │───▶│  发送     │───▶│  评估      │──▶ 循环 / 结束
│ 邮件质量  │    │ 邮件     │    │ 是否继续   │
└──────────┘    └──────────┘    └───────────┘

设计哲学

  • 状态驱动:所有数据在 ReachoutState 中单向流动,每个节点只读取和更新自己负责的字段
  • 逐步丰富:从原始 GitHub 数据到最终邮件发送,人员信息在每个步骤中逐步被充实
  • 可中断恢复:基于 Checkpoint 机制,任何步骤中断后均可从断点恢复,不丢失进度

环境配置

所有配置通过项目根目录下的 .env 文件管理。首次使用前,请复制模板并填写:

# ============================================
# github-reachout 环境变量配置
# 复制此文件为 .env 并填写实际值
# ============================================

# ── LLM 配置 ──
# LLM API Key(兼容 OpenAI / DeepSeek )
LLM_API_KEY=
# LLM API Base URL
LLM_BASE_URL=
# LLM 模型名称
LLM_MODEL=
# LLM 请求超时时间(秒)
LLM_TIMEOUT=120
# LLM 最大重试次数
LLM_MAX_RETRIES=3

# ── GitHub 配置 ──
# GitHub Personal Access Token(可选,不填则使用匿名请求,速率限制更严)
GITHUB_TOKEN=

# ── SMTP 邮件配置 ──
# SMTP 服务器地址
SMTP_HOST=smtp.gmail.com
# SMTP 服务器端口
SMTP_PORT=587
# SMTP 登录用户名(通常为邮箱地址)
SMTP_USER=
# SMTP 登录密码/授权码
SMTP_PASSWORD=
# 发件人邮箱地址
SENDER_EMAIL=
# 发件人姓名
SENDER_NAME=

# ── 业务配置 ──
# 我方公司名称
COMPANY_NAME=
# 发件人职位
SENDER_TITLE=
# 目标技术方向
TARGET_TECH=

LLM 配置

变量名 必填 默认值 说明
LLM_API_KEY LLM API 密钥,兼容 OpenAI / DeepSeek
LLM_BASE_URL LLM API 地址,如 https://api.openai.com/v1
LLM_MODEL deepseek-v3.1-terminus-chat 模型名称
LLM_TIMEOUT 120 请求超时时间(秒)
LLM_MAX_RETRIES 3 失败重试次数(指数退避策略)

GitHub 配置

变量名 必填 默认值 说明
GITHUB_TOKEN GitHub Personal Access Token。不填则匿名请求,速率限制为 60 次/小时

SMTP 邮件配置

变量名 必填 默认值 说明
SMTP_HOST smtp.gmail.com SMTP 服务器地址
SMTP_PORT 587 SMTP 端口(465 自动启用 SSL,其他使用 STARTTLS)
SMTP_USER ✅* SMTP 登录用户名(通常为邮箱地址)
SMTP_PASSWORD ✅* SMTP 登录密码或授权码
SENDER_EMAIL SMTP_USER 发件人邮箱地址
SENDER_NAME 发件人显示姓名

* 使用 --dry-run 模式时不需要配置 SMTP 凭据。

业务配置

变量名 必填 默认值 说明
COMPANY_NAME 我方公司名称(用于邮件生成)
SENDER_TITLE 发件人职位
TARGET_TECH 目标技术方向(用于候选人匹配过滤)

CLI 参数优先级高于 .env 配置,两者可同时使用。


快速开始

1. 创建虚拟环境

# 使用 conda 创建 Python 3.10 环境
conda create -n github-reachout python=3.10 -y
conda activate github-reachout

2. 安装项目

# 进入项目目录
cd github-reachout

# 以开发模式安装(支持直接运行 gh-reachout 命令)
pip install -e .

3. 配置环境变量

# 复制环境变量模板
cp .env.example .env

# 编辑 .env,至少填写以下配置:
#   LLM_API_KEY=your-api-key
#   LLM_BASE_URL=https://api.openai.com/v1

4. 运行

# ✅ 试运行(不发送邮件,推荐首次使用时验证配置)
gh-reachout run sak0 -t "AI/ML" -c "MyCompany" -n "Sender" -d

# 正式运行(单人)
gh-reachout run sak0 -t "AI/ML" -c "MyCompany" -n "Sender"

# 正式运行(多人)
gh-reachout run user1 user2 user3 -t "Cloud Native" -c "MyCompany" -n "Sender"

# 输出结果到 JSON 文件
gh-reachout run sak0 -t "AI/ML" -d -o result.json

试运行模式(--dry-run)

添加 -d--dry-run 参数后,流程会完整执行(获取信息、分析、生成邮件),但 不会实际发送邮件,仅打印邮件接收信息。适合:

  • 首次使用时验证 LLM / GitHub 等配置是否正确
  • 预览生成的邮件内容
  • 测试完整流程而不产生副作用

架构设计

LangGraph 状态图

项目基于 LangGraph 构建有向状态图,通过条件路由实现灵活的步骤编排:

                         ┌──────────────────────────────────────────────┐
                         │                                              │
                         ▼                                              │
                     ┌────────┐                                         │
                     │  plan  │ ◀────────────────────────────────────┐  │
                     └───┬────┘                                      │  │
                         │ 条件路由(plan 决定本轮执行哪些步骤)         │  │
                         ▼                                           │  │
                     ┌────────┐                                      │  │
                     │  fetch │  获取 GitHub 用户信息 + 仓库列表       │  │
                     └───┬────┘                                      │  │
                         ▼                                           │  │
                     ┌────────┐                                      │  │
                     │ enrich │  读取 LinkedIn / 博客 / 个人主页       │  │
                     └───┬────┘                                      │  │
                         ▼                                           │  │
                     ┌───────────┐                                   │  │
                     │ summarize │  LLM 总结候选人技术方向              │  │
                     └───┬───────┘                                   │  │
                         ▼                                           │  │
                     ┌──────────┐                                    │  │
                     │ generate │  LLM 生成个性化触达邮件               │  │
                     └───┬──────┘                                    │  │
                         ▼                                           │  │
                     ┌──────────┐                                    │  │
                     │ validate │  校验邮件 + 技术方向匹配              │  │
                     └───┬──────┘                                    │  │
                         ▼                                           │  │
                     ┌────────┐                                      │  │
                     │  send  │  SMTP 发送邮件                        │  │
                     └───┬────┘                                      │  │
                         ▼                                           │  │
                     ┌───────────┐                                   │  │
                     │ evaluate  │  评估处理进度,决定是否继续循环       │  │
                     └─────┬─────┘                                   │  │
                           │                                         │  │
                 ┌─────────┴──────────┐                              │  │
                 │                    │                              │  │
           continue_loop=True    continue_loop=False                 │  │
                 │                    │                              │  │
                 └──── 回到 plan ─────┘         结束 ────────────────┘  │

关键设计

设计要点 说明
依赖注入 build_graph() 通过闭包将 LLM、GitHub、Email 等客户端注入到各节点,便于测试和替换
条件路由 plan 节点决定每轮执行哪些步骤,evaluate 节点决定是否继续循环,支持智能跳过已完成步骤
增量处理 fetch 节点通过 processed_logins 实现增量去重,避免重复请求 GitHub API
循环控制 evaluate 节点根据处理进度和 max_loops 参数决定是否回到 plan 重新规划

模块说明

cli.py — CLI 入口

基于 Typer 构建的命令行界面,提供 5 个子命令:runresumelistshowcleanup。详见 CLI 命令参考 章节。

graph.py — LangGraph 图编排

负责构建和编译 LangGraph 状态图:

  • build_graph(llm, github, web_reader, email_client) — 注册所有节点和条件路由,编译为可执行图
  • create_initial_state(...) — 创建初始 ReachoutState,包含输入参数和空的结果集合

nodes.py — 节点函数

定义图中的 8 个节点和 3 个路由函数:

节点 职责 依赖组件
plan 规划本轮执行步骤(首轮全量,后续由 LLM 根据状态决策) LLM
fetch 获取 GitHub 用户基本信息 + 仓库列表(增量处理,跳过已处理 login) GitHub API
enrich 读取 LinkedIn / 博客 / 个人主页网页内容,丰富候选人信息 Web Reader
summarize LLM 分析并总结候选人技术方向、主要语言、资历级别 LLM
generate LLM 根据候选人背景生成个性化触达邮件(主题 + 正文) LLM
validate 校验邮件可发送性:无占位符 + 技术方向匹配 + 有公开邮箱 LLM + 规则
send 通过 SMTP 发送校验通过的邮件 SMTP
evaluate 评估处理进度,决定是否继续循环

llm.py — LLM 客户端

封装 OpenAI 兼容 API 的轻量客户端:

  • 支持 OpenAI / DeepSeek / Ollama 等任何兼容 OpenAI Chat API 的服务
  • 内置流式请求 + 指数退避重试机制(针对 429 / Timeout)
  • chat() — 返回纯文本响应
  • chat_json() — 自动解析 JSON 响应(支持 markdown 代码块提取)
  • 自动处理 base_url 末尾 /v1 路径,避免与 openai 库重复拼接

github_client.py — GitHub API 客户端

轻量级 GitHub REST API 客户端:

  • get_user(login) — 获取用户基本信息(bio、location、email 等)
  • get_user_repos(login) — 获取公开仓库列表(按 star 数降序,跳过 fork)
  • fetch_person(login) — 一次性获取完整用户信息(基本信息 + 仓库 + LinkedIn 提取)
  • _extract_linkedin(bio, blog) — 从 bio/blog 字段中提取 LinkedIn URL
  • 内置速率控制(请求间隔 0.5s)

email_client.py — 邮件客户端

SMTP 邮件发送与校验:

  • send_email(to, subject, body, html) — 通过 SMTP 发送邮件(支持 SSL / STARTTLS 自动切换)
  • validate_email_ready(email_body, subject, to) — 静态方法,校验邮件是否可直接发送:
    • 无占位符({name}{{company}}[NAME]<<name>> 等多种格式)
    • 收件人邮箱有效
    • 主题和正文非空

web_reader.py — 网页阅读器

轻量级网页内容抓取器:

  • fetch_page(url) — 获取网页并提取纯文本(HTML → Text,正则实现,无外部依赖)
  • read_person_pages(linkedin_url, github_url, blog_url) — 读取一个人的所有相关网页,合并为结构化文本
  • 内置速率控制(请求间隔 1s)
  • 内容截断保护(默认最大 8000 字符)

checkpoint.py — 断点续跑

Checkpoint 持久化模块,详见 断点续跑 章节。

state.py — 状态定义

定义 LangGraph 图中流转的 TypedDict 结构:

  • PersonInfo — 单个 GitHub 用户的完整信息(从基本信息逐步丰富到包含技术方向、邮件等)
  • ReachoutState — 主状态,包含输入参数、规划信息、执行结果、循环控制、错误记录等

CLI 命令参考

gh-reachout run

执行完整的触达流程。

gh-reachout run <login_ids...> [OPTIONS]
参数 短选项 说明 默认值
login_ids GitHub login ID 列表(必填,位置参数)
--target-tech -t 目标技术方向 .envTARGET_TECH
--company -c 我方公司名称 .envCOMPANY_NAME
--sender-name -n 发件人姓名 .envSENDER_NAME
--sender-title 发件人职位 .envSENDER_TITLE
--max-loops -l 最大循环次数 3
--dry-run -d 试运行,不实际发送邮件 False
--output -o 输出结果到 JSON 文件

gh-reachout resume

从断点恢复中断的运行。

gh-reachout resume <run_id> [-d]
参数 说明
run_id 要恢复的运行 ID(必填)
-d, --dry-run 以试运行模式恢复

gh-reachout list

列出所有可恢复的 checkpoint 运行记录。

gh-reachout list

输出示例:

Run ID       技术方向           循环   步骤   人数   已发送
--------------------------------------------------------
bbfdd38e     AI/ML              1      8      1      0
a3f21bc9     Cloud Native       3      24     5      3

gh-reachout show

查看某次运行的完整 state(JSON 格式输出)。

gh-reachout show <run_id>

gh-reachout cleanup

删除某次运行的 checkpoint 数据。

gh-reachout cleanup <run_id>

断点续跑

存储结构

每次运行会自动在本地保存 checkpoint,便于中断恢复和数据查看:

.github_reachout_checkpoints/
└── {run_id}/
    ├── state.json              # 完整 state 快照(始终指向最新状态)
    ├── step_001_plan.json      # 各步骤完成后的增量快照
    ├── step_002_fetch.json
    ├── step_003_enrich.json
    ├── ...
    └── persons/
        ├── all_persons.json    # 所有候选人汇总数据
        ├── sak0.json           # 每个人的独立数据文件
        └── user2.json

自动保存机制

  • 每个步骤完成后自动保存 checkpoint
  • Ctrl+C 中断时自动保存当前状态
  • 发生异常时自动保存错误状态

使用方式

# 1. 查看所有运行记录
gh-reachout list

# 2. 查看某次运行的详情
gh-reachout show <run_id>

# 3. 从断点恢复运行
gh-reachout resume <run_id>

# 4. 清理不再需要的 checkpoint 数据
gh-reachout cleanup <run_id>

项目结构

github-reachout/
├── .env.example              # 环境变量配置模板
├── .gitignore                # Git 忽略规则
├── LICENSE                   # MIT 许可证
├── README.md                 # 项目文档(本文件)
├── pyproject.toml            # 项目打包配置(PyPI 发布用)
├── requirements.txt          # pip 依赖清单
└── github_reachout/          # 核心源码包
    ├── __init__.py           # 包初始化 + 版本号
    ├── __main__.py           # 支持 python -m github_reachout
    ├── checkpoint.py         # 断点续跑持久化
    ├── cli.py                # CLI 入口(Typer)
    ├── email_client.py       # SMTP 邮件客户端
    ├── github_client.py      # GitHub API 客户端
    ├── graph.py              # LangGraph 图编排
    ├── llm.py                # LLM 客户端(OpenAI 兼容)
    ├── nodes.py              # LangGraph 节点函数
    ├── state.py              # 状态类型定义(TypedDict)
    └── web_reader.py         # 网页内容抓取与提取

免责声明

  1. GitHub API 使用条款:使用者应遵守 GitHub 服务条款API 使用政策。建议配置 GITHUB_TOKEN 以提高速率限制(认证请求 5000 次/小时),避免频繁匿名请求。

  2. 邮件发送合规:批量发送邮件前,请确保遵守所在地区的相关法律法规,包括但不限于:

    • 中国《个人信息保护法》
    • 欧盟 GDPR(通用数据保护条例)
    • 美国 CAN-SPAM Act
    • 其他适用地区的反垃圾邮件法律
  3. 隐私保护:本工具获取的 GitHub 用户信息(邮箱、个人主页等)仅应用于合法的技术招聘目的。请勿将数据用于骚扰、垃圾邮件或其他违反隐私法规的用途。

  4. LLM 生成内容:邮件内容由 LLM 自动生成,发送前请务必人工审核,确保内容准确、得体且符合公司规范。

  5. 责任限制:本项目以 "AS IS" 方式提供,作者不对因使用本工具产生的任何直接或间接损失承担责任。


License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

github_reachout-0.1.2.tar.gz (32.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

github_reachout-0.1.2-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file github_reachout-0.1.2.tar.gz.

File metadata

  • Download URL: github_reachout-0.1.2.tar.gz
  • Upload date:
  • Size: 32.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for github_reachout-0.1.2.tar.gz
Algorithm Hash digest
SHA256 1e6e89ec5dc0740efa350dd1adeffdd4da39339aa16145d1eacd067db71a9f44
MD5 ab056aaa042f6f24c32bcf2f5626342f
BLAKE2b-256 bdd463fbfa2d8436b12561d308d8f83c25f38564715dcd3f783f82eed37c610f

See more details on using hashes here.

File details

Details for the file github_reachout-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for github_reachout-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 196f7776da1150f5a2f2e3752944794fa6e98445b9d4e25cf0a3b77e1242602b
MD5 28d3ba121bc22095f9deb278040bc527
BLAKE2b-256 31aa1631093611438c3715df495ce208f5ce5a96f2339ba07261b7a61aaa604b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page