career-ops_brief.template.md深度解析:为 Triage 首筛设计约 2K Token 的紧凑画像简报
【免费下载链接】career-opsOpen-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)项目地址: https://gitcode.com/GitHub_Trending/ca/career-ops
本文围绕 career-ops 仓库中的模板文件modes/_brief.template.md展开,讲清它在"两轮评估(two-pass triage)"体系中的角色:它是一份被自动复制为modes/_brief.md的紧凑候选人画像,让 triage 首筛 Agent 只需一次约 1.5–2K token 的读取,就能替代cv.md + _shared.md + _profile.md + profile.yml + oferta.md数万个 token 的完整上下文,完成每个岗位的 go/no-go 预判。读完本文,你将理解模板中每个字段如何被modes/triage.md的消费逻辑逐一对应使用、triage_threshold等配置项的默认值与生效位置,以及doctor.mjs如何自动拷贝模板并检测"未个性化"状态。
1. 为什么需要一份紧凑简报:两轮评估的 token 经济学
career-ops 的完整评估(A–G 报告)需要读取整套评估上下文:cv.md、config/profile.yml、modes/_shared.md、modes/_profile.md、modes/oferta.md。按 modes/triage.md 的说明,这"costs tens of thousands of tokens",而 triage 首筛只需要回答一个问题:这个岗位值不值得做完整评估?
为此项目设计了 modes/_brief.template.md,文件头注释明确了三点定位:
- 归属层:它是 USER LAYER 文件——复制为
modes/_brief.md后"never auto-updated bynode update-system.mjs",DATA_CONTRACT.md 的数据契约也将其列为用户层:"Your compact profile brief (~1.5–2K tokens) read by the two-pass triage first pass";模板本体则属于系统层,可随版本更新。 - 创建方式:
doctor.mjs首次运行时自动从模板拷贝,用户只需填充占位符。 - 写作纪律:"KEEP IT SHORT. Every line here is read once per role during a batch triage."——简报中的每一行都会在批量首筛中被逐岗位读取一次,所以只保留"能改变 go/no-go 决策"的信息:原型(archetypes)、薪酬底线(comp floor)、地点政策(location policy)、硬性淘汰项(hard disqualifiers)和最强证明点(proof points);深度叙事、谈判脚本、STAR 故事留在
_profile.md/cv.md中。
这正是"信息按消费路径分层"的设计:triage 首筛读小文件,完整评估才读全量上下文。config/profile.example.yml 的注释称,在混合批量的批次上,这条 gate "cuts total tokens by roughly half"。
2. 模板的九个字段:每一节对应 triage 的一步消费
模板共 89 行,结构固定、全部为占位符,用户复制到modes/_brief.md后填充。以下逐节说明其设计意图,以及 modes/triage.md 如何消费它。
2.1 Identity:一行身份
一行写完:级别、领域、年限、地点/时区、工作许可约束。模板给出的示例是 "Senior Backend Engineer — 10+ yrs. Remote (ET). US citizen, no sponsorship."。这行给 triage 提供全局锚点,尤其工作许可约束常是硬淘汰项的来源(见 2.6)。
2.2 Target Archetypes:目标原型表
这是简报中权重最高的部分。模板提供一张三列表格:
| # | Archetype | What they buy (your proof) |
|---|---|---|
| 1 | {Archetype name} | {the capability/experience that makes you a fit} |
| 2 | {Archetype name} | {...} |
| 3 | {Archetype name} | {...} |
并给定了评分语义:直接命中 = 4–5 分;邻近头衔 = 3 分;不匹配 = 1–2 分。modes/triage.md 的 "Archetype fit (weight 30%)" 维度直接复用这套语义。模板还有一段可选注释:可列出"analogue"原型——技能相同但头衔不同的岗位——"List them so triage recognizes them as valid targets instead of scoring them as misses",防止同技能异头衔的岗位被误判为不匹配。
2.3 Proof Points:可量化的证明点
要求写"最强、可量化"的成就,格式为{Accomplishment — metric, scope, impact}。triage 的 "CV match estimate (weight 15%)" 维度就是拿这些证明点与 JD 要求做映射计数:"Triage checks how many map to a JD"——强重叠 = 4–5,部分 = 3,无匹配 = 1–2。注意模板刻意要求"exact metrics",因为首筛不做深度阅读,只能靠数字做模式匹配。
2.4 Comp Strategy:薪酬策略与硬底线
模板要求一张双行表(目标薪酬 + 达成条件),例如低强度高远程对应一个档位、可接受高强度对应更高档位,然后给出一条硬底线:"Hard floor: {$X}. Below that, FAIL regardless of other signals."。这对应 triage 的 "Comp (weight 25%)" 维度:优先用 JD 公布的薪酬区间,没有就按头衔/公司/地点估算,判断是否越过简报中的门槛。"低于底线即 FAIL regardless of other signals" 这条让薪酬成为一个独立否决器,而非可被其他维度补偿的软项。
2.5 Location Scoring:地点维度评分标尺
模板给出了一套默认分档,允许用户改写为自己的政策:
- Fully remote / async-first →5.0
- Light hybrid (flexible, few days/month) →4.0–5.0
- Regular hybrid or on-site, local (no move) →{your score / comp condition}
- On-site requiring relocation →{your score / comp condition}
- High travel (>25%) →deduct 0.5–1.0
中间两档特意留成占位符,因为"混合办公/异地重定位"的容忍度因人而异,且往往与薪酬条件挂钩("no move 但接受降薪"这类个性化政策无法由模板代答)。triage 的 "Location (weight 25%)" 维度就是"Score per the Location Scoring rules in_brief.md",并要求显式标记高差旅/重定位风险。
2.6 Hard DQ Criteria:硬性淘汰项(立即 FAIL,< 3.0)
模板要求列出"你无法弥补的硬缺口",并强调"be specific so triage can pattern-match them"——首筛没有推理预算,条目必须具体到可做字符串/语义模式匹配。模板内置四个典型示例:不持有的执照/保密资质、主技能不在你领域内的纯动手岗位、JD 明示薪酬上限低于你的底线、差旅超出你该岗位类型可接受上限。
消费侧 modes/triage.md 的步骤 2 就是"Hard DQ check (takes 30 seconds)":扫一遍 JD 文本,任何一条命中即知得分 ≤ 2.5,记录 DQ 原因并跳过打分直接进入步骤 4。
2.7 Quick Scoring Guide:判定分档表
模板内嵌的分档表与 modes/triage.md 的判定表保持一致,且都锚定同一个配置键:
| Score | Verdict | What it means |
|---|---|---|
| ≥ threshold (default 3.5) | PASS | 过线——强原型 + 薪酬 + 地点,缺口可弥补 |
| 3.0 – (threshold − 0.1) | MARGINAL | 边缘——以一行展示给用户 |
| < 3.0 | FAIL | 未过线——被过滤 |
这里有一个值得注意的细节:分档边界用"threshold − 0.1"来表达 MARGINAL 带的上沿,依赖 0.1 的打分粒度——triage.md 中全局分"Round to nearest 0.1 — matching theX.X/5scores the tracker and reports already carry, and the 0.1 granularity the MARGINAL band below depends on"。也就是说,打分精度不是随意选的,而是判定分档表能成立的前提。
2.8 Soft Red Flags:软性减分项(每项 −0.5,可叠加)
模板要求列出"不构成淘汰但拉低分数"的信号,示例包括:JD 列为 required 而你自认缺口的证书、需要"改写叙事"才能包装的交付模式或领域、你更愿意回避的公司阶段/规模。triage 端对应规则是"Apply the Soft Red Flags from_brief.mdat −0.5 each",且"Hard DQs override to ≤2.5"——软性减分只在下调总分时有效,硬淘汰直接封顶 2.5。
2.9 Priority Override List:优先覆盖清单(无条件 PASS)
模板最后一节允许列出"无论如何都要被呈现"的公司——具体兴趣、内推关系等,格式{Company name — reason}。triage.md 明确规定:"If the company is on the Priority Override List inmodes/_brief.md, return PASS regardless of score. Check the company name before returning a verdict." 这给了用户一个绕过纯分数逻辑的显式后门,且检查发生在返回判定之前。
3. triage 如何把简报变成一行机器可读判定
理解模板各字段的价值,需要看消费端的完整流程。modes/triage.md 定义了 triage Agent 的行为约束:
只读一份文件。步骤 0 即"Read ONLYmodes/_brief.md. Do NOT read: cv.md / config/profile.yml / modes/_shared.md / modes/_profile.md / modes/oferta.md"。并且明确了失败回退:"modes/_brief.mdis a user-layer file created frommodes/_brief.template.md(auto-copied bydoctor.mjson first run). If it does not exist or has not been filled in, triage cannot run — fall back to full evaluation."
四维度加权打分。简报字段与打分维度的对应关系是:
| 维度 | 权重 | 消费简报中的哪一节 |
|---|---|---|
| Archetype fit | 30% | Target Archetypes(含 analogue 原型) |
| Comp | 25% | Comp Strategy(硬底线) |
| Location | 25% | Location Scoring |
| CV match estimate | 15% | Proof Points |
| Red flags(调整项) | −0.5/项 | Soft Red Flags;Hard DQ 直接封顶 ≤2.5 |
全局分公式为(archetype × 0.30) + (comp × 0.25) + (location × 0.25) + (cv_match × 0.15) + red_flag_adjustment,四舍五入到 0.1。triage.md 还注明这些是默认权重——"if_brief.mddefines its own dimension weights, use those",即简报拥有覆盖默认权重的能力。
输出契约。triage 只返回一行、总输出上限 500 token、不写任何文件、不生成 cover letter:
TRIAGE: {PASS|MARGINAL|FAIL|SKIP} | {Company} | {Role} | {Score}/5 | {reason ≤ 25 words}TRIAGE:前缀、判定词和三个单元格"machine-readable and stay exactly as written above whatever the output language — the caller parses them";只有{reason}是人读文本,按language.output输出(缺省en)。triage_threshold由调用方注入,triage 自身永远不读config/profile.yml——这与模板第 2.7 节"caller injects the resolved value"的说法一致。triage.md 还给出四条完整示例(PASS 4.3/5、FAIL 2.0/5 硬淘汰、MARGINAL 3.4/5、SKIP 0/5),可直接作为解析与测试的参照。
JD 获取规则也值得一并了解,因为它决定 SKIP 判定的边界:PDF URL 直接用 Read 工具读(WebFetch 无法提取 PDF 文本,会把活帖误判 SKIP);local:前缀读本地文件;其余先 WebFetch,失败且会话中有 Playwright 时重试一次——因为 Workday 等 SPA 招聘页 WebFetch 读不到,"most of that gap turned out to be exactly this, not actually-dead postings"。拿不到 JD 才返回TRIAGE: SKIP | ... | 0/5 | Posting inaccessible or expired。
4. 配置项:triage_threshold与triage_min_urls
模板 2.7 节引用的阈值键定义在 config/profile.example.yml 的 "Two-pass triage gate" 注释块中:
# pipeline: # triage_threshold: 3.5 # triage_min_urls: 5triage_threshold:进入完整评估的最低 triage 分(满分 5)。3.0 到阈值之间的角色为 MARGINAL 并展示给用户;低于 3.0 被静默过滤。键缺省时默认3.5。triage_min_urls:存活 URL 少于该数量的批次跳过 triage 直接进完整评估——"triage overhead isn't worth it on a handful of roles"。默认5。
这两个键由/career-ops pipeline路径读取。由于 triage Agent 不读 profile.yml,调用方(pipeline/batch 编排层)负责把解析后的值注入 triage 的提示,这正是模板分档表写成"≥ threshold (default 3.5)"而非写死 3.5 的原因。
5. 生命周期源码佐证:doctor.mjs 的自动拷贝与"未个性化"检测
模板注释声称"doctor.mjs auto-copies it on first run",doctor.mjs 的源码可以印证。
冷启动自动拷贝。onboardingState()内置一份"单一事实来源"的冷启动清单(doctor.mjs):
const templates = [ { target: 'modes/_profile.md', template: 'modes/_profile.template.md' }, { target: 'modes/_custom.md', template: 'modes/_custom.template.md' }, { target: 'modes/_brief.md', template: 'modes/_brief.template.md' }, { target: 'voice-dna.md', template: 'voice-dna.template.md' }, ];目标文件不存在而模板存在时执行copyFileSync,并把结果记入--json输出的autoCopied字段;拷贝失败(如只读文件系统的 CI 环境)会静默跳过,交由后续的 missing/prereq 检查呈现。
"文件存在 ≠ 已填好"的检测。由于 doctor 总会自动拷贝_brief.md,存在性检查永远通过,所以 doctor.mjs 对内容本身做了二次校验:PERSONALIZATION_FILES把modes/_brief.md与modes/_profile.md并列为两个"必须个性化"的文件,其中_brief.md的 impact 描述正是模板要防的失败模式——"triage reads literal {placeholders} instead of your archetypes"(triage 首筛读到的是字面量{placeholders},而非你的原型、薪酬底线和硬淘汰项)。检测逻辑是:
- 目标文件与模板完全相同 → 报告
still identical to the shipped template; - 否则提取模板自带的占位符集合(
templatePlaceholders用\{[^{}\n]{2,60}\}匹配),凡目标文件中仍残留的即计为未填充,报告still has N unfilled placeholder(s) (e.g. ...)。
比较基准刻意取"模板自己的占位符集合"而非任意花括号串——源码注释解释了原因:避免把用户合法写入的花括号内容(代码片段、JSON 示例)误报。检测结果作为unpersonalized警告而非硬门禁(career-ops 开箱即用),但 AGENTS.md 要求 Agent 在带着非空unpersonalized跑scan/pipeline/batch之前必须告知用户这一影响。该行为有专门测试覆盖:tests/doctor-unfilled-templates.test.mjs 分别验证了"与模板相同"、"残留占位符"、"已填写则不误报"三种_brief.md状态。
6. 填写实践要点(来自模板自身的纪律条款)
把模板的注释约束汇总为可操作的填写准则:
- 宁短勿长:目标 1.5–2K token;每一行都会被逐岗位复读一次,批量场景下是乘数成本。
- 只写改变 go/no-go 决策的信息:原型、comp floor、地点政策、硬淘汰项、最强证明点这五类;深度叙事、谈判脚本、STAR 故事一律留在
_profile.md/cv.md。 - 硬淘汰项要具体:写成可模式匹配的短语(如"requires active PMP license"),而不是"不匹配的技能"这类模糊描述,因为 triage 的步骤 2 只有 30 秒预算。
- 薪酬底线独立成句:"Below that, FAIL regardless of other signals"——这条让 Comp 维度拥有否决权,其他维度的高分不能弥补。
- 地点分档留白要填:hybrid 与 relocation 两档是占位符,必须写成自己的分数或薪酬条件,否则 triage 的 Location 维度无规则可套。
- 优先覆盖清单放真名:公司名要能被精确匹配("Check the company name before returning a verdict")。
- 填完跑一次 doctor:
node doctor.mjs(或node doctor.mjs --json)会报告unpersonalized中的残留占位符,确认_brief.md已无{...}模板残留后再跑批量流程。
7. 小结:一份模板如何撑起首筛体系
modes/_brief.template.md 表面上是一份约 90 行的占位符表格,实质上是 career-ops 两轮评估的成本控制点:它的每个字段都精确对应 modes/triage.md 的一个打分维度或否决规则,它的分档表与 config/profile.example.yml 的pipeline.triage_threshold(默认 3.5)联动,它的生命周期由 doctor.mjs 的自动拷贝与未个性化检测兜底,而 DATA_CONTRACT.md 保证了用户填好的modes/_brief.md永远不会被update-system.mjs覆盖。理解这份模板的最佳方式不是把它当作表单,而是当作 triage Agent 的"工作记忆接口"——写得越短、越具体、越可模式匹配,首筛的 token 效率与判定质量就越高。
关键路径索引:模板 modes/_brief.template.md · 消费方 modes/triage.md · 配置示例 config/profile.example.yml · 自动拷贝与检测 doctor.mjs · 数据契约 DATA_CONTRACT.md · 行为测试 tests/doctor-unfilled-templates.test.mjs
【免费下载链接】career-opsOpen-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)项目地址: https://gitcode.com/GitHub_Trending/ca/career-ops
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考