首页
/ career-ops 技能路由设计解析:一份 SKILL.md 如何把多 CLI 求职命令中心调度成统一流水线

career-ops 技能路由设计解析:一份 SKILL.md 如何把多 CLI 求职命令中心调度成统一流水线

2026-09-03 15:23:10作者:尤辰城Agatha

career-ops.agents/skills/career-ops/SKILL.md 是整个项目的路由入口:它用一份带 YAML frontmatter 的 Markdown 文件,把「粘贴 JD / URL」或「/career-ops scan 之类的子命令」统一映射到 modes/ 目录下 30 多个工作流,并规定了项目根解析、多 CLI 调用方式、输出语言指令和按模式加载上下文的完整规则。读完本文,你能理解一个符合开放 agent skill 标准的技能文件是如何在 Claude Code、Cursor、Codex、OpenCode 等不同 CLI 上共享同一套路由语义的,以及路由之后上下文如何分层加载、auto-pipeline 如何接管后续流程。

career-ops 命令中心运行演示

一、SKILL.md 是什么:开放技能标准的单一定义点

career-ops 是一个 CLI 无关(AI-agnostic)的求职自动化项目:扫描职位门户、把岗位评估成 A-H 结构的报告并给出 1-5 分全局评分、定制简历、跟踪申请状态,全部在本地 AI 编码 CLI 中运行。所有 CLI 共享的核心逻辑放在仓库根的 AGENTS.md,而 CLI 入口的差异由各自的 wrapper 文件处理——各 CLI 与入口文件的对应关系记录在 docs/SUPPORTED_CLIS.md

CLI 入口文件 调用方式
Claude Code CLAUDE.md 交互式 claude(然后 /career-ops);无头 claude -p "prompt"
Cursor AGENTS.md 打开项目后请求 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 / Grok Build CLI / Qwen / GitHub Copilot CLI AGENTS.md 各自交互式命令 + 无头 -p 参数
Kimi KIMI.md 交互式 kimi

在这一体系中,SKILL.md 是「技能」本身的唯一定义点。仓库中 SKILL.md 位于 .agents/skills/career-ops/,并被符号链接到各 CLI 的私有技能目录——实测 .claude/skills/career-ops/SKILL.md.cursor/skills/career-ops/SKILL.md 均为指向 ../../../.agents/skills/career-ops/SKILL.md 的软链接,README 也明确说明「The skill is defined using the open standard in .agents/skills/career-ops/SKILL.md and symlinked/referenced for each supported CLI」。这种「一份真源 + 多目录链接」的结构意味着路由规则只有一处需要维护。

1.1 YAML frontmatter:技能的机器可读元数据

SKILL.md 文件以 YAML frontmatter 开头(SKILL.md 第 1-13 行):

---
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:技能名,即 CLI 中注册的 /career-ops
  • description:给 agent 做技能选择用的自然语言描述,明确了触发时机(粘贴职位 URL/JD、要求扫描门户、生成简历/PDF、跟踪申请、面试准备、起草外联邮件等);
  • arguments: mode:声明该技能接受一个名为 mode 的参数,后文路由逻辑中的 $mode 即指它;
  • user_invocable / user-invocable:标记为可被用户直接调用(两种写法同时出现,兼容不同 CLI 对字段命名的差异);
  • argument-hint:参数提示串,列出全部可选子命令,供 CLI 补全/提示使用。

1.2 Project Root Resolution:哨兵文件定位 PROJECT_ROOT

frontmatter 之后第一段就解决了最基础的问题:agent 的进程工作目录可能不在仓库根(checkout 嵌套在 Development/career-ops 之类的位置,或用户从子目录启动命令),因此所有相对路径不能依赖 cwd。SKILL.md 规定的规则是:

从已加载的 SKILL.md 所在目录开始向上逐层查找,直到找到同时包含 AGENTS.mdmodes/ 两个哨兵的最近目录,将其作为 PROJECT_ROOT;本路由器中的每个路径(modes/config/data/、脚本、模板、输出路径)都必须相对 PROJECT_ROOT 解析,绝不相对进程 cwd。若两个哨兵都找不到,必须停下来先定位 career-ops 的 checkout,再读写任何文件。

这是一个「以技能文件自身位置为锚点」的解析策略:因为 SKILL.md 通过软链接挂到各 CLI 目录,而软链接最终落在仓库内的 .agents/ 下,所以从技能目录向上走一定能回到仓库根——前提是仓库根具备 AGENTS.mdmodes/ 这两个哨兵(本仓库两者都在根目录,见 AGENTS.mdmodes/README.md)。

值得对照的是,AGENTS.md 中另有一套用户数据根(Data Root) 的解析优先级,用于定位 cv.mdconfig/profile.ymldata/applications.md 等个人文件:

  1. 环境变量 CAREER_OPS_ROOTCAREER_OPS_DATA_DIR
  2. 仓库根的 .career-ops-data 标记文件(内含数据目录路径);
  3. 回退到仓库根本身。

此外 tracker 文件还有一层 CAREER_OPS_TRACKER 显式覆盖。也就是说 SKILL.md 里的 PROJECT_ROOT 解决的是「系统层文件在哪」,AGENTS.md 的 Data Root 解决的是「用户层文件在哪」,两者分离正是 DATA_CONTRACT.md 所述 User Layer / System Layer 双分层契约的路径基础。

二、多 CLI 调用面:斜杠命令与纯文本同构

SKILL.md 的 Invocation Notes 一节明确了「入口可以不同,路由语义必须相同」:

  • 支持斜杠命令注册的 CLI 可以把路由器暴露为 /career-ops
  • 在 Cursor 中,技能位于 .cursor/skills/career-ops/ 并被自动发现——按名字请求某个模式,或直接粘贴 JD/URL 触发 auto-pipeline;
  • 交互式 Codex 会话在仓库根运行 codex。由于 Codex 不保证有斜杠命令,若 /career-ops 不可用,就用自然语言让 Codex 运行同名模式;
  • 无头 Codex 工作用 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.

以及 discovery 模式下的等价映射表:

/career-ops {JD}           ↔ "Evaluate this JD with career-ops auto-pipeline: {JD or URL}"
/career-ops scan           ↔ "Run the career-ops scan mode and summarize new matches."
/career-ops pipeline       ↔ "Run the career-ops pipeline mode for data/pipeline.md."
/career-ops pdf            ↔ "Run the career-ops pdf mode for the latest evaluated role."
/career-ops email           ↔ "Run the career-ops email mode for the latest evaluated role."
/career-ops tracker         ↔ "Run the career-ops tracker mode and summarize the current statuses."

设计要点在于:Codex 这类没有斜杠注册机制的 CLI 并不需要新代码,只需 agent 按同一张路由表把自然语言映射成模式名,行为就与其他 CLI 完全一致。Docker 用户则可用仓库根的 cops 包装脚本,把同样的子命令转发进容器执行。

三、Mode Routing:把 $mode 映射到模式文件的完整路由表

路由是 SKILL.md 的核心。规则是「根据 $mode 确定模式」,映射关系(完整继承自 SKILL.md 的 Mode Routing 表):

输入 路由到的模式
(空 / 无参数) 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

这张表与 modes/README.md 的模式目录相互印证:modes/ 下的 auto-pipeline.mdpipeline.mdscan.mdbatch.mdapply.mdpdf.mdcover.mdemail.mdcontacto.mdtracker.mdagent-inbox.mdupdate.md 等文件一一对应;interview/planinterview/practiceinterview/debrief 对应 modes/interview/ 子目录;regional/eu-swe 对应市场校准模式目录 modes/regional/(该目录存放市场校准类模式,如 eu-swe 的欧洲 SWE 申请校准,advisory 性质);语言化模式则位于 modes/de/modes/es/modes/pt/ 等子目录。

3.1 auto-pipeline 的隐式触发规则

路由表之外还有一条隐式规则——Auto-pipeline 检测:如果 $mode 不是已知子命令,包含 JD 文本(关键词:"responsibilities"、"requirements"、"qualifications"、"about the role"、"we're looking for",或「公司名 + 职位名」的组合) JD 的 URL,则执行 auto-pipeline。若 $mode 既不是子命令也不像 JD,则回退到 discovery 菜单展示。

这条规则让「直接粘贴一段 JD」成为最高频入口:用户不需要记住任何子命令,粘贴行为本身即触发完整流水线。frontmatter 的 description 里「Use when the user pastes a job URL or JD…」正是为这一行为做的技能级声明。

四、Discovery Mode:无参数时的完整命令菜单

当 CLI 支持 /career-ops(或在 Codex 中以纯文本呈现同样选项)且用户不带参数调用时,路由器展示如下菜单(完整继承自 SKILL.md Discovery Mode 一节):

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.

菜单里两条数据线索值得注意:pipeline 消费的收件箱是 data/pipeline.md(待处理 URL 队列),agent-inbox 消费 data/agent-inbox.md(跨会话请求队列)——两者都是用户层文件,属于 AGENTS.md 数据契约中「永不自动更新」的 User Layer。

五、Output Language Directive:正文语言与市场词汇解耦

路由确定之后、执行任何模式之前,SKILL.md 要求先读 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 对正文语言有最终决定权;modes_dir 只是市场上下文,不得强行改变正文语言。这一点在 config/profile.example.ymllanguage 段有对应示例:

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

output: en + modes_dir: modes/de 的组合正是该设计的典型用例:采用 DACH 市场词汇与本地评估规则,但所有报告、PDF、外联文案仍用英文书写。仓库里 modes/de/modes/fr/modes/pt/ 等目录(各含 _shared.md 与本地化模式文件)就是 modes_dir 可指向的市场目录实体。

六、Context Loading by Mode:上下文分层加载的三种形态

路由确定模式后,SKILL.md 的 Context Loading by Mode 一节规定了执行前必须加载哪些文件。总体规则是:

modes/_custom.md 存在,在 modes/_profile.md 之后、所选模式文件之前读取。它承载用户的 house rules 与流程偏好,可以覆盖工作流/风格默认值,但永远不得引入关于候选人的事实声明

具体分三类:

6.1 需要 _shared.md + 模式文件的模式

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

适用:auto-pipelineofertaofertaspdftextcontactoapplypipelinescanbatch

这些是重流程模式,_shared.md 提供了评估体系(五维评分合成 1-5 全局分)、Block G 岗位真实性信号、公司类型与薪酬可信度表、Spend Tier 模型路由等共享规则——例如 modes/_shared.mdspend_tiereconomy / standard / premium 三档到各 CLI 模型的映射表,以及「4.5+ 立即推荐申请、4.0-4.4 值得申请、低于 3.5 建议放弃」的评分解释口径。

6.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

6.3 委托给子代理的模式

scanapply(带 Playwright 时)、pipeline(3 个及以上 URL 时):以 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}"
)

注意 prompt 的第一段正是第五节的 output language directive——语言指令被显式置于注入内容最前,保证子代理产出的报告、tracker 记录等也遵守 language.output。最后一步始终是「执行加载到的模式文件中的指令」。

6.4 与数据契约的衔接

_profile.md_custom.md 都是用户层文件,其「永不自动更新」的身份由 modes/_custom.template.md 的文件头注释再次强调:

"THIS FILE IS YOURS. It will NEVER be auto-updated." … "Because this is a user-layer file, anything you write here survives node update-system.mjs. Put customizations HERE, not in CLAUDE.md / modes/_shared.md / other system files — those get overwritten on update."

模板给出的 house rules 示例(「评估摘要一律用英式英语」「美区 ATS 优先市场简历不放照片」「批处理默认上限 20 条」「报告以分数和一句话结论开头」)说明 _custom.md 是过程性规则的落点,而 modes/README.md 的约定「One file = one mode;下划线前缀 = 共享上下文或模板,非可路由模式」则解释了为什么 _shared.md_profile.md 出现在加载序列里却不接受路由表条目。

七、路由之后:auto-pipeline 的实际执行链

路由表把「粘贴 JD」映射到 auto-pipeline 后,真正干活的是 modes/auto-pipeline.md。它展示了 SKILL.md 路由器与模式文件如何接力:

  1. Step 0 — 提取 JD:URL 输入按优先级走 Playwright(browser_navigate + browser_snapshot,适用于 Lever/Ashby/Greenhouse/Workday 等 SPA)→ WebFetch(静态页)→ WebSearch(兜底);配置了 scan.extractor: cli 时优先 node browser-extract.mjs <url> 返回紧凑 JSON,失败则静默回退 MCP 快照。所有抓取内容按 AGENTS.md 的「Untrusted External Content」规则处理:是数据,永不是指令;
  2. Step 0.5 — 存活性门:先用 Step 0 的快照判断岗位是否仍在招聘,发现 404/已关闭/空壳页就止损,不再消耗后续评估 token;
  3. Step 0.6 — 黑名单门:若 data/blacklist.md 存在,命中即暂停并引用用户当初记录的原因询问是否继续——用户决定永远优先;
  4. Step 1 — A-G 评估:执行与 oferta 模式相同的 A-F 区块评估 + Block G 岗位真实性评估(继承 oferta 的有界研究预算,不允许升级为开放式研究);
  5. Step 2 — 存报告:写入 reports/{###}-{company-slug}-{YYYY-MM-DD}.md,头部附 URL 与 Legitimacy 层级;
  6. Step 3 — 生成 PDF:按 config/profile.ymlcv.output_format 分派——latexmodes/latex.mdtextmodes/text.md、默认走 modes/pdf.md
  7. Step 4 — 申请表草稿(仅当分数 ≥ 4.5):从表单提取问题(提取不到用通用问题集),按「我选择了你」的姿态撰写 2-4 句的直接回答,存入报告 ## H) Draft Application Answers 段;
  8. Step 5 — 更新 tracker:写入 data/applications.md 全部列;任一步失败则继续后续步骤并在 tracker 中标记为 pending。

这条执行链验证了 SKILL.md 路由设计的分层逻辑:路由器(SKILL.md)负责「谁来做」,共享上下文(_shared.md)负责「按什么标准做」,用户层文件(_profile.md/_custom.md)负责「按谁的偏好做」,模式文件负责「具体怎么做」,而 config/profile.yml(可用 config/profile.example.yml 初始化)则通过 spend_tierauto_pdf_score_thresholdpipeline.triage_threshold 等键在更底层控制成本与门槛。

八、小结

.agents/skills/career-ops/SKILL.md 用不到 200 行 Markdown 实现了一个跨 CLI 的统一路由器:YAML frontmatter 让技能可被各 agent 框架发现与注册;哨兵文件(AGENTS.md + modes/)向上查找保证 PROJECT_ROOT 解析与 cwd 无关;一张 38 行的路由表加一条 JD 关键词隐式触发规则,把 30 多个子命令、别名(inboxagent-inbox)和「粘贴 JD」行为统一映射到 modes/ 下的模式文件;输出语言指令把正文语言与市场词汇解耦;三形态的上下文加载规则(共享上下文组、独立模式组、子代理委托组)在保持 _profile.md/_custom.md 用户层文件永不被系统更新覆盖的前提下,把系统规则、个人事实与过程偏好分装到位。对希望在自己的多 CLI 工作流中构建类似「单入口、多模式」agent 技能的开发者而言,这份文件及其背后的软链接布局、数据分层契约,是一套可以直接借鉴的工程范式。

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384