Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Week 1 FastAPI Service

第 1 周目标:跑通一个最小后端服务,掌握 Git、Docker、HTTP API、FastAPI、文件上传和基础调试。

功能

  • GET /health:健康检查。
  • GET /ready:部署就绪检查,确认上传目录、LLM 配置、向量库配置可用。
  • GET /metrics:查看服务运行指标,包括请求数、平均耗时和最后一次请求。
  • GET /logs/recent:查看最近请求日志,包括 request_id、路径、状态码和耗时。
  • GET /ui/:JD/简历匹配主页面,支持上传 JD、上传简历、生成匹配报告、运行 LangGraph Agent,RAG 作为辅助资料检索能力。
  • 可选 API Key 鉴权:设置 APP_API_KEY 后,写入类和模型调用类接口需要请求头 X-API-Key
  • GET /rate-limit/status:查看当前限流配置,默认保护写入类和模型调用类接口。
  • POST /chat:聊天接口占位,当前返回 echo,后续替换为 LLM/RAG 调用。
  • POST /rag-chat:最小版 RAG 问答,先检索资料片段,再拼接 prompt,然后交给 LLM provider。
  • POST /rag-evaluate:评测最小 RAG 链路是否命中资料、是否生成 prompt 和回答。
  • POST /jd/analyze:分析岗位 JD,抽取技能、职责、要求、关键词和技能分类。
  • POST /resume/analyze:分析简历,抽取技能、项目经历、工作经历和关键词。
  • POST /match:对比 JD 和简历,计算匹配度、已覆盖技能和缺失技能。
  • POST /gap-plan:根据匹配结果生成技能差距、周计划、项目行动和简历优化建议。
  • POST /agent/chat:LangGraph Agent 接口,把 JD 分析、简历分析、匹配和学习计划编排成一个工作流。
  • POST /upload:文件上传接口,支持 .txt.md.csv.json.pdf,用于上传岗位 JD、简历和可选学习资料。
  • POST /ingest/{filename}:把已上传文本切块、生成向量,并写入 Chroma 向量数据库。
  • GET /collections:查看本地 Chroma 向量库里的 collection 和文档块数量。
  • GET /uploads:查看已经上传到后端的文件。
  • GET /uploads/{filename}/preview:预览文件内容,支持 .txt.md.csv.json,并通过 pypdf 支持可提取文本的 PDF。
  • GET /uploads/{filename}/chunks:把文本文件切成 RAG 后续可检索的小块。
  • GET /uploads/{filename}/embeddings:把每个 chunk 转成教学版向量。
  • GET /uploads/{filename}/search:用问题检索最相关的 chunk。
  • GET /uploads/{filename}/vector-search:从 Chroma 向量数据库检索最相关的 chunk。
  • GET /docs:FastAPI 自动生成的 Swagger API 文档。

本地运行

cd C:\Users\wcy\Documents\vibcoding\apps\week1-fastapi-service
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000

打开:

项目页面使用流程

推荐优先打开项目页面,不需要一直在 Swagger 里手动复制参数:

http://127.0.0.1:8000/ui/

页面里的主演示流程:

  1. 在左侧“岗位 JD”区域上传 JD 文件,页面会自动读取正文并填入 JD 输入框。
  2. 在左侧“我的简历”区域上传简历文件,页面会自动读取正文并填入简历输入框。
  3. 点击“生成匹配报告”,查看匹配分、已覆盖技能、缺失技能、优先补齐方向和周学习计划。
  4. 输入 Agent 问题并点击“运行 Agent”,查看 LangGraph 如何串联 JD 分析、简历分析、匹配度计算、学习计划生成和可选 RAG 检索。
  5. 如果需要演示知识库能力,再切换到“辅助资料 RAG”,上传学习资料并执行预览、切分、入库、检索问答。

页面不会默认固定填入 JD 和简历;“演示数据”按钮只用于快速演示。示例文件在 docs/demo-jd.mddocs/demo-resume.md

Docker 运行

先复制环境变量文件:

Copy-Item .env.example .env
docker compose up --build

服务地址:

http://127.0.0.1:8000

项目页面:

http://127.0.0.1:8000/ui/

接口示例

健康检查:

Invoke-RestMethod http://127.0.0.1:8000/health

部署就绪检查:

Invoke-RestMethod http://127.0.0.1:8000/ready

运行指标:

Invoke-RestMethod http://127.0.0.1:8000/metrics

最近请求日志:

Invoke-RestMethod "http://127.0.0.1:8000/logs/recent?limit=5"

限流状态:

Invoke-RestMethod http://127.0.0.1:8000/rate-limit/status

可选 API Key 鉴权:

默认不启用鉴权。启用后,下面几个接口需要请求头 X-API-Key

POST /chat
POST /rag-chat
POST /rag-evaluate
POST /jd/analyze
POST /resume/analyze
POST /match
POST /gap-plan
POST /agent/chat
POST /upload
POST /ingest/{filename}

本地启动前设置:

$env:APP_API_KEY = "dev-secret"
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000

PowerShell 请求时带请求头:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/chat `
  -Headers @{"X-API-Key"="dev-secret"} `
  -ContentType "application/json" `
  -Body '{"message":"我正在学习大模型应用开发","session_id":"demo"}'

聊天接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/chat `
  -ContentType "application/json" `
  -Body '{"message":"我正在学习大模型应用开发","session_id":"demo"}'

最小版 RAG 问答接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/rag-chat `
  -ContentType "application/json" `
  -Body '{"message":"RAG 是什么?","filename":"把这里换成saved_filename.md","session_id":"demo","top_k":3,"chunk_size":500,"overlap":80}'

如果你已经执行过 /ingest/{filename}/rag-chat 会优先使用 Chroma 检索;如果还没入库,会退回到本地文件检索。

最小版 RAG 评测接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/rag-evaluate `
  -ContentType "application/json" `
  -Body '{"message":"RAG 是什么?","filename":"把这里换成saved_filename.md","session_id":"demo","top_k":3,"chunk_size":500,"overlap":80,"min_score":0.2}'

岗位 JD 分析接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/jd/analyze `
  -ContentType "application/json" `
  -Body '{"jd_text":"负责大模型 RAG 知识库系统开发,熟悉 Python、FastAPI、Chroma、Agent、Prompt Engineering、Ragas 和 Langfuse。","max_keywords":20}'

也可以先用 /upload 上传 JD 文本文件,再这样分析:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/jd/analyze `
  -ContentType "application/json" `
  -Body '{"filename":"把这里换成saved_filename.md","max_keywords":20}'

简历分析接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/resume/analyze `
  -ContentType "application/json" `
  -Body '{"resume_text":"项目:大模型 JD 简历匹配 RAG-Agent。使用 FastAPI、Chroma、RAG、Agent、Docker、Ragas 和 Langfuse,实现上传、检索、评测和技能差距分析。","max_keywords":20}'

也可以先用 /upload 上传简历文本文件,再这样分析:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/resume/analyze `
  -ContentType "application/json" `
  -Body '{"filename":"把这里换成saved_filename.md","max_keywords":20}'

JD 和简历匹配接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/match `
  -ContentType "application/json" `
  -Body '{"jd_text":"要求熟悉 Python、FastAPI、RAG、Chroma、Agent、LangGraph、Ragas 和 Langfuse。","resume_text":"项目:使用 FastAPI、Chroma 和 RAG 做过知识库问答,加入 Docker 和基础评测。","max_keywords":20}'

也可以用已经上传的 JD 和简历文件:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/match `
  -ContentType "application/json" `
  -Body '{"jd_filename":"把这里换成JD的saved_filename.md","resume_filename":"把这里换成简历的saved_filename.md","max_keywords":20}'

技能差距和学习计划接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/gap-plan `
  -ContentType "application/json" `
  -Body '{"jd_text":"要求熟悉 Python、FastAPI、RAG、Chroma、Agent、LangGraph、Ragas 和 Langfuse。","resume_text":"项目:使用 FastAPI、Chroma 和 RAG 做过知识库问答,加入 Docker 和基础评测。","max_keywords":20,"weeks":4}'

返回里重点看:

match_score       当前匹配分
priority_gaps     优先补齐的技能缺口
weekly_plan       每周学习任务和交付物
resume_actions    简历改进动作
project_actions   项目改进动作

LangGraph Agent 接口:

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/agent/chat `
  -ContentType "application/json" `
  -Body '{"message":"我和这个岗位差距在哪里?请给我第一周任务。","jd_text":"要求熟悉 Python、FastAPI、RAG、Chroma、Agent、LangGraph、Ragas 和 Langfuse。","resume_text":"项目:使用 FastAPI、Chroma 和 RAG 做过知识库问答,加入 Docker 和基础评测。","max_keywords":20,"weeks":4}'

返回里重点看:

framework        当前编排框架,应该是 LangGraph
workflow         Agent 图里的节点顺序
tool_calls       每个工具节点是否执行、为什么执行、执行摘要
match_score      当前岗位匹配分
missing_skills   当前缺失技能
weekly_plan      Agent 汇总出来的周计划

大模型配置:

默认不调用外部模型,LLM_PROVIDER=stub 会返回教学版回答。以后要接真实大模型,先复制一份本地配置文件:

Copy-Item .env.example .env

然后打开 .env,如果使用 Qwen / 通义千问,改成:

LLM_PROVIDER=qwen
LLM_API_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_API_KEY=替换成你的 API Key
LLM_MODEL=qwen2.5-7b-instruct

如果你使用的是其他兼容 OpenAI Chat Completions 格式的平台,比如 OpenRouter、硅基流动等,使用:

LLM_PROVIDER=openai-compatible
LLM_API_BASE_URL=替换成平台提供的 base_url
LLM_API_KEY=替换成你的 API Key
LLM_MODEL=替换成平台提供的模型名

.env 已经被 .gitignore 排除,不会上传 GitHub。配置完成后重启服务:

python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000

配置真实大模型后,/chat 会直接调用模型,/rag-chat 会把检索片段拼成 prompt 后调用模型,/jd/analyze/resume/analyze 会优先用模型抽取结构化 JSON,失败时自动退回规则词典。/match/gap-plan/agent/chat 在同时拿到 JD 和简历时会优先使用一次“JD+简历联合抽取”,减少模型调用次数,再由代码完成匹配分计算和后续计划生成。

如果使用 OpenRouter,可以参考:

LLM_PROVIDER=openai-compatible
LLM_API_BASE_URL=https://openrouter.ai/api/v1
LLM_API_KEY=替换成你的 OpenRouter API Key
LLM_MODEL=替换成 OpenRouter 模型名

文件上传:

curl.exe -X POST http://127.0.0.1:8000/upload `
  -F "file=@README.md"

查看已经上传的文件:

Invoke-RestMethod http://127.0.0.1:8000/uploads

预览某个已经上传的文本文件:

Invoke-RestMethod http://127.0.0.1:8000/uploads/把这里换成saved_filename.md/preview

切分某个已经上传的文本文件:

Invoke-RestMethod "http://127.0.0.1:8000/uploads/把这里换成saved_filename.md/chunks?chunk_size=500&overlap=80"

生成某个已经上传文本文件的教学版 embedding:

Invoke-RestMethod "http://127.0.0.1:8000/uploads/把这里换成saved_filename.md/embeddings?chunk_size=500&overlap=80"

把某个已经上传的文本文件写入 Chroma:

Invoke-RestMethod `
  -Method Post `
  -Uri "http://127.0.0.1:8000/ingest/把这里换成saved_filename.md?chunk_size=500&overlap=80"

查看 Chroma collection:

Invoke-RestMethod http://127.0.0.1:8000/collections

检索某个已经上传文本文件里的相关片段:

Invoke-RestMethod "http://127.0.0.1:8000/uploads/把这里换成saved_filename.md/search?query=RAG&top_k=3&chunk_size=500&overlap=80"

从 Chroma 检索某个已经入库文件里的相关片段:

Invoke-RestMethod "http://127.0.0.1:8000/uploads/把这里换成saved_filename.md/vector-search?query=RAG&top_k=3"

一键验证核心接口:

powershell -ExecutionPolicy Bypass -File .\scripts\smoke_test.ps1

你需要能解释清楚

  • /health/ready 的区别:前者表示服务活着,后者表示服务准备好接请求。
  • /metrics 为什么能帮助你观察服务运行状态。
  • request_id 为什么能帮助你定位一次具体请求。
  • /logs/recent 为什么不能记录请求正文和密钥。
  • X-API-Key 为什么能保护上传和大模型调用接口。
  • rate limit 为什么能保护服务器和模型调用成本。
  • Docker Compose 中 portsvolumesenv_file 的作用。
  • /chat 为什么先做成本地 stub,后续如何替换为 LLM API。
  • /rag-chat 如何把用户问题、检索结果、prompt 和 LLM provider 串起来。
  • /rag-evaluate 如何用 checks 判断 RAG 链路是否基本可用。
  • /jd/analyze 如何把岗位 JD 转成结构化技能分类,后续用于简历匹配。
  • /resume/analyze 如何把简历转成结构化技能、项目和经验,后续用于匹配度计算。
  • /match 如何用集合交集和差集计算匹配技能、缺失技能和整体匹配度。
  • /gap-plan 如何把缺失技能转成可执行的周计划和项目交付物。
  • /agent/chat 如何用 LangGraph 的节点和边把多个工具编排成一个 Agent 工作流。
  • /upload 为什么要限制文件类型和文件大小。
  • /uploads/uploads/{filename}/preview 为什么是 RAG 读取知识库材料的第一步。
  • /uploads/{filename}/chunks 为什么要有 chunk_sizeoverlap
  • /uploads/{filename}/embeddings 为什么会返回一串数字向量。
  • /uploads/{filename}/search 为什么会返回 score 最高的片段。
  • /ingest/{filename}/uploads/{filename}/embeddings 的区别:前者会把向量持久化写入 Chroma,后者只是展示向量。
  • /uploads/{filename}/vector-search 为什么更接近真实 RAG 项目的知识库检索。
  • FastAPI 如何通过 Pydantic 做请求参数校验。

下一步

第 2 周会在这个服务上继续强化 RAG 和 Agent:

  1. 上传文档。
  2. 文档切分。当前已做最小版本:GET /uploads/{filename}/chunks
  3. 生成 embedding。当前已做教学版:GET /uploads/{filename}/embeddings
  4. 写入向量数据库。当前已接入 Chroma:POST /ingest/{filename}
  5. 检索相关片段。当前支持教学版检索和 Chroma 检索:GET /uploads/{filename}/searchGET /uploads/{filename}/vector-search
  6. 查询时检索相关片段并拼接 prompt。当前已做最小版:POST /rag-chat
  7. 分析岗位 JD。当前已做规则版:POST /jd/analyze
  8. 分析简历。当前已做规则版:POST /resume/analyze
  9. 计算 JD 和简历匹配度。当前已做规则版:POST /match
  10. 生成技能差距和学习计划。当前已做规则版:POST /gap-plan
  11. 用 LangGraph 编排 Agent。当前已做最小版:POST /agent/chat
  12. 调用大模型。当前支持 stubopenai-compatible 两种 provider。
  13. 评测 RAG 链路。当前已做最小版:POST /rag-evaluate
  14. 部署就绪检查。当前已做最小版:GET /ready
  15. 服务运行指标。当前已做最小版:GET /metrics
  16. 请求日志。当前已做最小版:GET /logs/recent
  17. 可选 API Key 鉴权。当前通过 APP_API_KEYX-API-Key 实现。
  18. 简单限流。当前通过 RATE_LIMIT_REQUESTSRATE_LIMIT_WINDOW_SECONDS 实现。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages