A local-first workspace for graduate recommendation applications
院校通知 · 导师搜集 · 相关度匹配 · 个性化邮件 · 草稿审核 · 申请材料
What it does · Workflow · Quick Start · Email Safety · Roadmap
Auto-Connection 把保研过程中分散在浏览器收藏夹、表格、邮箱和本地文件夹里的工作,整理为一个可追踪的本地工作台。它围绕两条主线构建:项目申请管理与导师套磁管理。
系统可以搜集夏令营与预推免通知、维护统一申请档案、整理导师信息、解释匹配度、生成个性化邮件,并把通过检查的版本写入邮箱草稿箱。所有实际发送都被隔离在独立页面,并要求人工选择和二次确认。
Important
Auto-Connection 默认绑定 127.0.0.1,不应在没有身份认证的情况下暴露到公网。生成邮件只会写入草稿箱;实际发送必须在「发送管理」中明确执行。
| Workspace | Capability | Result |
|---|---|---|
| Today Dashboard | 汇总近期截止、材料完整度、导师漏斗和院校进度 | 知道今天最该推进什么 |
| Opportunity Tracker | 同步公开数据、录入官网通知、保留原文链接和截止日期 | 不再靠零散收藏夹追报名 |
| Application Profile | 维护 GPA、排名、科研、获奖、英语成绩和材料路径 | 重复报名字段只维护一次 |
| Form Filler | 将网页字段映射到个人档案并生成 fill-only 脚本 | 自动填值,但永不自动提交 |
| Professor CRM | 管理院校、院系、主页、邮箱、方向、论文和标签 | 构建可筛选的导师数据库 |
| Fit Matching | 根据申请档案计算 0–100 分并解释共同研究主题 | 快速找到值得优先联系的人 |
| Draft Studio | 模板固定骨架,LLM 只生成命名定制段 | 获得可审查、可编辑的完整邮件 |
| Send Manager | 仅接受已写入草稿箱的版本,按导师防重复发送 | 把真实发送控制在最后一步 |
- Explainable matching: 匹配分不仅给出排序,还展示多模态、Agent、视频理解、RAG、强化学习等共同主题。
- Fine-grained taxonomy: 支持学校、院系、学校组、研究分类、匹配等级、标签和发送状态组合筛选。
- Deterministic email assembly: LLM 不再返回整封邮件,只生成定制段落;称呼、固定经历、签名与字段替换由程序完成。
- Fail-closed validation: 未替换字段、错误称呼、模板标记、思考标签和代码围栏都会阻止草稿写入与发送。
- Mailbox drafts via IMAP: 最终候选正文写入真实邮箱草稿箱,方便在熟悉的邮件客户端继续审核。
- Professor-level deduplication: 即使存在多个历史草稿,也不会对已有
actually_sent记录的导师重复发送。 - Local-first storage: 导师、邮件、报名记录、配置和材料清单默认保存在本机 SQLite 中。
- Responsive interface: 面向高频操作设计的桌面工作台,同时支持移动端查看和筛选。
flowchart LR
A["院校通知<br/>同步 / 官网录入"] --> B["申请档案<br/>个人信息 / 材料"]
B --> C["导师搜集<br/>主页 / 邮箱 / 方向"]
C --> D["相关度匹配<br/>分数 + 原因"]
D --> E["邮件生成<br/>固定模板 + 定制段"]
E --> F["内容验收<br/>称呼 / 字段 / 标记"]
F --> G["邮箱草稿箱<br/>人工逐封审核"]
G --> H["发送管理<br/>选择 + 二次确认"]
H --> I["SMTP 发送<br/>导师级防重复"]
F -. "不合格立即停止" .-> X["返回修改"]
X --> E
| Module | Owns | Does not own |
|---|---|---|
| Application | 通知、截止日期、申请状态、个人档案、材料清单、填表映射 | 邮件发送状态 |
| Outreach | 导师库、匹配度、邮件模板、草稿箱、发送记录 | 夏令营材料要求 |
这两个模块共享申请人档案,但使用独立状态,避免把“报名完成”和“邮件已发送”混为一谈。
邮件不是一次 LLM 调用后直接发出,而是一个有明确状态的审核流程:
| Status | Meaning | Can send? |
|---|---|---|
draft_generated |
本地已有正文,或正文刚被编辑,尚未确认写入邮箱 | No |
draft_box_written |
当前版本已通过检查并成功写入邮箱草稿箱 | Yes, after confirmation |
actually_sent |
SMTP 已成功发送并记录 | No repeat send |
Before IMAP or SMTP is called, the backend checks:
- 收件邮箱真实且不带
邮箱待核验标签。 - 称呼与目标导师一致,主题和正文不为空。
- 所有
{{placeholder}}均已替换。 - 不含
CUSTOM、FIXED、SIGNATURE、<think>或代码围栏等内部语法。 - 该导师不存在任何
actually_sent历史记录。
任何一项失败都会终止操作。模型输出格式错误时不会退化成“勉强可用正文”。
git clone https://github.com/Jackey0903/Auto-Connection.git
cd Auto-Connection
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
npm --prefix frontend install
cp .env.example .env在 .env 中填写本地凭据,或启动后在「系统设置」中配置:
LLM_BASE_URL=https://api.openai.com/v1
LLM_API_KEY=your_api_key
LLM_MODEL=gpt-4o
EMAIL_ADDRESS=your_mailbox@example.com
EMAIL_AUTH_CODE=your_mailbox_auth_code
EMAIL_SUBJECT_TEMPLATE=Graduate application inquiry - {{applicant_name}} - {{university}}
RESUME_PATH=resume.pdf163 邮箱需要使用 SMTP/IMAP 授权码,不是网页登录密码。请先在邮箱设置中开启对应服务。
Production-like local mode:
./start.shOpen http://127.0.0.1:8000.
For frontend hot reload:
./dev.sh| Service | URL |
|---|---|
| Vue development server | http://127.0.0.1:5173 |
| FastAPI backend | http://127.0.0.1:8000 |
| OpenAPI docs | http://127.0.0.1:8000/docs |
模板是完整邮件的唯一骨架。CUSTOM 区域只用于告诉模型哪些段落需要根据导师方向定制:
尊敬的{{teacher_name}}老师:
您好!
我叫{{applicant_name}},来自{{university}}。
<!-- CUSTOM:teacher_fit -->
请根据老师的真实研究信息生成一段克制、具体的方向匹配说明。
<!-- /CUSTOM -->
随信附上个人简历,感谢您的审阅。
此致
敬礼!
<!-- SIGNATURE -->
{{applicant_name}}
{{university}}
{{applicant_email}}程序会提取命名段、请求 LLM 返回结构化 JSON、将段落放回模板、替换申请档案字段,最后移除所有内部标记。可用字段包括:
teacher_name · professor_research · applicant_name · applicant_email · university · college · major · gpa · rank · research_interests · research_experience · project_experience
| Layer | Stack | Responsibility |
|---|---|---|
| Frontend | Vue 3, TypeScript, Vite | 工作台、筛选、审查、状态操作 |
| API | FastAPI, Pydantic | 业务边界、验证、状态转换 |
| Persistence | SQLAlchemy, SQLite | 本地档案、导师、项目、邮件记录 |
| Intelligence | Deterministic rules + OpenAI-compatible API | 相关度解释与定制段生成 |
| Integrations | Requests, BeautifulSoup, Playwright, IMAP, SMTP | 通知/导师采集、草稿写入与实际发送 |
Auto-Connection/
├── backend/
│ ├── routers/ API boundaries
│ ├── services/ matching, scraping, mail and validation
│ ├── database.py SQLite initialization and migrations
│ ├── models.py domain records
│ └── main.py FastAPI application
├── frontend/
│ ├── src/pages/ nine operational workspaces
│ ├── src/components/ui/ local UI primitives
│ └── package.json
├── docs/ architecture notes and README assets
├── tests/ offline regression tests
├── template.md reusable email skeleton
├── sync_opportunities.py opportunity synchronization entry point
├── dev.sh development mode
└── start.sh local production mode
| Table | Stores |
|---|---|
professors |
导师身份、院校层级、研究元数据、匹配分与标签 |
emails |
最终主题/正文、导师关系和草稿/发送状态 |
opportunities |
夏令营与预推免通知、截止日期、来源链接和申请状态 |
applicant_profiles |
可复用的个人背景与研究经历 |
application_materials |
简历、成绩单、证明文件及其准备状态 |
configs |
本地 LLM、邮箱和模板配置 |
数据库默认位于 data/app.db,已通过 .gitignore 排除,不会随代码提交。
Run backend regression tests:
python -m unittest discover -s ./tests -p 'test_*.py' -vBuild and type-check the frontend:
npm --prefix frontend run buildThe current suite covers professor matching, opportunity normalization, deterministic email assembly, malformed marker cleanup, greeting validation, and fail-closed LLM responses.
.env、SQLite 数据库、简历、申请材料和个人套磁名单均不应提交。start.sh与dev.sh默认只监听127.0.0.1。- GitHub Pages 只能托管静态前端,无法安全承载 SQLite、邮箱凭据、IMAP/SMTP 与 FastAPI。
- 若要部署到公网,需要独立后端、HTTPS、身份认证、访问控制、加密凭据存储和审计日志。
- 如果授权码或 API Key 曾进入 Git 历史,仅删除文件不够,必须轮换凭据并清理历史。
- Background jobs with progress polling for large draft batches
- Provider-agnostic mailbox configuration
- Import/export for professor and opportunity lists
- Official-page monitoring with source-diff alerts
- Per-opportunity material requirements and deadline reminders
- Authentication and encrypted secrets for protected deployment
See docs/baoyan_agent_plan.md for the module plan.
No license is currently granted. The source is publicly viewable, but reuse and redistribution require the author's permission unless a license is added later.
Collect broadly. Match carefully. Review every message.
