English version: see
README.en.md
当前仓库是一个用于 AI 简历优化与岗位判断流程的 MVP 单仓项目,定位为轻量级、本地单用户的简历展示型 Agent 项目(暂不考虑多用户与商业化账户体系)。
目标是以最快速度形成可演示、可验证、可讲清楚的项目闭环。当前判断为:免费入口仅能展示单次简历优化,核心业务价值在付费顾问工作台;工作台默认 chat 优先,在需要完整岗位判断或简历优化时通过表单中断固化关键信息。
- 付费工作台 chat 主路径:
/api/workspace/verify-key→bootstrap/chat/intake/memory-flush(页面/workspace) - Access key 门禁:本地测试 key
yxl(使用仓库根目录.env中的DEEPSEEK_API_KEY转发给 Agent);或PAID_ACCESS_KEYS中配置的 key - 意图分流(关键词):
quick_qa/deep_consultation(见 Agentintent_service.DEEP_KEYWORDS) - 深咨询:弹 intake 表单 → 提交后自动续聊(LLM 分析 + 可选
followup_question),无需再发第二条消息 - 长期记忆 JSON(
apps/web/data/local-store.json):经 AgentPOST /memory/extractLLM 抽取后写入(非直写);bootstrap 注入memory_summary - 记忆抽取触发:深咨询每 5 轮 / 轻量每 10 轮 / 累计 10000 tokens / 刷新前
page_unload/ intake 提交;范围均为上次抽取位置至今;抽取后轮次与 token 清零 - 会话:刷新页面 = 新对话(不恢复消息列表);刷新前强制 flush 一次
- LLM:LiteLLM;Web 与 Agent 均读取仓库根目录
.env;未配置 key 时付费 chat 模板兜底 - 交互:Enter 发送、Shift+Enter 换行;助手回复时显示加载态
- 本地一键启动:
scripts/dev-local.sh(端口占用时先结束旧进程) - 免费简历:
/free单列布局(使用方式 → 简历输入);/api/free-resume;FREE_RESUME_MAX_TOKENS默认 8192;截断时返回truncated并提示 - 旧版 token 会话 API:
/api/session/*(非工作台主 demo) - 测试:Vitest、pytest、Playwright E2E(端到端浏览器自动化,见下文「验证方式」)
- 决策报告页数据接通:
/report/[reportId]仍为结构壳层,无 chat 生成的真实报告 - 报告持久化与跳转:无
decision_reports落库、无从 chat 一键进入报告 - 完整岗位判断报告链路:深咨询后的结构化多维结论、简历交付物与报告页联动
- 多用户隔离、账户体系、跨设备会话恢复
- token 消耗、账本权威写入、扣费一致性、对账等能力
- Go 业务平台下沉与三层拆分(Next.js / Go / Python)
- 第三方售卖平台回调、风控规则、运营策略
- 生产化部署链路完善与复杂基础设施治理
低优先任务统一维护在 docs/backlog.md。
apps/web:基于 Next.js 的 Web 应用,包含免费单次简历优化入口,以及作为当前主线的付费顾问工作台(chat + 表单中断)与报告页流程services/agent:基于 FastAPI 的 Agent 服务,为当前 MVP 使用到的 Web API 路由提供后端能力.env.example:当前 Web 与 Agent 本地运行所需的环境变量模板docker-compose.yml:目前仅为脚手架占位文件,并不是当前 MVP 的主要启动方式
- 前端:
Next.js、React、TypeScript - Web 测试:
Vitest、Playwright - Agent 服务:
Python、FastAPI、Pydantic - AI 能力:
LiteLLM(支持 DeepSeek / Claude 等) - 本地存储:
JSON文件(apps/web/data/local-store.json) - 本地联调:
npm、pytest
- 将仓库根目录
.env.example复制为.env(Web 与 Agent 共用,勿使用apps/web/.env.local)。 - 本地记忆数据默认写入
apps/web/data/local-store.json(首次写入时自动创建,无需 SQLite)。 - 安装依赖:
cd apps/web && npm install;cd services/agent && pip install -e ".[test]"(含litellm,LLM 功能必需)。 - 在
.env配置DEEPSEEK_API_KEY(或其它 LiteLLM 支持的 key);未配置时付费 chat 返回模板兜底。 LLM_MODEL默认deepseek/deepseek-chat;FREE_RESUME_MAX_TOKENS默认8192(免费简历输出上限)。- 保持
NEXT_PUBLIC_AGENT_API_URL与AGENT_BASE_URL指向http://127.0.0.1:8000。 - 可选
PAID_ACCESS_KEYS(旧版 token 会话);工作台主路径不扣 token。 apps/web/next.config.ts启动时会加载根目录.env;./scripts/dev-local.sh也会source同一文件。
在仓库根目录执行(会自动加载根目录 .env,缺依赖时尝试安装):
chmod +x scripts/dev-local.sh # 首次需要
./scripts/dev-local.sh脚本会先后台启动 Agent(127.0.0.1:8000),再前台启动 Web(127.0.0.1:3000);按 Ctrl+C 会同时结束两者。
若对应端口已有进程在监听(包括上次未关干净的实例),脚本会先 终止旧进程再启动新实例,可直接重复执行以重启本地环境。
可选环境变量:AGENT_PORT、WEB_PORT、AGENT_HOST、WEB_HOST。
先启动 Agent 服务:
cd services/agent
pip install -e ".[test]"
set -a && source ../../.env && set +a
python3 -m uvicorn app.main:app --host 127.0.0.1 --port 8000再在另一个终端启动 Web(next.config.ts 会加载根目录 .env):
cd apps/web
npm run dev -- --hostname 127.0.0.1 --port 3000当前建议访问的页面:
http://127.0.0.1:3000/http://127.0.0.1:3000/freehttp://127.0.0.1:3000/workspacehttp://127.0.0.1:3000/report/demo-report
- Mermaid 源文件:
docs/architecture/mvp-architecture.mmd - SVG 图:
docs/architecture/mvp-architecture.svg
架构图源文件与 README 内嵌 Mermaid 保持一致。若需更新 PNG/SVG,在本地对 docs/architecture/mvp-architecture.mmd 运行 Mermaid CLI(例如 npx @mermaid-js/mermaid-cli -i ... -o ...)。
flowchart LR
User["用户 / Browser"] --> Web["apps/web\nNext.js + React + TypeScript"]
Web -->|免费简历优化| FreeAPI["/api/free-resume"]
Web -->|工作台 verify-key| VerifyAPI["/api/workspace/verify-key"]
Web -->|工作台 bootstrap| BootstrapAPI["/api/workspace/bootstrap"]
Web -->|工作台 chat| WorkspaceChatAPI["/api/workspace/chat"]
Web -->|工作台 intake| WorkspaceIntakeAPI["/api/workspace/intake"]
Web -->|记忆抽取 flush| MemoryFlushAPI["/api/workspace/memory-flush"]
Web -->|旧版 token 会话| SessionAPI["/api/session/*"]
VerifyAPI --> KeyAuth["Access Key\nyxl → 根目录 .env\n或 PAID_ACCESS_KEYS"]
FreeAPI --> Agent["services/agent\nFastAPI + Pydantic"]
WorkspaceChatAPI --> Agent
MemoryFlushAPI --> Agent
WorkspaceIntakeAPI --> Agent
SessionAPI --> Agent
Agent --> MemoryExtract["POST /memory/extract\nLLM 结构化抽取"]
MemoryExtract --> JsonStore["local-store.json\nmemories + intakeSnapshots"]
BootstrapAPI --> JsonStore
WorkspaceIntakeAPI --> JsonStore
SessionAPI --> KeyState["Session 内存"]
Agent --> LLM["LiteLLM"]
Web --> Pages["/\n/free\n/workspace\n/report"]
Web 单元测试:
cd apps/web
npm run test:unit这部分覆盖了仓库内的 Next.js 路由与辅助逻辑,包括付费会话相关 API 行为。但这些测试并不能证明浏览器界面已经真正接入实时付费会话。
Agent 测试:
cd services/agent
python3 -m pytest这部分覆盖了 FastAPI 服务自身的独立行为。
E2E = End-to-End:用 Playwright 驱动真实浏览器,从用户视角点击页面、填表、断言 UI 结果。本仓库 E2E 在 apps/web/tests/e2e/,运行:
cd apps/web
npm run test:e2e覆盖首页、/free、/workspace、/report/[reportId] 等。注意:/free 的 E2E 会 mock POST /api/free-resume,只验证前端交互,不能代替「真实 Agent + LLM」联调;后者请用手动冒烟清单。
如果你想做自动化测试之外的本地人工确认,可以按下面步骤执行:
- 打开
/,确认它能跳转到/free与/workspace - 打开
/free,在本地 Agent 服务运行时提交简历文本和岗位描述 - 打开
/workspace(记忆文件apps/web/data/local-store.json)- 输入 access key:
yxl(需根目录.env中DEEPSEEK_API_KEY)或PAID_ACCESS_KEYS中的 key - 确认进入 chat(非独立表单页)
- 轻量问题(如「简历项目经历怎么写一行?」)→ 配置 key 后应有 LLM 回复
- 「深度咨询」或「这个岗位值得投吗」→ 弹表单 → 提交后经 LLM 抽取记忆 + 系统摘要,并自动出现助手分析(加载态)与可选补问
- 多轮对话后(或累计 token 达标)应更新记忆摘要横幅;刷新前会 flush 未抽取片段
- 刷新页面 → 消息清空;再次进入可见记忆摘要横幅(若曾有成功抽取)
- 输入 access key:
/report/demo-report:仍为报告壳层,无真实生成数据- (可选)旧版
POST /api/session/*
免费流程与工作台均需 Agent 可访问,且在根目录 .env 配置 DEEPSEEK_API_KEY。