新增 RAG、阶段0~2、Agent 项目 M1~M4、后端补强与部署、简历包装和面试周计划;补充易错点和面试常问,移除旧的 RAG/Agent 合并文件

This commit is contained in:
Shikui Wang committed 2026-10-23 11:11:37 +08:00
1 parent 27c1965070
commit 32b111606f
13 files changed
+9402 -861

No files matched your search

+394
View File
@@ -0,0 +1,394 @@
# 第 15 周:阶段 4(上)——作品集、简历、STAR 经历、口述稿
> 第四段的第 2 周。上周 `week14-backend-extend-deploy.md`,下周 `week16-interview.md`。
**本周目标**:把前 14 周的成果变成招聘方能快速看懂的材料:3 个公开仓库 + 1 份简历 + 3 条 STAR 工作经历 + 1 份口述稿(含演示视频)。
**原则**
- **只写做过的、能演示的**:简历上每一条都要能当场打开代码或演示讲清楚。
- **数字必须是自己跑出来的**:评测指标、耗时等都来自 `evals/reports/` 或自己的记录;没有数字就写现象和做法,不编。
- **脱敏**:公司经历只写机制和自己的贡献,不写公司内部的项目名、接口、数据(总纲第 10 节)。
## 本周最终目录
```text
career/
├── resume.md # 简历(Markdown 写,导出 PDF)
├── resume-variants/ # 针对不同岗位微调的版本
├── star.md # 3 条 STAR 工作经历
├── pitch.md # 口述稿:3 分钟架构 + 1 分钟踩坑
├── portfolio.md # 作品清单:仓库地址、演示链接、视频
├── jd/ # 收集的岗位描述(纯文本,一个岗位一个文件)
├── keyword_check.py # 简历和岗位描述的关键词对照
└── tests/test_keyword_check.py
```
---
## 第 1 天:整理作品集(3 个公开仓库)
### 学习内容
- 说明:招聘方看作品通常只花几分钟:先看 README 顶部(一句话介绍 + 演示动图 + 快速开始),再看目录结构和一两个核心文件。所以每个项目要单独一个公开仓库(GitHub 或其他公开平台),而不是让人在学习仓库里翻。
- 说明:**不要直接公开学习仓库的历史**:历史里可能有早期误提交的内容。最稳妥的做法是把项目目录复制到一个新仓库,作为第一次提交,再做一遍脱敏检查。
- 案例:每个仓库 README 顶部的结构
```markdown
# agent-mini:可崩溃恢复的多 Agent 编排(LangGraph + FastAPI)
![演示](docs/demo.gif)
多个 Agent(提议者、审查者、协调者)协作完成方案讨论;任务在后台执行,进程被杀后自动续跑;
需要澄清时暂停等用户回答;全过程可通过 SSE 实时查看,并生成过程报告。
**亮点**:LangGraph 检查点续跑 · interrupt 人机协作 · 租约防重复执行 · MCP 工具服务 · 评测集 + 回归测试
## 快速开始(不需要模型密钥)
docker compose up -d && open http://localhost:8100
```
- 动图:用录屏工具录 20~30 秒的关键流程(创建任务 → 流式输出 → 杀进程 → 恢复),转成 GIF 或放视频链接。
### 易错点 / 面试常问
- 易错点:公开前在新仓库里再跑一次 `python3 tools/check_sensitive.py`(第 8 周的脚本,复制过去)并人工看一遍 `git diff --cached`;`.env`、数据目录、`*.db` 都要在 `.gitignore` 里。
- 易错点:README 里的命令要在一台干净的电脑(或新目录)上从头跑一遍,常见问题是漏了依赖、端口冲突、缺示例数据。
- 面试常问:“介绍一下你的项目”——先一句话说清解决什么问题,再说架构,最后说你做的最难的一个点(第 6 天的口述稿就是答案)。
### 要建的文件
- 3 个公开仓库:`task-board`(含 `web/board-vue` 前端)、`rag-qa`(含 `web/rag-react`)、`agent-mini`;`career/portfolio.md` 记录地址和演示链接
### 运行方式
```bash
mkdir ~/pub && cp -r ~/zhuangang/agent-mini ~/pub/agent-mini && cd ~/pub/agent-mini
rm -rf .venv data && git init && git add -A && git diff --cached --stat # 检查要提交的文件
python3 ~/zhuangang/tools/check_sensitive.py && git commit -m "agent-mini 初始版本"
```
### 完成标准
- 3 个仓库公开;每个 README 顶部有一句话介绍、动图或视频、快速开始;脱敏检查通过。
---
## 第 2 天:简历结构、学历和技能栏
### 学习内容
- 说明:简历一到两页,招聘方一般先扫 10 秒:**目标岗位、核心技能、最近的经历、项目亮点**。所以顺序是:
```markdown
# 王士奎 · AI 应用 / Agent 开发工程师
电话 · 邮箱 · GitHub · 作品集链接
## 个人优势(3 行以内)
- 7 年 Web 开发经验,参与公司多 Agent 产品的前端和网关联调,熟悉多 Agent 编排、流式输出、长任务的工程问题
- 独立完成 3 个可演示项目:LangGraph 多 Agent(崩溃续跑、人机协作)、RAG 知识库问答(混合检索、评测)、Go 全栈任务看板
- 熟练使用 AI 编程工具(Cursor 等),负责设计、审查和调试
## 专业技能
- Python:FastAPI、asyncio、pydantic、pytest
- AI 应用:LangChain、LangGraph、RAG(Chroma、BM25 混合检索、重排)、MCP、Function Calling、Agent 评测
- 前端:Vue 3、React、TypeScript、Vite、Pinia、pnpm monorepo、Vitest
- 后端:Go(Gin)、PostgreSQL / MySQL、Redis、RabbitMQ、gRPC 基础
- 工程:Docker、Compose、Nginx、Linux、CI/CD、Git
## 工作经历
(第 4 天写)
## 项目经历
(第 3 天写,项目三放第一)
## 教育经历
本科 · 学校名 · 专业 · 起止年月
```
- 说明:**学历**:写“本科”,加上学校、专业、起止时间即可。标注了“统招”的岗位也可以投递试试,结果以对方的反馈为准;准备的重点放在项目和经验上——这次调研里绝大多数岗位写的是“本科”,没看到要求 985 / 211 的。
- 说明:**技能栏**按岗位关键词排序(总纲第 4 节的表),每一项都要有项目里的对应代码;“了解”的放后面或不写,免得被追问答不上。
### 易错点 / 面试常问
- 易错点:技能栏写“精通”要谨慎,面试官会按“精通”的标准追问;一般用“熟练 / 熟悉 / 了解”区分。
- 易错点:不要把所有学过的技术都堆上去,和目标岗位无关的(比如很老的框架)删掉,突出主线。
- 易错点:简历导出 PDF 发送,文件名写“姓名-岗位-电话.pdf”;Markdown 原文留在仓库,方便修改。
### 要建的文件
- `career/resume.md`:头部、个人优势、技能栏、教育经历
### 运行方式
- 用编辑器的 Markdown 预览或 `pandoc resume.md -o resume.pdf` 导出(排版不满意就粘到简历模板里)。
### 完成标准
- 头部、个人优势、技能栏、教育经历写完;技能栏每项都能说出对应的项目文件。
---
## 第 3 天:项目经历怎么写
### 学习内容
- 说明:每个项目 4~6 行,格式“**背景 / 目标 → 我的设计(带关键词)→ 结果(可验证)**”。关键词就是岗位要求里的词,招聘方和筛选系统都会搜这些词。结果写可验证的东西:评测数字(来自报告)、演示链接、测试覆盖的场景。
- 案例(方括号里填你自己的真实数据,没有就删掉那半句):
```markdown
### agent-mini · 可崩溃恢复的多 Agent 编排系统(个人项目) GitHub 链接
技术栈:Python、LangGraph、FastAPI、SQLite、MCP、SSE、Docker
- 用 LangGraph 实现“协调者—提议者—审查者”多 Agent 编排,共识条件 + 最大轮数兜底,路由规则可单元测试
- 编排状态用检查点持久化,任务表 + 租约保证同一任务只被一个进程执行;演示中 kill -9 后重启可自动续跑
- 用 interrupt 实现“需要澄清时暂停等用户回答”,支持换模型后从检查点恢复
- 用 MCP 实现知识库工具服务,可同时被 Cursor 和自己的 Agent 调用
- 建立 [N] 条用例的评测集(规则检查 + 模型评分),调整提示词后通过率从 [x] 提升到 [y](见仓库 evals/reports)
### rag-qa · 带引用的知识库问答(个人项目) GitHub 链接
技术栈:Python、FastAPI、Chroma、BM25、Redis、LangChain、React
- 手写加载—切分—向量化—检索—带引用生成全流程,检索不到时直接拒答,减少编造
- 实现 BM25 + 向量混合检索(RRF 融合)和重排,用 [N] 题评测集对比:Hit@K [x] → [y]
- Redis 实现会话记忆、嵌入缓存和答案缓存(按知识库版本失效);SSE 流式输出
### task-board · 团队任务看板(个人项目) GitHub 链接
技术栈:Go、Gin、PostgreSQL、Redis、Redis Streams、Vue 3、Docker、Nginx
- 多人看板 + 成员角色权限,拖动排序用事务保证位置一致
- Redis 实现缓存、限流、分布式锁;Redis Streams 异步处理通知,消费者幂等
- Docker Compose + Nginx 部署,CI 自动测试
```
### 易错点 / 面试常问
- 易错点:写“负责 / 参与了 XX”看不出能力,改成“用 A 实现了 B,解决了 C”。
- 易错点:评测数字一定要能在仓库里找到出处(报告文件、提交记录),面试官可能会问“怎么测的、测了多少题”。
- 面试常问:每一行都可能被追问“为什么这样做、有没有别的方案、遇到什么问题”——写完后对每一行准备一句追问的回答,记到下周的面试笔记里。
### 要建的文件
- `career/resume.md` 的“项目经历”部分
### 完成标准
- 3 个项目都写完;方括号里的数字全部替换成真实数据或删除。
---
## 第 4 天:工作经历——3 条 STAR
### 学习内容
- 说明:STAR = **情境(Situation)、任务(Task)、行动(Action)、结果(Result)**。面试官问“讲一个你解决过的难题”时,就按这个顺序讲。素材来自第 9 周的案例卡(已脱敏),三条分别对应:编排可靠性、状态权威源、业务落地。
- 说明:工作经历里写你**实际做过的部分**。如果某个问题你是发现者和分析者、方案是团队一起定的,就如实写“定位根因并提出方案”;你在学习项目里做了“若重做的设计”,可以写成“在个人项目中验证了改进方案”。
- 案例(结构示例,内容按你自己的案例卡改写):
```markdown
### 情境
公司的多 Agent 研讨功能由前端驱动多轮调用,用户关掉页面后研讨就中断,进度无法恢复。
### 任务
定位中断原因,提出让长任务不依赖浏览器的方案。
### 行动
- 梳理前端和 Agent 网关之间的调用链,画出时序图,确认循环跑在浏览器里、服务端只做单轮调用
- 对比“前端循环”和“后台作业”两种模式,整理出状态权威源、断线续传、防重复执行三个关键问题
- 在个人项目 agent-mini 中实现了后台作业 + 检查点续跑 + 事件回放,验证方案可行
### 结果
形成了可落地的改进方案和演示;[如果方案在公司被采纳或部分实施,写实际结果;没有就不写]
```
### 易错点 / 面试常问
- 易错点:STAR 讲成流水账。行动部分只讲 2~3 个关键动作,每个动作说清“为什么这么做”。
- 易错点:脱敏——不说公司内部的系统名、接口名、表名,用通用说法(“Agent 网关”“任务表”)。
- 面试常问:“你在这个项目里具体做了什么?”“如果重来一次你会怎么做?”“最大的困难是什么?”——三条 STAR 都要能回答这三个追问。
### 要建的文件
- `career/star.md`(3 条,每条口述不超过 2 分钟);简历的“工作经历”部分写每条的一句话版本
### 完成标准
- 3 条 STAR 写完并各口述计时一次;全部通过脱敏检查。
---
## 第 5 天:针对岗位调整简历(关键词对照)
### 学习内容
- 说明:不同岗位侧重点不同(偏 RAG、偏 Agent、偏全栈)。投递前把岗位描述(JD)保存成文本,和简历对照关键词:岗位要求里有、你也会、但简历里没写的,补上;你不会的,不要硬写,记下来作为面试准备。
- 案例:写一个小脚本做关键词对照。
```python
# 文件:career/keyword_check.py
"""用法:python keyword_check.py jd/某公司.txt resume.md"""
import re
import sys
from pathlib import Path
# 关键词表:同一组里任一写法出现就算命中(按需要自己补充)
KEYWORDS: dict[str, list[str]] = {
"Python": ["python"],
"FastAPI": ["fastapi"],
"Flask": ["flask"],
"LangChain": ["langchain"],
"LangGraph": ["langgraph"],
"LlamaIndex": ["llamaindex", "llama-index"],
"RAG": ["rag", "检索增强"],
"向量数据库": ["向量数据库", "向量库", "milvus", "chroma", "pgvector", "faiss"],
"MCP": ["mcp"],
"Function Calling": ["function calling", "tool calling", "工具调用", "函数调用"],
"Agent": ["agent", "智能体"],
"多 Agent": ["多 agent", "多agent", "multi-agent", "多智能体"],
"评测": ["评测", "评估", "evaluation", "eval"],
"Prompt": ["prompt", "提示词"],
"Dify / Coze": ["dify", "coze", "扣子", "ragflow", "fastgpt"],
"Vue": ["vue"],
"React": ["react"],
"TypeScript": ["typescript", "ts"],
"Go": ["go", "golang"],
"MySQL": ["mysql"],
"PostgreSQL": ["postgresql", "postgres", "pgsql"],
"Redis": ["redis"],
"消息队列": ["消息队列", "rabbitmq", "kafka", "mq"],
"微服务": ["微服务", "grpc"],
"Docker": ["docker", "容器"],
"Linux": ["linux"],
"CI/CD": ["ci/cd", "cicd", "持续集成"],
}
def _has(text: str, word: str) -> bool:
# 纯英文短词按“单词边界”匹配,避免 ts 命中 tests、go 命中 google
if re.fullmatch(r"[a-z0-9/.\- ]+", word):
return re.search(rf"(?<![a-z0-9]){re.escape(word)}(?![a-z0-9])", text) is not None
return word in text
def found(text: str) -> set[str]:
t = text.lower()
return {name for name, words in KEYWORDS.items() if any(_has(t, w) for w in words)}
def compare(jd: str, resume: str) -> dict[str, list[str]]:
need, have = found(jd), found(resume)
return {"covered": sorted(need & have), "missing": sorted(need - have), "extra": sorted(have - need)}
def main() -> None:
jd_path, resume_path = sys.argv[1], sys.argv[2]
r = compare(Path(jd_path).read_text(encoding="utf-8"), Path(resume_path).read_text(encoding="utf-8"))
print("岗位要求、简历已覆盖:", "、".join(r["covered"]) or "无")
print("岗位要求、简历未提到:", "、".join(r["missing"]) or "无")
print("(未提到的:会就补进简历;不会就记进面试准备,不要硬写)")
if __name__ == "__main__" and len(sys.argv) == 3:
main()
```
```python
# 文件:career/tests/test_keyword_check.py
from keyword_check import compare, found
def test_found_uses_word_boundaries():
assert found("熟悉 Go 和 TypeScript") >= {"Go", "TypeScript"}
assert "Go" not in found("google tests") # 不误判
assert "TypeScript" not in found("pytest tests")
def test_compare():
jd = "要求:熟悉 Python、FastAPI,有 RAG 和向量数据库(Milvus)经验,了解 Kafka。"
resume = "Python / FastAPI;RAG(Chroma、BM25 混合检索);Redis"
r = compare(jd, resume)
assert r["covered"] == ["FastAPI", "Python", "RAG", "向量数据库"]
assert r["missing"] == ["消息队列"]
assert r["extra"] == ["Redis"]
```
### 易错点 / 面试常问
- 易错点:关键词对上了只是第一步,简历里每个关键词都要有对应的项目描述,不能只出现在技能栏。
- 易错点:不同岗位只调整“个人优势”和项目里的侧重点,不要为了迎合岗位编造经历。
### 要建的文件
- `career/jd/`(至少收集 10 个目标岗位的描述)、`keyword_check.py`、`tests/test_keyword_check.py`;`career/resume-variants/`:偏 Agent、偏 RAG、偏全栈三个版本
### 运行方式
```bash
cd career && uv run --with pytest python -m pytest -q tests # 用 python -m 才能导入同目录的 keyword_check
python keyword_check.py jd/某公司.txt resume.md
```
### 完成标准
- 10 个岗位都对照过一次;把多次出现、你又没准备的关键词列进下周的面试笔记。
---
## 第 6 天:口述稿和演示视频
### 学习内容
- 说明:面试里最常见的开场是“自我介绍 + 介绍一个项目”。准备两段:
- **自我介绍(1 分钟)**:方向 + 经验 + 3 个项目一句话 + 为什么想做 AI 应用。
- **项目讲解(3 分钟架构 + 1 分钟踩坑)**:总长不超过 4 分钟,覆盖重点 A(编排)、B(状态权威)、C(流式与长任务)中至少两项。
- 案例:项目讲解的骨架(`career/pitch.md`)
```markdown
1. 问题(30 秒):多 Agent 任务时间长、步骤多,跑在浏览器里关页面就断,状态也说不清在哪。
2. 架构(90 秒):对着架构图讲——API 创建任务 → 后台执行器领取租约 → LangGraph 按图执行,
每步写检查点和事件 → 前端用 SSE 订阅事件,断线按 Last-Event-ID 补齐 → 结束写结论和报告。
两层状态:检查点是编排草稿,任务表是对外权威。
3. 演示(60 秒):创建任务 → 看流式输出 → 杀进程 → 重启后自动续跑 → 查看报告。
4. 踩坑(60 秒):崩溃时正在执行的节点会重跑一次,所以有副作用的操作要幂等;
一开始用“先查再改”领取任务,并发时两个进程都抢到了,改成带条件的 UPDATE 看影响行数。
```
- 说明:录一个 2~3 分钟的演示视频放进作品集(有些面试是线上的,可以直接共享屏幕或发链接)。
### 易错点 / 面试常问
- 易错点:讲解时一直念代码细节,面试官会失去耐心;先讲整体,细节等对方追问。
- 易错点:没有计时练习,实际讲起来会超时。至少完整讲 3 遍并录音回听。
- 面试常问:“这个项目和直接用 Dify / Coze 搭有什么区别?”(第 13 周的对比笔记)“如果用户量变大,哪里先出问题?”(SQLite 换 PostgreSQL、执行器多实例、事件推送改用消息队列)
### 要建的文件
- `career/pitch.md`(自我介绍 + 项目讲解),演示视频链接写进 `career/portfolio.md`
### 完成标准
- 自我介绍 ≤ 1 分钟、项目讲解 ≤ 4 分钟,各计时 3 遍;视频已录好。
---
## 第 7 天:自查、请人审阅、阶段 4(上)验收
### 学习内容
- 说明:简历写完后最好请一位做后端或 AI 应用的朋友看一遍,问他三个问题:10 秒内看出我想找什么岗位吗?哪一条最想追问?哪一条看起来不可信?按反馈修改。
- 自查清单:
```text
[ ] 目标岗位和简历标题一致
[ ] 技能栏每一项都有项目对应
[ ] 项目经历每一行都是“做了什么 + 怎么做 + 结果”,数字都能找到出处
[ ] 工作经历已脱敏,没有公司内部名称、接口、数据
[ ] 仓库、演示链接都能打开(用手机和别人的电脑试一次)
[ ] 简历 PDF 两页以内,没有错别字,联系方式正确
```
### 要建的文件
- 根据反馈修改 `resume.md`、`star.md`、`pitch.md`
### 完成标准(阶段 4 上半验收)
- [ ] 3 个公开仓库 + 演示视频
- [ ] 简历(主版本 + 3 个岗位方向版本)
- [ ] 3 条 STAR、口述稿计时达标
- [ ] 至少 1 位他人审阅过并完成修改
- [ ] 在总纲进度表勾掉第 15 周