首页
/ career-ops SKILL.md 路由机制深度解析:一份共享 Router 如何让多个 AI 编程 CLI 复用同一套求职命令中心

career-ops SKILL.md 路由机制深度解析:一份共享 Router 如何让多个 AI 编程 CLI 复用同一套求职命令中心

2026-09-03 15:28:21作者:薛曦旖Francesca

在 career-ops 项目中,.antigravitycli/skills/career-ops/SKILL.md 是一份以开放技能标准编写的"路由器"文档:它不直接实现任何求职功能,而是负责把用户输入(一个模式名、一段 JD 文本、一个职位 URL)解析为正确的执行路径,并按模式按需加载 modes/ 下的指令文件。读完本文,你将掌握 Skill Router 的 frontmatter 声明、PROJECT_ROOT 哨兵解析、38 种模式的完整路由表、输出语言指令的注入时机,以及多 CLI 入口文件如何通过 symlink/指针机制保持单源同步的设计。

一、SKILL.md 是什么:多 CLI 共享的求职命令中心入口

career-ops 是一个"AI 无关"(AI-agnostic)的求职搜索工作台:扫描招聘门户、把职位评估为带全局 1–5 分的 A–H 结构化报告、定制 CV、跟踪申请状态,全部运行在你本地的 AI 编程 CLI 中。docs/SUPPORTED_CLIS.md 列出了它支持的 CLI 矩阵:

CLI 入口文件 调用方式
Claude Code CLAUDE.md 交互式 claude(然后 /career-ops);无头 claude -p "prompt"
Cursor AGENTS.md 在 Cursor 中打开项目请求 career-ops(技能入口在 .cursor/skills/career-ops/SKILL.md
Codex CODEX.md 交互式 codex(纯文本);无头 codex exec "prompt"
OpenCode OPENCODE.md 交互式 opencode(然后 /career-ops);无头 opencode run "prompt"
Antigravity CLI AGENTS.md 交互式 agy(然后 /career-ops);无头 agy -p "prompt"
Grok Build CLI AGENTS.md 交互式 grok(然后 /career-ops);无头 grok -p "prompt"
Qwen AGENTS.md 交互式 qwen;无头 qwen -p "prompt"
Kimi KIMI.md 交互式 kimi
GitHub Copilot CLI AGENTS.md 无头 copilot -p "prompt"
Gemini GEMINI.md 遗留封装,重定向到 AGENTS.md

核心逻辑共享在 AGENTS.md,而各 CLI 的技能入口(Claude Code 的 .claude/skills/、Cursor 的 .cursor/skills/、Antigravity CLI 的 .antigravitycli/skills/ 等)最终都指向同一份 Router 文档。.antigravitycli/skills/career-ops/SKILL.md 就是其中面向 Antigravity CLI 的入口副本,其正文字首声明:

career-ops is a multi-CLI job-search command center. The routing below is shared across supported agent CLIs even when the invocation surface differs.

(career-ops 是一个多 CLI 求职搜索命令中心。下面的路由在所有受支持的 agent CLI 之间共享,即使各自的调用表面不同。)

1.1 Frontmatter:技能声明头

文件开头的 YAML frontmatter 是开放技能标准的元数据声明,决定了这个技能如何被发现、能否被用户直接调用:

---
name: career-ops
description: >-
  AI job search command center -- evaluate offers, generate CVs, scan portals,
  track applications. Use when the user pastes a job URL or JD, asks to scan
  portals, generate a CV/PDF, track applications, prepare for interviews, draft
  outreach/emails, or run any career-ops mode.
arguments: mode
user_invocable: true
user-invocable: true
argument-hint: "[scan | discover | deep | pdf | text | latex | latex-tex | cover | email | add | expand | eu-swe | oferta | ofertas | apply | batch | tracker | agent-inbox | pipeline | contacto | training | project | interview-prep | interview | interview/plan | interview/practice | interview/debrief | interview-redflag | patterns | offer-prep | titles | upskill | followup | reply-watch | outcome | update]"
license: MIT
---

各字段的作用:

  • name:技能标识,与目录名 skills/career-ops/ 一致;
  • description:给 LLM 的触发描述——何时该加载本技能(粘贴 JD/URL、扫描门户、生成 CV/PDF、跟踪申请、面试准备、起草外联邮件等);
  • arguments: mode:声明该技能接受一个位置参数 mode,后文所有路由逻辑都围绕解析这个变量展开;
  • user_invocable: true(同时写出 user-invocable 双下划线/连字符两种写法):允许用户以 /career-ops 形式直接调用,而不只是被 agent 自动触发;
  • argument-hint:CLI 交互提示中展示的可选模式列表,覆盖 scan、pdf、tracker、pipeline 等全部子命令;
  • license: MIT:技能本身的许可证声明。

需要区分的是:argument-hint 是"建议输入",真正的模式判定表在正文的 Mode Routing 一节,二者允许存在差异(例如 hint 中出现的 discover 在路由表中对应 discover 模式)。

二、PROJECT_ROOT 解析:用哨兵文件定位仓库根目录

Router 中所有路径(modes/config/data/、脚本、模板、输出路径)都必须相对"项目根目录"解析,而不是相对进程当前工作目录。SKILL.md 给出了一套哨兵文件(sentinel)算法:

  1. 从当前加载的这份 SKILL.md 所在目录出发;
  2. 逐级向上走,直到找到同时包含 AGENTS.mdmodes/ 的最近目录,该目录即 PROJECT_ROOT
  3. 之后本路由中的所有相对路径一律对 PROJECT_ROOT 解析;
  4. 若两个哨兵都找不到,则停止一切读写操作,先定位 career-ops 的 checkout。

原文强调这是硬性要求:

This is required even when the checkout itself is nested (for example Development\career-ops) or the command starts from a subdirectory.

(即使 checkout 本身是嵌套的,或者命令从某个子目录启动,也必须执行该解析。)

从源码结构看,这套算法的健壮性设计针对的是真实使用场景:用户可能在深层嵌套目录克隆仓库,或在子目录里启动 CLI 会话,此时 CWD 解析会拿到错误路径,而"从 SKILL.md 位置向上找双哨兵"与 CWD 完全解耦。哨兵选择 AGENTS.md + modes/ 而非 package.json 这类通用文件,也避免了误匹配嵌套 monorepo 中其他子项目。

三、调用方式:斜杠命令与自然语言两条入口

SKILL.md 的 Invocation Notes 一节明确了不同 CLI 的调用表面,但强调路由语义与入口无关

  • 支持斜杠命令注册的 CLI 可以暴露 /career-ops
  • Cursor 中技能位于 .cursor/skills/career-ops/,会被自动发现——直接按名字要一个模式,或粘贴 JD/URL 触发 auto-pipeline;
  • Codex 交互会话在仓库根目录运行 codex。由于 Codex 不保证支持斜杠命令,/career-ops 不可用时,让 Codex 按名字运行同一个模式即可;
  • Codex 无头 worker 使用 codex exec "prompt"
  • 无论入口是斜杠命令还是自然语言提示,下面的路由语义保持一致。

文档给出了等价的 Codex 提示词示例,全部映射到同一套路由语义:

Evaluate this JD with career-ops auto-pipeline: https://company.com/jobs/123
Run the career-ops scan mode and summarize new matches.
Run the career-ops pipeline mode for data/pipeline.md.
Run the career-ops pdf mode for the latest evaluated role.
Run the career-ops tracker mode and summarize the current statuses.

这五条示例恰好覆盖了四种输入形态:JD URL(auto-pipeline)、纯模式名(scan)、模式 + 数据文件(pipeline + data/pipeline.md)、针对最近评估角色的 pdf、以及状态汇总(tracker)。

四、Mode Routing:完整的模式判定表

模式判定规则是:从 $mode(即 arguments: mode 传入的值)确定执行模式。SKILL.md 内置的完整路由表如下(这是本文件的核心资产,必须完整理解):

输入 模式
(空 / 无参数) discovery — 显示命令菜单
JD 文本或 URL(无子命令) auto-pipeline
oferta oferta
ofertas ofertas
contacto contacto
deep deep
interview-prep interview-prep
interview interview
eu-swe regional/eu-swe
eu-fintech regional/eu-fintech
interview/plan interview/plan
interview/practice interview/practice
interview/debrief interview/debrief
pdf pdf
text text
latex latex
latex-tex latex-tex
email email
add add
expand expand
training training
project project
tracker tracker
agent-inbox agent-inbox
inbox agent-inbox(别名)
pipeline pipeline
apply apply
scan scan
discover discover
batch batch
patterns patterns
offer-prep offer-prep
titles titles
upskill upskill
followup followup
reply-watch reply-watch
outcome outcome
interview-redflag interview-redflag
update update
cover cover

表中值得注意的路由细节:

  • 子路径模式interview/planinterview/practiceinterview/debriefregional/eu-sweregional/eu-fintech 指向 modes/ 下的子目录文件,说明模式名即文件路径;
  • 别名归并inbox 归并到 agent-inbox,两者读取同一 data/agent-inbox.md 队列;
  • 空输入兜底:无参数进入 discovery(显示菜单);
  • auto-pipeline 兜底:见下节。

每个模式在 modes/ 目录中都有对应的指令文件(如 modes/tracker.mdmodes/scan.mdmodes/pdf.mdmodes/latex.mdmodes/cover.md),Router 只负责"选哪份文件",具体执行语义由各模式文件定义。

4.1 Auto-pipeline 自动检测

$mode 不是已知子命令时,Router 还要判断它是否"长得像一份 JD":

Auto-pipeline detection: If $mode is not a known sub-command AND contains JD text (keywords: "responsibilities", "requirements", "qualifications", "about the role", "we're looking for", company name + role) or a URL to a JD, execute auto-pipeline.

$mode 既不是子命令,也不像 JD,则显示 discovery 菜单。

即三段式判定:已知子命令 → 对应模式;未知但含 JD 特征(六个关键词或职位 URL)→ auto-pipeline;其余 → discovery。这条规则让"粘贴一段 JD 就自动跑完整流程"成为零配置行为。auto-pipeline 本身的执行步骤定义在 modes/auto-pipeline.md:提取 JD → 存活检查(Liveness gate)→ 黑名单检查 → A–G 评估 → 保存报告到 reports/ → 按 cv.output_format 生成 PDF/文本/LaTeX → 分数 ≥ 4.5 时起草申请表答案 → 更新 data/applications.md 跟踪表,任何一步失败都会继续后续步骤并在跟踪表中标记 pending。

五、Output Language Directive:输出语言指令的注入时机

Router 在执行任何模式之前读取 config/profile.yml(若存在),解析两个键:

  • language.output → 面向人类输出的 ISO 语言码,默认 en
  • language.modes_dir → 可选的市场模式目录,只控制市场词汇与本地评估规则,不控制行文语言。

然后在加载完模式指令文件之后、产出任何用户可见内容之前,注入如下指令:

Write all human-facing output in {language.output} regardless of the language of these instructions or of the job description. This includes reports, tracker notes, PDFs, cover letters, outreach, interview prep, form answers, and summaries. If language.modes_dir supplies market-specific vocabulary, keep the market logic but explain terms in {language.output} when needed.

关键设计是两者的权限划分:

language.output is authoritative for prose. modes_dir is market context; it must not force the prose language.

output 对行文语言有最终决定权;modes_dir 只是市场语境(例如 modes/de 提供 DACH 市场词汇),不得强行改变行文语言。这一点在 config/profile.example.yml 中有完整注释佐证:

language:
  # Human-facing output language for reports, tracker notes, PDFs, cover
  # letters, outreach, and form answers. Use an ISO language code such as
  # `en` or `zh-CN`; `zh-CN` also enables Chinese PDF typography rules.
  # This is separate from language.modes_dir: modes_dir selects market
  # vocabulary/rules, while output selects the prose language.
  output: en
  # modes_dir: modes/de  # optional: use DACH market vocabulary while still writing in English

项目还有可执行的实现层印证这条指令。profile-language.mjs 提供了 parseOutputLanguage()outputLanguageInstruction() 两个函数:前者从 profile YAML 中解析 language.output,对非字符串、空值、超长(>64 字符)或含控制字符的取值一律回退到默认 en;后者生成注入模型提示词的规范语言规则,核心断言与 SKILL.md 一致——"配置的 language.output 始终优先于职位描述的语言"。测试 tests/output-language.test.mjs 对该行为做了回归验证。

六、Discovery Mode:无参数时的命令菜单

当 CLI 支持 /career-ops 且用户不带参数时,Router 要求展示完整命令菜单;在 Codex 等无斜杠命令的环境中,则以纯文本列出同样选项,并按同一套语义映射模式名。SKILL.md 中给出的完整菜单原文如下:

career-ops -- Command Center

Available commands:
  /career-ops {JD}      → AUTO-PIPELINE: evaluate + report + PDF + tracker (paste text or URL)
  /career-ops pipeline  → Process pending URLs from inbox (data/pipeline.md)
  /career-ops oferta    → Evaluation only A-F (no auto PDF)
  /career-ops ofertas   → Compare and rank multiple offers
  /career-ops contacto  → LinkedIn power move: find contacts + draft message
  /career-ops deep      → Deep research prompt about company
  /career-ops interview-prep → Generate company-specific interview prep doc
  /career-ops interview    → Interactive profile/CV onboarding interview
  /career-ops eu-swe    → Calibrate a European SWE application before CV/apply/interview
  /career-ops eu-fintech → Scan 21 EU fintech portals for Product Manager roles (zero-token)
  /career-ops interview/plan → Time-blocked prep plan for an upcoming interview
  /career-ops interview/practice → Practice interview, one question at a time with feedback
  /career-ops interview/debrief → Post-interview debrief: close gaps, predict next round
  /career-ops pdf       → PDF only, ATS-optimized CV
  /career-ops text      → Tailored markdown CV (mirrors cv.md, no PDF)
  /career-ops latex     → Export CV as LaTeX/Overleaf .tex
  /career-ops latex-tex → Tailor your own resume.tex in place (opt-in; cv.md stays default)
  /career-ops cover     → Cover letter: standalone JD paste or /career-ops cover {slug}
  /career-ops email     → Formal application email draft (draft-only; never sends, submits, or clicks)
  /career-ops add       → Add a project/paper/role to your CV (fetch + preview + confirm)
  /career-ops expand    → Auto-discover and add missing competencies from profile links
  /career-ops training  → Evaluate course/cert against North Star
  /career-ops project   → Evaluate portfolio project idea
  /career-ops tracker   → Application status overview
  /career-ops agent-inbox → Queue/drain requests for the next session (data/agent-inbox.md)
  /career-ops apply     → Live application assistant (reads form + generates answers)
  /career-ops scan      → Scan portals and discover new offers
  /career-ops discover  → Resolve a company list to scannable ATS boards + append to portals.yml (zero-token)
  /career-ops batch     → Batch processing with parallel workers
  /career-ops patterns  → Analyze rejection patterns and improve targeting
  /career-ops offer-prep → Read a received offer/contract with the candidate: clause walk + lawyer questions (not legal advice)
  /career-ops titles    → Suggest adjacent job titles from your CV to broaden the search
  /career-ops upskill   → Aggregate skill-gap analysis from your evaluated reports
  /career-ops followup  → Follow-up cadence tracker: flag overdue, generate drafts
  /career-ops outcome   → Record application outcome & archive artifacts
  /career-ops update    → Update career-ops system files with diff preview + compat check

Inbox: add URLs to data/pipeline.md → /career-ops pipeline
Or paste a JD directly to run the full pipeline.

这份菜单与第四节的路由表逐条对应,同时为每个模式补充了"用户视角"的一句话说明(例如 email 强调 draft-only、绝不发送/提交/点击;offer-prep 明确"不构成法律建议")。它也是 Discovery 模式的行为规范:Router 在此场景下只输出菜单、不执行任何有副作用的操作。

七、Context Loading by Mode:三类上下文加载策略

模式确定后,Router 规定了执行前的文件加载顺序。这里的关键是 _shared.md_profile.md_custom.md 三个基础文件与模式文件的组合方式:

前置规则(适用于所有模式):若 modes/_custom.md 存在,须在 modes/_profile.md 之后、所选模式文件之前读取。它承载用户的"家规"与流程偏好,可以覆盖流程/风格默认值,但永远不允许为候选人添加事实性声明(factual claims)。

7.1 需要 _shared.md 的模式

加载顺序:modes/_shared.md + modes/_profile.md(若存在)+ modes/_custom.md(若存在)+ modes/{mode}.md

适用模式:auto-pipelineofertaofertaspdftextcontactoapplypipelinescanbatch

这些是"重"模式——评估、报告、PDF、扫描等需要共享评估规则与候选人画像的场景,modes/_shared.md 中的 A–G 评估块、查询预算(bounded research budget)等规则在此被统一注入。

7.2 独立的 Profile/Custom 模式

加载顺序:modes/_profile.md(若存在)+ modes/_custom.md(若存在)+ modes/{mode}.md不加载 _shared.md

适用模式:trackeragent-inboxdeepinterview-prepinterviewregional/eu-sweinterview/planinterview/practiceinterview/debrieflatexlatex-textrainingprojectpatternstitlesupskillfollowupreply-watchoutcomecoveremailaddoffer-prepdiscover

这一组多为"读数据 + 生成产物"的轻量模式(跟踪表查询、邮件/信草稿、技能差距聚合等),不需要完整评估上下文,减少无关 token 注入。

7.3 委派给 subagent 的模式

对于 scanapply(配合 Playwright)、pipeline(3 个以上 URL)三种长任务模式,Router 要求将其作为 worker/subagent 启动,并把 _shared.md + _profile.md(若存在)+ _custom.md(若存在)+ modes/{mode}.md 的内容注入 worker 的提示词。若 CLI 暴露了 Agent(...) 原语,调用形态如下:

Agent(
  subagent_type="general-purpose",
  prompt="[output language directive]\n\n[content of modes/_shared.md]\n\n[content of modes/_profile.md if exists]\n\n[content of modes/_custom.md if exists]\n\n[content of modes/{mode}.md]\n\n[invocation-specific data]",
  description="career-ops {mode}"
)

注意注入顺序中 output language directive 排在最前——这与第五节"注入指令必须先于任何用户可见内容"的规则一致。从源码结构看,主会话把长任务整体外包给 subagent 是为了隔离 token 预算:modes/auto-pipeline.md 明确要求评估继承 oferta 的有界研究预算,不得升级成开放式 deep-research;AGENTS.md 中还规定了并行 fan-out 前先用 node reserve-report-num.mjs --count N 预留报告编号区间,避免并行 worker 各自计算 max+1 造成编号竞争。最后一步指令是"Execute the instructions from the loaded mode file"——Router 的职责到"把正确文件装进正确上下文"为止。

八、单源多入口:SKILL.md 的同步机制

.antigravitycli/skills/career-ops/SKILL.md 并非独立维护的副本。项目以 .agents/skills/career-ops/SKILL.md唯一正源(canonical path),为各 CLI 生成入口文件。scaffolder/bin/skill-entrypoints.mjs 定义了全部七个入口及其指针目标:

export const CANONICAL_SKILL_PATH = '.agents/skills/career-ops/SKILL.md';

export const SKILL_ENTRYPOINTS = [
  { path: '.claude/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
  { path: '.cursor/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
  { path: '.opencode/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
  { path: '.qwen/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
  { path: '.antigravitycli/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
  { path: '.grok/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
  { path: '.kimi/skills/career-ops/SKILL.md',
    pointer: '../../../.agents/skills/career-ops/SKILL.md' },
];

该模块提供两个函数,覆盖了两种文件系统能力:

  • ensureSkillEntrypoints(root):初始化(npx init)时为缺失的 CLI 创建目录与指针文件,并把"内容为指针路径"的普通文件物化为正源全文(materialize)——用于不支持 symlink 的文件系统;
  • materializeSkillEntrypoints(root):更新(update-system)时遍历已存在的入口,跳过真实 symlink,把指针文件替换为正源内容。

物化逻辑的判定条件是"文件内容恰好等于指针字符串"(content !== entry.pointer 则跳过),既保证幂等,也避免误改用户自定义过的文件。test-all.mjs 中则把七个入口路径列为必须存在的文件清单,纳入全量测试回归,确保任何一个 CLI 的入口丢失都会在测试中暴露。

由此可以推断出该设计的目标:修改路由语义只需改一份文件,其余 CLI 入口由初始化/更新工具与测试共同保障同步,这正是 README 中"skill 以开放标准定义在 .agents/skills/career-ops/SKILL.md,并为每个受支持的 CLI 建立 symlink 或引用"的机制落地。

九、如何阅读与验证这份 Router

如果你想在自己的 checkout 中验证本文描述的行为,建议按以下路径阅读:

  1. 入口与正源:对比 .antigravitycli/skills/career-ops/SKILL.md.agents/skills/career-ops/SKILL.md,确认入口是正源的 symlink/指针;
  2. 路由落点:挑一个路由表中的模式(如 tracker),打开 modes/tracker.md 看 Router 选中的文件如何定义实际执行语义;
  3. 上下文文件:阅读 modes/_shared.mdmodes/_profile.md、modes/_custom.md(后两者为可选项),理解 7.1/7.2 两类加载差异;
  4. 语言指令:对照 config/profile.example.ymllanguage 段与 profile-language.mjs 的实现,验证 SKILL.md 中的指令与代码行为一致;
  5. 多入口同步:查看 scaffolder/bin/skill-entrypoints.mjstest-all.mjs 中的入口清单;
  6. 端到端示例:从 modes/auto-pipeline.md 走一遍"粘贴 JD → A–G 评估 → 报告 → PDF → 跟踪表"的完整链路,这是整条路由最终服务的核心工作流。

这套 Router 的价值在于把"多 CLI × 数十种模式"的组合复杂度压缩成一张声明式表格加三条加载规则:哨兵算法解决路径解析,路由表 + auto-pipeline 检测解决输入判定,三类上下文加载策略解决 token 预算,而单源多入口机制保证所有 CLI 看到的永远是同一套语义。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
docsdocs
暂无描述
Markdown
889
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341