project-interview-skill 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/README.md +68 -53
  2. package/README_EN.md +203 -0
  3. package/bin/project-interview-skill.js +11 -7
  4. package/package.json +5 -4
  5. package/skill/project-interview-skill/SKILL.md +211 -0
  6. package/skill/project-interview-skill/references/examples/bullet-few-shots.md +100 -0
  7. package/{references → skill/project-interview-skill/references/examples}/oral-style-samples.md +19 -0
  8. package/skill/project-interview-skill/references/excellent-resumes/README.md +14 -0
  9. package/skill/project-interview-skill/references/excellent-resumes/ai4se-agent-infra.md +62 -0
  10. package/skill/project-interview-skill/references/excellent-resumes/deer-flow-harness.md +64 -0
  11. package/skill/project-interview-skill/references/rules/internal-terms.md +51 -0
  12. package/skill/project-interview-skill/references/rules/oral-and-resume-patterns.md +140 -0
  13. package/skill/project-interview-skill/references/rules/repository-investigation.md +26 -0
  14. package/skill/project-interview-skill/references/rules/star-framework.md +51 -0
  15. package/skill/project-interview-skill/references/templates/output-templates.md +101 -0
  16. package/{scripts → skill/project-interview-skill/scripts}/build_prompt.py +22 -7
  17. package/skill/project-interview-skill/scripts/validate_output.py +55 -0
  18. package/SKILL.md +0 -208
  19. package/references/oral-and-resume-patterns.md +0 -26
  20. package/references/output-templates.md +0 -77
  21. package/references/star-framework.md +0 -29
  22. /package/{references → skill/project-interview-skill/references/rules}/interview-rubric.md +0 -0
  23. /package/{scripts → skill/project-interview-skill/scripts}/check_inputs.py +0 -0
@@ -0,0 +1,140 @@
1
+ # 口播叙述与简历(抽象模板)
2
+
3
+ 本文件是**可移植规则**,适用于任意项目 / 岗位。写简历 bullet 前再打开 [excellent-resumes/](../excellent-resumes/README.md),那里才放项目级金样;**不要**把金样里的产品名、层名、数字抄进用户项目。生成 bullet 时同时对照领域中立的 [bullet few-shot](../examples/bullet-few-shots.md),只学习结构,不复制素材。
4
+
5
+ ## 口播长答(工程向)推荐结构
6
+
7
+ 来自典型高质量回答的抽象,**不固定标题名**,但信息块应齐全,便于第一人称口述 ≥150 字。
8
+
9
+ 1. **场景(现象)**:线上/联调/上线初期的具体现象;可带比例、范围、如何发现(DevTools、日志、监控)。术语可加英文(如 `option`、`JSON.parse`)。
10
+ 2. **归因(根因)**:为何会发生——错把不确定输出当稳定 API、缺防御层、契约不清等;一句话点出**本质**。
11
+ 3. **动作(方案)**:分层写清:我先……再……最后……;可用编号列表(容错提取 → Schema 校验 → sanitize → 边界兜底);每层说**手段 + 目的**。
12
+ 4. **结果与兜底**:指标或(待测);若仍有异常路径,写降级(如 Error Boundary)与观测。
13
+
14
+ 口播语气:**面经全文第一人称「我」**;导学讲解可用「你应当理解」或中性说明,但涉及「如何答面试」的示范段可用第一人称口播。
15
+
16
+ 口播正文遵守 SKILL 的内部名词密度预算。简历 bullet 的名词策略见下文「名词分层」:**不要**把口播黑名单套到一级支柱上,把外部可检索的范式名一起剥掉。
17
+
18
+ ---
19
+
20
+ ## 简历「项目简介 / 一句话」写法
21
+
22
+ 用 **1~2 句** 说清:**做什么 + 关键技术/形态 + 可选一句价值**,避免形容词堆砌。
23
+
24
+ **抽象公式**:
25
+
26
+ > 基于 {核心技术栈/范式} 的 {产品形态},用户/业务侧能 {核心操作},系统支持 {关键能力 A、B},{可选:差异点如同步/异步、端侧等}。
27
+
28
+ **示例形态(勿照抄项目名)**:
29
+
30
+ > 基于 AI 大模型的智能 BI:用户上传 Excel 后,AI 自动生成 ECharts 图表与分析结论,支持同步/异步生成与拖拽看板组合多图。
31
+
32
+ 面经文档中的 **项目概要** 必须接近此密度与信息量,可直接贴简历「项目描述」栏。有真实 star / 奖项可以写;没有就省略,禁止编造。
33
+
34
+ ---
35
+
36
+ ## 先定简历海拔(写 bullet 的第一步)
37
+
38
+ 优先级:**架构演进 > 系统机制 > 交互 / 实现细节**。
39
+
40
+ | 海拔 | 形态(按形态识别,不锁项目) | 默认去向 |
41
+ |------|------------------------------|----------|
42
+ | 架构演进 | 旧形态 → 新形态:固定流程变为可编排;逻辑散落变为可扩展分层 | 一级支柱 |
43
+ | 系统机制 | 状态/一致性、隔离、预算、降级、扩展点、契约 | 一级,或该支柱的二级 |
44
+ | 交互 / 实现细节 | 某一控件、某一协议字段、某一文件的读写、某一布局约束 | **追问**,不进一级 bullet |
45
+
46
+ - **求职方向只调口播侧重点,不改变简历海拔。** 不要把系统机制降成该方向上的功能清单(前端写成页面交互列表、后端写成 CRUD 列表、AI 写成调了某个模型)。候选人先写自己实际碰过的架构支柱,再用口播讲自己在链路上的落点。
47
+ - 用户明确只做子模块时:一级 bullet 仍写**该模块**的机制与约束,文首标注假设;不要把局部改动扩成全仓 owner,也不要把全仓边角堆成多条工单。
48
+ - **禁止**把导学「重点亮点与学习顺序」原样粘成简历 bullet。导学是读代码地图,简历是面试官 30 秒能追问的支柱。
49
+
50
+ 职责动词按所有权,不要一刀切:
51
+
52
+ | 职责 | 可用动词 | 避免 |
53
+ |------|----------|------|
54
+ | 核心作者 / owner / 0 到 1 架构升级 | 主导、把 X 从 Y 收到 Z、抽出、定下约束 | 假客气写成「接入了核心分层」 |
55
+ | 实习 / 参与某子模块 | 接入、新增、开发、主 O 某子模块 | 把全仓说成自己「搭建」 |
56
+
57
+ 「避免搭建/设计」只约束**没有所有权却声张从 0 到 1**;有演进事实时,「把固定流程收成可扩展分层」是正确海拔。
58
+
59
+ ---
60
+
61
+ ## 简历 bullet 四槽公式(正例配方)
62
+
63
+ 一级通常 4~6 条,证据不足时宁可少写。每条以 `- **具体支柱名:** 正文` 独立成行,先给可概括该机制的标题,再展开四槽(可写在同一句,也可用 2~4 条二级展开):
64
+
65
+ 1. **痛点或演进**:以前为什么不行(散落、不可扩展、无预算、失败不可见)。
66
+ 2. **机制**:业界可检索的结构名 + 一句话怎么做。
67
+ 3. **硬约束或数字**:层数、并发、超时、配额、SLO、接口个数。这是设计约束,不是装饰。
68
+ 4. **结果**:架构效果(主路径零改、可降级、可续跑)或真实指标。没有数就写架构结果;用(待测)只标**尚未测量的线上指标**,禁止用(待测)代替机制。
69
+
70
+ 允许嵌套:一级是支柱标题,二级补痛点 / 机制 / 约束。面试官应能只看一级列出 4~6 个追问钩子。
71
+
72
+ 压缩正例(结构示范,领域可替换;完整项目级对照见样例库):
73
+
74
+ > 把首页从整页 CSR 改为 Streaming SSR:聚合数据先做契约校验,不合法则降级 CSR,避免渲染脏数据;水合成功率单独观测。
75
+
76
+ > 把限流、幂等、库存预扣从下单主函数拆成分层:入口按用户限流 + 请求级幂等键 + 原子预扣。P95 目标明确;关键依赖不可用时软降级,靠对账兜底超卖。
77
+
78
+ 槽位填法:`把 {旧方案} 收成 {新机制}:{怎么做}。约束 {数字}。结果 {主路径/调用方看到什么}`。
79
+
80
+ ## Few-shot 生成流程与硬检查
81
+
82
+ 规则描述“必须满足什么”,few-shot 用于对齐“成稿应该长什么样”。生成时不得直接复述金样或把技术名词堆成简历风格,必须按以下顺序执行:
83
+
84
+ 1. **支柱抽取**:从项目演进、核心失败模式、系统机制和关键约束中选 4~6 个候选支柱;局部控件、单个接口和单文件改动默认下沉到追问。
85
+ 2. **事实归档**:按 [仓库探索与证据归档](repository-investigation.md) 追踪链路;每个支柱先记录「核心矛盾、我的动作、机制、约束、结果、证据」。没有职责或指标证据的说法不进入肯定口吻的简历。
86
+ 3. **Few-shot 对齐**:对照 [bullet-few-shots.md](../examples/bullet-few-shots.md) 的正例、反例和改写对照,学习因果链,不复制其中的项目名、数字、领域名词或场景。
87
+ 4. **成稿**:首句交代问题/演进与职责;随后说明机制、边界和结果。每条只表达一个支柱,结果必须紧跟机制。
88
+ 5. **逐条质检**:每条至少有「问题或演进 + 机制 + 结果」;关键支柱尽量四槽齐全;能自然导出一个关于动机、权衡、边界或验证方式的主问。
89
+
90
+ 以下句式不算结果,必须改写为可验证的架构结果或测量计划:`提升性能`、`提高稳定性`、`优化体验`、`增强可维护性`、`降低成本`。真实数字只能来自用户材料、仓库或明确测量;没有数字时不要为了模仿 few-shot 编造数字。
91
+
92
+ ---
93
+
94
+ ## 反例(禁止的简历调性)
95
+
96
+ 写成下面这样就是**功能工单型**,即使每句都真实也不通过:
97
+
98
+ > - 接入某某列表刷新:处理两类竞态,成功率(待测)。
99
+ > - 开发某某确认弹窗:未知版本降级为纯文本。
100
+ > - 把渲染做成节流 / 截断,卡顿(待测)。
101
+ > - 接入某某开关与权限门控。
102
+
103
+ 失败特征(按形态识别):没有痛点或演进;海拔停在交互细节;结果用(待测)顶上;面试官无法从 bullet 问出「为什么是这种结构、约束怎么来的」。这些内容可以出现在对应支柱的**追问口播**里,不能当一级简历。
104
+
105
+ 项目级失败对照(同一仓库被写成工单清单)见 [excellent-resumes/](../excellent-resumes/README.md) 各金样文末,不要把那里的专有名词带回本文件当规则。
106
+
107
+ ---
108
+
109
+ ## 名词分层
110
+
111
+ | 位置 | 允许 | 禁止 |
112
+ |------|------|------|
113
+ | 简历简介 + 一级/二级 bullet | 外部可检索的范式名(SSR、幂等、中间件、熔断、配额、隔离……以**本项目领域**为准) | 私有函数名、文件路径、issue 号、私有枚举、打点事件名、灰度开关键 |
114
+ | 口播正文 | 通用工程语言为主;黑名单私名每题有次数预算,且必须翻译 | 私名堆叠型(见 `oral-style-samples.md`) |
115
+ | 源码证据索引 | 函数名、路径、内部符号 | (此处集中存放即可) |
116
+
117
+ 判断「业界可检索」:外部面试官用该词能搜到论文 / 框架 / 工程实践,而不是只能在本仓库 grep 到。公开 API / 标准协议可以留在简历;仓库私有函数必须下沉到索引。
118
+
119
+ ---
120
+
121
+ ## 出题契约(面试官只看过简历)
122
+
123
+ 生成顺序:**简介 → bullet →「简历 → 面试展开」表 → 主问/追问/口播 → 索引**。禁止先按测试文件扫出十几道源码题,再倒挤 bullet。
124
+
125
+ **主问必须能回指某一条一级 bullet**(简介级通用题除外,见 `star-framework.md`)。题干假设面试官手里只有简介和 bullet,没有仓库。
126
+
127
+ 允许的题干(简历可读,形态):
128
+
129
+ - 为什么用这种结构,而不是把逻辑写在主路径里?
130
+ - 预算 / 超时 / 并发是怎么定的?打满之后调用方看到什么?
131
+ - 失败时如何降级?为什么不重试到成功?
132
+
133
+ 禁止的题干(像读过代码,形态):
134
+
135
+ - 某个内部函数 / 配置键为什么必须是这个字面量?
136
+ - 某个布局或入口文件为什么不能调用某个浏览器 / 容器 API?
137
+ - 某个 SDK 私有开关为什么不能原样转发给网关?
138
+ - 某一对内部事件名为什么不能同时发送?
139
+
140
+ 题干禁则:文件路径、私有函数名、issue 号、只有读源码才知道的开关 / 枚举 / 内部协议字段。追问问权衡、失败、数字怎么来的,不要问「那个函数为什么分两套」。
@@ -0,0 +1,26 @@
1
+ # 仓库探索与证据归档
2
+
3
+ 写导学和面经前执行。目标是找出**能由用户职责和项目证据共同支撑**的工程支柱,不是罗列目录、技术栈或测试文件。用户只提供描述而没有仓库时,明确标注「仅据描述」;不得假装看过源码。
4
+
5
+ ## 1. 确定分析边界
6
+
7
+ - 确认目标项目根目录、主要语言和可运行入口;区分业务源码、生成代码、依赖、示例与测试。
8
+ - 从 README、架构说明、配置和入口文件了解产品目标,再对照用户描述确认候选人的实际职责。仓库存在某机制,不代表候选人实现过它。
9
+ - 仓库很大时,按用户职责和主要链路选代表性模块,不要求逐文件扫完。仓库很小或材料不足时,保留实际找到的数量,不为凑亮点扩写。
10
+
11
+ ## 2. 沿链路追踪,而非按目录摘抄
12
+
13
+ 对 2~4 条最能解释项目价值的核心链路,追踪「入口 → 状态/数据变化 → 关键机制 → 对外结果」。每条至少找出:
14
+
15
+ 1. **为何存在**:旧方案、失败模式、需求或约束是什么?没有历史证据就写当前要解决的问题,不编造旧架构。
16
+ 2. **如何工作**:调用关系、状态转换、数据契约,以及跨模块的责任分界。
17
+ 3. **哪里会失败**:超时、并发、一致性、重试、降级、回滚、资源预算、权限或观测;按项目实际选,不机械套全项。
18
+ 4. **如何证明**:实现、测试、配置、文档、运行结果分别能证明什么;结果是代码可见的架构效果,还是需要测量的线上收益。
19
+
20
+ 对每条候选支柱记录一行事实卡:`问题/演进 | 我的动作与职责证据 | 机制 | 硬约束/边界 | 结果 | 源码/测试/文档相对路径 | 可信度与缺口`。路径指向关键实现或测试,能标行号时标行号。事实卡可先放在工作草稿;成稿将有价值的证据写进导学的「链路与证据」及面经的「源码证据索引」。
21
+
22
+ ## 3. 筛选含金量
23
+
24
+ 优先选择能回答「为什么这样设计、与什么方案相比、失败时怎样、怎样验证」的事实;跨模块约束、架构演进和系统机制优先于单点功能。每个一级简历 bullet 应有一条可回查的事实卡;没有职责证据时,用「项目采用」解释项目,不写成「我主导」。没有可验证结果时,说明待验证的指标与测法,不用空泛收益充数。
25
+
26
+ 发现关键事实缺口时,先完成能独立进行的仓库探索,再向用户集中询问所有权、上线效果或旧方案等高信号问题。无法确认的事实保留为待确认,不进入肯定口吻的简历 bullet。
@@ -0,0 +1,51 @@
1
+ # STAR、追问与口播要求
2
+
3
+ ## 口播版(面经中的答题正文)
4
+
5
+ - **第一人称**:面经文档里「主问题 / 追问」的**口播正文**一律用「我」作主语(协作题可一句内用「我们」说明边界)。
6
+ - **字数**:每一道**主问题**、每一道**追问**的口播版均 **≥150 个汉字**(或等价符号不计入时以汉字为主),且须能单独讲清**完整 STAR**(情境—任务—行动—结果),禁止只列关键词。
7
+ - **结构**:推荐「场景(现象)→ 归因(根因)→ 动作(分层方案)→ 结果/兜底/待测」;详见 [口播与简历抽象](oral-and-resume-patterns.md)。
8
+ - **术语**:关键 API、库名、协议可加英文括号,如:`JSON.parse`、`safeParse`。口播里的私有函数名仍受 SKILL 密度预算约束。
9
+ - **待测数据**:口播中涉及性能、错误率等若暂无实测,用 **(待测)** 标出;测量思路写在导学文末「量化与验证」(见 SKILL 输出契约)。
10
+
11
+ ## STAR 四要素(口播内需隐含或显式点到)
12
+
13
+ - **S**:业务与现场约束(上线初期、某环境、流量特征)。
14
+ - **T**:你的目标与可验证标准(哪怕定性)。
15
+ - **A**:你具体落地的步骤与权衡(为何不用更简单的做法)。
16
+ - **R**:结果、指标或(待测)+ 后续观测/降级。
17
+
18
+ ## 出题顺序(禁止颠倒)
19
+
20
+ 1. 已写完项目简介与有证据支撑的一级简历 bullet(通常 4~6 条,可嵌套)。
21
+ 2. 填「简历 → 面试展开」表:每条一级 bullet 对应 1 道主问。
22
+ 3. 再写口播。禁止先按仓库目录 / 测试文件巡检出题,再倒挤 bullet。
23
+
24
+ ## 主问题设计
25
+
26
+ - **默认来源**:该条简历支柱里最硬的权衡或失败模式(面试官只看 bullet 就会问的那个)。
27
+ - 题干必须是**简历可读**的通用问题,见 [口播与简历抽象 · 出题契约](oral-and-resume-patterns.md)。
28
+ - 禁止题干出现:文件路径、私有函数名、issue 号、只有读过代码才知道的开关 / 枚举 / 内部字段。
29
+ - 正例形态:「为什么用这种结构,而不是把逻辑写在主路径里?」
30
+ - 反例形态:「某个内部配置键 / 函数为什么必须是这个字面量?」(像读过仓库)
31
+ - 题干正反例见 [oral-style-samples.md](../examples/oral-style-samples.md)(与该文件已有的 SSR 样例对齐);完整契约见 [oral-and-resume-patterns.md](oral-and-resume-patterns.md)。
32
+
33
+ ## 数量(只统计主问,追问不计入)
34
+
35
+ - **必出**:每个一级简历 bullet → **1 主问 + 2 追问**(约 4~6 道主问)。
36
+ - **可加**:0~4 道**简介级通用题**(该领域的基础权衡:一致性、隔离、降级、评估方法)。必须能从简介或 bullet 找到钩子,不要为凑数去扫鉴权样式、包体预算、点击时序等边角。
37
+ - **主问通常 4~10 道**,证据少时更少。不要为凑数把导学里的实现细节逐条改成主问。
38
+
39
+ 按主题分组时:建议 **一个一级 bullet 一个主题**;简介级通用题可单独成组或附在最相关支柱后面。
40
+
41
+ ## 追问递进(每个主问固定 2 个)
42
+
43
+ 1. **权衡与数字**:为什么是这个结构 / 这个阈值;不用更简单做法会怎样。
44
+ 2. **失败与演化**:超时、降级、下游打满、回滚、重做会改什么。
45
+
46
+ 追问仍然是面试官口吻,不要变成「那个内部函数为什么分两套」。实现细节放口播和源码证据索引。
47
+
48
+ ## 频率标注
49
+
50
+ - 题目排序:**简历一级支柱(高)> 简介级通用题(中)> 不要为频率标签去发明边角题**。
51
+ - 标签 `通用` / `前端` / `后端` / `AI`。
@@ -0,0 +1,101 @@
1
+ # 输出骨架(项目根目录下的专用文件夹)
2
+
3
+ 约定:在目标项目根目录生成:
4
+
5
+ - `interview-prep/{简称}/导学.md`
6
+ - `interview-prep/{简称}/面经.md`
7
+
8
+ `{简称}` 由用户在输入中给出,或由你从项目描述中提炼(2~8 个字符为宜),并在文首写明。需要深入讲解的主题可新增 `导学/01-主题.md` 等子文件,主导学用相对链接指向它们;不要预先创建空文件。
9
+
10
+ 面经必须按此顺序写完再进入下一节:简介 → 简历 bullet → 简历→面试展开表 → 面试问题 → 源码证据索引。禁止先堆 15+ 道源码题再倒挤 bullet。
11
+
12
+ ---
13
+
14
+ ## `导学.md` 骨架
15
+
16
+ ```markdown
17
+ # 导学:{简称}
18
+
19
+ > 证据范围:仓库源码 / 用户描述;待确认:……
20
+
21
+ ## 1. 前置知识(面试高频标注)
22
+ | 知识点 | 为何需要 | 在本项目中的位置 | 高频度 |
23
+
24
+ ## 2. 重点亮点与学习顺序(先看这个)
25
+ - (3~6 条:亮点标题 / 为什么重要 / 先看哪些文件(相对路径)/ 建议学习顺序)
26
+
27
+ ## 3. 必备知识点
28
+ - ( checklist:必须搞懂的点,可与上表呼应)
29
+
30
+ ## 4. 推荐阅读(结合仓库)
31
+ > 每条必须包含 **项目相对路径**(如 `src/views/xxx.vue`),无代码则写 `(仓库未提供路径,待用户补充)`。
32
+
33
+ | 主题 | 建议阅读的代码/文档位置 | 预计时间 | 读完能回答什么 |
34
+
35
+ ## 5. 自学提醒
36
+ - 若某文件或原理看不懂,请继续追问 AI;本 skill 负责给学习路径与题目,不提供逐行讲解。
37
+
38
+ ## 6. 项目技术定位
39
+ - 倾向:前端 / 后端 / AI / 交叉;依据一句话
40
+
41
+ ## 7. 核心原理解析
42
+ ### 7.x 主题
43
+ - 问题 → 机制 → 在本项目中的落点
44
+
45
+ ## 8. 关键设计决策
46
+ | 决策点 | 备选 | 取舍 | 风险 | 验证 |
47
+
48
+ ## 9. 链路与证据
49
+ | 链路 | 入口→机制→结果 | 失败边界 | 源码/测试相对路径 | 证据缺口 |
50
+
51
+ ## 10. 量化与验证(含待测,建议)
52
+ - 文中涉及优化/性能/错误率等:无实测数据处标注 **(待测)**
53
+ - **可选放在本文件末尾**:列出与本项目相关的 **如何测**(性能优化场景建议写:环境、指标、工具、基线/对比注意点);无则写「本项目量化点较少,面试诚实说明」。
54
+ ```
55
+
56
+ 导学亮点可以偏实现细节(方便读代码)。**不要**把本节原样粘进面经简历 bullet。
57
+
58
+ ---
59
+
60
+ ## `面经.md` 骨架
61
+
62
+ ```markdown
63
+ # 面经:{简称}
64
+
65
+ > 证据范围:仓库源码 / 用户描述;待确认:……
66
+
67
+ ## 项目简介(简历可用,1~2 句)
68
+ > 基于……的……;用户能……;支持……(参见同目录 `oral-and-resume-patterns.md`)
69
+
70
+ ## 简历 bullet(通常 4~6 条一级,可嵌套二级)
71
+ > 每条一级独立成行,格式为 `- **具体支柱名:** 正文`。标题在前、正文紧随其后;不允许省略标题。
72
+ > 内容含:痛点或演进 + 机制(业界可检索名)+ 硬约束或数字 + 结果(架构效果或指标;无线上数据才待测)。
73
+ > 动词按职责海拔;交互细节不要写进一级。完整公式见 `oral-and-resume-patterns.md`。
74
+
75
+ - **分层容错:** 痛点/演进;机制与约束;架构结果或真实指标。
76
+ - (可选二级:机制 / 约束)
77
+ - **可扩展编排:** 痛点/演进;机制与约束;架构结果或真实指标。
78
+
79
+ ## 简历 → 面试展开
80
+ | 简历一级 bullet(短标题) | 面试官主问(只看简历能问出口) | 对应题号 |
81
+ | {支柱短标题} | {该支柱最硬的权衡,不含内部符号} | Q1 |
82
+
83
+ ## 面试问题(按简历支柱展开)
84
+ > 每个一级 bullet:1 主问 + 2 追问。可另加 0~4 道简介级通用题;主问通常 4~10 道,证据少时更少。
85
+ > 题干禁止文件路径、私有函数、issue 号、内部开关。不单独输出「亮点拆解」。
86
+
87
+ ### Q1(频率:高)[标签] ← 对应 bullet:……
88
+ **面试官问题**:……
89
+
90
+ **口播版(第一人称,≥150 字,完整 STAR)**
91
+ (场景→归因→动作→结果/兜底,可含英文术语括号)
92
+
93
+ **追问 1**:……
94
+ **口播版(≥150 字)**:……
95
+
96
+ **追问 2**:……
97
+ **口播版(≥150 字)**:……
98
+
99
+ ## 源码证据索引
100
+ | 主题 | 关键路径与内部符号 | 对应正文位置 |
101
+ ```
@@ -23,7 +23,7 @@ def _escape_md(text: str) -> str:
23
23
 
24
24
  def _validate_short_name(short_name: str) -> str:
25
25
  """
26
- Validate filename-safe short name used in 导学-{简称}.md / 面经-{简称}.md.
26
+ Validate directory-safe short name used in interview-prep/{简称}/.
27
27
  """
28
28
  cleaned = short_name.strip()
29
29
  if not cleaned:
@@ -52,19 +52,18 @@ def build_prompt(
52
52
  description: Required project description.
53
53
  tech_stack: Optional stack string.
54
54
  role_focus: Optional frontend/backend/AI.
55
- short_name: Optional short name for `导学-{简称}.md` / `面经-{简称}.md`.
55
+ short_name: Optional short name for `interview-prep/{简称}/`.
56
56
  extra: Optional free-form notes.
57
57
 
58
58
  Returns:
59
59
  Markdown string to paste into a chat or pipe to an LLM.
60
60
  """
61
61
  lines: list[str] = [
62
- "请严格按 `project-interview-skill` 执行:在**工作区根目录**写入两个文件:",
63
- "`导学-{简称}.md` 与 `面经-{简称}.md`;量化与验证仅作为导学中的可选建议项。",
62
+ "请严格按 `project-interview-skill` 执行:在目标项目根目录的 `interview-prep/{简称}/` 写入 `导学.md` 与 `面经.md`;量化与验证仅作为导学中的可选建议项。",
64
63
  "",
65
64
  "## 已确认输入",
66
65
  "",
67
- "### 项目简称(用于文件名)",
66
+ "### 项目简称(用于目录名)",
68
67
  "",
69
68
  ]
70
69
  if short_name and short_name.strip():
@@ -101,10 +100,26 @@ def build_prompt(
101
100
  [
102
101
  "## 输出要求(摘要)",
103
102
  "",
104
- "- 面经:项目简介 1~2 句(简历向);主问题 15~25;追问不计入总数;建议按 3~6 个主题组织,每主题至少 1 主问 + 2 追问。",
103
+ "- 先探索仓库:确认入口与职责范围,追踪 2~4 条核心链路,逐条记录问题/演进、我的动作、机制、失败边界、结果、源码/测试相对路径与证据缺口;只有用户描述时标明证据限制,不编造职责、指标或旧架构。",
104
+ "- 面经:从事实卡抽取有证据的架构支柱,再写简介与 bullet;每条一级 bullet 独立成行,格式为 `- **具体支柱名:** 正文`,先给标题,再交代问题/演进和职责、机制、约束/边界与结果,最后填「简历 → 面试展开」表并按表出题。证据不足时少写。",
105
+ "- 面经 bullet:对照领域中立 few-shot 的正例、反例和改写对照,只学习表达结构;禁止复制样例的项目名、数字、领域名词或指标。",
106
+ "",
107
+ "## Bullet few-shot(仅学习结构,不复制素材)",
108
+ "",
109
+ "**合格**:- **分层容错:** 针对异常处理逻辑散落、改动容易波及主流程的问题,将错误处理收敛为分层容错机制:按错误类型区分有限重试、降级与快速失败,并统一输出可观测结果,降低新增场景对主链路的改动面;线上收益需通过基线对比验证。",
110
+ "",
111
+ "**不合格**:接入缓存和重试,优化接口请求。",
112
+ "",
113
+ "**改写原则**:把实现动作还原成问题/演进;说明机制如何工作及其边界;结果写可验证的架构变化或真实指标,没有证据就写测量计划,不得编造数字。",
114
+ "",
115
+ "- 面经 bullet 质检:每条只表达一个支柱,至少包含「问题或演进 + 机制 + 结果」;关键支柱尽量补充约束或数字。",
116
+ "- 面经 bullet 质检:删除“提升性能/提高稳定性/优化体验”等不可验证结果;私有函数、路径、内部枚举只进入源码证据索引。",
117
+ "- 面经 bullet 质检:支柱名必须是通用架构/工程能力;`RunManager`、`Stream Bridge`、`execution id` 等项目实现名改写为通用表达或下沉到源码证据索引。",
118
+ "- 面经:每个一级 bullet 1 主问 + 2 追问;可另加 0~4 道简介级通用题;主问通常 4~10 道,证据少时更少,追问不计入总数。题干须简历可读,禁止源码巡检型。",
105
119
  "- 面经:正文重心放在面试题口播,不单独输出「亮点拆解」章节。",
106
120
  "- 口播:第一人称;主问与每个追问口播均 **≥150 字**,完整 STAR(场景→归因→动作→结果/兜底)。",
107
121
  "- 导学:必须包含「重点亮点与学习顺序」和「推荐阅读」表,含 **仓库相对路径**。",
122
+ "- 导学:写「链路与证据」,说明入口→机制→结果、失败边界和证据缺口;复杂主题可在 `导学/01-主题.md` 中展开并从主导学链接。",
108
123
  "- 导学:加一条固定自学提醒——看不懂继续问 AI,本 skill 不做逐行讲解。",
109
124
  "- 量化与验证:仅导学可选添加(建议语气);面经不强制该章节。",
110
125
  "",
@@ -135,7 +150,7 @@ def main(argv: list[str] | None = None) -> int:
135
150
  "--short-name",
136
151
  "-s",
137
152
  default="",
138
- help="Short name for filenames: 导学-{简称}.md / 面经-{简称}.md",
153
+ help="Short name for output directory: interview-prep/{简称}/",
139
154
  )
140
155
  parser.add_argument("--tech", default="", help="Technology stack string.")
141
156
  parser.add_argument(
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env python3
2
+ """Check that every top-level resume bullet has a visible title prefix."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import re
8
+ from pathlib import Path
9
+
10
+
11
+ TITLE_PATTERN = re.compile(r"^- \*\*[^*:\s][^*:]*:\*\*\s+\S")
12
+
13
+
14
+ def check_resume_bullets(markdown: str) -> list[str]:
15
+ in_section = False
16
+ found = 0
17
+ errors: list[str] = []
18
+
19
+ for number, line in enumerate(markdown.splitlines(), 1):
20
+ if line.startswith("## 简历 bullet"):
21
+ in_section = True
22
+ continue
23
+ if in_section and line.startswith("## "):
24
+ break
25
+ if in_section and line.startswith("- "):
26
+ found += 1
27
+ if not TITLE_PATTERN.match(line):
28
+ errors.append(f"line {number}: use '- **具体支柱名:** 正文'")
29
+
30
+ if not in_section:
31
+ errors.append("missing '## 简历 bullet' section")
32
+ elif not found:
33
+ errors.append("no top-level resume bullets found")
34
+ return errors
35
+
36
+
37
+ def main() -> int:
38
+ parser = argparse.ArgumentParser(description=__doc__)
39
+ parser.add_argument("path", type=Path, help="Path to generated 面经.md")
40
+ args = parser.parse_args()
41
+ try:
42
+ markdown = args.path.read_text(encoding="utf-8")
43
+ except OSError as exc:
44
+ parser.error(str(exc))
45
+ errors = check_resume_bullets(markdown)
46
+ if errors:
47
+ for error in errors:
48
+ print(error)
49
+ return 1
50
+ print("Resume bullet titles: OK")
51
+ return 0
52
+
53
+
54
+ if __name__ == "__main__":
55
+ raise SystemExit(main())