Files

1 line
235 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"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://<BACKEND_PUBLIC_HOST>/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://<BACKEND_PUBLIC_HOST>/api/auth/google/callback\n```\n\n如果控制台要求 Authorized JavaScript origins,可填前端来源:\n\n```text\nhttp://localhost:3000\nhttps://<FRONTEND_PUBLIC_HOST>\n```\n\n生产环境同站点或同父域部署时,Cookie 与 CORS 推荐:\n\n```bash\nFRONTEND_URL=https://<FRONTEND_PUBLIC_HOST>\nNEXT_PUBLIC_API_URL=https://<BACKEND_PUBLIC_HOST>\nBACKEND_CORS_ORIGINS=https://<FRONTEND_PUBLIC_HOST>\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://<FRONTEND_PUBLIC_HOST>\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 <repository-url>\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"}}}}