23 个 commit · 跨 5.5 小时(09:44 – 15:12)· 从 Sprint 1 起步推到 Sprint 3 收官。
| 阶段 | 时间 | commit 数 |
|---|---|---|
| Sprint 1 — 持久化 & 会话态 | 09:44 – 10:42 | 7 |
| Sprint 2 — FastAPI HTTP 层 | 10:47 – 11:15 | 6 |
| Sprint 3 — Milvus + RAG | 11:27 – 15:12 | 9 |
| 中段切 LLM provider 到 OpenAI | 12:03 | 1 |
数据源:git log --since='2026-06-11 00:00'。本文档不包含未 commit 的中间探索与 monkey-patch 诊断过程,那部分见对话本身。
项目首个 commit,把 Sprint 0 骨架代码全部入库。16 个文件 / 1114 行。
- 新增:
ARCHITECTURE.mdCLAUDE.mdsprint.mdpyproject.toml.env.example.gitignore - 新增:
src/{schemas, llm, agents/{planner,interviewer,evaluator,analyzer}, orchestrator, main.py} - 安全注意:把
.env.example里之前误存的真实 ANTHROPIC_API_KEY 脱敏。
SQLAlchemy 2.0 + psycopg3 接入。两张表 + ORM + repository。
- 新增:
src/db/{base,models,repository}.py、src/db/__init__.py - 改:
pyproject.toml(+sqlalchemy, +psycopg)、.env.example(+POSTGRES_URL) - 设计:JSONB 存嵌套结构,顶层可索引字段提列。本地 round-trip 验过。
进行中的 InterviewSession 走 Redis 热存储 + TTL。
- 新增:
src/cache/{base,session_store}.py、src/cache/__init__.py - 改:
pyproject.toml(+redis)、.env.example(+REDIS_URL, +SESSION_TTL_SECONDS) - 设计:
session:{id}整体 JSON,与 PG 配合:"Redis 进行中 / PG 归档"。
/init 改造 + Sprint 1 同步:补真实命令、加 5 条「关键设计模式」、删「(计划)」标记。
- 改:
CLAUDE.md(+92 / -40)
项目级 hooks 配置。注:实际上只有 Stop hook 在工作,PostToolUse 没注册成功(本 session 末才发现)。
- 新增:
.claude/settings.json(PostToolUse Write/Edit/NotebookEdit + Stop)
Orchestrator 三段式 API:start_session / submit_answer / resume_session / finalize,加 run_interview() 便利封装保 Sprint 0 接口。
- 新增:
src/cache/plan_store.py - 改:
src/orchestrator/__init__.py(+200/-54)、src/cache/{base,session_store,__init__}.py、src/schemas/__init__.py(+TurnResult) - 设计:session 与 plan 同 TTL 同生共死;
finalize归档 PG + 清 Redis。中断恢复验过。
透明 LLM 缓存。stub 不入缓存;Redis 不可用静默降级。
- 新增:
src/cache/llm_cache.py - 改:
src/llm/__init__.py、src/cache/__init__.py、.env.example(+LLM_CACHE_TTL_SECONDS) - 验证:monkey-patch
anthropic.Anthropic计数 → 3 次 complete → 2 次 API。
第一个 eval。15 个 TestCase,含合规分区不变量护栏。
- 新增:
evals/test_skeleton.py229 行、evals/__init__.py - 改:
CLAUDE.md(+11 / -2) 补 eval 命令段
应用工厂 + 健康检查端点。
- 新增:
api/{__init__,main}.py、evals/test_api.py(3 个 TestClient 冒烟) - 改:
pyproject.toml(+fastapi, +uvicorn)、CLAUDE.md
3 张新表 + ORM + repository。FK 全 ondelete=RESTRICT。
- 新增:
evals/test_repository.py(8 个 round-trip / FK 护栏 / setUpClass 自动 init_db) - 改:
src/db/{models,repository,__init__}.py、src/schemas/__init__.py(+CandidateProfile.job_id Optional)
第一个业务端点 + 集中异常映射。
- 新增:
api/{schemas,exceptions}.py、api/routes/{__init__,jobs}.py - 改:
api/main.py、evals/test_api.py(+CreateJobTests + ExceptionMappingTests) - 映射:
DatabaseNotConfigured/RedisNotConfigured→ 503。
候选人上传 → 202 + BackgroundTasks 跑 Planner 并双写 PG+Redis。
- 新增:
api/routes/candidates.py - 改:
api/{schemas,main}.py、src/db/{repository,__init__}.py(+load_latest_plan_for_candidate)、evals/test_api.py(+CreateCandidateTests) - 设计:plan 存在性作为就绪信号(不加 status 列);轮询
GET .../plan。
POST /interviews + POST /answers + GET /interviews/{id}。
- 新增:
api/routes/interviews.py - 改:
api/{exceptions,schemas,main}.py、src/orchestrator/__init__.py(+plan 可选参数避免重跑 planner)、evals/test_api.py(+10 个 InterviewSessionTests) - 修隐性 bug:API 路径强制传 PG 里的 plan,避免 orchestrator 重跑 planner 产出新 plan_id 漂移。
隐式 finalize + 幂等报告。Sprint 2 收官。
- 改:
api/routes/interviews.py、src/{db,orchestrator}/__init__.py(+get_report)、evals/test_api.py(+5 个测试)、sprint.md(Sprint 1 + 2 全勾)
OpenAI text-embedding-3-small 的镜像 src/llm 设计:stub 降级 + Redis 缓存。
- 新增:
src/embeddings/__init__.py、src/cache/embedding_cache.py、evals/test_embeddings.py(8 个新 eval) - 改:
pyproject.toml(+openai)、.env.example(+OPENAI_*)、src/cache/__init__.py - 设计:stub 向量 = 全零;
is_stub_vector()让调用方在入 Milvus 前判断是否跳过。
惰性 MilvusClient + questions / documents 两个 collection。
- 新增:
src/vector_store/{__init__,base,collections,operations}.py、evals/test_vector_store.py(10 个 eval) - 改:
pyproject.toml(+pymilvus, +milvus-lite)、.gitignore(+milvus_lite*)、.env.example - 踩坑:pymilvus 的 ORM import 时读
MILVUS_URI当 http URL 解析 → 用MILVUS_LITE_URI避开。
LLM 生成(或 fallback 模板)→ PG → embed → Milvus。可重跑(内容哈希 question_id)。
- 新增:
scripts/{__init__,seed_questions}.py、evals/test_seed_questions.py(9 个 eval) - 改:
src/db/{models,repository,__init__}.py(+SeedQuestionORM 表)、src/schemas/__init__.py(+SeedQuestion) - 踩坑:pymilvus 还会
load_dotenv()把 .env 塞回 env → eval 的 OPENAI_API_KEY pop 必须放 setUp,不能在模块顶。
LLM 切到 OpenAI Chat Completions(默认 gpt-4o-mini),删 anthropic 依赖。
- 改:
src/llm/__init__.py、.env.example(-ANTHROPIC_* +OPENAI_CHAT_MODEL)、pyproject.toml(-anthropic)、CLAUDE.md6 处同步、evals/test_skeleton.py(pop OPENAI 而非 ANTHROPIC) - 顺手修 monkey-patch 泄漏:
test_embeddings.py之前没 restoreopenai.OpenAI,LLM 切到 openai 才暴露。
中文友好滑动窗口切片(~500 + 50 overlap);三个独立 ingest(JD / 公司资料 / Resume)。
- 新增:
src/ingestion/{__init__,chunker,pipeline}.py、evals/test_ingestion.py(11 个 eval) - 改:
api/routes/{jobs,candidates}.py挂 BG 任务
Planner 的 knowledge 题:题库召回 + LLM 精修。四级 fallback。
- 新增:
evals/test_planner_rag.py(5 个 eval:hit / miss / role_family mismatch / stub embed skip) - 改:
src/agents/planner/__init__.py(+127 / -18)、src/schemas/__init__.py(+Question.source_question_id, +JobContext.role_family)
Planner 的 project 题:Resume 切片 RAG + LLM 围绕具体内容生成。
- 改:
src/agents/planner/__init__.py(+95 / -15)、src/schemas/__init__.py(+Question.source_chunk_ids)、evals/test_planner_rag.py(+3 个 eval:hit / no ingest / 跨候选人隔离)
Evaluator summary 接 JD + 公司资料 RAG;合规护栏:overall 严格不受 RAG 影响。
- 新增:
evals/test_evaluator_rag.py(5 个 eval:含合规不变量 + 跨 job 隔离 + PG round-trip) - 改:
src/agents/evaluator/__init__.py(+115 / -14)、src/db/{base,models,repository}.py(+rag_context_chunk_ids 列 + 增量迁移_apply_incremental_migrations)、src/schemas/__init__.py
API 驱动端到端 + 综合跨 job/candidate 隔离。Sprint 3 收官。
- 新增:
evals/test_rag_e2e.py(3 个 eval:全链路 provenance / 跨 job resume / 跨 job JD) - 改:
api/routes/candidates.py(修隐性 bug:BG 任务顺序应当是ingest_resume → planner,FastAPI BackgroundTasks 是顺序执行而非并行)、sprint.md
| 路径 | 行数 |
|---|---|
src/orchestrator/__init__.py |
~230 |
src/agents/planner/__init__.py |
~245 |
src/agents/evaluator/__init__.py |
~210 |
src/db/{base,models,repository}.py |
~360 |
src/cache/{base,session_store,plan_store,llm_cache,embedding_cache}.py |
~280 |
src/vector_store/{base,collections,operations}.py |
~340 |
src/ingestion/{chunker,pipeline}.py |
~150 |
api/routes/{jobs,candidates,interviews}.py |
~210 |
evals/test_*.py |
~2000(111 个 TestCase) |
| 发现 | 修法 | 修在 |
|---|---|---|
.env.example 里有真实 ANTHROPIC_API_KEY |
脱敏 + 提醒轮换 | b099c16 |
orchestrator.start_session 重跑 planner 导致 plan_id 漂移 |
加可选 plan 参数 |
fed2e17 |
pymilvus.settings import 时 load_dotenv() 把 .env 塞回 env |
eval setUp 里再 pop | f094085 |
pymilvus 把 MILVUS_URI 当 http URL 解析 |
用 MILVUS_LITE_URI 避开 |
e17de0a |
test_embeddings 没 restore openai.OpenAI,LLM 切 openai 才暴露 |
tearDown 恢复 | 2610fa5 |
POST /candidates BG 顺序错:planner 先于 ingest_resume,Resume RAG 沉默失效 |
调换顺序 + 注释 | 66abac1 |
.claude/settings.json 的 PostToolUse hook 没注册成功(Stop 工作) |
未修,待 update-config 处理 | — |
datetime.utcnow()deprecation(Python 3.14 + pydantic)psycopg ResourceWarning(进程退出 engine 没显式 dispose)—— Sprint 4 接 FastAPI lifespan 时一并处理- FastAPI BackgroundTasks 是顺序非并行 —— Sprint 7 接 RQ/Celery 真正并行化
- PostToolUse hook 没在工作 —— 需 update-config 修 +
/hooks重载