career-ops 实战:用 aplicar 模式逐题应答巴西求职表单的完整工作流
主题与场景:本文围绕 career-ops 的葡萄牙语(巴西市场)模式
aplicar(modes/pt/aplicar.md)展开,讲解候选人在 Chrome 中实时填写求职申请表单(Gupy、LinkedIn BR、Greenhouse BR 等)时,如何让 AI 助手"读屏 → 匹配历史评估报告 → 逐题生成个性化应答"的全流程。 读者收获:读完可掌握 aplicar 模式八步工作流的每一步操作规范、巴西市场特有的字段应答规则(pretensão salarial、CLT/PJ、aviso prévio 等)、与 reports/tracker 的联动机制,以及如何用set-status.mjs、application-answers.mjs等仓库内脚本完成状态回写与快照持久化。
一、aplicar 模式是什么:为"正在填表"这一时刻设计的实况助手
career-ops 的核心闭环是"扫描职位 → 结构化评估(A-F 报告)→ 定制简历 → 跟踪申请"。其中最容易出问题的环节,恰恰是最后一步:候选人已经打开了招聘方的申请表单,面对"为什么选择我们""期望薪资""最快入职时间"等一堆问题,需要把此前评估得到的素材现场转化为贴合的逐题应答。
aplicar(葡萄牙语"申请")模式就是为此设计的交互式模式。它面向候选人正在 Chrome 中填写申请表单的场景,是一个实况(live)助手:
- 读取屏幕上正在显示的内容;
- 加载该职位此前的评估上下文(
reports/中的报告); - 针对表单中的每一道问题生成个性化应答。
它属于 career-ops 的葡萄牙语模式族(modes/pt/),与 _shared.md(巴西市场共享上下文)、oferta.md(A-F 完整评估)、pipeline.md(URL 收件箱)共同构成面向巴西市场的四大核心模式。aplicar.md 本身是英文版 modes/apply.md 的葡萄牙语移植——英文版在后续版本中演进出了更丰富的 preflight 关卡与 ATS 经验,而 aplicar.md 保留了最核心的逐题应答工作流,并按巴西求职市场的习惯做了本地化(Bloco G 术语、CLT/PJ 字段等)。
何时该用这套模式
根据 modes/pt/README.md 的界定,当你满足以下条件时应使用 modes/pt/ 下的模式:
- 你主要申请葡萄牙语职位(Gupy、Greenhouse BR、LinkedIn BR、Vagas.com.br、Catho、InfoJobs);
- 你的简历语言是葡萄牙语,或在 PT-BR 与 EN 之间按职位切换;
- 你需要自然、地道的"巴西科技葡萄牙语"应答(而非机翻腔);
- 你需要处理巴西市场特有的概念:CLT vs PJ、13º salário、FGTS、PLR、vale-refeição、plano de saúde、aviso prévio、período de experiência。
激活方式有二:会话级(开场告诉 Claude "Use os modos em português de modes/pt/.")或持久级(在 config/profile.yml 中配置 language.modes_dir: modes/pt)。注意 language.modes_dir 是模式目录约定,而 language.output 才决定报告与应答的书面语言,两者相互独立(详见 config/profile.example.yml 中的注释)。
二、前置条件:有 Playwright 与没有 Playwright 两条路径
aplicar 模式对运行环境有明确的要求分级:
| 环境 | 工作方式 | 适用性 |
|---|---|---|
| Playwright 可见模式(推荐) | 助手直接操作浏览器,通过 browser_snapshot 等读取活动标签页 |
候选人在可视窗口里看到浏览器,助手能滚动、点击、读取页面并交互,全程可见可控 |
| 无 Playwright | 候选人手动共享截图,或粘贴表单问题文本 | 助手只能读取静态信息,无法自动交互 |
两条路径从 Step 1 就开始分流,后续的所有步骤都依赖"屏幕上到底有哪些问题"这一输入质量。如果走截图/粘贴路径,助手无法自行验证职位是否仍为有效职位,也无法自动滚动——这也是 Scroll handling 一节存在的原因(见后文)。
仓库中英文版 modes/apply.md 对该环境要求补充了重要约束:Playwright 模式下绝不可同时启动两个以上并发的 Playwright agent,因为浏览器实例是共享的(这一点同样写入 modes/pt/_shared.md 的 Tools 表)。在做多职位会话前,建议先跑一次 liveness 清理,避免在一个已过期的职位上打开标签页。
三、八步工作流总览:从读屏到交付可粘贴的应答
aplicar.md 将整个实况应答过程抽象为 8 个步骤:
1. DETECTAR → 读取 Chrome 活动标签页(截图/URL/标题)
2. IDENTIFICAR → 从页面提取公司 + 职位
3. BUSCAR → 与 reports/ 中已有报告做匹配
4. CARREGAR → 读取完整报告 + Bloco G(如存在)
5. COMPARAR → 屏幕上的职位与已评估职位是否一致?若变化 → 提醒
6. ANALISAR → 识别表单中所有可见问题
7. GERAR → 为每个问题生成个性化应答
8. APRESENTAR → 以可复制粘贴的格式展示应答
下面按"检测 → 匹配 → 比较 → 分析 → 生成 → 收尾"的逻辑主线逐一展开,其中 Step 6/7/8 是模式的核心产出环节。
四、Step 1–2:检测职位并加载评估上下文
Step 1 -- 检测职位
- 有 Playwright:对活动页面做 snapshot,读取标题、URL 与可见内容。
- 无 Playwright:请候选人做三件事之一——
- 分享表单截图(Read 工具可以读取图片);
- 以文本粘贴表单问题;
- 直接说出"公司 + 职位",由助手据此检索上下文。
Step 2 -- 识别并检索上下文
识别出公司名与职位标题后,检索遵循如下顺序:
- 按公司名在
reports/目录中大小写不敏感地 grep(例如使用 ripgrep / grep -i); - 命中 → 加载完整报告;
- 报告中存在 Bloco G → 加载此前起草的应答草稿作为基础;
- 未命中 → 提示候选人,并提议执行一次快速的 auto-pipeline(modes/auto-pipeline.md),先补一份评估再回来填表。
这里的 reports/ 目录与报告命名规则来自 modes/pt/oferta.md:每个评估报告保存为 reports/{###}-{company-slug}-{YYYY-MM-DD}.md,其中 {###} 是三位零填充的序号(需用 node reserve-report-num.mjs 原子分配)、{company-slug} 是公司小写 slug、日期为评估当天。报告头部固定携带 **Data:**、**Arquétipo:**、**Score:**、**URL:**、**PDF:** 等字段。
Bloco G 是什么:在 modes/pt/oferta.md 的报告中,## G) Rascunhos de Respostas para Candidatura 是仅当 Score ≥ 4.5 时才生成的"申请表单应答草稿"块。也就是说,aplicar 模式第 4 步说"有 Bloco G 就加载",背后依赖的是评估阶段已经为高匹配职位预写了应答素材——两个模式通过报告文件形成接力。
从源码层面看,这条链路在较新版本中已被显式化为结构化持久化:根目录下的 application-answers.mjs 定义了 ## Application Answers 段(常量 APPLICATION_ANSWERS_HEADING = '## Application Answers'),并用 node application-answers.mjs --report reports/NNN-company-role-date.md --read --strict 读取既有应答快照、--read-draft 读取评估期草稿块。--strict 模式下任何一行无法解析都会让读取以非零码失败并在 stderr 逐行点名,绝不静默丢弃应答。aplicar 文档使用的"Bloco G"术语与代码中的 ## Application Answers / Draft Application Answers 是同一职责的不同命名代际,理解这一对应关系有助于在不同版本间保持一致性。
五、Step 3:检测职位变化——填写前的"一致性护栏"
表单页面上的职位如果与已评估报告不一致,盲目照搬应答会酿成事故。aplicar.md 规定:
- 不一致 → 明确提醒:"A vaga mudou de [X] para [Y]. Quer que eu reavalie ou adapto as respostas ao novo título?"(职位从 X 变成了 Y,要我重新评估还是按新标题调整应答?)
- 选择"适配":按新标题微调应答,但不重新做完整评估;
- 选择"重新评估":执行完整 A-F 评估、更新报告、重新生成 Bloco G;
- 同步 tracker:必要时在
applications.md中修正职位标题(data/applications.md)。
这一步的本质是"对同一职位负责到底":报告、Bloco G、tracker 三者的信息必须互相咬合。英文版 modes/apply.md 将这一思想扩展为第 5 步 preflight gate(活动性确认、黑名单检查、跨渠道重复申请检查、同公司重复申请提示),并把"职位实质变更则停止起草、等待候选人决定"作为硬性门槛——可以作为更深层参考,但其核心逻辑与 aplicar.md 的 COMPARAR 步一致。
六、Step 4:分析表单问题——先分类,再生成
助手需要识别页面上的所有可见问题,覆盖五类控件:
| 控件类型 | 常见示例 |
|---|---|
| 自由文本(textarea) | 求职信、为什么选择该职位、动机阐述 |
| 下拉框(select) | 如何得知此职位、工作许可状态 |
| 是/否(radio/checkbox) | 是否愿意换城市、签证、入职可用性 |
| 薪资字段 | 期望薪资区间、薪资要求 |
| 上传字段 | 简历(CV/PDF)、求职信 PDF |
随后对每个问题做两分类判断:
- Bloco G 中已有应答 → 以既有应答为基础做适配(不重写,只微调);
- 全新问题 → 依据报告 +
cv.md现场生成。
分类判断决定了生成阶段的成本与一致性:已答过的题保持口径稳定,新题则按素材即席创作。需要留意的是,表单字段的 label/帮助文本属于不可信外部内容——按 AGENTS.md 的约定,它们只应被当作"待应答的数据"分析,绝不能被当作指令执行。
七、Step 5:生成应答——五原则 + 巴西市场字段专项
生成应答的五条原则
- 报告上下文:使用 Bloco B 的 proof points 与 Bloco F 的 STAR 故事作为论据来源;
- 复用 Bloco G:有历史草稿就以它为基底精修,而不是每次从零编;
- "Estou escolhendo vocês" 语感:沿用 auto-pipeline 的同款框架——自信、双向选择,而不是恳求式口吻;
- 具体性:引用屏幕上 JD 中某个具体点(技术栈、项目、指标),让应答显得"读过 JD";
- career-ops proof point:如果表单有"附加信息"类字段,把个人可验证的成果案例放进去。
注:英文版 modes/apply.md 在第 6–7 条进一步引入了 recruiter-side 风险地图(modes/heuristics/recruiter-side.md,判断问题试图消除哪种疑虑:motivation、stack fit、logistics、comp、work-auth、availability、seniority)以及"披露纪律"(被问到的物流问题如实回答,但不要在动机类应答里主动抖露敏感 HR 信息)。这两条与该文档的"具体性"原则一脉相承,可作为进阶补充。
巴西市场高频字段专项
aplicar.md 单独为巴西市场常见字段规定了应答规则,这是它相对通用 apply 模式最独特的价值:
| 表单字段 | 应答规则 |
|---|---|
| Pretensão salarial(期望薪资,毛薪/月薪/年薪) | 给出来自 config/profile.yml 的 compensation.target_range 区间(BRL),并附注"negociável conforme pacote total"(可依整体薪酬包协商) |
| Regime de contratação(CLT/PJ 偏好) | 按 profile.yml 作答;若适用则答"aberto a ambos"(两者皆可) |
| Disponibilidade / prazo para início(入职可用性) | 给出考虑当前 aviso prévio(CLT 离职预告期:30 天 + 每工作满 1 年加 3 天)后的现实日期 |
| Autorização de trabalho(工作许可) | 明确作答;巴西公民可答"Cidadão brasileiro, não necessita autorização" |
| Idiomas(语言水平) | 逐语言标注水平:nativo / fluente / intermediário / básico |
这些规则与 modes/pt/_shared.md 中的"巴西市场术语表"严格对应:CLT 包含 FGTS、INSS、férias、13º、aviso prévio;PJ 是开票制的服务合同,月薪更高但无 CLT 福利。因此"pretensão salarial"这类字段不能只看月薪数字,还要在应答中体现对"总薪酬包"的认知——这与 _shared.md 谈判脚本"Para comparar de forma justa, preciso entender a composição completa..."的框架互相印证。薪资、签证、搬迁、法务、人口学等敏感字段的原则是:答案必须来自 profile.yml 或候选人明确提供,否则标记为"需候选人确认"并给出最稳妥的提问方式,绝不替候选人编造。
输出格式
生成的应答以"逐题、可复制粘贴"的结构化格式交付(直接复制粘贴即可用):
## Respostas para [Empresa] -- [Vaga]
Base: Report #NNN | Score: X.X/5 | Arquétipo: [tipo]
---
### 1. [Pergunta exata do formulário]
> [Resposta pronta para copy-paste]
### 2. [Próxima pergunta]
> [Resposta]
...
---
Notas:
- [观察到的职位/表单变化等注意事项]
- [候选人应自行复查的个性化建议]
头部承载报告溯源(报告编号、评分、原型),正文每题一段引述原文问题并给出应答,末尾的 Notas 区专门存放需要人工介入的提示。英文版在需要候选人确认的字段上会输出 "Ask candidate: ..." 占位符,同一语义下 aplicar.md 的模式同样要求:有疑问就问,而不是猜。
八、Step 6:提交后的收尾——状态回写、Bloco G 更新与下一步
候选人确认已提交申请后,aplicar.md 规定三个收尾动作:
-
用规范 CLI 更新状态为 Applied:
node set-status.mjs <report#> Applied绝不要手工编辑
applications.md表格。若实际提交日期不是今天,英文版补充了--on YYYY-MM-DD参数,让状态日志记录"真实发生时间"而非"录入时间"。 -
更新该报告的 Bloco G:把最终实际填写的应答回写进报告,让"草稿"升级为"已投递版本"。
-
建议下一步:执行
/career-ops contacto(对应 modes/contacto.md)做 LinkedIn 触达——把申请动作无缝衔接到主动 outreach。
从仓库实现看,这条链路有充分的可执行工具支撑,且都强调幂等与原子性:
- set-status.mjs 的用法为
node set-status.mjs <report#|company> <state> [--note "..."] [--role "..."] [--on YYYY-MM-DD] [--force] [--dry-run] [--json]。它通过与merge-tracker相同的文件锁原子替换表格,并且进入 Applied 的转换会自动触发 follow-up 排期钩子——状态一变,后续跟进计划随即就位。 - followup-seed.mjs 用于播种跟进计划:
node followup-seed.mjs {num} --json({num}为 tracker 行号),跨日提交时传--date YYYY-MM-DD;它幂等,重复执行安全。英文 apply 模式在set-status之外还会调用它完成"提交 → 排期跟进"的衔接。 - 若要持久化应答快照本身,仓库提供了 application-answers.mjs:
它会在报告末尾追加(或仅替换既有)node application-answers.mjs --report reports/NNN-company-role-date.md --input answers.json --state filled## Application Answers段,包含**Date:**、**State:** filled|submitted、自由文本答案(原样逐字保存)、下拉/单选/复选选择、数字或短答案字段(薪酬、可用性、入职日期、工作许可)以及所用文件(CV、求职信、作品集,含版本/路径)。该段只做追加式更新,绝不重排或改动报告既有的 A–H 区块与## Keywords extracted。
aplicar.md 第 6 步所说"Atualizar Bloco G do report",在上述 CLI 尚未出现的版本中用人工编辑完成;而代码层面的规范化做法,就是让 application-answers.mjs 以 --state filled(填完未投)与 --state submitted(已投)两态管理这一快照。把两者对照理解,就能在新旧命名之间自由切换。
九、Scroll handling:表单比屏幕长怎么办
单屏 snapshot 往往看不到完整表单。aplicar.md 给出明确的分段处理约定:
- 请候选人滚动页面后再次分享截图;
- 或粘贴剩余问题;
- 以迭代方式反复执行"分析 → 生成",直到覆盖整个表单。
注意这要求每轮迭代只处理新出现的可见问题,避免与上一轮重复作答;英文版 modes/apply.md 的 Known ATS Quirks 一节(基于约 12 次真实 Playwright 填表经验)进一步说明了为什么分段很重要:Lever 的 hCaptcha 会拦截程序化的 checkbox/radio 点击、Workable 的 SPA 会在填充间隙重渲染使元素引用失效、react-select 组件每次击键都会重建内部 DOM……这些 ATS 怪癖正是"人与 AI 分段落盘、逐题粘贴"这一设计背后的现实原因。填表从来不是纯自动化问题,而是人机协同问题。
十、与 career-ops 其他模块的协作全景
把 aplicar 放回 career-ops 的整体数据流中,它的上下游关系一目了然:
| 阶段 | 模块 / 文件 | 职责 |
|---|---|---|
| 评估上游 | modes/pt/oferta.md | A–F 六块评估 + 生成 Bloco G 草稿(Score ≥ 4.5) |
| 素材真源 | cv.md、article-digest.md、config/profile.yml、modes/_profile.md |
所有应答论据的唯一来源(见 modes/pt/_shared.md 的 Fontes da Verdade 表) |
| 上下文规则 | modes/pt/_shared.md | 巴西市场术语、评分口径、谈判脚本、NUNCA/SEMPRE 规则 |
| 本文主角 | modes/pt/aplicar.md | 表单实况应答(读屏 → 匹配 → 逐题生成) |
| 状态回写 | set-status.mjs / followup-seed.mjs | Applied 状态 + 跟进排期 |
| 快照持久化 | application-answers.mjs | ## Application Answers 段的追加/读取 |
| 后续触达 | modes/contacto.md | LinkedIn outreach |
其中需要反复强调的是 _shared.md 的作者身份护栏:绝不可以把候选人"使用过的工具"表述成"候选人创建的项目",所有关于候选人经验与指标的论断必须能追溯到 cv.md 或 article-digest.md,且不允许硬编码 proof point 指标——这些约束天然约束了表单应答的生成边界,防止助手在自由文本字段里越界夸大。
十一、常见命令速查
| 目标 | 命令 |
|---|---|
| 状态置为 Applied | node set-status.mjs <report#> Applied |
| 指定真实提交日期 | node set-status.mjs <report#> Applied --on YYYY-MM-DD |
| 播种跟进计划 | node followup-seed.mjs {tracker行号} --json(跨日提交加 --date YYYY-MM-DD) |
| 持久化最终应答快照 | node application-answers.mjs --report reports/NNN-company-role-date.md --input answers.json --state submitted |
| 读取既有应答快照 | node application-answers.mjs --report reports/NNN-company-role-date.md --read --strict |
| 读取评估期草稿块 | node application-answers.mjs --report reports/NNN-company-role-date.md --read-draft |
| 预留报告编号 | node reserve-report-num.mjs(写完后 --release {###} 释放 sentinel) |
小结
aplicar 模式解决的是求职流程中最细碎也最关键的"最后一公里":把 A-F 评估的静态素材,转化为面对招聘方表单时的逐题实况应答。它的核心设计哲学可以概括为三句话:
- 先匹配再作答——屏幕上出现任何职位,都先回溯
reports/与其评估报告、Bloco G,保证口径连续; - 变化必须显式处理——职位变更时把"适配 / 重评"的选择权交给候选人,绝不静默将错就错;
- 人机协同、绝不代投——助手负责起草与准备,提交与最终确认始终由候选人完成(
_shared.md的 guardrail 明令 "Never submit, send, or click Apply/Send on the user's behalf")。
对巴西求职市场而言,这套模式的价值不止于翻译:pretensão salarial、CLT/PJ、aviso prévio 等字段规则把巴西劳动制度的具体性嵌入了每一步应答生成,配合 modes/pt/_shared.md 的本地化术语表与 config/profile.example.yml 的配置样例,它形成了一个可复制、可检验、带完整回写链路的"巴西市场实况申请"方案。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00