面向计算机专业学生,将技术学习、项目证据评审、简历优化与模拟面试连接成一条
可追踪、可补证、可恢复、可迭代的求职成长工作流。
项目定位 · 系统架构 · 核心 Agent · RAG · 快速开始 · 接口演示 · License
很多 AI 求职项目只是把四个 Prompt 放在四个页面里。CareerFlow 更关注两个问题:
- 如何让多个 Agent 使用同一份可信上下文协作,而不是各说各话?
- 如何让 LLM 输出可验证、可恢复、可人工修正,而不是一次性生成一段看似合理的文本?
CareerFlow 因此围绕“证据”设计完整链路:
技术知识学习
→ 项目材料三轨评审
→ 关键证据补充
→ 简历六维审查
→ 基于可信证据生成项目经历
→ 人工确认并冻结简历版本
→ 基于项目风险与简历问题开展定向面试
→ 输出下一轮成长任务
本仓库的主要展示入口是 Swagger / ReDoc、自动化测试和架构图。React 前端作为可选参考客户端保留,但不依赖前端页面也能完整理解和验证核心能力。
| 维度 | 当前实现 |
|---|---|
| 核心 Agent | QA、Portfolio、Resume、Interview 共 4 个 |
| 跨 Agent 协作 | Portfolio → Resume → Interview 快照编排 |
| QA 检索 | BGE-M3 Dense/Sparse + Milvus 混合召回 + BGE Reranker |
| Portfolio 评审 | 证据完整性、技术深度、代码与岗位匹配三轨评审 |
| Resume 评审 | 6 个维度并行评分,权重化汇总 |
| Interview 状态机 | WARMUP、TECH_BASE、PROJECT、CLOSING、FINISHED |
| Human-in-the-Loop | Portfolio 补证;简历条目接受、编辑、拒绝 |
| 持久化 | PostgreSQL 业务数据、工作流、报告、版本与 Portfolio Checkpoint |
| 模型可靠性 | Pydantic 结构化输出、重试、逐轨规则降级、数字证据校验 |
| 接口形态 | REST、SSE、MCP、JWT |
| 自动化验证 | 23 项后端测试通过;前端生产构建通过 |
系统划分为六层:
- 访问层:Swagger、ReDoc、可选 React 客户端;
- API 层:FastAPI、JWT、REST、SSE、MCP;
- 业务编排层:统一助手与 Career Workflow;
- Agent 层:四个 LangGraph Agent;
- 模型与检索层:DeepSeek、BGE-M3、Milvus、Reranker、Web Search;
- 数据层:PostgreSQL、Milvus、MinIO、etcd。
Portfolio 和 Resume 不直接把内部 State 全量传给 Interview。系统先生成稳定快照,再由 Career Workflow 构建联合上下文:
{
"interview_focus": {
"target_position": "目标岗位",
"verified_project_evidence": ["已验证项目亮点"],
"risk_questions": ["建议深挖的问题"],
"evidence_gaps": ["尚未充分证明的内容"],
"missing_skills": ["岗位能力缺口"],
"resume_issues": ["简历问题"],
"resume_projects": ["结构化项目"],
"resume_skills": ["结构化技能"]
}
}这种快照隔离让下游 Agent 不依赖上游内部字段的频繁变化,也避免在接口中复制完整代码和原始材料。
QA Agent 不会对所有问题机械执行向量检索,而是先进行三级分类:
- 规则快速识别闲聊、时间和明确通用问题;
- 课程、项目、章节等关键词进入专业问题快速通道;
- MiniLM 二分类器判断
general或specialized。
专业问题继续划分为:
| Query 类型 | 处理策略 |
|---|---|
PRECISE |
原问题直接检索 |
VAGUE |
先用 HyDE 生成假设文档,再检索 |
BROAD |
改写为 3~5 个子问题,并行检索后合并去重 |
GENERAL |
跳过私有知识库,直接回答或按需联网 |
检索链路:
BGE-M3 Query 编码
→ Milvus Dense ANN + Sparse 词法召回
→ WeightedRanker 融合
→ BGE Cross-Encoder 精排
→ Top-1 置信度判断
Top-1 分数达到 0.75 时,系统严格基于 Top-K 知识库内容生成回答;低于阈值时转入 LLM 或 Web Search 兜底,并将低置信度问题写入待补知识队列,供老师后续维护知识库。
对应代码:
backend/agents/qa/graph.pybackend/agents/qa/nodes.pybackend/core/knowledge_base.pybackend/core/reranker.pybackend/core/query_classifier.py
Portfolio Agent 接收项目说明、岗位 JD 和核心代码,从三个维度并行评审:
| 评审轨道 | 关注内容 |
|---|---|
| 证据与工程完整性 | README、测试、部署、接口文档、指标和复现条件 |
| 技术方案深度 | 架构、技术选型、难点、失败处理和方案取舍 |
| 代码与岗位匹配 | 核心实现质量、技能覆盖、岗位要求和面试追问 |
每条轨道都先计算规则基线,再调用结构化 LLM。某一轨 LLM 调用失败时,只对该轨降级,不丢失其他轨道结果。
当评审发现关键证据缺口时,LangGraph 执行 interrupt:
Graph 暂停
→ PostgreSQL Checkpointer 保存状态
→ API 返回补证清单
→ 学生 submit 或 skip
→ 使用原 thread_id 恢复
→ 合并新证据并重新评审
默认最多补证 2 轮,可配置为 1~5 轮。最终输出固定报告快照,包括:
- 综合评分和置信度;
- 已验证亮点;
- 匹配技能和缺失技能;
- 证据缺口;
- 面试追问;
- 可执行改进任务;
- 规则或 LLM 评审模式。
对应代码:
backend/agents/portfolio/graph.pybackend/agents/portfolio/nodes.pybackend/agents/portfolio/repository.pybackend/core/portfolio_checkpoint.py
Resume 能力由两个协同部分组成,但仍视为一个 Agent:
- 使用 PyMuPDF 提取 PDF 文本,并处理常见单双栏布局;
- 使用结构化 LLM 提取教育、技能、项目和经历;
- 并行执行六维度评审;
- 生成问题定位、优先级、修改建议和综合评价;
- 将结构化结果与评分保存到 PostgreSQL。
六维度权重:
| 维度 | 权重 |
|---|---|
| 项目深度 | 30% |
| 技术匹配度 | 25% |
| 表达规范性 | 15% |
| 简历结构 | 15% |
| 量化程度 | 10% |
| 真实可信度 | 5% |
Resume Optimizer 只允许使用 Portfolio 已验证快照和原简历项目中的事实。生成后执行数字证据校验:
模型生成内容中的数字
- 输入证据中存在 → 保留
- 输入证据中不存在 → 自动替换为规则条目并记录告警
学生可以逐条:
accepted:接受建议;edited:修改后接受;rejected:拒绝建议。
确认完成后生成不可变版本,保留证据引用和决策记录,避免后续编辑覆盖历史结果。
对应代码:
backend/agents/resume/graph.pybackend/agents/resume/nodes.pybackend/agents/resume_optimizer/graph.pybackend/agents/resume_optimizer/repository.py
Interview Agent 使用五阶段状态机:
WARMUP → TECH_BASE → PROJECT → CLOSING → FINISHED
开始会话时并行加载:
- 目标岗位;
- Resume 项目和技能;
- Portfolio 已验证亮点;
- 项目证据缺口;
- 推荐风险问题;
- PostgreSQL 面试题库。
技术题优先由 LLM 按岗位动态生成,数据库题库负责补充和兜底。每轮回答被分类为:
| 回答质量 | 行为 |
|---|---|
EXCELLENT |
深挖原理、边界或性能 |
ADEQUATE |
追问关键细节 |
WEAK |
给出提示后继续追问 |
NO_ANSWER |
简要解释并切换问题 |
单个问题最多追问 2 次,避免陷入无效循环。面试结束后生成结构化报告,包括综合得分、优势、薄弱点、建议复习主题和下一步计划;结构化生成两次失败时返回保守报告,保证流程能够结束。
对应代码:
backend/agents/interview/graph.pybackend/agents/interview/nodes.pybackend/agents/interview/state.pybackend/agents/interview/prompts.py
Milvus 中保存的是经过分块的知识单元,而不是整份文档:
content Chunk 正文
embedding BGE-M3 Dense 向量,1024 维
sparse_embedding BGE-M3 Sparse 词法权重
document_id 文档幂等更新键
tenant_id 租户隔离
course_id 知识范围过滤
metadata 来源、标题、章节、页码等
document_id 用于幂等更新:同一文档重新入库时可以定位旧 Chunk,避免重复写入。
| 组件 | 负责的数据 |
|---|---|
| PostgreSQL | 用户、会话、评审、报告、工作流、草稿、决策、简历版本 |
| PostgreSQL Checkpointer | Portfolio LangGraph 的暂停点和恢复状态 |
| Milvus | 知识 Chunk、Dense/Sparse 向量和检索元数据 |
| MinIO | Milvus 向量索引与对象数据 |
| etcd | Milvus 元数据与服务协调 |
项目当前没有把 Redis 作为必需基础设施,避免在架构图中展示“代码中并未真正使用”的组件。
CareerFlow 同时使用:
- Pydantic Schema 约束输出结构;
- LLM 重试;
- 单轨或单节点规则降级;
- 空结果防御;
- 数字证据校验;
- Human-in-the-Loop 人工确认。
目标不是假设 LLM 永不出错,而是让错误发生后仍能得到可解释、可继续的业务结果。
Portfolio 的 LangGraph Checkpoint 负责“Graph 从哪里恢复”,业务表负责“用户看到什么评审记录”。两者职责不同:
Checkpoint:执行状态、暂停位置、thread_id
业务记录:review_id、评分、证据轮次、报告、用户所有权
这种设计避免把 LangGraph 内部 State 直接当业务数据库使用。
Portfolio、Resume、Interview 的 State 结构不同。Career Workflow 只复制下游真正需要的最小可信字段,降低耦合并减少敏感材料传播。
Portfolio、Resume、Interview、版本和工作流数据访问均以:
tenant_id + student_id + resource_id
作为所有权边界,避免只凭 UUID 查询导致越权读取。
- FastAPI、PostgreSQL、LLM 调用使用异步接口;
- BGE 推理、PyMuPDF、Milvus 阻塞调用通过线程池执行;
- Resume 六维评审使用
asyncio.gather并行; - QA Multi-Query 检索并发执行并合并去重。
- REST:创建、查询、绑定、版本管理;
- SSE:QA 与 Interview 流式输出;
- MCP:知识库和 Web Search 工具;
- Swagger / ReDoc:无需前端即可验证核心能力。
| 层级 | 技术 |
|---|---|
| Agent 编排 | LangGraph、LangChain |
| 大模型 | DeepSeek OpenAI-Compatible API |
| API | FastAPI、Uvicorn、Pydantic v2 |
| 流式通信 | SSE |
| RAG | BGE-M3、BGE Reranker、Milvus |
| 数据库 | PostgreSQL、SQLAlchemy Async、asyncpg、psycopg |
| Checkpoint | langgraph-checkpoint-postgres |
| 文档解析 | PyMuPDF |
| 工具协议 | MCP |
| 鉴权 | JWT、Passlib、bcrypt |
| 日志与容错 | Structlog、Tenacity |
| 可选客户端 | React、TypeScript、Vite、Ant Design |
| 基础设施 | Docker Compose、PostgreSQL、Milvus、MinIO、etcd、Attu |
| 测试 | Pytest、pytest-asyncio |
CareerFlow/
├── .github/
│ └── workflows/
│ └── ci.yml # 后端测试与前端构建流水线
├── backend/
│ ├── agents/
│ │ ├── qa/ # 混合 RAG 技术问答
│ │ ├── portfolio/ # 三轨项目评审与 HITL
│ │ ├── resume/ # PDF 简历六维审查
│ │ ├── resume_optimizer/ # 项目经历生成与版本管理
│ │ ├── interview/ # 多阶段模拟面试
│ │ └── career_workflow/ # 跨 Agent 快照服务与仓储
│ ├── api/
│ │ ├── router.py
│ │ └── v1/ # REST / SSE API
│ ├── core/
│ │ ├── llm_factory.py
│ │ ├── knowledge_base.py
│ │ ├── reranker.py
│ │ ├── query_classifier.py
│ │ ├── memory.py
│ │ ├── portfolio_checkpoint.py
│ │ └── retry.py
│ ├── db/
│ ├── mcp/
│ └── main.py
├── frontend/ # 可选 React 客户端
├── models/
│ └── README.md # 模型下载与训练教程
├── scripts/
│ ├── init_db.sql
│ ├── seed_data.py
│ ├── init_milvus.py
│ └── build_knowledge_base.py
├── docs/
│ ├── diagrams/ # Mermaid 图表源文件
│ └── images/ # README 使用的 SVG
├── docker-compose.yml
├── requirements.txt
├── pytest.ini
├── .gitattributes # 跨平台换行符约定
├── .env.example
├── LICENSE # MIT License
└── README.md
- Python 3.11;
- Conda 或
venv; - Docker Desktop;
- DeepSeek API Key;
- 建议预留至少 6 GB 模型磁盘空间;
- 可选:Node.js 20+,仅在运行 React 客户端时需要。
当前项目主要在 Windows 10/11 环境开发。后端、数据库和向量库均使用跨平台组件。
git clone https://github.com/etsfengcheng/CareerFlow.git
cd CareerFlow
conda create -n careerflow python=3.11 -y
conda activate careerflow
pip install -r requirements.txtCopy-Item .env.example .env.local至少配置:
DB_USER=careerflow_user
DB_PASSWORD=请替换为本地强密码
DEEPSEEK_API_KEY=请替换为有效密钥
JWT_SECRET_KEY=请替换为至少32位随机字符串.env.local 已被 .gitignore 排除,不能上传。
模型权重不存入 Git。所需模型:
models/
├── embedding/bge-m3/
├── reranker/bge-reranker-large/
└── classifier/
├── all-MiniLM-L6-v2/
└── my-classifier/
完整下载命令、分类器训练步骤和验证方法见:
docker compose --env-file .env.local up -d
docker compose ps默认端口:
| 服务 | 地址 |
|---|---|
| PostgreSQL | localhost:5433 |
| Milvus | localhost:19531 |
| Attu | http://localhost:30000 |
首次创建 PostgreSQL 数据卷时会自动执行 scripts/init_db.sql。后端启动时还会执行幂等迁移,补充后续阶段增加的表。
python scripts/seed_data.py本地演示账号:
用户名:student01
密码:Student@123456
演示账号只允许用于本地开发,不能用于公网部署。
python scripts/init_milvus.py
python scripts/build_knowledge_base.py
init_milvus.py会重建目标 Collection。已有正式知识库时不要直接运行。
python -m backend.main访问:
- 健康检查:http://127.0.0.1:8000/health
- Swagger:http://127.0.0.1:8000/docs
- ReDoc:http://127.0.0.1:8000/redoc
Windows 下推荐使用 python -m backend.main,确保 Uvicorn 创建事件循环前切换 WindowsSelectorEventLoopPolicy,兼容异步 PostgreSQL Checkpointer。
可选:启动 React 客户端
cd frontend
npm install
npm run dev访问 http://127.0.0.1:5173。前端不是本仓库的主要演示方式,核心接口可以全部通过 Swagger 验证。
不启动前端也可以完成完整演示:
POST /api/v1/auth/login获取 JWT;POST /api/v1/qa/chat/stream验证技术问答和 SSE;POST /api/v1/portfolio/reviews创建项目评审;GET /api/v1/portfolio/reviews/{review_id}/status查看是否等待补证;POST /api/v1/portfolio/reviews/{review_id}/evidence提交或跳过补证;POST /api/v1/resume/upload上传虚构简历;POST /api/v1/career-workflows创建求职成长工作流;- 绑定 Portfolio 和 Resume 评审;
POST /api/v1/resume-optimizer/drafts生成项目经历;- 对建议执行接受、编辑或拒绝;
- 创建不可变简历版本;
POST /api/v1/career-workflows/{workflow_id}/interview开始定向面试;- 获取结构化面试报告。
除登录接口外,请在 Swagger 中使用:
Authorization: Bearer <access_token>| 模块 | 代表接口 |
|---|---|
| 认证 | POST /auth/login、GET /auth/me |
| 统一助手 | POST /chat/stream |
| QA | POST /qa/chat、POST /qa/chat/stream |
| Portfolio | POST /portfolio/reviews、GET /portfolio/reviews/{review_id}/status、POST /portfolio/reviews/{review_id}/evidence |
| Resume | POST /resume/upload、GET /resume/reviews/{review_id} |
| Resume Optimizer | POST /resume-optimizer/drafts、PATCH /resume-optimizer/drafts/{draft_id}/items/{item_id}、POST /resume-optimizer/drafts/{draft_id}/versions |
| Interview | POST /interview/sessions、POST /interview/sessions/{session_id}/chat/stream、GET /interview/sessions/{session_id}/report |
| Career Workflow | POST /career-workflows、绑定两个评审、创建定向 Interview |
接口的准确请求体和响应结构以 Swagger 为准。
python -m pytest -q当前结果:
23 passed
覆盖重点:
- Portfolio 规则评审、LLM 降级和 HITL;
- Portfolio PostgreSQL 持久化;
- Portfolio API;
- Career Workflow API;
- Resume Optimizer;
- 简历版本和决策 API。
cd frontend
npm run build当前构建成功。Vite 会提示主 Bundle 大于 500 KB,这是已知的前端分包优化项,不影响后端和 Agent 能力演示。
python backend/agents/portfolio/review_hitl.py该脚本使用虚构材料演示:
初次评审
→ Graph interrupt
→ 返回补证清单
→ Command resume
→ 重新评审
→ 输出最终报告
仓库中的“李明”简历、联系方式、项目经历和岗位材料均为虚构测试数据,不对应任何真实个人。
公开仓库不应包含:
- 真实简历、电话、邮箱或学校隐私;
.env.local;- DeepSeek、Tavily 等 API Key;
- PostgreSQL 真实密码;
- JWT Secret;
- 本地模型权重;
- 用户上传的 PDF、Word 和代码材料;
- IDE、缓存、日志和数据库数据卷。
模型目录只提交 models/README.md,约 5 GB 的本地模型权重由使用者自行下载。
- 密码使用哈希存储;
- JWT 负责认证;
- Repository 查询同时校验租户、学生和资源 ID;
- 配置从
.env.local读取; - Portfolio 和 Resume 不向下游复制完整代码材料;
- LLM 新增数字会被证据校验拦截;
- 演示账号与默认密码只用于本地环境。
这是一个面向学习、作品集和求职展示的工程项目,仍有以下边界:
- QA 和 Interview 的部分短期 Graph 状态仍使用进程内 MemorySaver;多 Worker 部署前应迁移到共享 Checkpointer;
- 本地 BGE 模型首次预热耗时较长;
- 当前没有把 Redis 作为必需基础设施;
- 尚未完成生产级指标监控、链路追踪和大规模并发压测;
- 前端主 Bundle 尚未拆包;
- LLM 评审仍可能存在随机性,因此保留规则降级和人工确认。
- 将 QA、Interview Checkpoint 迁移到 PostgreSQL;
- 增加 RAG 离线评测集与 Recall、MRR、NDCG 指标;
- 增加 Portfolio 评审一致性测试;
- 接入 OpenTelemetry,记录跨 Agent 调用链;
- 增加 GitHub Actions 自动运行后端测试与前端构建;
- 增加 Docker 化后端和一键启动命令;
- 完成压力测试和延迟分析;
- 优化前端代码分包。
README 中的架构图均有可追踪的 Mermaid 源文件:
修改 Agent Graph 后,应同步修改 .mmd 文件并重新生成 SVG,避免文档和代码拓扑不一致。
如果只想快速了解项目的技术含量,建议按以下顺序阅读:
backend/agents/portfolio/graph.py:HITL 条件路由;backend/agents/portfolio/nodes.py:三轨评审与逐轨降级;backend/core/portfolio_checkpoint.py:PostgreSQL Checkpointer;backend/agents/qa/graph.py:四类 Query 路由;backend/core/reranker.py:混合召回与精排;backend/agents/resume_optimizer/nodes.py:数字证据校验;backend/agents/career_workflow/service.py:跨 Agent 快照;backend/agents/interview/nodes.py:多阶段面试与动态追问。
本项目基于 MIT License 开源。你可以自由使用、修改和分发本项目,但需要保留原始版权声明和许可声明。
Copyright © 2026 etsfengcheng
CareerFlow 不只是调用四次大模型,而是在尝试回答一个工程问题:
如何让多个 Agent 围绕可信证据协作,并在人、模型和数据库之间形成可恢复的业务闭环。
Built for learning, engineering practice and technical career growth.