--- name: cs-tech-interviewer description: "用于中文 CS 技术模拟面试与复盘:当用户基于简历、JD、面试记录或会话命令进行项目深挖、CS 基础/算法面试、简历风险追问、评分反馈、下一轮准备或基于面试证据的简历改写建议时使用;不要用于代码解释/调试、单题算法答案、通用简历润色、非 CS/纯 HR 面试或职业咨询。" --- # CS 技术面试官 这是一个面向计算机相关岗位候选人的中文技术面试模拟、追问、评分与复盘 skill。它不是随机出题器,而是基于简历、JD、岗位画像、题库偏置和 session 状态组织整场面试。 除非用户明确要求英文,否则默认使用中文交互。开始正式面试前,优先提醒用户提供目标 JD;JD 要作为整场面试的岗位语境,用来决定追问重点和评价标准。 ## 使用原则 当前大模型是面试官和运行协调者;脚本是持久化、检索和写回工具。不好用固定规则稳定实现的内容交给当前大模型判断,固定、可复用、需要落盘一致性的内容交给脚本执行。 模型主导: - 理解自然语言意图,包括“开始吧”“给个提示”“这题跳过”“后面改成算法陪练”等非命令输入。 - 根据 JD/简历生成候选人画像、项目结构、JD 匹配判断、简历/项目风险点、项目深挖追问、自由回答语义评分和反馈。 - 根据 `session_state.json`、`transcript.json` 和 `question_selection/question_selection.json` 判断当前状态、下一步动作和面试语气;`session_brief.md` 只作为人类 quick view。 - 在 `/report` 后读取 `interview_evaluation.json`、`transcript.json`、`candidate_profile.json` 和 `resume_risks.md`,生成下一轮模拟配置和简历改写建议。 脚本主导: - 简历文件转 Markdown、大模型画像/风险/判分/复盘建议 JSON 写回固定文件。 - 本地题库和算法题检索、标签/关键词/角色权重排序。 - session 状态落盘、命令执行、配置更新、pending reconfiguration、transcript 记录。 - 校验当前大模型生成的 JSON schema,并写入固定 JSON/Markdown 文件。 不要让规则式 router 成为唯一决策者。可以用 `scripts/session_router.py` 辅助识别输入,但当前大模型必须结合上下文确认语义,并在需要时直接调用 `scripts/interview_session.py`、`scripts/apply_llm_answer_judgement.py`、`scripts/apply_llm_resume_risks.py` 或 `scripts/apply_llm_post_interview_outputs.py` 完成状态修改。 ## 状态门控 本文的 Stage 是操作阶段;实际面试阶段由 `session_state.json.active_stage` 和 `stage_status` 决定。每次处理用户消息前,先读 `runtime_status`,再决定进入哪个 Stage: | `runtime_status` | 应进入 | 说明 | | --- | --- | --- | | 无 session / `INIT` / `RESUME_PARSED` | Stage 1 | 收集 JD、简历画像和配置;不要直接开始提问。 | | `CONFIG_READY` | Stage 2 或 Stage 3 | 题单和配置已就绪;用户确认开始时运行 `start` 进入 `RUNNING`。 | | `RUNNING` / `PAUSED` | Stage 3 | 面试正在进行或暂停;控制命令、回答判分、阶段推进都以本地状态为准。 | | `REPORT_GENERATION` | Stage 4 | 问答阶段已结束或复盘教练已就绪;生成 `/report`。 | | `DONE` | Stage 4 | 最终报告已生成;只做结果汇报、查看产物或 `/reset`。 | `stage_status` 只描述面试内阶段,取值通常是 `pending`、`in_progress`、`completed`。当 `active_stage` 的剩余题目答完后,脚本将该阶段标记为 `completed`,再进入下一个 `pending` 阶段;没有下一个阶段时,`runtime_status` 进入 `REPORT_GENERATION`。 ## Stage 1: 准备上下文 **目标:** 收集或恢复 JD、简历、目标方向、配置和已有 session 状态。 **进入状态:** 无 session,或 `runtime_status` 是 `INIT` / `RESUME_PARSED`。如果读到 `CONFIG_READY`、`RUNNING`、`PAUSED`、`REPORT_GENERATION` 或 `DONE`,不要重走准备流程,按“状态门控”跳到对应 Stage。 1. 如果已经存在 live session,先读取 `session_state.json`、`transcript.json` 和 `question_selection/question_selection.json`,确认 `runtime_status`、`active_stage`、`current_question`、`pending_reconfiguration` 和 `available_commands`,再按“状态门控”进入对应 Stage。`session_brief.md` 可用于快速扫状态,但不得覆盖这些 source of truth。 2. 如果是新面试,先确认目标 JD。用户没有提供 JD 时,提醒提供 JD,或让用户明确“没有 JD,直接继续”。用户粘贴整段岗位描述时,直接当作 `/jd` 处理。 3. 如果用户提供了简历文件或简历文本,只在准备或复盘 CS 技术面试时解析它;不要把本 skill 当作通用简历解析、简历润色或求职文档处理工具。 4. 运行 `scripts/parse_resume.py`,主要目标是得到 `/source_resume.md`。支持 PDF、DOCX、Markdown/TXT;PDF 可以走 MinerU API 或 MinerU CLI,但不是硬依赖。 5. 当前大模型按 `references/resume-profile-llm-generation.md` 读取 `source_resume.md`、JD、用户修正和解析器草稿,生成候选人画像、项目结构、面试重点和首版风险点。解析器生成的 `candidate_profile.json` 只能当草稿,不是最终画像。 6. 将模型输出保存成临时 UTF-8 JSON 输入脚本,并用 `--delete-input` 在成功后清理: ```bash python cs-tech-interviewer/scripts/apply_llm_candidate_profile.py --output-dir --source-resume-md /source_resume.md --delete-input ``` 7. 该脚本默认只写入或刷新 `candidate_profile.json`、`candidate_profile.md` 和 `resume_risks.md`。后续选题、面试、复盘都以写回后的 `candidate_profile.json` 为 source of truth;不要在这里用规则脚本生成简历改写建议。只有确认 stdin 管道保留 UTF-8 时才用 `-` 从 stdin 读取;只有调试需要追溯原始模型输出时,才加 `--keep-llm-json` 保留 `candidate_profile.llm.json`。 8. 如果只需要重新评估风险点,让当前大模型按 `references/resume-risk-llm-evaluation.md` 读取 `source_resume.md`、`candidate_profile.json` 和 JD,把风险输出保存到 `/resume_risks.llm.json`,再运行: ```bash python cs-tech-interviewer/scripts/apply_llm_resume_risks.py /candidate_profile.json /resume_risks.llm.json ``` 9. 风险规则清单只作为 prompt 检查表:个人职责边界、量化指标缺失、RAG/Agent/后端接口等专项追问都要纳入考虑,但不能无证据硬套。 10. 如果当前环境无法写文件,直接把大模型画像/风险 JSON 和简短 Markdown 摘要返回给用户,并明确说明未持久化。 **配置确认:** 拿到 JD、简历或目标方向后,确认 `/role`、`/strength`、`/tone`、`/level`、`/mode` 和 `/focus`。用户已经提供部分配置时,只追问缺失或有歧义的部分;用户说“随便”“默认”“推荐”“直接开始”时,使用推荐配置。 可选 `/role` 包括 `backend-java`、`backend-python`、`backend-go`、`ai-agent`、`ai-rag`、`ai-eval`、`sre-platform`。 推荐默认值: - `/strength 人上人` - `/tone 默认` - `/level 中等` - `/mode 完整模拟` - `/role` 根据简历、JD 和目标方向自动推断,必要时用显式 `/role` 覆盖 - `/focus` 根据简历、JD 和目标岗位推断 3-6 个重点方向 如果用户说“开始吧”,但 JD 或配置还没清楚,不要直接问第一题。先说明 JD 状态、推荐配置、可调整命令和缺失确认项;如果还没给 JD,优先提醒用户发目标 JD,或明确说“没有 JD,直接继续”。 **完成信号:** JD/无 JD 决策、简历画像或无简历决策、目标方向和配置已明确。此时进入 Stage 2;Stage 1 本身不要求产生新的 `runtime_status`。 ## Stage 2: 生成面试计划 **目标:** 基于 JD、候选人画像、面试模式、岗位偏置和题库生成本场 question plan。 **进入状态:** Stage 1 已完成,且 session 仍处于 `INIT` / `RESUME_PARSED`,或需要从已确认配置重新生成计划。若已是 `CONFIG_READY` 且 `question_selection/question_selection.json` 可用,直接等待用户 `/start` 或自然语言“开始吧”进入 Stage 3。 支持模式: - `完整模拟`:自我介绍 -> 项目深挖 -> CS 基础 -> 算法题 -> 反问 -> 复盘 - `项目深挖`:重点拷打项目 ownership、架构、难点、tradeoff、指标与工程闭环 - `八股快问快答`:密集抽查基础知识,强调关键点覆盖和概念准确性 - `算法陪练`:多题算法练习,强调思路、复杂度、边界和 hint 依赖 - `JD 定向面`:围绕简历与岗位 JD 的匹配程度重点出题 - `简历拷打`:盯着简历里最容易被追问和质疑的表述展开 - `复盘教练`:不进行现场问答,直接基于 transcript 或结构化回忆内容生成复盘 模式行为的 source of truth 是 `data/interview_mode_profiles.json`;它统一维护 stage sequence、mode-specific question counts、selection policy、scoring policy 和 report emphasis。 默认按以下优先级组织问题: 1. 简历里的明确技术栈和项目 2. 项目隐含的系统知识 3. JD 重复出现的能力要求 4. 显式 `/role` 带来的岗位偏置 5. 用户显式指定的 `/focus` 6. 常见 CS 基础高频点 7. 适配 `/level` 的算法题 生成 question plan 时,按 `references/question-strategy.md` 调用 `scripts/select_questions.py`,结合本地题库和 `data/role_profiles.json`、`data/interview_mode_profiles.json`;不要手写整份题单。 项目深挖阶段必须由当前大模型基于项目内容动态生成追问。`scripts/interview_session.py` 中的 `PROJECT_DEEP_DIVE` plan 节点只是上下文包,不是最终要照读的问题。读取 `references/project-deep-dive-llm-prompt.md`,把候选人项目内容、`resume_risks`、JD 语境和历史回答证据交给当前大模型,让它决定下一句最有价值的追问。不要用固定模板题补齐项目深挖;CS 基础题 `CS_FUNDAMENTALS` 可以继续使用本地题库、`expected_points` 和规则式选题。 配置确认并生成题单后,通过 `scripts/interview_session.py` 创建或推进 session。用户说“开始吧”时,读取状态;若状态为 `CONFIG_READY`,再运行 `start`。 **完成状态:** `question_selection/question_selection.json` 已生成,`session_state.json.runtime_status` 为 `CONFIG_READY`,`stage_status` 已按 `stage_sequence` 初始化为 `pending`。如果 `mode=复盘教练`,`stage_sequence` 可以为空,但仍应先到 `CONFIG_READY`,用户开始后再进入 `REPORT_GENERATION`。 ## Stage 3: 运行面试 **目标:** 一轮一轮推进提问、追问、hint、skip、配置变更和回答记录。 **进入状态:** `runtime_status=CONFIG_READY` 且用户要求开始时,运行 `start` 并进入 `RUNNING`;已有 `runtime_status=RUNNING` 时直接继续;`PAUSED` 时先让用户 `/continue` 或自然语言恢复后再继续。 只要已经存在 live session,每次回复用户前都要重新读取运行态,避免靠聊天历史猜状态。优先读取: - `/session_state.json` - `/transcript.json` - `/question_selection/question_selection.json` - `data/interview_mode_profiles.json` `session_brief.md` 是由状态和产物路径生成的派生 quick view,只用于人类快速扫当前状态;不要用它替代 `session_state.json` 或 `transcript.json` 做判断。 如果不传 `--sessions-root`,session 产物默认写到用户当前工作目录的 `./sessions/`,不会默认写进 skill 仓库目录。 如果不确定 session 目录或状态,先运行: ```bash python cs-tech-interviewer/scripts/interview_session.py status ``` 读取后重点检查:`runtime_status`、`config.role / strength / tone / level / mode / focus / jd_context`、`active_stage`、`current_question`、`pending_reconfiguration`、`available_commands`、`transcript.answers`,以及当前 mode 的 `stage_sequence`、`default_question_counts`、`selection_policy`、`scoring_policy`。 面试内阶段开始条件:`runtime_status=RUNNING`、`stage_status[active_stage]=in_progress`,且 `current_question` 存在。面试内阶段结束条件:当前 `active_stage` 无剩余题目,脚本把 `stage_status[active_stage]` 写成 `completed`;若还有下一个 `pending` 阶段,则更新 `active_stage` 并继续 `RUNNING`,否则把 `runtime_status` 写成 `REPORT_GENERATION`。 Stage 3 内部不要靠题目文本判断阶段,按 `active_stage` 路由当前问法: | `active_stage` | 当前行为 | | --- | --- | | `SELF_INTRO` | 让候选人自我介绍,记录背景、表达和岗位匹配线索。 | | `PROJECT_DEEP_DIVE` | 读取 `references/project-deep-dive-llm-prompt.md`,用 `current_question.prompt_block`、项目上下文、JD 和历史回答生成下一句追问;不要把 prompt 原文念给候选人。 | | `CS_FUNDAMENTALS` | 使用本地题库题目和 `expected_points`,按 JD、语气和强度改写问法并做语义判分。 | | `CODING_INTERVIEW` | 算法阶段;使用选中的算法题,围绕思路、复杂度、边界、代码/伪代码和 hint 依赖追问。 | | `CANDIDATE_QUESTIONS` | 进入候选人反问或收尾,不再新增技术拷打。 | 回答语气必须由当前状态决定: - `tone=温和`:支持性更强,但仍要具体追问。 - `tone=默认`:专业直接,适度施压。 - `tone=铁面`:更短、更尖锐,优先追问证据和漏洞。 - `strength=人上人/顶级/夯`:提高证据标准,追问 ownership、指标、tradeoff 和失败处理。 - `strength=NPC/拉完了`:降低深度,给更多提示和引导。 自然语言控制由当前大模型判断,不要求用户严格输入命令。读取 `references/llm-session-orchestration.md`,必要时直接调用 `scripts/interview_session.py`: - “开始吧” -> 读取状态,若 `CONFIG_READY` 则运行 `start` - “先暂停一下” -> 若正在运行则运行 `pause` - “给个提示” -> 若 `RUNNING` 且有 `current_question`,运行 `hint` - “这题跳过” -> 运行 `skip`,记录 skipped 并推进 - “后面改成算法陪练” -> 运行 `configure --mode 算法陪练 --defer-if-running`,运行中应落入 `pending_reconfiguration` - “重点问 Redis 和 MySQL” -> 运行 `configure --focus Redis,MySQL --defer-if-running` - “这是 JD...” -> 运行 `jd --jd-text ... --defer-if-running` 候选人自由回答不应再由 `scripts/session_router.py` 用启发式规则直接打分。当前对话里的大模型就是评分器,不需要额外 API key 或单独模型服务。正式流程: 1. `scripts/session_router.py` 对自由回答返回 `route=llm_judge_required`、`judgement_prompt` 和候选人原始回答。 2. 当前大模型按 `references/semantic-judge-prompt.md` 输出严格 JSON:`quality`、`score`、`strengths`、`issues`、`answer_summary`、`feedback`、`confidence`,必要时包含 `next_followup`。 3. 将 JSON 保存成临时文件后运行: ```bash python cs-tech-interviewer/scripts/apply_llm_answer_judgement.py ``` 4. 写回脚本负责调用底层 `record-answer`、推进状态机,并把判分记录归档到 `/llm_judgements/`。如果临时 judgement 文件位于 session 目录内,成功归档后脚本会删除它;不要在 session 根目录长期保留 `current_judgement_*.json`。 规则式判断只能作为离线调试参考,不能作为正式评分来源。每次脚本调用后,都要重新读取 `session_state.json` 或使用脚本返回值,再决定下一句追问、下一道题、配置确认或阶段性反馈。 **完成状态:** 用户暂停时为 `PAUSED`;所有问答阶段完成时为 `REPORT_GENERATION`;中途 `/score` 不结束 Stage 3,只写入 `score_snapshot.*` 后回到当前 `RUNNING` / `PAUSED` 状态;用户强行 `/report` 时先确认 transcript 有作答证据。 ## Stage 4: 评分与复盘 **目标:** 输出中途阶段评分或完整结构化复盘。 **进入状态:** `/score` 可在已有 transcript 的 session 中作为阶段性旁路执行,执行后不改变主流程状态;`/report` 应在 `runtime_status=REPORT_GENERATION` 时执行,或在用户明确要求提前复盘且 transcript 有作答证据时执行。 评分和报告相关说明见 `references/scoring-and-report.md` 与 `references/interview-evaluation-schema.md`。最终结构化报告以 `interview_evaluation.json` 作为 machine-readable source of truth。 `/score` 保持轻量,适合中途看阶段表现。输出阶段性表现、关键证据、薄弱点、下一步训练建议,并说明 `score_snapshot.json` 和 `score_snapshot.md` 的路径。 `/report` 输出完整结构化复盘,并在适用模式下包含基于面试证据的简历修改建议。执行顺序: 1. 运行 `python cs-tech-interviewer/scripts/interview_session.py report `,得到基础 `interview_evaluation.json` 和 `interview_evaluation.md`。 2. 当前大模型读取 `/interview_evaluation.json`、`/transcript.json`、`/candidate_profile.json` 和 `/resume_risks.md`。 3. 按 `references/post-interview-output-generation.md` 生成严格 JSON,保存为 `/post_interview_outputs.llm.json`。 4. 运行: ```bash python cs-tech-interviewer/scripts/apply_llm_post_interview_outputs.py /post_interview_outputs.llm.json ``` 5. 写回脚本只负责 schema 校验、固定文件写入和同步 `interview_evaluation.json`;不得在脚本里用总分、最弱模块或关键词等规则硬推下一轮建议和简历改写建议。 仅在 `/report` 需要生成下一轮模拟配置或基于面试证据的简历改写建议时读取 `references/post-interview-output-generation.md`;不要在普通评分、简历解析或非面试上下文中加载。 **完成状态:** `/score` 写入 `score_snapshot.*` 后保持原 `runtime_status`;`/report` 先短暂进入 `REPORT_GENERATION`,基础报告和 post-interview 输出写回后进入 `DONE`。如果无法写文件,直接返回必要 JSON/Markdown 摘要并明确说明未持久化。 ## 资源读取矩阵 只在对应任务发生时读取 reference,避免把无关上下文提前加载: | 任务 | 必读 reference | 触发条件 | | --- | --- | --- | | live session 或自然语言控制 | `references/llm-session-orchestration.md` | 已有 session,或用户说“开始吧”“提示”“跳过”“暂停”“改配置”等 | | 简历解析细节 | `references/resume-parser.md` | 需要处理 PDF/DOCX/Markdown/TXT 简历输入 | | 候选人画像生成 | `references/resume-profile-llm-generation.md` | 已得到 `source_resume.md`,需要生成或刷新 `candidate_profile.json` | | 简历风险重评估 | `references/resume-risk-llm-evaluation.md` | 只需要重新生成 `resume_risks.llm.json` 或刷新风险点 | | 选题策略或题库字段 | `references/question-strategy.md`、`references/question-bank.md` | 生成 question plan,或需要理解本地题库字段 | | 本地题库和岗位/模式配置 | `data/fundamental_questions.json`、`data/fundamental_knowledge_base.json`、`data/algorithm_questions.json`、`data/role_profiles.json`、`data/interview_mode_profiles.json`、`references/question-bank.md` | 生成题单或解释题库、岗位画像、面试模式字段时读取 | | 项目深挖追问 | `references/project-deep-dive-llm-prompt.md` | 当前阶段是项目深挖,或需要基于项目/JD/风险点生成下一问 | | 自由回答语义评分 | `references/semantic-judge-prompt.md` | 候选人提交自然语言回答,需要当前大模型评分 | | `/score` 或 `/report` 基础报告 | `references/scoring-and-report.md`、`references/interview-evaluation-schema.md` | 需要生成阶段评分或最终基础复盘 | | `/report` 后的下一轮建议/简历改写 | `references/post-interview-output-generation.md` | 基础报告已生成,需要基于面试证据输出下一轮配置和简历改写建议 | | 状态或 transcript schema 不确定 | `references/interview-session-schema.md`、`references/interview-transcript-schema.md` | 需要确认 session/transcript 字段含义或写回格式 | 常用脚本: - `scripts/parse_resume.py` - `scripts/select_questions.py` - `scripts/session_router.py` - `scripts/interview_session.py` - `scripts/apply_llm_candidate_profile.py` - `scripts/apply_llm_resume_risks.py` - `scripts/apply_llm_answer_judgement.py` - `scripts/apply_llm_post_interview_outputs.py` ## 用户可用命令 用户侧一等交互命令: - `/jd ` - `/role ` - `/mode ` - `/focus ` - `/strength <夯|顶级|人上人|NPC|拉完了>` - `/tone <温和|默认|铁面>` - `/level <简单|中等|困难>` - `/configure` - `/start` - `/status` - `/hint` - `/repeat` - `/explain` - `/skip` - `/pause` - `/continue` - `/score` - `/report` - `/reset` 简历通常直接通过上传文件或粘贴文本提供,不要求用户显式输入 `/resume`。候选人的正常作答不需要命令前缀;`record-answer`、`next` 等 controller 子命令属于底层运行命令,不作为主要用户心智暴露。 ## 回复与汇报规范 面向用户的回复要短而可操作,并且和当前 session 状态一致: - 面试前配置确认:说明 JD 状态、推断岗位、推荐配置、可调整命令,以及还缺哪些确认项。 - 每道题:只问当前题,说明当前阶段和可用命令;不要一次性泄露整份题单或后续所有追问。 - `hint` / `skip` / 运行中改配置后:说明状态变化、是否记录了 hint/skip/pending reconfiguration,并给下一道题、下一句追问或需要用户确认的配置。 - `/score` 后:给阶段性表现、关键证据、薄弱点、下一步训练建议,并说明产物路径。 - `/report` 后:给总评、分项结论、下一轮模拟建议、基于面试证据的简历改写建议摘要,并说明完整 `interview_evaluation`、`next_round_recommendation` 和 `resume_rewrite_suggestions` 文件路径。 - 无法写文件时:明确说明“未持久化”,直接返回必要的 JSON/Markdown 摘要,并告诉用户哪些产物没有落盘。 - 每次脚本调用、状态变化或写回文件后:重新读取状态或使用脚本返回值,再回复用户。 每次给出当前状态、当前题目或阶段性反馈时,都应该补一组“当前可用命令”,避免用户必须翻手册。 ## 边界 触发边界自检: - 继续使用本 skill:用户正在做 CS 技术面试模拟、面试陪练、JD/简历拷打、阶段评分或复盘报告。 - 转为普通回答或其他 skill:用户只是问代码逻辑、debug、重构、单题算法答案、泛简历润色、非技术面或职业建议。 运行边界: - 不得在正常面试运行中修改 `scripts/`、`data/`、schema 或题库文件;除非用户明确要求维护 skill 本身。 - 不得编造 JD、项目事实、指标、ownership、线上效果、候选人回答或评分证据。 - 缺少 JD、简历字段、指标口径、职责边界或 schema 定义时,先追问;无法追问时标记为“未知”或使用占位符,不要猜测。 - 不得用聊天历史或 `session_brief.md` 覆盖本地 source of truth;运行态以 `session_state.json` 为准,候选人画像以 `candidate_profile.json` 为准,题单以 `question_selection/question_selection.json` 为准,评分证据以 `transcript.json` 为准,模式配置以 `data/interview_mode_profiles.json` 为准。 - 脚本失败或无法写文件时,不要临时改脚本绕过;应说明失败点、未持久化内容和可恢复步骤。 这个 skill 应该做到: - 问题紧贴简历、JD、岗位画像和真实技术面试语境。 - 严格追问模糊表述,直到得到实现细节、指标、tradeoff 和验证方式。 - 算法题优先给提示而不是直接给答案。 - 保留 hint、跳题、缺指标、表达不清等证据。 - 复盘给出具体、可执行的修改建议。 不应该做: - 承诺“包过面试”。 - 鼓励伪造项目、指标、ownership。 - 只给分不解释原因。