{"repo": "849261680/chat-resume", "files": {"README.md": {"6d2b227e9c3dad576400adda3b616ae07d024da0": {"t": 1785747261.8928776, "n": 7736, "h": "6d9e7524fc0d2951", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- OpenAI Agents SDK 驱动的 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> OpenAI Agents SDK ResumeAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:OpenAI Agents SDK\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # OpenAI Agents SDK 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENAI_AGENTS_PROVIDER=openai\nOPENAI_API_KEY=\nOPENAI_AGENTS_MODEL=gpt-5.5\nDEEPSEEK_API_KEY=\nDEEPSEEK_API_BASE=https://api.deepseek.com\nDEEPSEEK_THINKING_TYPE=disabled\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n将简历优化 Agent 切到 DeepSeek 官方 API 时,设置\n`OPENAI_AGENTS_PROVIDER=deepseek`、`OPENAI_AGENTS_MODEL=deepseek-v4-pro`,\n并填写 `DEEPSEEK_API_KEY`。该分支使用 OpenAI-compatible Chat Completions,\n默认用 `DEEPSEEK_THINKING_TYPE=disabled` 避免工具确认后的 reasoning_content 回放错误。\n\n### Agent 评估\n\nResume Agent 评估保留本地 `eval/` 跑法,同时输出 OpenAI Agents SDK 标准兼容产物:\n\n- `openai_agents_eval.trace`:写入 SDK `RunConfig.workflow_name`、`trace_id`、`group_id` 和 metadata,真实 OpenAI provider 运行时可在 Traces 中定位。\n- `openai_agents_eval.dataset_item`:把本地 case 转成 dataset item 形状,包含输入、期望决策、期望工具、关键词和禁止内容。\n- `openai_agents_eval.model_sample`:把 Agent 回复、工具调用和最终简历状态转成 grader sample。\n- `openai_agents_eval.grader`:提供 OpenAI Python grader 配置,用于评分决策、工具调用、关键词、禁止内容和回复形态。\n\n普通评估:\n\n```bash\ncd backend\nuv run python ../eval/run_eval.py --cases TC001 --output ../eval/results/latest.json\n```\n\n优秀简历黄金样例:\n\n```bash\ncd backend\nuv run python ../eval/run_excellent_eval.py --cases excellent-002 --output ../eval/results/excellent_latest.json\n```\n\n默认 OpenAI provider 使用 `OPENAI_API_KEY`;切到 `OPENAI_AGENTS_PROVIDER=deepseek`\n时使用 `DEEPSEEK_API_KEY`。DeepSeek 兼容分支仍可本地评分,但不会上传 OpenAI 平台 trace。\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 豆包端到端语音面试:`VOLCENGINE_DIALOGUE_*`、`VOLCENGINE_ACCESS_TOKEN`、`VOLCENGINE_TTS_*`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "ec4c37d0b90bcb1274405d10f825f1a986e458d3": {"t": 1785771969.4172928, "n": 7736, "h": "6d9e7524fc0d2951", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- OpenAI Agents SDK 驱动的 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> OpenAI Agents SDK ResumeAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:OpenAI Agents SDK\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # OpenAI Agents SDK 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENAI_AGENTS_PROVIDER=openai\nOPENAI_API_KEY=\nOPENAI_AGENTS_MODEL=gpt-5.5\nDEEPSEEK_API_KEY=\nDEEPSEEK_API_BASE=https://api.deepseek.com\nDEEPSEEK_THINKING_TYPE=disabled\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n将简历优化 Agent 切到 DeepSeek 官方 API 时,设置\n`OPENAI_AGENTS_PROVIDER=deepseek`、`OPENAI_AGENTS_MODEL=deepseek-v4-pro`,\n并填写 `DEEPSEEK_API_KEY`。该分支使用 OpenAI-compatible Chat Completions,\n默认用 `DEEPSEEK_THINKING_TYPE=disabled` 避免工具确认后的 reasoning_content 回放错误。\n\n### Agent 评估\n\nResume Agent 评估保留本地 `eval/` 跑法,同时输出 OpenAI Agents SDK 标准兼容产物:\n\n- `openai_agents_eval.trace`:写入 SDK `RunConfig.workflow_name`、`trace_id`、`group_id` 和 metadata,真实 OpenAI provider 运行时可在 Traces 中定位。\n- `openai_agents_eval.dataset_item`:把本地 case 转成 dataset item 形状,包含输入、期望决策、期望工具、关键词和禁止内容。\n- `openai_agents_eval.model_sample`:把 Agent 回复、工具调用和最终简历状态转成 grader sample。\n- `openai_agents_eval.grader`:提供 OpenAI Python grader 配置,用于评分决策、工具调用、关键词、禁止内容和回复形态。\n\n普通评估:\n\n```bash\ncd backend\nuv run python ../eval/run_eval.py --cases TC001 --output ../eval/results/latest.json\n```\n\n优秀简历黄金样例:\n\n```bash\ncd backend\nuv run python ../eval/run_excellent_eval.py --cases excellent-002 --output ../eval/results/excellent_latest.json\n```\n\n默认 OpenAI provider 使用 `OPENAI_API_KEY`;切到 `OPENAI_AGENTS_PROVIDER=deepseek`\n时使用 `DEEPSEEK_API_KEY`。DeepSeek 兼容分支仍可本地评分,但不会上传 OpenAI 平台 trace。\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 豆包端到端语音面试:`VOLCENGINE_DIALOGUE_*`、`VOLCENGINE_ACCESS_TOKEN`、`VOLCENGINE_TTS_*`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "58c31610fb096ce016db0eb6809251e9c684cced": {"t": 1785771970.8081858, "n": 7761, "h": "32e7f898a6636fd9", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- OpenAI Agents SDK 驱动的 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> OpenAI Agents SDK ResumeAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:OpenAI Agents SDK\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # OpenAI Agents SDK 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENAI_AGENTS_PROVIDER=openai\nOPENAI_API_KEY=\nOPENAI_AGENTS_MODEL=gpt-5.5\nDEEPSEEK_API_KEY=\nDEEPSEEK_API_BASE=https://api.deepseek.com\nDEEPSEEK_THINKING_TYPE=disabled\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n将简历优化 Agent 切到 DeepSeek 官方 API 时,设置\n`OPENAI_AGENTS_PROVIDER=deepseek`、`OPENAI_AGENTS_MODEL=deepseek-v4-pro`,\n并填写 `DEEPSEEK_API_KEY`。该分支使用 OpenAI-compatible Chat Completions,\n默认用 `DEEPSEEK_THINKING_TYPE=disabled` 避免工具确认后的 reasoning_content 回放错误。\n\n### Agent 评估\n\nResume Agent 评估保留本地 `eval/` 跑法,同时输出 OpenAI Agents SDK 标准兼容产物:\n\n- `openai_agents_eval.trace`:写入 SDK `RunConfig.workflow_name`、`trace_id`、`group_id` 和 metadata,真实 OpenAI provider 运行时可在 Traces 中定位。\n- `openai_agents_eval.dataset_item`:把本地 case 转成 dataset item 形状,包含输入、期望决策、期望工具、关键词和禁止内容。\n- `openai_agents_eval.model_sample`:把 Agent 回复、工具调用和最终简历状态转成 grader sample。\n- `openai_agents_eval.grader`:提供 OpenAI Python grader 配置,用于评分决策、工具调用、关键词、禁止内容和回复形态。\n\n普通评估:\n\n```bash\ncd backend\nuv run python ../eval/run_eval.py --cases TC001 --output ../eval/results/latest.json\n```\n\n优秀简历黄金样例:\n\n```bash\ncd backend\nuv run python ../eval/run_excellent_eval.py --cases excellent-002 --output ../eval/results/excellent_latest.json\n```\n\n默认 OpenAI provider 使用 `OPENAI_API_KEY`;切到 `OPENAI_AGENTS_PROVIDER=deepseek`\n时使用 `DEEPSEEK_API_KEY`。DeepSeek 兼容分支仍可本地评分,但不会上传 OpenAI 平台 trace。\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "81a22b8561afead93fd39bd8b36827526869e4e6": {"t": 1785771972.987875, "n": 6895, "h": "0d21ae9646a9e595", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- OpenAI Agents SDK 驱动的 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> OpenAI Agents SDK ResumeAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:OpenAI Agents SDK\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # OpenAI Agents SDK 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENAI_AGENTS_PROVIDER=openai\nOPENAI_API_KEY=\nOPENAI_AGENTS_MODEL=gpt-5.5\nDEEPSEEK_API_KEY=\nDEEPSEEK_API_BASE=https://api.deepseek.com\nDEEPSEEK_THINKING_TYPE=disabled\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n将简历优化 Agent 切到 DeepSeek 官方 API 时,设置\n`OPENAI_AGENTS_PROVIDER=deepseek`、`OPENAI_AGENTS_MODEL=deepseek-v4-pro`,\n并填写 `DEEPSEEK_API_KEY`。该分支使用 OpenAI-compatible Chat Completions,\n默认用 `DEEPSEEK_THINKING_TYPE=disabled` 避免工具确认后的 reasoning_content 回放错误。\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "a7e9364e68622ad820bb52655f3d839b77d914bb": {"t": 1785771974.8437102, "n": 6792, "h": "bb9af46d8535d87e", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- OpenAI Agents SDK 驱动的 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> OpenAI Agents SDK ResumeAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:OpenAI Agents SDK\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # OpenAI Agents SDK 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENAI_AGENTS_PROVIDER=openai\nOPENAI_API_KEY=\nOPENAI_AGENTS_MODEL=gpt-5.5\nDEEPSEEK_API_KEY=\nDEEPSEEK_API_BASE=https://api.deepseek.com\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n将简历优化 Agent 切到 DeepSeek 官方 API 时,设置\n`OPENAI_AGENTS_PROVIDER=deepseek`、`OPENAI_AGENTS_MODEL=deepseek-v4-pro`,\n并填写 `DEEPSEEK_API_KEY`。该分支使用 OpenAI-compatible Chat Completions。\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "fab8f80cdd9c7d6e17ce8c72547e9a3536aa0afe": {"t": 1785771977.395557, "n": 6526, "h": "426fcf4449b2d084", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- OpenAI Agents SDK 驱动的 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> OpenAI Agents SDK ResumeAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:OpenAI Agents SDK\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # OpenAI Agents SDK 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENAI_API_KEY=\nOPENAI_AGENTS_MODEL=gpt-5.5\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "07918641e585f027c3895a70455ab0c46b9c6062": {"t": 1785771979.0206146, "n": 6434, "h": "ebcf315dd78e45ea", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- 自定义 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-pro\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-pro\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "29573d419612a0cbb800da0bff497ba16253dcf8": {"t": 1785771980.4239225, "n": 6425, "h": "37661e49057092aa", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- 自定义 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nDEEPSEEK_API_KEY=\nDEEPSEEK_API_BASE=https://api.deepseek.com\nDEEPSEEK_MODEL=deepseek-v4-pro\nDEEPSEEK_JOB_MATCH_MODEL=deepseek-v4-pro\nDEEPSEEK_RESUME_PARSER_MODEL=deepseek-v4-pro\nDEEPSEEK_THINKING_TYPE=disabled\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "53d45cfc6d263f539fb44ce8cd93412c23c99274": {"t": 1785771982.9737923, "n": 6347, "h": "13edd7d489ef09fc", "c": "# Chat Resume \n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- 自定义 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有要点。\n- `add_bullet`:新增要点。\n- `remove_bullet`:删除要点。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core\n- 语音:火山引擎实时语音对话\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-flash\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "30c86b0b59366b4f8e3e18c84d03a819a7fd175b": {"t": 1785771985.4385834, "n": 6515, "h": "b502536640361159", "c": "# Chat Resume — Human-in-the-loop Resume Agent\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- 自定义 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n- 为每个 Top gap 返回 JD 证据、建议写入位置、优先级原因、建议补强方向和风险类型。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-flash\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "f685080f38785c4250807ee8d203a1f4073c56ae": {"t": 1785771989.0535505, "n": 6553, "h": "0b025520990e4b4c", "c": "# Chat Resume — Human-in-the-loop Resume Agent\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n- 自定义 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n- 为每个 Top gap 返回 JD 证据、建议写入位置、优先级原因、建议补强方向和风险类型。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-flash\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "17a3b60ba5c010b6fb12ad23fa619519d69755f9": {"t": 1785771990.351083, "n": 7565, "h": "c192414a14cf621c", "c": "# Chat Resume — Human-in-the-loop Resume Agent\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个展示 Agent 工程能力的 AI 求职工作台:从上传简历、解析目标 JD、结构化工具调用、用户确认式 diff 修改,到导出和语音模拟面试,串成一条完整求职闭环。\n\n它不是简单的 ChatGPT wrapper。核心工程点是:\n\n- 自定义 ReAct runtime\n- 结构化 tool calling\n- Human-in-the-loop diff confirmation gate\n- SSE 流式工具事件\n- Session replay / resume\n- Agent eval\n- Agent observability\n\n## For reviewers\n\n如果你只想快速判断这个项目的 Agent 工程含量,请优先看:\n\n| Area | File | Why it matters |\n|---|---|---|\n| Runtime | `backend/app/runtime/pi_agent_runtime.py` | 显式 ReAct loop、流式模型响应、工具执行和确认等待 |\n| Agent definition | `backend/app/agents/resume/agent.py` | Prompt、tool schema、tool profile 和工具执行器组合 |\n| Tool boundary | `backend/app/tools/resume/registry.py` | 结构化工具、字段白名单和防编造约束 |\n| Stream orchestration | `backend/app/services/agent/resume_agent_stream_service.py` | SSE session、事件持久化、cursor replay 和恢复 |\n| Diff UX | `frontend/src/app/[locale]/resume/[id]/edit/page.tsx` | 工具状态、diff confirmation card 和实时简历更新 |\n| Eval | `eval/score.py` | 工具调用正确性、决策规则、关键词提升和 LLM-as-judge 评分 |\n| Observability | `docs/OBSERVABILITY.md` | request/session/tool 级日志关联和排障入口 |\n\n## Demo path\n\n推荐演示链路:\n\n1. 上传或创建一份简历。\n2. 粘贴目标岗位 JD,或上传 JD 截图识别文字。\n3. 询问:“我和这个岗位差距在哪?”\n4. Agent 调用 `generate_job_match_summary` 生成岗位匹配摘要和 Top gaps。\n5. 选中一段经历,点击“快速优化”。\n6. Agent 生成结构化工具调用和 diff。\n7. 用户确认或拒绝修改。\n8. 简历实时更新,并继续导出 PDF 或进入模拟面试。\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## Why this is an Agent system\n\nLLM 不能直接修改简历数据,只能通过受约束的工具提出结构化变更。\n\n```text\nObserve\n -> 读取当前简历、目标 JD、聊天历史和已确认 diff\nReason\n -> 判断用户想咨询、分析匹配度,还是实际修改简历\nAct\n -> 调用只读分析工具或修改类工具\nConfirm\n -> 修改类工具先在 preview context 上执行,生成 diff 等待用户确认\nPersist\n -> 用户确认后才在真实 resume_content 上执行并写入数据库\nReplay\n -> SSE 连接中断后,可通过 session event cursor 回放并恢复\n```\n\nAgent 的输出不是“自然语言声称已修改”。只有真实工具调用成功,并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `upsert_job_application`:创建或更新目标公司、目标岗位和 JD。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n- 为每个 Top gap 返回 JD 证据、建议写入位置、优先级原因、建议补强方向和风险类型。\n\n它当前不会:\n\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## Reliability and eval\n\n项目包含三层验证:\n\n- 后端测试覆盖 runtime 边界、session 恢复、工具执行、SSE cursor 和岗位匹配摘要。\n- 前端 Playwright 覆盖上传、编辑器工作流、diff confirmation、导出、认证、dashboard、i18n 和面试链路。\n- Agent eval 评分工具覆盖工具调用正确性、optimize-first 决策规则、JD 关键词提升和可选 LLM-as-judge。\n\n最近一次本地验收结果:\n\n```text\nbackend basedpyright: passed\nbackend key tests: 128 passed\nfrontend type-check: passed\nfrontend build: passed\nfrontend e2e: 55 passed\n```\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-flash\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "2b2e618b4efb2824af9986a236d7a892d6512b67": {"t": 1785771991.9979086, "n": 7019, "h": "70ef2ea0d3d04213", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 不是普通简历编辑器,而是一个 AI 求职工作台。它的核心是 Human-in-the-loop Resume Optimization Agent:从上传简历到分析目标 JD,再到结构化工具调用、用户确认式改写、导出和模拟面试,串成一条完整求职闭环。\n\n它重点展示的 Agent 工程能力是:自定义 ReAct runtime、结构化工具、SSE 实时可观测、diff confirmation gate、防编造边界和 Agent eval。\n\n## Demo\n\n> TODO: 放 3 分钟演示视频或 GIF:上传简历 -> 粘贴 JD -> 工具调用 -> Top gaps -> 确认 diff -> 简历更新。\n\n建议演示链路:\n\n1. 上传或创建一份简历。\n2. 粘贴目标岗位 JD,或上传 JD 截图识别文字。\n3. Resume Agent 分析简历和 JD 的匹配情况。\n4. Agent 调用 `generate_job_match_summary` 生成岗位匹配摘要。\n5. Agent 生成结构化简历修改 diff。\n6. 用户确认或拒绝修改。\n7. 简历实时更新,并继续导出或进入模拟面试。\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## 为什么这是 Agent 系统\n\nChat Resume 不是固定表单,也不是简单关键词检查器。Resume Agent 运行在 `PiAgentRuntime` 上,通过 pi-agent-core 和 OpenRouter 完成 ReAct loop:\n\n- Observe:读取当前简历、JD、聊天历史和已确认改动。\n- Reason:判断用户想要咨询、匹配分析,还是实际修改简历。\n- Act:调用结构化工具读取、分析或修改简历。\n- Confirm:修改类工具暂停并展示 diff,等待用户确认后继续。\n- Resume:如果 SSE 连接中断,确认结果可以通过 session 恢复链路继续处理。\n\nAgent 的输出不是“自然语言声称已修改”,只有真实工具调用成功并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n- 为每个 Top gap 返回 JD 证据、建议写入位置、优先级原因、建议补强方向和风险类型。\n\n它当前不会:\n\n- 对 JD 做完整语义匹配。\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n关键模块:\n\n- `frontend/src/app/[locale]/resumes/page.tsx`:简历中心,上传、创建、列表和缩略预览。\n- `frontend/src/app/[locale]/resume/[id]/edit/page.tsx`:编辑、预览、Agent 对话和导出主页面。\n- `frontend/src/app/[locale]/resume/[id]/interview/page.tsx`:语音模拟面试页面。\n- `backend/app/entrypoints/http/upload.py`:简历上传后台任务和 JD OCR。\n- `backend/app/entrypoints/http/resume_agent.py`:Resume Agent SSE、工具确认和 session 恢复入口。\n- `backend/app/agents/resume/`:Agent 定义、提示词上下文和工具执行。\n- `backend/app/runtime/`:pi-agent-core 适配、流事件、确认策略和恢复逻辑。\n- `backend/app/tools/resume/`:结构化简历工具。\n- `backend/app/services/agent/job_match_summary.py`:JD 匹配摘要和 Top gaps 逻辑。\n- `backend/app/entrypoints/http/interviews.py`:模拟面试 session API。\n- `eval/`:Agent eval 用例、评分和趋势分析脚本。\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_JOB_MATCH_MODEL=deepseek/deepseek-v4-flash\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "66f55671cfb3c3057c2f098876dcf824abefec09": {"t": 1785771994.1939533, "n": 6965, "h": "900c4d5d20474c65", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 不是普通简历编辑器,而是一个 AI 求职工作台。它的核心是 Human-in-the-loop Resume Optimization Agent:从上传简历到分析目标 JD,再到结构化工具调用、用户确认式改写、导出和模拟面试,串成一条完整求职闭环。\n\n它重点展示的 Agent 工程能力是:自定义 ReAct runtime、结构化工具、SSE 实时可观测、diff confirmation gate、防编造边界和 Agent eval。\n\n## Demo\n\n> TODO: 放 3 分钟演示视频或 GIF:上传简历 -> 粘贴 JD -> 工具调用 -> Top gaps -> 确认 diff -> 简历更新。\n\n建议演示链路:\n\n1. 上传或创建一份简历。\n2. 粘贴目标岗位 JD,或上传 JD 截图识别文字。\n3. Resume Agent 分析简历和 JD 的匹配情况。\n4. Agent 调用 `generate_job_match_summary` 生成岗位匹配摘要。\n5. Agent 生成结构化简历修改 diff。\n6. 用户确认或拒绝修改。\n7. 简历实时更新,并继续导出或进入模拟面试。\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## 为什么这是 Agent 系统\n\nChat Resume 不是固定表单,也不是简单关键词检查器。Resume Agent 运行在 `PiAgentRuntime` 上,通过 pi-agent-core 和 OpenRouter 完成 ReAct loop:\n\n- Observe:读取当前简历、JD、聊天历史和已确认改动。\n- Reason:判断用户想要咨询、匹配分析,还是实际修改简历。\n- Act:调用结构化工具读取、分析或修改简历。\n- Confirm:修改类工具暂停并展示 diff,等待用户确认后继续。\n- Resume:如果 SSE 连接中断,确认结果可以通过 session 恢复链路继续处理。\n\nAgent 的输出不是“自然语言声称已修改”,只有真实工具调用成功并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_summary`:更新个人总结,调整整份简历的职业定位和核心能力摘要。\n- `update_profile`:更新个人信息中的求职定位、headline、地点和公开链接;不修改姓名、邮箱、电话。\n- `update_item_fields`:更新工作、项目、教育条目的非 bullet 字段,例如职位、项目简介、角色、技术栈、学历字段。\n- `update_skills`:更新技能分类名称和技能列表,支持替换或合并。\n- `add_resume_item`:新增工作、项目、教育、技能、语言或自定义条目;必须提供用户明确事实来源。\n- `remove_resume_item`:删除已有工作、项目、教育、技能、语言或自定义条目。\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n- 为每个 Top gap 返回 JD 证据、建议写入位置、优先级原因、建议补强方向和风险类型。\n\n它当前不会:\n\n- 对 JD 做完整语义匹配。\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n关键模块:\n\n- `frontend/src/app/[locale]/resumes/page.tsx`:简历中心,上传、创建、列表和缩略预览。\n- `frontend/src/app/[locale]/resume/[id]/edit/page.tsx`:编辑、预览、Agent 对话和导出主页面。\n- `frontend/src/app/[locale]/resume/[id]/interview/page.tsx`:语音模拟面试页面。\n- `backend/app/entrypoints/http/upload.py`:简历上传后台任务和 JD OCR。\n- `backend/app/entrypoints/http/resume_agent.py`:Resume Agent SSE、工具确认和 session 恢复入口。\n- `backend/app/agents/resume/`:Agent 定义、提示词上下文和工具执行。\n- `backend/app/runtime/`:pi-agent-core 适配、流事件、确认策略和恢复逻辑。\n- `backend/app/tools/resume/`:结构化简历工具。\n- `backend/app/services/agent/job_match_summary.py`:JD 匹配摘要和 Top gaps 逻辑。\n- `backend/app/entrypoints/http/interviews.py`:模拟面试 session API。\n- `eval/`:Agent eval 用例、评分和趋势分析脚本。\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "d38f16e93ff4188c8e42ba9387dd142a581d809e": {"t": 1785771995.5209227, "n": 6639, "h": "773889d0e868d6bc", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 不是普通简历编辑器,而是一个 AI 求职工作台。它的核心是 Human-in-the-loop Resume Optimization Agent:从上传简历到分析目标 JD,再到结构化工具调用、用户确认式改写、导出和模拟面试,串成一条完整求职闭环。\n\n它重点展示的 Agent 工程能力是:自定义 ReAct runtime、结构化工具、SSE 实时可观测、diff confirmation gate、防编造边界和 Agent eval。\n\n## Demo\n\n> TODO: 放 3 分钟演示视频或 GIF:上传简历 -> 粘贴 JD -> 工具调用 -> Top gaps -> 确认 diff -> 简历更新。\n\n建议演示链路:\n\n1. 上传或创建一份简历。\n2. 粘贴目标岗位 JD,或上传 JD 截图识别文字。\n3. Resume Agent 分析简历和 JD 的匹配情况。\n4. Agent 调用 `generate_job_match_summary` 生成岗位匹配摘要。\n5. Agent 生成结构化简历修改 diff。\n6. 用户确认或拒绝修改。\n7. 简历实时更新,并继续导出或进入模拟面试。\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:同一个工具返回命中关键词、缺失关键词、已确认改动、待补充事实提示和优先补强 Top gaps。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成匹配摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## 为什么这是 Agent 系统\n\nChat Resume 不是固定表单,也不是简单关键词检查器。Resume Agent 运行在 `PiAgentRuntime` 上,通过 pi-agent-core 和 OpenRouter 完成 ReAct loop:\n\n- Observe:读取当前简历、JD、聊天历史和已确认改动。\n- Reason:判断用户想要咨询、匹配分析,还是实际修改简历。\n- Act:调用结构化工具读取、分析或修改简历。\n- Confirm:修改类工具暂停并展示 diff,等待用户确认后继续。\n- Resume:如果 SSE 连接中断,确认结果可以通过 session 恢复链路继续处理。\n\nAgent 的输出不是“自然语言声称已修改”,只有真实工具调用成功并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要,返回 `matched_keywords`、`missing_keywords`、`resume_changes`、`fact_gaps` 和 `top_gaps`。\n\n修改工具需要用户确认:\n\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词、证据链和能力缺口归并,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 汇总本轮已确认 diff,说明已经补强了哪些表达。\n- 把零散缺失关键词归并成 2-3 个能力缺口,例如 RAG 落地经验、Agent 工具调用与工作流编排、工程基础设施经验。\n- 为每个 Top gap 返回 JD 证据、建议写入位置、优先级原因、建议补强方向和风险类型。\n\n它当前不会:\n\n- 对 JD 做完整语义匹配。\n- 证明用户真实做过某项缺失能力。\n- 编造简历里没有证据支撑的经历。\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n关键模块:\n\n- `frontend/src/app/[locale]/resumes/page.tsx`:简历中心,上传、创建、列表和缩略预览。\n- `frontend/src/app/[locale]/resume/[id]/edit/page.tsx`:编辑、预览、Agent 对话和导出主页面。\n- `frontend/src/app/[locale]/resume/[id]/interview/page.tsx`:语音模拟面试页面。\n- `backend/app/entrypoints/http/upload.py`:简历上传后台任务和 JD OCR。\n- `backend/app/entrypoints/http/resume_agent.py`:Resume Agent SSE、工具确认和 session 恢复入口。\n- `backend/app/agents/resume/`:Agent 定义、提示词上下文和工具执行。\n- `backend/app/runtime/`:pi-agent-core 适配、流事件、确认策略和恢复逻辑。\n- `backend/app/tools/resume/`:结构化简历工具。\n- `backend/app/services/agent/job_match_summary.py`:JD 匹配摘要和 Top gaps 逻辑。\n- `backend/app/entrypoints/http/interviews.py`:模拟面试 session API。\n- `eval/`:Agent eval 用例、评分和趋势分析脚本。\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "59c85f505315826bb080394de1314365086b58f5": {"t": 1785771997.0605388, "n": 6597, "h": "905047b1adb62e74", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 不是普通简历编辑器,而是一个 AI 求职工作台。它的核心是 Human-in-the-loop Resume Optimization Agent:从上传简历到分析目标 JD,再到结构化工具调用、用户确认式改写、导出和模拟面试,串成一条完整求职闭环。\n\n它重点展示的 Agent 工程能力是:自定义 ReAct runtime、结构化工具、SSE 实时可观测、diff confirmation gate、防编造边界和 Agent eval。\n\n## Demo\n\n> TODO: 放 3 分钟演示视频或 GIF:上传简历 -> 粘贴 JD -> 工具调用 -> Top gaps -> 确认 diff -> 简历更新。\n\n建议演示链路:\n\n1. 上传或创建一份简历。\n2. 粘贴目标岗位 JD,或上传 JD 截图识别文字。\n3. Resume Agent 分析简历和 JD 的匹配情况。\n4. Agent 调用工具生成岗位匹配摘要和 Top gaps。\n5. Agent 生成结构化简历修改 diff。\n6. 用户确认或拒绝修改。\n7. 简历实时更新,并继续导出或进入模拟面试。\n\n## 核心能力\n\n- 简历上传解析:支持 PDF、DOC、DOCX、TXT,后台解析后生成结构化简历。\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、布局配置、一页适配和导出。\n- JD 管理:保存目标公司、目标岗位和 JD 文本,支持 JD 图片 OCR。\n- Resume Agent:基于当前简历、目标 JD 和对话上下文进行 ReAct 式工具调用。\n- 用户确认式改写:所有修改类工具先展示 diff,用户确认后才写入简历。\n- JD 匹配摘要:展示命中关键词、缺失关键词、Top gaps、JD 证据和建议补强位置。\n- 模拟面试:基于简历和目标岗位创建语音面试 session,保存问答并生成报告。\n- Agent eval:提供评估用例和评分脚本,用于检查关键词提升、工具调用正确性和决策规则。\n\n## 主要用户流程\n\n```text\n上传/创建简历\n -> 结构化编辑\n -> 填写或识别 JD\n -> Resume Agent 分析匹配\n -> 工具调用生成摘要 / Top gaps / 修改 diff\n -> 用户确认后应用修改\n -> 预览、一页适配、导出\n -> 基于简历进入模拟面试\n```\n\n## 为什么这是 Agent 系统\n\nChat Resume 不是固定表单,也不是简单关键词检查器。Resume Agent 运行在 `PiAgentRuntime` 上,通过 pi-agent-core 和 OpenRouter 完成 ReAct loop:\n\n- Observe:读取当前简历、JD、聊天历史和已确认改动。\n- Reason:判断用户想要咨询、匹配分析,还是实际修改简历。\n- Act:调用结构化工具读取、分析或修改简历。\n- Confirm:修改类工具暂停并展示 diff,等待用户确认后继续。\n- Resume:如果 SSE 连接中断,确认结果可以通过 session 恢复链路继续处理。\n\nAgent 的输出不是“自然语言声称已修改”,只有真实工具调用成功并通过确认门后,简历内容才会被写入。\n\n## Agent 工具\n\n当前 Resume Agent 的工具分为只读分析和写入修改两类。\n\n只读工具会自动执行:\n\n- `generate_job_match_summary`:生成岗位匹配摘要。\n- `analyze_jd_top_gaps`:返回本轮最值得优先处理的 2-3 个岗位缺口。\n\n修改工具需要用户确认:\n\n- `update_overview`:更新项目简介。\n- `update_bullet`:更新已有 bullet。\n- `add_bullet`:新增 bullet。\n- `remove_bullet`:删除 bullet。\n\n每个修改工具都会返回结构化 diff,包括修改前、修改后和修改原因。前端展示确认卡,用户接受后才应用到简历。\n\n## JD 匹配能力边界\n\n当前 JD 匹配是轻量关键词和证据链分析,不是完整语义匹配模型。\n\n它会:\n\n- 从 JD 中提取中英文关键词。\n- 排除 JD 字段后,在简历正文中判断命中和缺失。\n- 根据 JD 出现次数、出现位置,以及“必须、要求、负责、核心、优先、加分”等提示词给缺口排序。\n- 为每个 Top gap 生成 JD 原文证据、简历可补位置、优先级原因、建议补强方向和风险类型。\n\n风险类型包括:\n\n- `can_improve`:简历已有相邻经历,可直接补强表达。\n- `needs_user_confirmation`:需要用户确认是否有真实经历。\n- `insufficient_evidence`:简历暂无可支撑证据,不能编造。\n\n## 系统架构\n\n```text\nFrontend (Next.js / React)\n -> FastAPI HTTP API\n -> ResumeAgentStreamService\n -> PiAgentRuntime\n -> Resume Tools\n -> Tool Confirmation Gate\n -> ResumeService / AgentSessionStore\n -> Database\n```\n\n关键模块:\n\n- `frontend/src/app/[locale]/resumes/page.tsx`:简历中心,上传、创建、列表和缩略预览。\n- `frontend/src/app/[locale]/resume/[id]/edit/page.tsx`:编辑、预览、Agent 对话和导出主页面。\n- `frontend/src/app/[locale]/resume/[id]/interview/page.tsx`:语音模拟面试页面。\n- `backend/app/entrypoints/http/upload.py`:简历上传后台任务和 JD OCR。\n- `backend/app/entrypoints/http/resume_agent.py`:Resume Agent SSE、工具确认和 session 恢复入口。\n- `backend/app/agents/resume/`:Agent 定义、提示词上下文和工具执行。\n- `backend/app/runtime/`:pi-agent-core 适配、流事件、确认策略和恢复逻辑。\n- `backend/app/tools/resume/`:结构化简历工具。\n- `backend/app/services/agent/job_match_summary.py`:JD 匹配摘要和 Top gaps 逻辑。\n- `backend/app/entrypoints/http/interviews.py`:模拟面试 session API。\n- `eval/`:Agent eval 用例、评分和趋势分析脚本。\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:pi-agent-core、OpenRouter、自定义 runtime adapter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 支付:PayPal Subscription\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词上下文\nbackend/app/runtime/ # pi-agent-core 运行时适配、确认和恢复\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nbackend/app/state/ # Agent session 存储和 SSE 回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "4f1f1fd6989231d4b095e023b107b7e79adb9360": {"t": 1785771999.9939263, "n": 4055, "h": "d47175a0600b17a5", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个 AI 求职应用,核心流程是:上传简历 -> 上传 JD -> Agent 优化 -> 确认修改 -> 导出简历 -> 模拟面试。\n\n## 核心功能\n\n- 简历上传解析:支持 `PDF`、`DOC`、`DOCX`、`TXT`\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、一页适配\n- Resume Agent:AGENT根据JD定向优化简历\n- 模拟面试:基于简历创建语音面试 session,保存问答记录和报告\n\n\n## 技术栈\n\n- 前端:Next.js 16.2、React 18、TypeScript、Tailwind CSS、next-intl\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- AI:pi-agent-core、OpenRouter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/agents/resume/ # 简历 Agent 定义和提示词\nbackend/app/runtime/ # pi-agent-core 运行时适配\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务(auth、agent、domain、interview、llm、processing、voice)\nbackend/app/state/ # Agent session 存储和回放\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\nfrontend/src/hooks/ # 页面级业务 hooks\nfrontend/src/i18n/ # 国际化配置\nfrontend/locales/ # 中英文翻译文件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n路由:\n\n- `/login` / `/register`:登录注册\n- `/dashboard`:工作台\n- `/resumes`:简历中心\n- `/resume/{id}/edit`:简历编辑、预览、Agent 优化和导出\n- `/resume/{id}/interview`:语音面试\n- `/interviews`:面试记录\n- `/pricing`:套餐价格\n- `/settings`:账户设置\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n- ASR/TTS:`VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`、`MINIMAX_API_KEY`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "96f85b54f45304327d561585f952b3071ca82fc0": {"t": 1785772001.1513555, "n": 3428, "h": "f6e9a3185fd88ae0", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个 AI 求职应用,核心流程是:上传简历 -> 上传 JD -> Agent 优化 -> 确认修改 -> 导出简历 -> 模拟面试。\n\n## 核心功能\n\n- 简历上传解析:支持 `PDF`、`DOC`、`DOCX`、`TXT`\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、一页适配\n- Resume Agent:AGENT根据JD定向优化简历\n- 模拟面试:基于简历创建语音面试 session,保存问答记录和报告\n\n\n## 技术栈\n\n- 前端:Next.js 16、React 18、TypeScript、Tailwind CSS\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- AI:pi-agent-core、OpenRouter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/runtime/ # pi-agent-core 运行时适配\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "5009c407e48a876685fba4df2671d47a026abb35": {"t": 1785772003.2332354, "n": 3439, "h": "da1ca230675dff81", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个 AI 求职应用,核心流程是:上传简历 -> 上传 JD -> Agent 优化 -> 确认修改 -> 导出简历 -> 模拟面试。\n\n## 核心功能\n\n- 简历上传解析:支持 `PDF`、`DOC`、`DOCX`、`TXT`\n- 简历编辑工作台:结构化编辑、实时预览、自动保存、一页适配\n- Resume Agent:AGENT根据JD定向优化简历\n- 模拟面试:基于简历创建语音面试 session,保存问答记录和报告\n\n\n## 技术栈\n\n- 前端:Next.js 16、React 18、TypeScript、Tailwind CSS\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- AI:Deep Agents、LangChain OpenAI、OpenRouter\n- 语音:火山引擎实时语音对话、ASR、MiniMax TTS\n- 测试:pytest、Playwright\n\n## 主要目录\n\n```text\nbackend/app/entrypoints/http/ # FastAPI 路由\nbackend/app/runtime/ # Deep Agents 运行时\nbackend/app/tools/resume/ # 简历工具\nbackend/app/services/ # 业务服务\nfrontend/src/app/ # Next.js 页面\nfrontend/src/components/ # 前端组件\neval/ # Agent eval 脚本和用例\n```\n\n## 本地启动\n\n要求:\n\n- Python 3.11+\n- Node.js 18+\n- uv\n- npm\n\n启动前后端:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n\n单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地最少需要:\n\n```bash\n# backend/.env\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nOPENROUTER_API_KEY=\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n可选能力按需配置:\n\n- Google 登录:`GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET`、`GOOGLE_OAUTH_REDIRECT_URI`\n- PayPal 订阅:`PAYPAL_CLIENT_ID`、`PAYPAL_CLIENT_SECRET`、`PAYPAL_PLAN_ID`、`PAYPAL_WEBHOOK_ID`\n- 语音面试:`DIGITAL_HUMAN_PROVIDER=volcengine` 和 `VOLCENGINE_DIALOGUE_*`\n\n## 数据库\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 测试\n\n```bash\n# 后端\ncd backend\nuv run --extra dev python -m pytest tests\n\n# 前端类型检查\ncd frontend\nnpm run type-check\n\n# 前端构建\nnpm run build\n\n# E2E\nnpm run e2e\n```\n\n## 设计\n\n前端设计规范见 [DESIGN.md](./DESIGN.md)。\n"}, "43863434363a93a851d79839a8703ce6cd2968ef": {"t": 1785772004.4127622, "n": 9287, "h": "a721d2de9467f5e0", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\nChat Resume 是一个围绕「结构化简历优化 + AI Agent 改写 + 语音模拟面试」的求职应用。\n\n当前主链路是:\n\n1. 上传或创建结构化简历。\n2. 在编辑工作台维护岗位、个人信息、教育、工作、项目、技能等模块。\n3. Resume Agent 基于 Deep Agents 调用简历工具,生成可确认的 diff。\n4. 用户确认后写回结构化简历,并导出 PDF / DOCX / HTML。\n5. 基于简历创建实时语音模拟面试,沉淀面试记录和报告。\n\n## 功能状态\n\n- 账号系统\n - 邮箱注册、登录、刷新会话\n - Google OAuth 登录\n - Cookie 鉴权保护简历、面试、AI、语音、账单等 API\n- 简历管理\n - 上传解析 `PDF`、`DOC`、`DOCX`、`TXT`\n - 结构化编辑与实时预览\n - 自动保存、布局控制、一页适配\n - 导出 `PDF`、`DOCX`、`HTML`\n- Resume Agent\n - Deep Agents 是当前唯一主执行内核\n - SSE 流式输出\n - 显示工具调用状态\n - 支持 `read_resume`、`update_bullet`、`add_bullet`、`remove_bullet`、`update_overview`\n - 工具改动先生成 diff,用户确认后落库\n - 使用官方 Deep Agents memory 文件 `/memories/AGENTS.md` 保存用户偏好和简历策略\n- 模拟面试\n - 面试中心管理 session\n - 实时语音面试页面\n - 火山引擎端到端实时语音对话\n - 面试官问题和候选人回答写入 `interview_turns`\n - 支持结束面试并生成报告数据\n- 账单\n - PayPal Plus 订阅创建、状态查询、Webhook 同步\n - 本地持久化 `billing_subscriptions` 与 webhook 事件\n- 评测与观测\n - `eval/` 下有离线 eval case、schema 校验、打分、趋势对比和证据报告脚本\n - LangSmith / Langfuse / Sentry 配置入口\n - Resume Agent eval 可输出 trace artifacts\n\n## 技术栈\n\n- 前端:Next.js 16、React 18、TypeScript、Tailwind CSS、Framer Motion、Playwright\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic、uv\n- Agent:Deep Agents、LangChain OpenAI、OpenRouter\n- 语音:火山引擎实时语音对话、火山引擎 ASR、MiniMax TTS\n- 支付:PayPal Subscriptions\n- 观测:Sentry、Langfuse、LangSmith\n\n## 目录结构\n\n```text\nchat-resume/\n├── backend/\n│ ├── alembic/ # 数据库迁移\n│ ├── app/\n│ │ ├── agents/ # Resume / Interview agent 业务入口\n│ │ ├── entrypoints/http/ # FastAPI HTTP 路由\n│ │ ├── evals/ # 后端 eval 任务定义\n│ │ ├── infra/ # 配置、数据库、日志、观测\n│ │ ├── models/ # SQLAlchemy models\n│ │ ├── prompts/ # Agent prompts\n│ │ ├── runtime/ # Deep Agents runtime adapter\n│ │ ├── schemas/ # Pydantic schemas\n│ │ ├── services/ # 认证、账单、面试、LLM、解析、语音服务\n│ │ ├── state/ # Agent 状态快照和回放\n│ │ ├── tools/ # 简历工具\n│ │ └── types/ # 运行时/流式事件类型\n│ ├── scripts/\n│ └── tests/\n├── frontend/\n│ ├── e2e/ # Playwright 用例\n│ ├── scripts/\n│ └── src/\n│ ├── app/ # Next.js App Router 页面\n│ ├── components/\n│ ├── hooks/\n│ ├── lib/\n│ └── types/\n├── eval/ # Agent eval CLI、case、gate 配置\n├── docs/\n│ └── architecture.html\n├── DESIGN.md # Coinbase 风格设计规范\n├── backend.sh\n├── frontend.sh\n├── restart.sh\n├── railway.json # 后端部署配置\n└── frontend/vercel.json # 前端部署配置\n```\n\n## 关键页面\n\n- `/`:产品首页\n- `/login`、`/register`:账号入口\n- `/dashboard`:登录后的概览入口\n- `/resumes`:简历中心\n- `/resume/[id]/edit`:简历编辑与 Agent 优化工作台\n- `/resume/print`:简历打印/导出页面\n- `/interviews`:面试中心\n- `/resume/[id]/interview`:实时语音模拟面试\n- `/settings`:账号设置与套餐选择\n\n## 本地开发\n\n环境要求:\n\n- Python 3.11+\n- Node.js 18+\n- `uv`\n- `npm`\n\n首次启动推荐直接用根目录脚本:\n\n```bash\n./restart.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- API Docs: `http://localhost:8000/docs`\n- Web: `http://localhost:3000`\n\n`restart.sh` 会同时启动前后端,并把完整日志写入:\n\n- `backend.log`\n- `frontend.log`\n\n需要完整终端日志时:\n\n```bash\nVERBOSE=1 ./restart.sh\n```\n\n也可以单独启动:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n脚本支持端口覆盖:\n\n```bash\nBACKEND_PORT=8010 FRONTEND_PORT=3010 ./restart.sh\n```\n\n## 数据库\n\n本地默认使用 SQLite:\n\n```bash\nbackend/chat_resume.db\n```\n\n迁移命令:\n\n```bash\ncd backend\nuv run alembic upgrade head\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n本地脚本会在缺失时复制为:\n\n- `backend/.env`\n- `frontend/.env.local`\n\n### 后端常用配置\n\n```bash\nDATABASE_URL=sqlite:///./chat_resume.db\nSECRET_KEY=your-secret-key-here\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\nAUTH_COOKIE_SECURE=false\nAUTH_COOKIE_SAMESITE=lax\nAUTH_COOKIE_DOMAIN=\n```\n\n### OpenRouter / Agent\n\n```bash\nOPENROUTER_API_KEY=\nOPENROUTER_API_BASE=https://openrouter.ai/api/v1\nOPENROUTER_MODEL=google/gemini-2.5-flash\nOPENROUTER_VISION_MODEL=qwen/qwen2.5-vl-72b-instruct\nOPENROUTER_VISION_FALLBACK_MODELS=google/gemini-2.5-flash\nOPENROUTER_RESUME_PARSER_MODEL=deepseek/deepseek-v4-flash\n```\n\n### Google 登录\n\nGoogle 登录采用后端授权码流程。前端跳转到后端启动端点,不处理 Google token。\n\n```bash\nGOOGLE_OAUTH_CLIENT_ID=\nGOOGLE_OAUTH_CLIENT_SECRET=\nGOOGLE_OAUTH_REDIRECT_URI=http://localhost:8000/api/auth/google/callback\n```\n\nGoogle Cloud Console 的 OAuth Client 类型选择 `Web application`。本地 Authorized redirect URI:\n\n```text\nhttp://localhost:8000/api/auth/google/callback\n```\n\n生产环境必须和 `GOOGLE_OAUTH_REDIRECT_URI` 完全一致:\n\n```text\nhttps:///api/auth/google/callback\n```\n\n常见错误:\n\n- `redirect_uri_mismatch`:Google Console 的 redirect URI 与 `GOOGLE_OAUTH_REDIRECT_URI` 不一致。\n- `config_missing`:后端缺少 `GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET` 或 `GOOGLE_OAUTH_REDIRECT_URI`。\n- 登录后无登录态:检查 `NEXT_PUBLIC_API_URL`、`BACKEND_CORS_ORIGINS`、Cookie `Secure` / `SameSite` / `Domain`。\n\n### PayPal 订阅\n\n```bash\nPAYPAL_CLIENT_ID=\nPAYPAL_CLIENT_SECRET=\nPAYPAL_PLAN_ID=\nPAYPAL_WEBHOOK_ID=\nPAYPAL_API_BASE=https://api-m.sandbox.paypal.com\n```\n\n本地/沙箱默认使用 PayPal sandbox。生产环境把 `PAYPAL_API_BASE` 改成:\n\n```bash\nPAYPAL_API_BASE=https://api-m.paypal.com\n```\n\n后端暴露的账单接口包括:\n\n- `GET /api/billing/status`\n- `GET /api/billing/paypal/plan`\n- `POST /api/billing/paypal/subscriptions`\n- `GET /api/billing/paypal/subscriptions/{subscription_id}/sync`\n- `POST /api/billing/paypal/subscriptions/{subscription_id}/cancel`\n- `POST /api/billing/paypal/webhook`\n\n`/api/billing/paypal/webhook` 是鉴权豁免路径,但仍会做 PayPal webhook 签名校验。\n\n### 语音与数字人\n\n```bash\nDIGITAL_HUMAN_PROVIDER=volcengine\nVOLCENGINE_DIALOGUE_APP_ID=\nVOLCENGINE_DIALOGUE_ACCESS_KEY=\nVOLCENGINE_DIALOGUE_RESOURCE_ID=volc.speech.dialog\nVOLCENGINE_DIALOGUE_SPEAKER_ID=\nVOLCENGINE_DIALOGUE_WS_URL=wss://openspeech.bytedance.com/api/v3/realtime/dialogue\n```\n\n其他可选语音/数字人配置:\n\n- `MINIMAX_API_KEY`、`MINIMAX_GROUP_ID`\n- `VOLCENGINE_APP_KEY`、`VOLCENGINE_ACCESS_TOKEN`\n- `VOLCENGINE_ASR_API_KEY`、`VOLCENGINE_ASR_APP_ID`\n- `VOLCENGINE_TTS_API_KEY`、`VOLCENGINE_TTS_APP_ID`\n- `TAVUS_*`\n- `LIVEAVATAR_*`\n\n### 前端配置\n\n```bash\nNEXT_PUBLIC_API_URL=http://localhost:8000\nNEXT_PUBLIC_APP_ENV=development\nNEXT_PUBLIC_APP_NAME=Chat Resume\nNEXT_PUBLIC_APP_DESCRIPTION=AI驱动的智能简历优化平台\n```\n\n## 生产模式本地运行\n\n后端:\n\n```bash\ncd backend\nuv sync --extra dev\nuv run alembic upgrade head\nuv run uvicorn app.main:app --host 0.0.0.0 --port 8000\n```\n\n前端:\n\n```bash\ncd frontend\nnpm install\nnpm run build\nnpm run start\n```\n\n## 测试与验证\n\n后端测试:\n\n```bash\ncd backend\nuv run --extra dev python -m pytest tests\n```\n\n前端类型检查:\n\n```bash\ncd frontend\nnpm run type-check\n```\n\n前端构建:\n\n```bash\ncd frontend\nnpm run build\n```\n\nPlaywright E2E:\n\n```bash\ncd frontend\nnpm run e2e\n```\n\nE2E 需要前端和后端服务同时可用,默认使用:\n\n- `http://localhost:3000`\n- `http://localhost:8000`\n\n## Eval 工作流\n\n`eval/` 是当前 Agent 评测入口,包含 case、gate、分析、打分和趋势对比。\n\n常用命令:\n\n```bash\ncd backend\nuv run python ../eval/validate_cases.py\nuv run python -m pytest \\\n tests/test_eval_analyzer.py \\\n tests/test_eval_case_validation.py \\\n tests/test_eval_score.py \\\n tests/test_eval_trend_comparison.py \\\n tests/test_evidence_report.py\n```\n\n真实模型 eval 依赖 `backend/.env` 中的 `OPENROUTER_API_KEY`:\n\n```bash\ncd backend\nuv run python ../eval/run_eval.py\n```\n\n分析已有结果:\n\n```bash\npython eval/analyze_results.py \\\n --results eval/eval_results.json \\\n --cases eval/test_cases.json \\\n --output eval/analysis.json \\\n --markdown-output eval/analysis.md\n```\n\n## 性能测速\n\n项目自带一份生产模式测速脚本:\n\n```bash\ncd frontend\nnpm run perf:prod -- \\\n --frontend-url http://localhost:3000 \\\n --api-url http://localhost:8000 \\\n --runs 3 \\\n --output perf-report.json\n```\n\n它会准备测试账号、简历和面试 session,并输出:\n\n- API 探针耗时\n- 浏览器页面导航耗时\n- 平均值、P95、最大值\n\n## 设计规范\n\n前端界面以 `DESIGN.md` 为准。当前设计系统采用 Coinbase 风格:\n\n- 主色:`#0052ff`\n- 文本:`#0a0b0d`\n- 次级文字:`#5b616e`\n- 次级表面:`#eef0f3`\n- CTA 使用 56px pill 圆角\n- 蓝色只用于主要可执行操作\n"}, "6b0622861d912fb3f7c4e083156e77c27d18f940": {"t": 1785772005.6743646, "n": 5883, "h": "cf502fdf1a89e92d", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\n一个围绕「简历优化 + 模拟面试」的 AI 求职应用。\n\n前端是 Next.js 14,后端是 FastAPI。当前主流程已经收敛为一套:结构化简历编辑、Agent 流式改写、工具级 diff 确认、模拟面试与报告。\n\n## 当前功能\n\n- 账号注册、登录、刷新登录态\n- 简历上传与解析\n - 支持 `PDF`、`DOC`、`DOCX`、`TXT`\n - 后端统一归一化为结构化简历 JSON\n- 简历工作台\n - 模块化编辑:岗位、个人信息、教育、工作、项目、技能\n - 自动保存\n - 实时预览\n - 布局控制与一页适配\n - 导出 `PDF`、`DOCX`、`HTML`\n- Resume Agent\n - SSE 流式输出\n - 工具调用直接修改结构化简历\n - 修改前先展示 diff,用户确认后才落库\n- 模拟面试\n - 基于简历创建 session\n - 追问、阶段推进、结束报告\n - 面试中心查看记录\n- 语音能力\n - TTS 播报\n - ASR 文件识别与流式识别接口\n\n## 技术栈\n\n- 前端:Next.js 14、React 18、TypeScript、Tailwind CSS、Framer Motion\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic\n- AI / 语音:OpenRouter、MiniMax TTS、火山引擎 ASR\n- 测试:pytest、Playwright\n\n## 目录\n\n```text\nchat-resume/\n├── backend/\n│ ├── alembic/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── agents/\n│ │ ├── infra/\n│ │ ├── models/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ ├── e2e/\n│ ├── scripts/\n│ └── src/\n├── restart.sh\n├── backend.sh\n├── frontend.sh\n└── railway.json\n```\n\n## 关键页面\n\n- `/resumes`:简历中心\n- `/resume/[id]/edit`:简历编辑工作台\n- `/interviews`:面试中心\n- `/resume/[id]/interview`:模拟面试工作台\n\n## 本地开发\n\n环境要求:\n\n- Python 3.11+\n- Node.js 18+\n- `uv`\n\n一键重启前后端:\n\n```bash\n./restart.sh\n```\n\n终端默认显示精简日志,完整日志会写入 `backend.log` 和 `frontend.log`。需要看完整输出时:\n\n```bash\nVERBOSE=1 ./restart.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n- Web: `http://localhost:3000`\n\n也可以单独启动某一端:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 生产模式本地运行\n\n后端:\n\n```bash\ncd backend\nuv sync\nuv run alembic upgrade head\nuv run uvicorn app.main:app --host 0.0.0.0 --port 8000\n```\n\n前端:\n\n```bash\ncd frontend\nnpm run build\nnpm run start\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n常用变量:\n\n- 后端\n - `DATABASE_URL`\n - `SECRET_KEY`\n - `BACKEND_CORS_ORIGINS`\n - `OPENROUTER_API_KEY`\n - `OPENROUTER_MODEL`\n - `MINIMAX_*`\n - `VOLCENGINE_*`\n - `DIGITAL_HUMAN_PROVIDER=volcengine`\n - `VOLCENGINE_DIALOGUE_APP_KEY`\n - `VOLCENGINE_DIALOGUE_ACCESS_KEY`\n- 前端\n - `NEXT_PUBLIC_API_URL`\n\n### Google 登录 OAuth 配置\n\nGoogle 登录采用后端授权码流程。前端只跳转到后端启动端点,不处理或保存 Google token。\n\n本地开发默认值:\n\n```bash\n# backend/.env\nGOOGLE_OAUTH_CLIENT_ID=\nGOOGLE_OAUTH_CLIENT_SECRET=\nGOOGLE_OAUTH_REDIRECT_URI=http://localhost:8000/api/auth/google/callback\nFRONTEND_URL=http://localhost:3000\nBACKEND_CORS_ORIGINS=http://localhost:3000,https://localhost:3000\nAUTH_COOKIE_SECURE=false\nAUTH_COOKIE_SAMESITE=lax\nAUTH_COOKIE_DOMAIN=\n\n# frontend/.env.local\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\nGoogle Cloud Console 中创建 OAuth Client 时选择 `Web application`。Authorized redirect URIs 本地填:\n\n```text\nhttp://localhost:8000/api/auth/google/callback\n```\n\n生产环境填真实后端域名,并且必须与 `GOOGLE_OAUTH_REDIRECT_URI` 完全一致:\n\n```text\nhttps:///api/auth/google/callback\n```\n\n如果控制台要求 Authorized JavaScript origins,可填前端来源:\n\n```text\nhttp://localhost:3000\nhttps://\n```\n\n生产环境同站点或同父域部署时,Cookie 与 CORS 推荐:\n\n```bash\nFRONTEND_URL=https://\nNEXT_PUBLIC_API_URL=https://\nBACKEND_CORS_ORIGINS=https://\nAUTH_COOKIE_SECURE=true\nAUTH_COOKIE_SAMESITE=lax\nAUTH_COOKIE_DOMAIN=<可选父域名>\n```\n\n生产环境前后端跨站点部署时,浏览器要求跨站 Cookie 使用 `Secure` 和 `SameSite=None`:\n\n```bash\nBACKEND_CORS_ORIGINS=https://\nAUTH_COOKIE_SECURE=true\nAUTH_COOKIE_SAMESITE=none\nAUTH_COOKIE_DOMAIN=<后端 Cookie 可用域名>\n```\n\n常见配置错误:\n\n- Google 回调返回 `redirect_uri_mismatch`:Google Cloud Console 的 Authorized redirect URI 与 `GOOGLE_OAUTH_REDIRECT_URI` 不完全一致,包括协议、域名、端口和路径。\n- 点击“使用 Google 继续”后访问不到后端:检查 `NEXT_PUBLIC_API_URL` 是否指向后端公开地址,本地默认是 `http://localhost:8000`。\n- 登录成功后没有登录态:检查前端 API 请求是否携带 Cookie、`BACKEND_CORS_ORIGINS` 是否包含前端来源,以及生产环境是否设置了正确的 `AUTH_COOKIE_SECURE`、`AUTH_COOKIE_SAMESITE` 和 `AUTH_COOKIE_DOMAIN`。\n- 后端返回 `config_missing`:检查后端是否设置了 `GOOGLE_OAUTH_CLIENT_ID`、`GOOGLE_OAUTH_CLIENT_SECRET` 和 `GOOGLE_OAUTH_REDIRECT_URI`。\n\n## 测试\n\n后端:\n\n```bash\ncd backend\nuv run --extra dev python -m pytest tests\n```\n\n前端类型检查:\n\n```bash\ncd frontend\nnpm run type-check\n```\n\n前端 E2E:\n\n```bash\ncd frontend\nnpm run e2e\n```\n\n## 生产性能测速\n\n项目自带一份生产模式测速脚本:\n\n```bash\ncd frontend\nnpm run perf:prod -- \\\n --frontend-url http://localhost:3000 \\\n --api-url http://localhost:8000 \\\n --runs 3 \\\n --output perf-report.json\n```\n\n它会自动准备测试账号、简历和面试 session,并输出:\n\n- API 探针耗时\n- 浏览器页面导航耗时\n- 平均值、P95、最大值\n\n脚本文件:\n\n- `frontend/scripts/measure-production.mjs`\n"}, "67f8b7be2b6bbe6c97601952d86d76e549decd03": {"t": 1785772007.4397364, "n": 4031, "h": "c30799ef88b5d918", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\n一个围绕「简历优化 + 模拟面试」的 AI 求职应用。\n\n前端是 Next.js 14,后端是 FastAPI。当前主流程已经收敛为一套:结构化简历编辑、Agent 流式改写、工具级 diff 确认、模拟面试与报告。\n\n## 当前功能\n\n- 账号注册、登录、刷新登录态\n- 简历上传与解析\n - 支持 `PDF`、`DOC`、`DOCX`、`TXT`\n - 后端统一归一化为结构化简历 JSON\n- 简历工作台\n - 模块化编辑:岗位、个人信息、教育、工作、项目、技能\n - 自动保存\n - 实时预览\n - 布局控制与一页适配\n - 导出 `PDF`、`DOCX`、`HTML`\n- Resume Agent\n - SSE 流式输出\n - 工具调用直接修改结构化简历\n - 修改前先展示 diff,用户确认后才落库\n- 模拟面试\n - 基于简历创建 session\n - 追问、阶段推进、结束报告\n - 面试中心查看记录\n- 语音能力\n - TTS 播报\n - ASR 文件识别与流式识别接口\n\n## 技术栈\n\n- 前端:Next.js 14、React 18、TypeScript、Tailwind CSS、Framer Motion\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic\n- AI / 语音:OpenRouter、MiniMax TTS、火山引擎 ASR\n- 测试:pytest、Playwright\n\n## 目录\n\n```text\nchat-resume/\n├── backend/\n│ ├── alembic/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── agents/\n│ │ ├── infra/\n│ │ ├── models/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ ├── e2e/\n│ ├── scripts/\n│ └── src/\n├── restart.sh\n├── backend.sh\n├── frontend.sh\n└── railway.json\n```\n\n## 关键页面\n\n- `/resumes`:简历中心\n- `/resume/[id]/edit`:简历编辑工作台\n- `/interviews`:面试中心\n- `/resume/[id]/interview`:模拟面试工作台\n\n## 本地开发\n\n环境要求:\n\n- Python 3.11+\n- Node.js 18+\n- `uv`\n\n一键重启前后端:\n\n```bash\n./restart.sh\n```\n\n终端默认显示精简日志,完整日志会写入 `backend.log` 和 `frontend.log`。需要看完整输出时:\n\n```bash\nVERBOSE=1 ./restart.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n- Web: `http://localhost:3000`\n\n也可以单独启动某一端:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 生产模式本地运行\n\n后端:\n\n```bash\ncd backend\nuv sync\nuv run alembic upgrade head\nuv run uvicorn app.main:app --host 0.0.0.0 --port 8000\n```\n\n前端:\n\n```bash\ncd frontend\nnpm run build\nnpm run start\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n常用变量:\n\n- 后端\n - `DATABASE_URL`\n - `SECRET_KEY`\n - `BACKEND_CORS_ORIGINS`\n - `OPENROUTER_API_KEY`\n - `OPENROUTER_MODEL`\n - `MINIMAX_*`\n - `VOLCENGINE_*`\n - `DIGITAL_HUMAN_PROVIDER=volcengine`\n - `VOLCENGINE_DIALOGUE_APP_KEY`\n - `VOLCENGINE_DIALOGUE_ACCESS_KEY`\n- 前端\n - `NEXT_PUBLIC_API_URL`\n\n## 测试\n\n后端:\n\n```bash\ncd backend\nuv run --extra dev python -m pytest tests\n```\n\n前端类型检查:\n\n```bash\ncd frontend\nnpm run type-check\n```\n\n前端 E2E:\n\n```bash\ncd frontend\nnpm run e2e\n```\n\n## 生产性能测速\n\n项目自带一份生产模式测速脚本:\n\n```bash\ncd frontend\nnpm run perf:prod -- \\\n --frontend-url http://localhost:3000 \\\n --api-url http://localhost:8000 \\\n --runs 3 \\\n --output perf-report.json\n```\n\n它会自动准备测试账号、简历和面试 session,并输出:\n\n- API 探针耗时\n- 浏览器页面导航耗时\n- 平均值、P95、最大值\n\n脚本文件:\n\n- `frontend/scripts/measure-production.mjs`\n"}, "4149f51b7ad9cc8d8cc84cfb7369e653960d5cad": {"t": 1785772008.993771, "n": 4031, "h": "169051bdced1bdd1", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\n一个围绕「简历优化 + 模拟面试」的 AI 求职应用。\n\n前端是 Next.js 14,后端是 FastAPI。当前主流程已经收敛为一套:结构化简历编辑、Agent 流式改写、工具级 diff 确认、模拟面试与报告。\n\n## 当前功能\n\n- 账号注册、登录、刷新登录态\n- 简历上传与解析\n - 支持 `PDF`、`DOC`、`DOCX`、`TXT`\n - 后端统一归一化为结构化简历 JSON\n- 简历工作台\n - 模块化编辑:岗位、个人信息、教育、工作、项目、技能\n - 自动保存\n - 实时预览\n - 布局控制与一页适配\n - 导出 `PDF`、`DOCX`、`HTML`\n- Resume Agent\n - SSE 流式输出\n - 工具调用直接修改结构化简历\n - 修改前先展示 diff,用户确认后才落库\n- 模拟面试\n - 基于简历创建 session\n - 追问、阶段推进、结束报告\n - 面试中心查看记录\n- 语音能力\n - TTS 播报\n - ASR 文件识别与流式识别接口\n\n## 技术栈\n\n- 前端:Next.js 14、React 18、TypeScript、Tailwind CSS、Framer Motion\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic\n- AI / 语音:OpenRouter、MiniMax TTS、火山引擎 ASR\n- 测试:pytest、Playwright\n\n## 目录\n\n```text\nchat-resume/\n├── backend/\n│ ├── alembic/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── agents/\n│ │ ├── infra/\n│ │ ├── models/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ ├── e2e/\n│ ├── scripts/\n│ └── src/\n├── restart.sh\n├── backend.sh\n├── frontend.sh\n└── railway.json\n```\n\n## 关键页面\n\n- `/resumes`:简历中心\n- `/resume/[id]/edit`:简历编辑工作台\n- `/interviews`:面试中心\n- `/resume/[id]/interview`:模拟面试工作台\n\n## 本地开发\n\n环境要求:\n\n- Python 3.10+\n- Node.js 18+\n- `uv`\n\n一键重启前后端:\n\n```bash\n./restart.sh\n```\n\n终端默认显示精简日志,完整日志会写入 `backend.log` 和 `frontend.log`。需要看完整输出时:\n\n```bash\nVERBOSE=1 ./restart.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n- Web: `http://localhost:3000`\n\n也可以单独启动某一端:\n\n```bash\n./backend.sh\n./frontend.sh\n```\n\n## 生产模式本地运行\n\n后端:\n\n```bash\ncd backend\nuv sync\nuv run alembic upgrade head\nuv run uvicorn app.main:app --host 0.0.0.0 --port 8000\n```\n\n前端:\n\n```bash\ncd frontend\nnpm run build\nnpm run start\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n常用变量:\n\n- 后端\n - `DATABASE_URL`\n - `SECRET_KEY`\n - `BACKEND_CORS_ORIGINS`\n - `OPENROUTER_API_KEY`\n - `OPENROUTER_MODEL`\n - `MINIMAX_*`\n - `VOLCENGINE_*`\n - `DIGITAL_HUMAN_PROVIDER=volcengine`\n - `VOLCENGINE_DIALOGUE_APP_KEY`\n - `VOLCENGINE_DIALOGUE_ACCESS_KEY`\n- 前端\n - `NEXT_PUBLIC_API_URL`\n\n## 测试\n\n后端:\n\n```bash\ncd backend\nuv run --extra dev python -m pytest tests\n```\n\n前端类型检查:\n\n```bash\ncd frontend\nnpm run type-check\n```\n\n前端 E2E:\n\n```bash\ncd frontend\nnpm run e2e\n```\n\n## 生产性能测速\n\n项目自带一份生产模式测速脚本:\n\n```bash\ncd frontend\nnpm run perf:prod -- \\\n --frontend-url http://localhost:3000 \\\n --api-url http://localhost:8000 \\\n --runs 3 \\\n --output perf-report.json\n```\n\n它会自动准备测试账号、简历和面试 session,并输出:\n\n- API 探针耗时\n- 浏览器页面导航耗时\n- 平均值、P95、最大值\n\n脚本文件:\n\n- `frontend/scripts/measure-production.mjs`\n"}, "e72bd17976c9e14fd946e1acbe2c09239ddb3655": {"t": 1785772012.371795, "n": 3794, "h": "7cdff567dff1247c", "c": "# Chat Resume\n\n[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/849261680/chat-resume)\n\n一个围绕「简历优化 + 模拟面试」的 AI 求职应用。\n\n前端是 Next.js 14,后端是 FastAPI。当前主流程已经收敛为一套:结构化简历编辑、Agent 流式改写、工具级 diff 确认、模拟面试与报告。\n\n## 当前功能\n\n- 账号注册、登录、刷新登录态\n- 简历上传与解析\n - 支持 `PDF`、`DOC`、`DOCX`、`TXT`\n - 后端统一归一化为结构化简历 JSON\n- 简历工作台\n - 模块化编辑:岗位、个人信息、教育、工作、项目、技能\n - 自动保存\n - 实时预览\n - 布局控制与一页适配\n - 导出 `PDF`、`DOCX`、`HTML`\n- Resume Agent\n - SSE 流式输出\n - 工具调用直接修改结构化简历\n - 修改前先展示 diff,用户确认后才落库\n- 模拟面试\n - 基于简历创建 session\n - 追问、阶段推进、结束报告\n - 面试中心查看记录\n- 语音能力\n - TTS 播报\n - ASR 文件识别与流式识别接口\n\n## 技术栈\n\n- 前端:Next.js 14、React 18、TypeScript、Tailwind CSS、Framer Motion\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic\n- AI / 语音:OpenRouter、MiniMax TTS、火山引擎 ASR\n- 测试:pytest、Playwright\n\n## 目录\n\n```text\nchat-resume/\n├── backend/\n│ ├── alembic/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── agents/\n│ │ ├── infra/\n│ │ ├── models/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ ├── e2e/\n│ ├── scripts/\n│ └── src/\n├── backend.sh\n├── frontend.sh\n└── railway.json\n```\n\n## 关键页面\n\n- `/resumes`:简历中心\n- `/resume/[id]/edit`:简历编辑工作台\n- `/interviews`:面试中心\n- `/resume/[id]/interview`:模拟面试工作台\n\n## 本地开发\n\n环境要求:\n\n- Python 3.10+\n- Node.js 18+\n- `uv`\n\n启动后端:\n\n```bash\n./backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n启动前端:\n\n```bash\n./frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 生产模式本地运行\n\n后端:\n\n```bash\ncd backend\nuv sync\nuv run alembic upgrade head\nuv run uvicorn app.main:app --host 0.0.0.0 --port 8000\n```\n\n前端:\n\n```bash\ncd frontend\nnpm run build\nnpm run start\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n常用变量:\n\n- 后端\n - `DATABASE_URL`\n - `SECRET_KEY`\n - `BACKEND_CORS_ORIGINS`\n - `OPENROUTER_API_KEY`\n - `OPENROUTER_MODEL`\n - `MINIMAX_*`\n - `VOLCENGINE_*`\n- 前端\n - `NEXT_PUBLIC_API_URL`\n\n## 测试\n\n后端:\n\n```bash\ncd backend\nuv run --extra dev python -m pytest tests\n```\n\n前端类型检查:\n\n```bash\ncd frontend\nnpm run type-check\n```\n\n前端 E2E:\n\n```bash\ncd frontend\nnpm run e2e\n```\n\n## 生产性能测速\n\n项目自带一份生产模式测速脚本:\n\n```bash\ncd frontend\nnpm run perf:prod -- \\\n --frontend-url http://localhost:3000 \\\n --api-url http://localhost:8000 \\\n --runs 3 \\\n --output perf-report.json\n```\n\n它会自动准备测试账号、简历和面试 session,并输出:\n\n- API 探针耗时\n- 浏览器页面导航耗时\n- 平均值、P95、最大值\n\n脚本文件:\n\n- `frontend/scripts/measure-production.mjs`\n"}, "139e8a9bb29bb0a10fedc24a7fbe7e6f09503ef6": {"t": 1785772015.242909, "n": 2265, "h": "225e108cf839262a", "c": "# Chat Resume\n\n一个围绕「简历优化 + 模拟面试」的 AI 求职应用。\n\n前端是 Next.js 14,后端是 FastAPI。当前主流程已经收敛为一套:结构化简历编辑、Agent 流式改写、工具级 diff 确认、模拟面试与报告。\n\n## 当前功能\n\n- 账号注册、登录、刷新登录态\n- 简历上传与解析\n - 支持 `PDF`、`DOC`、`DOCX`、`TXT`\n - 后端统一归一化为结构化简历 JSON\n- 简历工作台\n - 模块化编辑:岗位、个人信息、教育、工作、项目、技能\n - 自动保存\n - 实时预览\n - 布局控制与一页适配\n - 导出 `PDF`、`DOCX`、`HTML`\n- Resume Agent\n - SSE 流式输出\n - 工具调用直接修改结构化简历\n - 修改前先展示 diff,用户确认后才落库\n- 模拟面试\n - 基于简历创建 session\n - 追问、阶段推进、结束报告\n - 面试中心查看记录\n- 语音能力\n - TTS 播报\n - ASR 文件识别与流式识别接口\n\n## 技术栈\n\n- 前端:Next.js 14、React 18、TypeScript、Tailwind CSS、Framer Motion\n- 后端:FastAPI、SQLAlchemy 2、Pydantic v2、Alembic\n- AI / 语音:OpenRouter、MiniMax TTS、火山引擎 ASR\n- 测试:pytest、Playwright\n\n## 目录\n\n```text\nchat-resume/\n├── backend/\n│ ├── alembic/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── agents/\n│ │ ├── infra/\n│ │ ├── models/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ ├── e2e/\n│ ├── scripts/\n│ └── src/\n├── backend.sh\n├── frontend.sh\n└── railway.json\n```\n\n## 关键页面\n\n- `/resumes`:简历中心\n- `/resume/[id]/edit`:简历编辑工作台\n- `/interviews`:面试中心\n- `/resume/[id]/interview`:模拟面试工作台\n\n## 本地开发\n\n环境要求:\n\n- Python 3.10+\n- Node.js 18+\n- `uv`\n\n启动后端:\n\n```bash\n./backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n启动前端:\n\n```bash\n./frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 生产模式本地运行\n\n后端:\n\n```bash\ncd backend\nuv sync\nuv run alembic upgrade head\nuv run uvicorn app.main:app --host 0.0.0.0 --port 8000\n```\n\n前端:\n\n```bash\ncd frontend\nnpm run build\nnpm run start\n```\n\n## 环境变量\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n常用变量:\n\n- 后端\n - `DATABASE_URL`\n - `SECRET_KEY`\n - `BACKEND_CORS_ORIGINS`\n - `OPENROUTER_API_KEY`\n - `OPENROUTER_MODEL`\n - `MINIMAX_*`\n - `VOLCENGINE_*`\n- 前端\n - `NEXT_PUBLIC_API_URL`\n\n## 测试\n\n后端:\n\n```bash\ncd backend\nuv run --extra dev python -m pytest tests\n```\n\n前端类型检查:\n\n```bash\ncd frontend\nnpm run type-check\n```\n\n前端 E2E:\n\n```bash\ncd frontend\nnpm run e2e\n```\n\n## 生产性能测速\n\n项目自带一份生产模式测速脚本:\n\n```bash\ncd frontend\nnpm run perf:prod -- \\\n --frontend-url http://localhost:3000 \\\n --api-url http://localhost:8000 \\\n --runs 3 \\\n --output perf-report.json\n```\n\n它会自动准备测试账号、简历和面试 session,并输出:\n\n- API 探针耗时\n- 浏览器页面导航耗时\n- 平均值、P95、最大值\n\n脚本文件:\n\n- `frontend/scripts/measure-production.mjs`\n"}, "50679e7d09a28b97162012821e03bfb141c8d218": {"t": 1785772017.0008235, "n": 2566, "h": "6fbe486fe7fa4848", "c": "# Chat Resume\n\n一个用 AI驱动的求职网站,具有 Agent 一键简历优化和模拟面试功能。\n\n## 功能\n\n- 简历上传与解析\n - 支持 `PDF`、`DOCX`、`DOC`、`TXT`\n - 后端将简历解析为结构化 JSON\n- 简历编辑工作台\n - 分模块编辑个人信息、教育、工作经历、项目、技能\n - 实时预览、自动保存、模块显隐、排版控制\n- Resume Agent\n - 基于当前简历内容进行分析和改写\n - 支持工具调用直接修改结构化简历\n - 支持流式输出和用户确认修改\n- 模拟面试\n - 基于简历和 JD 创建面试会话\n - 动态生成问题、记录问答、生成报告\n- 语音能力\n - TTS 面试问题播报\n - ASR 一次性识别和 WebSocket 实时识别\n- 导出\n - 支持 `PDF`、`DOCX`、`HTML`\n\n## AGENT 相关实现\n\n项目的 Agent 部分不是简单聊天封装,核心实现包括:\n\n- 通用 `AgentRuntime`\n - 负责消息构建、prompt 渲染、模型调用、工具执行和多轮循环\n- `ResumeAgent`\n - 将简历优化逻辑与通用 runtime 解耦\n - 通过 prompt + tools schema + context builder 定义业务 Agent\n- Tool Calling\n - 当前支持:\n - `edit_resume`\n - `update_resume_item`\n - `add_resume_item`\n - `remove_resume_item`\n - 工具直接修改结构化简历 JSON,而不是返回非结构化建议文本\n- Human-in-the-loop\n - 流式返回 `tool_pending`\n - 用户确认后执行真实修改\n - 用户拒绝时保持原始简历不变\n- 流式事件协议\n - SSE 同时返回文本增量、工具状态、diff 摘要和最新 `resume_content`\n- 结构化数据驱动\n - 前端编辑器、Agent、导出模块共用统一简历 schema\n\n## 技术栈\n\n### 前端\n\n- Next.js 14\n- React 18\n- TypeScript\n- Tailwind CSS\n- Framer Motion\n- Zustand\n\n### 后端\n\n- FastAPI\n- SQLAlchemy 2\n- Pydantic v2\n- httpx\n- Playwright\n- PyPDF2 / pdfplumber / python-docx\n\n### AI / 语音\n\n- OpenRouter\n- MiniMax TTS\n- 火山引擎 ASR\n\n## 项目结构\n\n```text\nchat-resume/\n├── backend/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── agents/\n│ │ ├── infra/\n│ │ ├── models/\n│ │ ├── prompts/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ └── src/\n├── docs/\n├── backend.sh\n└── frontend.sh\n```\n\n## 核心目录\n\n- `backend/app/agents/runtime/agent_runtime.py`\n - 通用 Agent Runtime\n- `backend/app/agents/definitions/resume_agent.py`\n - 简历优化 Agent\n- `backend/app/agents/tools/resume_tools/`\n - Agent 工具集合\n- `backend/app/api/endpoints/resume_agent.py`\n - Agent 聊天与流式接口\n- `frontend/src/hooks/useStreamingChat.ts`\n - 前端流式事件消费\n- `frontend/src/app/resume/[id]/edit/page.tsx`\n - 简历编辑工作台\n- `frontend/src/app/resume/[id]/interview/page.tsx`\n - 模拟面试页面\n\n## 本地运行\n\n### 环境要求\n\n- Python 3.10+\n- Node.js 18+\n\n### 启动后端\n\n```bash\n./backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n### 启动前端\n\n```bash\n./frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 环境变量\n\n后端主要变量:\n\n- `DATABASE_URL`\n- `SECRET_KEY`\n- `OPENROUTER_API_KEY`\n- `OPENROUTER_API_BASE`\n- `OPENROUTER_MODEL`\n- `MINIMAX_API_KEY`\n- `MINIMAX_GROUP_ID`\n- `VOLCENGINE_*`\n- `FRONTEND_URL`\n\n前端主要变量:\n\n- `NEXT_PUBLIC_API_URL`\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n## 测试\n\n当前测试主要覆盖:\n\n- Resume schema 归一化\n- Resume Agent smoke tests\n- 流式确认 / 拒绝逻辑\n\n运行:\n\n```bash\ncd backend\nuv run pytest tests\n```\n"}, "106146df0c0b9b3db6d20a8f77025cde92f6aa55": {"t": 1785772018.3064747, "n": 2561, "h": "3f88de2e8b4929e7", "c": "# Chat Resume\n\n一个用 AI驱动的求职网站,具有 Agent 一键简历优化和模拟面试功能。\n\n## 功能\n\n- 简历上传与解析\n - 支持 `PDF`、`DOCX`、`DOC`、`TXT`\n - 后端将简历解析为结构化 JSON\n- 简历编辑工作台\n - 分模块编辑个人信息、教育、工作经历、项目、技能\n - 实时预览、自动保存、模块显隐、排版控制\n- Resume Agent\n - 基于当前简历内容进行分析和改写\n - 支持工具调用直接修改结构化简历\n - 支持流式输出和用户确认修改\n- 模拟面试\n - 基于简历和 JD 创建面试会话\n - 动态生成问题、记录问答、生成报告\n- 语音能力\n - TTS 面试问题播报\n - ASR 一次性识别和 WebSocket 实时识别\n- 导出\n - 支持 `PDF`、`DOCX`、`HTML`\n\n## AGENT 相关实现\n\n项目的 Agent 部分不是简单聊天封装,核心实现包括:\n\n- 通用 `AgentRuntime`\n - 负责消息构建、prompt 渲染、模型调用、工具执行和多轮循环\n- `ResumeAgent`\n - 将简历优化逻辑与通用 runtime 解耦\n - 通过 prompt + tools schema + context builder 定义业务 Agent\n- Tool Calling\n - 当前支持:\n - `edit_resume`\n - `update_resume_item`\n - `add_resume_item`\n - `remove_resume_item`\n - 工具直接修改结构化简历 JSON,而不是返回非结构化建议文本\n- Human-in-the-loop\n - 流式返回 `tool_pending`\n - 用户确认后执行真实修改\n - 用户拒绝时保持原始简历不变\n- 流式事件协议\n - SSE 同时返回文本增量、工具状态、diff 摘要和最新 `resume_content`\n- 结构化数据驱动\n - 前端编辑器、Agent、导出模块共用统一简历 schema\n\n## 技术栈\n\n### 前端\n\n- Next.js 14\n- React 18\n- TypeScript\n- Tailwind CSS\n- Framer Motion\n- Zustand\n\n### 后端\n\n- FastAPI\n- SQLAlchemy 2\n- Pydantic v2\n- httpx\n- Playwright\n- PyPDF2 / pdfplumber / python-docx\n\n### AI / 语音\n\n- OpenRouter\n- MiniMax TTS\n- 火山引擎 ASR\n\n## 项目结构\n\n```text\nchat-resume/\n├── backend/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── core/\n│ │ ├── models/\n│ │ ├── prompts/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ └── src/\n├── docs/\n├── start-backend.sh\n└── start-frontend.sh\n```\n\n## 核心目录\n\n- `backend/app/services/ai/agent_runtime.py`\n - 通用 Agent Runtime\n- `backend/app/services/ai/resume_agent.py`\n - 简历优化 Agent\n- `backend/app/services/ai/resume_tools/`\n - Agent 工具集合\n- `backend/app/api/endpoints/resume_agent.py`\n - Agent 聊天与流式接口\n- `frontend/src/hooks/useStreamingChat.ts`\n - 前端流式事件消费\n- `frontend/src/app/resume/[id]/edit/page.tsx`\n - 简历编辑工作台\n- `frontend/src/app/resume/[id]/interview/page.tsx`\n - 模拟面试页面\n\n## 本地运行\n\n### 环境要求\n\n- Python 3.10+\n- Node.js 18+\n\n### 启动后端\n\n```bash\n./start-backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n### 启动前端\n\n```bash\n./start-frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 环境变量\n\n后端主要变量:\n\n- `DATABASE_URL`\n- `SECRET_KEY`\n- `OPENROUTER_API_KEY`\n- `OPENROUTER_API_BASE`\n- `OPENROUTER_MODEL`\n- `MINIMAX_API_KEY`\n- `MINIMAX_GROUP_ID`\n- `VOLCENGINE_*`\n- `FRONTEND_URL`\n\n前端主要变量:\n\n- `NEXT_PUBLIC_API_URL`\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n## 测试\n\n当前测试主要覆盖:\n\n- Resume schema 归一化\n- Resume Agent smoke tests\n- 流式确认 / 拒绝逻辑\n\n运行:\n\n```bash\ncd backend\npython -m pytest tests\n```\n"}, "251978e0878b391b4218d562f9fd018368c2ddc1": {"t": 1785772020.186362, "n": 2562, "h": "dbd148a1e3f43bf4", "c": "# Chat Resume\n\n一个用 AI 助力求助的网站,具有 Agent 一键简历优化和模拟面试功能。\n\n## 功能\n\n- 简历上传与解析\n - 支持 `PDF`、`DOCX`、`DOC`、`TXT`\n - 后端将简历解析为结构化 JSON\n- 简历编辑工作台\n - 分模块编辑个人信息、教育、工作经历、项目、技能\n - 实时预览、自动保存、模块显隐、排版控制\n- Resume Agent\n - 基于当前简历内容进行分析和改写\n - 支持工具调用直接修改结构化简历\n - 支持流式输出和用户确认修改\n- 模拟面试\n - 基于简历和 JD 创建面试会话\n - 动态生成问题、记录问答、生成报告\n- 语音能力\n - TTS 面试问题播报\n - ASR 一次性识别和 WebSocket 实时识别\n- 导出\n - 支持 `PDF`、`DOCX`、`HTML`\n\n## AGENT 相关实现\n\n项目的 Agent 部分不是简单聊天封装,核心实现包括:\n\n- 通用 `AgentRuntime`\n - 负责消息构建、prompt 渲染、模型调用、工具执行和多轮循环\n- `ResumeAgent`\n - 将简历优化逻辑与通用 runtime 解耦\n - 通过 prompt + tools schema + context builder 定义业务 Agent\n- Tool Calling\n - 当前支持:\n - `edit_resume`\n - `update_resume_item`\n - `add_resume_item`\n - `remove_resume_item`\n - 工具直接修改结构化简历 JSON,而不是返回非结构化建议文本\n- Human-in-the-loop\n - 流式返回 `tool_pending`\n - 用户确认后执行真实修改\n - 用户拒绝时保持原始简历不变\n- 流式事件协议\n - SSE 同时返回文本增量、工具状态、diff 摘要和最新 `resume_content`\n- 结构化数据驱动\n - 前端编辑器、Agent、导出模块共用统一简历 schema\n\n## 技术栈\n\n### 前端\n\n- Next.js 14\n- React 18\n- TypeScript\n- Tailwind CSS\n- Framer Motion\n- Zustand\n\n### 后端\n\n- FastAPI\n- SQLAlchemy 2\n- Pydantic v2\n- httpx\n- Playwright\n- PyPDF2 / pdfplumber / python-docx\n\n### AI / 语音\n\n- OpenRouter\n- MiniMax TTS\n- 火山引擎 ASR\n\n## 项目结构\n\n```text\nchat-resume/\n├── backend/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── core/\n│ │ ├── models/\n│ │ ├── prompts/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ └── src/\n├── docs/\n├── start-backend.sh\n└── start-frontend.sh\n```\n\n## 核心目录\n\n- `backend/app/services/ai/agent_runtime.py`\n - 通用 Agent Runtime\n- `backend/app/services/ai/resume_agent.py`\n - 简历优化 Agent\n- `backend/app/services/ai/resume_tools/`\n - Agent 工具集合\n- `backend/app/api/endpoints/resume_agent.py`\n - Agent 聊天与流式接口\n- `frontend/src/hooks/useStreamingChat.ts`\n - 前端流式事件消费\n- `frontend/src/app/resume/[id]/edit/page.tsx`\n - 简历编辑工作台\n- `frontend/src/app/resume/[id]/interview/page.tsx`\n - 模拟面试页面\n\n## 本地运行\n\n### 环境要求\n\n- Python 3.10+\n- Node.js 18+\n\n### 启动后端\n\n```bash\n./start-backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n### 启动前端\n\n```bash\n./start-frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 环境变量\n\n后端主要变量:\n\n- `DATABASE_URL`\n- `SECRET_KEY`\n- `OPENROUTER_API_KEY`\n- `OPENROUTER_API_BASE`\n- `OPENROUTER_MODEL`\n- `MINIMAX_API_KEY`\n- `MINIMAX_GROUP_ID`\n- `VOLCENGINE_*`\n- `FRONTEND_URL`\n\n前端主要变量:\n\n- `NEXT_PUBLIC_API_URL`\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n## 测试\n\n当前测试主要覆盖:\n\n- Resume schema 归一化\n- Resume Agent smoke tests\n- 流式确认 / 拒绝逻辑\n\n运行:\n\n```bash\ncd backend\npython -m pytest tests\n```\n"}, "676d8d10f50c437f1c46fa8fca5326f0a21552df": {"t": 1785772021.5955162, "n": 2558, "h": "b85a1bba44fbe2de", "c": "# Chat Resume\n\n一个用 AI 助力求助的网站,具有Agent简历优化和模拟面试功能。\n\n## 功能\n\n- 简历上传与解析\n - 支持 `PDF`、`DOCX`、`DOC`、`TXT`\n - 后端将简历解析为结构化 JSON\n- 简历编辑工作台\n - 分模块编辑个人信息、教育、工作经历、项目、技能\n - 实时预览、自动保存、模块显隐、排版控制\n- Resume Agent\n - 基于当前简历内容进行分析和改写\n - 支持工具调用直接修改结构化简历\n - 支持流式输出和用户确认修改\n- 模拟面试\n - 基于简历和 JD 创建面试会话\n - 动态生成问题、记录问答、生成报告\n- 语音能力\n - TTS 面试问题播报\n - ASR 一次性识别和 WebSocket 实时识别\n- 导出\n - 支持 `PDF`、`DOCX`、`HTML`\n\n## AGENT 相关实现\n\n项目的 Agent 部分不是简单聊天封装,核心实现包括:\n\n- 通用 `AgentRuntime`\n - 负责消息构建、prompt 渲染、模型调用、工具执行和多轮循环\n- `ResumeAgent`\n - 将简历优化逻辑与通用 runtime 解耦\n - 通过 prompt + tools schema + context builder 定义业务 Agent\n- Tool Calling\n - 当前支持:\n - `edit_resume`\n - `update_resume_item`\n - `add_resume_item`\n - `remove_resume_item`\n - 工具直接修改结构化简历 JSON,而不是返回非结构化建议文本\n- Human-in-the-loop\n - 流式返回 `tool_pending`\n - 用户确认后执行真实修改\n - 用户拒绝时保持原始简历不变\n- 流式事件协议\n - SSE 同时返回文本增量、工具状态、diff 摘要和最新 `resume_content`\n- 结构化数据驱动\n - 前端编辑器、Agent、导出模块共用统一简历 schema\n\n## 技术栈\n\n### 前端\n\n- Next.js 14\n- React 18\n- TypeScript\n- Tailwind CSS\n- Framer Motion\n- Zustand\n\n### 后端\n\n- FastAPI\n- SQLAlchemy 2\n- Pydantic v2\n- httpx\n- Playwright\n- PyPDF2 / pdfplumber / python-docx\n\n### AI / 语音\n\n- OpenRouter\n- MiniMax TTS\n- 火山引擎 ASR\n\n## 项目结构\n\n```text\nchat-resume/\n├── backend/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── core/\n│ │ ├── models/\n│ │ ├── prompts/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ └── src/\n├── docs/\n├── start-backend.sh\n└── start-frontend.sh\n```\n\n## 核心目录\n\n- `backend/app/services/ai/agent_runtime.py`\n - 通用 Agent Runtime\n- `backend/app/services/ai/resume_agent.py`\n - 简历优化 Agent\n- `backend/app/services/ai/resume_tools/`\n - Agent 工具集合\n- `backend/app/api/endpoints/resume_agent.py`\n - Agent 聊天与流式接口\n- `frontend/src/hooks/useStreamingChat.ts`\n - 前端流式事件消费\n- `frontend/src/app/resume/[id]/edit/page.tsx`\n - 简历编辑工作台\n- `frontend/src/app/resume/[id]/interview/page.tsx`\n - 模拟面试页面\n\n## 本地运行\n\n### 环境要求\n\n- Python 3.10+\n- Node.js 18+\n\n### 启动后端\n\n```bash\n./start-backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n### 启动前端\n\n```bash\n./start-frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 环境变量\n\n后端主要变量:\n\n- `DATABASE_URL`\n- `SECRET_KEY`\n- `OPENROUTER_API_KEY`\n- `OPENROUTER_API_BASE`\n- `OPENROUTER_MODEL`\n- `MINIMAX_API_KEY`\n- `MINIMAX_GROUP_ID`\n- `VOLCENGINE_*`\n- `FRONTEND_URL`\n\n前端主要变量:\n\n- `NEXT_PUBLIC_API_URL`\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n## 测试\n\n当前测试主要覆盖:\n\n- Resume schema 归一化\n- Resume Agent smoke tests\n- 流式确认 / 拒绝逻辑\n\n运行:\n\n```bash\ncd backend\npython -m pytest tests\n```\n"}, "8b2528cad53ca9c7fd93e35592da32f5724eb9a9": {"t": 1785772023.2512553, "n": 2586, "h": "278f098b5f92f1df", "c": "# Chat Resume\n\n一个基于 LLM 的简历优化与模拟面试项目,包含结构化简历编辑、Agent 改写、流式交互、面试会话、语音能力和多格式导出。\n\n## 功能\n\n- 简历上传与解析\n - 支持 `PDF`、`DOCX`、`DOC`、`TXT`\n - 后端将简历解析为结构化 JSON\n- 简历编辑工作台\n - 分模块编辑个人信息、教育、工作经历、项目、技能\n - 实时预览、自动保存、模块显隐、排版控制\n- Resume Agent\n - 基于当前简历内容进行分析和改写\n - 支持工具调用直接修改结构化简历\n - 支持流式输出和用户确认修改\n- 模拟面试\n - 基于简历和 JD 创建面试会话\n - 动态生成问题、记录问答、生成报告\n- 语音能力\n - TTS 面试问题播报\n - ASR 一次性识别和 WebSocket 实时识别\n- 导出\n - 支持 `PDF`、`DOCX`、`HTML`\n\n## AGENT 相关实现\n\n项目的 Agent 部分不是简单聊天封装,核心实现包括:\n\n- 通用 `AgentRuntime`\n - 负责消息构建、prompt 渲染、模型调用、工具执行和多轮循环\n- `ResumeAgent`\n - 将简历优化逻辑与通用 runtime 解耦\n - 通过 prompt + tools schema + context builder 定义业务 Agent\n- Tool Calling\n - 当前支持:\n - `edit_resume`\n - `update_resume_item`\n - `add_resume_item`\n - `remove_resume_item`\n - 工具直接修改结构化简历 JSON,而不是返回非结构化建议文本\n- Human-in-the-loop\n - 流式返回 `tool_pending`\n - 用户确认后执行真实修改\n - 用户拒绝时保持原始简历不变\n- 流式事件协议\n - SSE 同时返回文本增量、工具状态、diff 摘要和最新 `resume_content`\n- 结构化数据驱动\n - 前端编辑器、Agent、导出模块共用统一简历 schema\n\n## 技术栈\n\n### 前端\n\n- Next.js 14\n- React 18\n- TypeScript\n- Tailwind CSS\n- Framer Motion\n- Zustand\n\n### 后端\n\n- FastAPI\n- SQLAlchemy 2\n- Pydantic v2\n- httpx\n- Playwright\n- PyPDF2 / pdfplumber / python-docx\n\n### AI / 语音\n\n- OpenRouter\n- MiniMax TTS\n- 火山引擎 ASR\n\n## 项目结构\n\n```text\nchat-resume/\n├── backend/\n│ ├── app/\n│ │ ├── api/\n│ │ ├── core/\n│ │ ├── models/\n│ │ ├── prompts/\n│ │ ├── schemas/\n│ │ └── services/\n│ └── tests/\n├── frontend/\n│ └── src/\n├── docs/\n├── start-backend.sh\n└── start-frontend.sh\n```\n\n## 核心目录\n\n- `backend/app/services/ai/agent_runtime.py`\n - 通用 Agent Runtime\n- `backend/app/services/ai/resume_agent.py`\n - 简历优化 Agent\n- `backend/app/services/ai/resume_tools/`\n - Agent 工具集合\n- `backend/app/api/endpoints/resume_agent.py`\n - Agent 聊天与流式接口\n- `frontend/src/hooks/useStreamingChat.ts`\n - 前端流式事件消费\n- `frontend/src/app/resume/[id]/edit/page.tsx`\n - 简历编辑工作台\n- `frontend/src/app/resume/[id]/interview/page.tsx`\n - 模拟面试页面\n\n## 本地运行\n\n### 环境要求\n\n- Python 3.10+\n- Node.js 18+\n\n### 启动后端\n\n```bash\n./start-backend.sh\n```\n\n默认地址:\n\n- API: `http://localhost:8000`\n- Docs: `http://localhost:8000/docs`\n\n### 启动前端\n\n```bash\n./start-frontend.sh\n```\n\n默认地址:\n\n- Web: `http://localhost:3000`\n\n## 环境变量\n\n后端主要变量:\n\n- `DATABASE_URL`\n- `SECRET_KEY`\n- `OPENROUTER_API_KEY`\n- `OPENROUTER_API_BASE`\n- `OPENROUTER_MODEL`\n- `MINIMAX_API_KEY`\n- `MINIMAX_GROUP_ID`\n- `VOLCENGINE_*`\n- `FRONTEND_URL`\n\n前端主要变量:\n\n- `NEXT_PUBLIC_API_URL`\n\n示例文件:\n\n- `backend/.env.example`\n- `frontend/.env.example`\n\n## 测试\n\n当前测试主要覆盖:\n\n- Resume schema 归一化\n- Resume Agent smoke tests\n- 流式确认 / 拒绝逻辑\n\n运行:\n\n```bash\ncd backend\npython -m pytest tests\n```\n"}, "f072ee862cdabffb0f569c7e32a36d70df76c5f1": {"t": 1785772026.6280706, "n": 1699, "h": "4a9a6c18b6bd693c", "c": "# Chat Resume\n\nAI 驱动的简历优化和模拟面试平台,帮助用户创建专业简历并提升面试技能。\n\n## ✨ 主要功能\n\n- 🤖 **AI 智能解析** - 自动提取和结构化简历内容\n- 📝 **实时编辑预览** - 所见即所得的简历编辑体验\n- 💡 **智能优化建议** - AI 助手提供个性化简历优化指导\n- 🎯 **模拟面试训练** - 与 AI 面试官进行真实面试演练\n- 📊 **面试评分分析** - 详细的面试表现反馈和改进建议\n- 📄 **多格式导出** - 支持 PDF、Word 等多种格式导出\n\n## 🏗️ 技术栈\n\n### 后端\n\n- **FastAPI** - 现代化的 Python Web 框架\n- **SQLAlchemy** - 强大的 ORM 数据库操作\n- **PostgreSQL** - 可靠的关系型数据库\n- **Redis** - 高性能缓存和会话存储\n- **Alembic** - 数据库版本管理\n\n### 前端\n\n- **Next.js 14** - React 全栈框架\n- **TypeScript** - 类型安全的 JavaScript\n- **Tailwind CSS** - 实用优先的 CSS 框架\n- **Zustand** - 轻量级状态管理\n- **Framer Motion** - 流畅的动画库\n\n### AI 服务\n\n- **OpenRouter** - 多模型 AI 服务集成\n- **火山引擎** - 语音识别和合成服务\n- **spaCy** - 自然语言处理\n\n## 🚀 快速开始\n\n### 环境要求\n\n- Python 3.8+\n- Node.js 18+\n- PostgreSQL 13+\n- Redis 6+\n\n### 安装步骤\n\n1. **克隆项目**\n\n```bash\ngit clone \ncd chat-resume\n```\n\n2. **启动后端**\n\n```bash\n./start-backend.sh\n```\n\n3. **启动前端**\n\n```bash\n./start-frontend.sh\n```\n\n4. **访问应用**\n\n- 前端地址: http://localhost:3000\n- 后端 API: http://localhost:8000\n- API 文档: http://localhost:8000/docs\n\n## 📁 项目结构\n\n```\nchat-resume/\n├── backend/ # FastAPI后端服务\n│ ├── app/\n│ │ ├── api/ # API路由端点\n│ │ ├── core/ # 核心配置和工具\n│ │ ├── models/ # 数据库模型\n│ │ ├── schemas/ # Pydantic数据模式\n│ │ └── services/ # 业务逻辑服务\n│ └── alembic/ # 数据库迁移文件\n├── frontend/ # Next.js前端应用\n│ ├── src/\n│ │ ├── app/ # App Router页面\n│ │ ├── components/ # React组件\n│ │ └── lib/ # 工具函数和配置\n└── docs/ # 项目文档\n```\n\n## 🔧 开发工具\n\n项目使用以下工具确保代码质量:\n\n- **Ruff** - Python 代码格式化和检查\n- **ty** - Python 类型检查\n- **ESLint** - JavaScript 代码检查\n\n## 📄 许可证\n\nMIT License - 详见 [LICENSE](LICENSE) 文件\n\n## 🤝 贡献\n\n欢迎提交 Issue 和 Pull Request 来改进项目!\n"}}}}