简介
本文基于一个github开源项目career-ops,分析了这个开源项目是如何与Antigravity IDE / Agent CLI 进行交互的。
整体交互图
本地数据层 (cv.md / applications.md) 本地 Node.js 脚本 (scan/set-status 等) modes/*.md (Prompt 逻辑) .agents/skills/career-ops/SKILL.md Antigravity IDE / CLI 本地数据层 (cv.md / applications.md) 本地 Node.js 脚本 (scan/set-status 等) modes/*.md (Prompt 逻辑) .agents/skills/career-ops/SKILL.md Antigravity IDE / CLI #mermaid-svg-1Z7mZ6EQlfFuAt6X{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .error-icon{fill:#552222;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .marker.cross{stroke:#333333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1Z7mZ6EQlfFuAt6X p{margin:0;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1Z7mZ6EQlfFuAt6X text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-1Z7mZ6EQlfFuAt6X .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .sequenceNumber{fill:white;}#mermaid-svg-1Z7mZ6EQlfFuAt6X #sequencenumber{fill:#333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .messageText{fill:#333;stroke:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .labelText,#mermaid-svg-1Z7mZ6EQlfFuAt6X .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .loopText,#mermaid-svg-1Z7mZ6EQlfFuAt6X .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-1Z7mZ6EQlfFuAt6X .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .noteText,#mermaid-svg-1Z7mZ6EQlfFuAt6X .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .actorPopupMenu{position:absolute;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-1Z7mZ6EQlfFuAt6X .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1Z7mZ6EQlfFuAt6X .actor-man circle,#mermaid-svg-1Z7mZ6EQlfFuAt6X line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-1Z7mZ6EQlfFuAt6X :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1. 技能识别与加载 2. 加载模式提示词 (Modes) 3. 读取用户事实层 4. 工具调用与自动化执行 开发者 / 用户 输入 "评估这个职位链接: https://..." 或 "/career-ops" 1 匹配到 career-ops 技能并读取路由规则 2 加载 modes/oferta.md + modes/_shared.md 3 读取 cv.md 与 config/profile.yml 4 执行 check-liveness.mjs / set-status.mjs 5 写入 reports/064-*.md 并更新 data/applications.md 6 返回结构化评估结果与行动建议 7 开发者 / 用户
具体交互机制与实现原理
1. 技能声明与自动发现
Antigravity IDE 在加载工作区时,Antigravity 会首先进行语义识别匹配到.agents/skills/career-ops/SKILL.md 的skill, skill在放置在特定agent的特定目录之后,会被根据它的description建立语义索引(Antigravity IDE 在加载工作区时,会自动扫描并加载根目录下的SKILL.MD文件,然后当出现关键的匹配语义信息或者实现定义的命令行加载SKILL的具体内容)。
- 前置元数据:声明了技能名称 name: career-ops、可接受的参数 arguments: mode、支持的子模式(如 scan, oferta, apply, pdf, tracker 等)。
- 自然语言与斜杠命令双触发:
用户在聊天框输入 /career-ops 会直接唤起该技能;
用户直接粘贴岗位链接或发送自然语言(例如"扫描今天的岗位"),IDE 的 Agent 会自动将意图路由至对应的处理逻辑。
2. 全局行为准则注入
IDE 会自动读取项目根目录下的 AGENTS.md作为 Agent 的最高行为准则:
- 数据契约:约束 Agent 绝不能将用户私有信息写入系统文件,也不能在升级时破坏用户文件
- 防幻觉门禁: 强制约束 Agent 只能根据 cv.md 和用户明确说过的事实生成内容,严禁捏造项目或量化数据。
- 冷启动与安全预检:规定 Agent 在会话开始时隐式调用 node doctor.mjs 检查配置完整性。
3. 提示词动态路由
当触发特定任务时,Agent 会根据 SKILL.md 的路由表读取 modes/目录下的对应 Prompt:
- 如果是职位评估,Agent 加载 modes/oferta.md 和 modes/_shared.md;
- 如果是准备面试,Agent 加载 modes/interview-prep.md;
- 如果是生成简历,Agent 加载 modes/pdf.md。
4.工具能力调度(Tool Use Loop)
Agent 拥有 IDE 赋予的系统工具权限,通过工具闭环操作项目:
- 终端执行:调用底层 Node 脚本完成繁重/确定性任务,如 node scan.mjs(免 Token 抓取)、node generate-pdf.mjs(Playwright 简历排版)。
- 文件读写(view_file / replace_file_content / write_to_file):读取用户的求职偏好,生成详细的评估报告(reports/),并通过 set-status.mjs安全更新看板。
- 浏览器与网络(browser_subagent / read_url_content):当用户提供招聘页面 URL 时,直接抓取页面 DOM 提取 JD。