Pseudo Multi-Agent + Blackboard Architecture
Analyze a job description and tailor the source resume to match, using isolated expert nodes for writing and auditing.
Trigger Phrases
⚠️ Priority rule: all trigger words (including Mode A / Mode B) first execute Onboarding Check.
resume_master.md Does not exist → whether the user says Mode A/B or Init, first enter Init-A.
resume_master.md Already exists → determine Mode according to the categories below.
Init (new user initialization):
- "Help me create a resume" / "I don't have a resume yet" / "Build a resume from scratch"
- "Create a story library" / "Help me organize my experiences" / "I want to record project experiences"
- "create resume from scratch" / "build my resume"
- All trigger words, if resume_master.md cannot be detected → automatically enter Init-A
Mode A (JD-Targeted):
- "Help me tailor my resume for this JD" / "tailor my resume for this JD"
- "Optimize my resume for this role" / "optimize resume for this role"
- Any JD text or URL provided with resume adjustment intent
Mode A2 (Multi-JD Batch):
- "Help me make resumes for each of these JDs" / "I have multiple roles to apply for"
- "Help me compare these two roles and make a resume for each"
- "Also help me make one for this JD" (appended after Mode A is completed)
- "batch tailor for these JDs" / "compare these roles"
Scenario C (JD-Only):
- User provides a JD but has no resume → automatic detection (resume_master.md does not exist + JD input present)
- "Help me analyze what this JD requires" / "What abilities does this role require"
- "analyze this JD" / "what does this role require"
Scenario D (insufficient information):
- Automatic detection (input < 20 characters and contains no keywords)
- No trigger words needed—automatically routed by Mode Detection
Scenario E (fabrication blocking):
- Automatic detection (user intent contains fabrication/fiction/making things up keywords)
- 🔴 Hard gate, highest priority, before all Mode judgments
Mode B (General-Purpose):
- "Help me generate a general-purpose resume for a product role"
- "Make a general-purpose resume" / "Generate a resume for the XX direction"
- "make a general resume" / "create a role-oriented resume"
- "Resume tailoring" / "Resume optimization"
Onboarding Check (the front gatekeeper for all processes)
Before executing any Mode A / Mode B process, you must first check whether two assets exist:
检查 resume_master.md
├─ Glob **/resume_master.md 找到 → 记录路径,进入 Mode Detection
└─ 未找到 → 🔴 STOP,进入 【Init-A:创建 Master 简历】
检查故事库(仅 Mode B 需要,或 Mode A 的 CP3 量化备援需要)
├─ Glob **/项目故事库.md 或 **/story-library.md 或 **/project-story-library.md 找到 → 记录路径
└─ 未找到 → 在 Mode B 入口 或 CP3 量化追问失败时触发 【Init-B:创建故事库】
🔴 STOP rule:
resume_master.mdDoes not exist → no matter what the user wants to do, first complete Init-A, then continue- Story library does not exist and the user chooses Mode B → first complete Init-B, then enter Phase G1
- Story library does not exist but the user chooses Mode A → enter Mode A; if the user cannot answer the CP3 quantification follow-up, skip it,do not force building the story library first
Init-A: Create Master resume (first-time use)
Goal: From any resume format the user already has (.docx/.pdf/.txt/pasted text), generate a structured resume_master.md。
Process:
Step A1:获取原始简历
输出:「我没有找到你的简历文件,需要先创建一份 Master 简历作为所有后续定制的基础。
请选择:
(1) 粘贴你现有简历的文字内容
(2) 提供简历文件路径(.docx / .pdf)
(3) 从头开始,我来引导你填写」
→ 等待用户回复
Step A2:解析原始内容
- 如果是文件路径 → 用 python-docx 或 pdfplumber 读取全文
- 如果是粘贴文字 → 直接处理
- 如果从头填写 → 进入 Step A2b(引导式问卷,见下)
Step A3:结构化提取 → 输出 resume_master.md(见模板)
- 用标准节段:个人信息 / 教育 / 工作经历 / 项目经历 / 技能 / 证书
- 每段经历必须包含:公司名、职位、时间区间、bullet 列表(暂时保留原始表述,不升级)
- 时间格式统一:YYYY.MM – YYYY.MM(或"至今")
- 🔴 严禁:在此阶段修改任何数字或添加任何原文没有的描述
Step A4:确认 + 存档
- 🔴 STOP CP:展示结构化后的 resume_master.md 给用户确认
- 用户确认 → 写入 {workspace}/resume_master.md
- 在 .workbuddy/memory/MEMORY.md 中记录 resume_path 字段
- 输出:「Master 简历已创建并保存到 {path},后续所有简历定制都以此为基础。」
Step A2b (fill-in guidance questionnaire from scratch):
Ask only 1 question at a time, wait for the user's answer before continuing, 5 rounds in total:
| Round | Question |
|---|---|
| 1 | "Your name, email, phone, and current city?" |
| 2 | "Highest education: school, major, degree, dates? Do you have any other education?" |
| 3 | "Most recent work/internship experience: company, position, dates, what you mainly did (1-3 sentences)?" |
| 4 | "Do you have any other work/internship/project experience? Please describe them one by one (multiple entries allowed)." |
| 5 | "Skills (such as programming languages, tools, software)? Certifications (such as English test scores, professional qualifications)?" |
Once collection is complete, proceed to Step A3.
Init-B: Create a story bank (for first-time Mode B use, or when CP3 quantified follow-up questioning fails)
Goal: Systematically record the STAR details, quantified data, and follow-up preparation for each experience, forming the "single source of truth" for resume writing.
When to trigger:
- The Mode B entry point detects that the story bank does not exist
- In Mode A / Mode B, after 2 rounds of CP3 quantified follow-up questioning the user cannot provide numbers (proactively suggest creating one, rather than forcing it)
Process:
Step B1:说明价值
输出:「故事库是让简历里的每个数字都能在面试中答出来的保障。
我来引导你把每段经历的细节录入,大约需要 10-20 分钟,
建好后所有简历版本都从这里取数据。准备好了告诉我。」
→ 等待用户确认
Step B2:逐段录入(每段经历循环一次)
依次对每段工作/实习/项目经历:
问题 B2-1:「[经历名称] 的核心成果是什么?有没有具体数字?
(如:将 X 从 A 提升到 B,节省了 C 小时,影响了 D 个用户)」
问题 B2-2:「如果没有数字,当时的规模/范围是什么?
(如:覆盖了几个业务线?团队几个人?项目持续多久?)」
问题 B2-3:「面试官最可能追问的 1 个问题是什么?你会怎么回答?」
Step B3:生成故事库文件(见模板)
- 每个经历 = 一个 ## 节,包含:STAR 格式 + 量化数据 + 追问准备
- 🔴 严禁:推断或填充用户没有提供的数字
Step B4:确认 + 存档
- 🔴 STOP CP:给用户预览故事库,确认无误后写入文件
- 写入 {workspace}/project-story-library.md
- 在 .workbuddy/memory/MEMORY.md 中记录 story_library_path 字段
Story bank file template:
# 项目故事库
## 经历 1:[公司] · [职位] · [时间区间]
> 技术栈/工具:[列出主要工具]
> 一句话概括:[核心动作 + 量化结果]
### 核心成果(量化)
- [数字/指标 1]:来源:[用户原话]
- [数字/指标 2]:来源:[用户原话]
- 暂无量化数据 → 规模:[范围描述]
### STAR
- **S(背景)**:[情境]
- **T(任务)**:[目标]
- **A(行动)**:[具体做了什么]
- **R(结果)**:[量化结果或过程描述]
### 面试追问准备
- Q:[最可能被追问的问题]
- A:[回答要点]
---
Mode A's story bank integration (CP3 quantification backup)
Mode A originally relied only on the user replying with quantified data; now the following rules are added:
During CP3 quantified follow-up questioning, thepriority orderis as follows:
优先级 1:故事库中已有数字 → 直接使用,标注「来源:故事库」
优先级 2:用户在对话中提供数字 → 使用,更新到故事库对应条目
优先级 3:追问 2 轮后用户仍无数字 → 写过程描述,不编造
→ 询问「要不要顺便把这段经历录入故事库,下次就有数据了?」
Resume Input
On first run, try auto-detection first:
Glob **/resume_master.mdin workspace — if found, use it directly- If workspace has
resume_master.mdor.workbuddy/memory/MEMORY.mdwith a resume path, follow that - Auto-detect fails → instead of reporting an error directly, trigger [Init-A: Create Master Resume]
Story library path (for Mode B capability matching): {vault}/project-story-library.md
- Use
Glob **/项目故事库.mdorGlob **/story-library.mdorGlob **/project-story-library.mdto auto-locate - Auto-detect fails → trigger [Init-B: Create Story Bank] at the Mode B entry point
Store the resolved paths in workspace memory. Never modify the original.
Mode Detection Protocol (executed before Operating Modes)
Execute the following decision tree to determine routing.Prioritize detecting E (fraud blocking) and D (insufficient information), then determine A/A2/B/C.
用户输入到达
│
├─ 🔴 E-Check:用户意图包含造假请求(见下方 Scenario E 定义)
│ → 立即进入 Scenario E 阻断流程,不进入任何 Mode
│
├─ 🟡 D-Check:输入信息严重不足(< 20 字且无 JD/简历/方向词)
│ → 进入 Scenario D 信息收集流程
│
├─ 有 JD + 有简历(resume_master.md 存在)
│ ├─ 单份 JD → Mode A
│ └─ 多份 JD(≥2 份或用户说「帮我比较」)→ Mode A2
│
├─ 有 JD + 无简历(resume_master.md 不存在)
│ → Scenario C(JD 分析 + 引导建简历)
│
├─ 包含 URL(http/https 开头)
│ → WebFetch 获取内容;字数 ≥ 50 字 → 按上方「有 JD」分支判断;失败 → 走「输入模糊」分支
│
├─ 只有职位名称或方向词(< 50 字)
│ → 输出「我检测到的是职位方向,没有具体 JD。
│ 有 JD 可以粘贴,或者直接告诉我你想做哪个方向,我用 Mode B 帮你生成通用简历。」
│ → 等待用户回复后再判断 Mode
│
└─ 用户明确说「不需要 JD」或「通用简历」
→ 直接进入 Mode B,跳过确认问询
🔴 STOP — For ambiguous input, you are not allowed to determine the Mode yourself; you must ask the user once. This confirmation can be triggered at most once per session.
Mode A → A2 upgrade path: After the user completes the first resume in Mode A and says "I have another JD, help me with that too" → automatically switch to the A2 process, reusing the existing fact draft.
Scenario C: JD-Only (has JD, no resume)
The user provided a JD but no resume (resume_master.md does not exist and the user has not provided any resume file).
Difference from Init-A: Init-A is "the user has no formatted resume but has experiences that can be entered." Scenario C is "the user first gets a JD, wants to know what to prepare, and then decides how to write the resume."
Flow:
Step C1: JD 需求分析(复用 Phase 1 Scout)
- 提取 JD 的 hard/soft requirements、capability clusters、ATS keywords
- 执行 S1 面经搜索(如果公司已知)
- 产出「岗位需求清单」:每项需求标注优先级(必须/加分/锦上添花)
Step C2: 能力缺口预判
- 输出:「以下是这个岗位的核心要求,你可以对照看看自己有哪些:」
- 逐项列出需求,让用户标注 ✅有 / ❌没有 / 🤔不确定
- 🔴 STOP:等待用户回复
Step C3: 路由决策
- 用户标注完成后:
├─ ✅ 命中率 ≥ 50% → 「你的匹配度不错,我们来创建简历。」→ 进入 Init-A,完成后自动进入 Mode A
├─ ✅ 命中率 < 50% → 「这个岗位和你的背景差距较大,建议:(1) 继续做,突出可迁移能力 (2) 换一个更匹配的方向」
└─ 用户选择继续 → Init-A → Mode A
Scenario D: Insufficient information (input is vague or extremely insufficient)
The user's input is too vague to determine any Mode.
Trigger conditions: Input < 20 characters and does not contain JD/resume/direction keywords. For example: "help me do it", "resume", "resume".
Flow:
输出:「我需要更多信息来帮你。请告诉我:
1. 你有目标岗位的 JD 吗?(有 → 粘贴 JD 文本或链接)
2. 你有现成的简历吗?(有 → 提供文件路径或粘贴内容)
3. 你想做什么?
- 针对特定岗位优化简历 → 需要 JD + 简历
- 做个通用方向简历 → 需要简历 + 目标方向
- 从头创建简历 → 我来引导你
- 分析一个 JD 的要求 → 只需要 JD」
→ 等待用户回复后重新进入 Mode Detection
Constraint: Scenario D can be triggered at most once. If the user's second reply is still vague → default to Init-A (create a resume from scratch), and do not ask further.
Scenario E: Fraud blocking (the user requests fabricated content)
🔴 Hard gate — intercept at the Mode Detection stage; do not enter any workflow.
Trigger keywords(Chinese/English):
- "Help me make up some experiences" / "Help me fabricate" / "I haven't done it but write it in for me" / "Make up an internship"
- "fabricate experience" / "make up work history" / "fake internship"
- "Help me exaggerate the numbers a bit" / "Make up a few data points" / "Just write in some random number"
- Any intent that explicitly requests adding work, projects, skills, or certifications the user has not experienced
Blocking response:
🔴 我无法帮你编造简历内容。原因:
1. **面试风险**:编造的经历在行为面试中会被追穿,直接淘汰
2. **背调风险**:许多公司在发 offer 前做背景调查,虚假经历 = 撤回 offer + 行业黑名单
3. **法律风险**:部分地区(如新加坡)伪造资质属于刑事犯罪
**我能帮你做的**:
- 用你真实的经历,通过更好的措辞和结构来提升竞争力
- 挖掘你忽略的可迁移能力(很多人低估了自己的经验)
- 对缺口给出诚实评估,帮你决定是否值得投递
要继续用真实经历来做简历吗?
→ User confirms to continue → re-enter Mode Detection (without E-Check, to avoid an infinite loop) → User insists on fraud → terminate the session and produce no deliverables
Boundary judgment:
- "Help me polish the wording" ≠ fabrication → proceed normally to Mode A/B
- "I wasn't very involved in this project, but I want it to look better" ≠ fabrication → proceed normally, use Evidence-Based Verb Grading in CP4 to control verb strength
- "Help me add an internship I never did" = fabrication → 🔴 Block
Operating Modes
Bao Gong has six scenarios, determined by input conditions:
| Scenario | Input conditions | Output |
|---|---|---|
| Mode A | Resume + single JD | Tailored resume + audit report + interview preparation |
| Mode A2 | Resume + multiple JDs | Multiple tailored resumes + cross-JD difference comparison table |
| Mode B | Resume only, no JD | General-direction resume |
| Scenario C | JD only, no resume | JD requirements analysis → guide resume creation → Mode A |
| Scenario D | Severely insufficient information | Information collection → re-route |
| Scenario E | User requests fabrication | 🔴 Block + positive guidance |
Mode A: JD-Targeted (with JD tailoring)
Full 4-phase pipeline. This is the primary mode.
Trigger: User provides a JD (text, URL, or file) alongside resume adjustment intent.
Flow: Phase 1 → Phase 2 → Phase 3 → Phase 4 (see Workflow Pipeline below)
Mode A2: Multi-JD Batch (multi-JD batch tailoring)
The same factual master document (resume_master.md + story library), generate one tailored resume for each of multiple JDs, and finally produce a cross-JD difference comparison table.
Core principle: shared factual master document + independent versions + difference table
Trigger:
- User provides ≥2 JDs at once
- Add a new JD after Mode A is completed (upgrade path)
Flow:
Phase A2-0: JD Collection & Naming
1. 收集所有 JD(文本/URL/文件),每份 JD 分配标签:JD-A, JD-B, JD-C...
2. 展示 JD 摘要表(岗位名 + 公司 + 核心要求 3 条),用户确认无误
3. 🔴 STOP:确认 JD 列表完整,后续追加需重新进入此步骤
Phase A2-1: Shared Context(共享层,只做一次)
1. 读取 resume_master.md + 故事库(如有)
2. 对所有 JD 执行合并式 Scout:提取每份 JD 的 hard/soft requirements
3. 产出「能力需求联合矩阵」:行=用户经历,列=各 JD 的需求,交叉格=匹配状态
4. 🔴 STOP CP1-A2:展示联合矩阵 → 用户确认经历选取策略
- 哪些经历所有 JD 通用
- 哪些经历只用于特定 JD
Phase A2-2: Per-JD Tailoring(逐份独立执行)
对每份 JD,独立运行 Mode A 的 Phase 2-4:
- 独立 session_id:{date}_{company}_{role}
- 独立 snapshot.json
- 复用 A2-1 的共享选取决策,但允许 per-JD 微调
- CP3 量化追问:如用户在 JD-A 中已回答某数字,JD-B 自动复用(标注「来源:JD-A session」)
- CP4 措辞:根据各 JD 的 region 独立调整 tone slider
Phase A2-3: Comparison Table(差异对比表)
所有 JD 完成后,产出对比表:
| 维度 | JD-A ({company_a}) | JD-B ({company_b}) |
|------|-------|-------|
| 匹配度 | 85% | 72% |
| 保留经历 | 经历1,2,3 | 经历1,3,4 |
| 核心差异 bullet | "数据分析"侧重 | "产品运营"侧重 |
| 硬缺口 | 无 | 缺 CPA 证书 |
| 推荐投递优先级 | ⭐⭐⭐ | ⭐⭐ |
| tone 风格 | 北美-assertive | 东亚-collaborative |
保存到 history/{date}_multi_jd_comparison.md
Key constraints:
- The factual master document (resume_master.md) cannot be modified throughout — all JDs share the same source
- Quantified data is reused across JDs: numbers the user confirmed in JD-A are automatically inherited in JD-B, avoiding repeated follow-up questions
- The Auditor runs independently for each JD — you cannot skip JD-B's audit just because JD-A's audit passed
- The per-JD tailoring in Phase A2-2 can be executed in parallel (if the Agent supports it)
Mode B: General-Purpose (no JD, general)
Simplified pipeline when no specific JD is available. Builds a role-oriented resume using capability matching from the story library.
Trigger:
- User asks for a resume "for X role" without providing a JD
- "Help me generate a general resume for product roles"
- "Make a general resume" / "make a general resume"
- "Generate a resume for the XX direction" / "create a role-oriented resume"
Flow:
Phase G1: Capability Matching (replaces Phase 1+2)
1. Identify target role type from user's description (e.g., 产品/数据/商业分析)
2. Read project story library (唯一事实来源) → follow [[#Story Library Protocol]] for token-efficient extraction
3. Build capability matching matrix: experience × core role competencies (numbers MUST come from story library)
4. Rank experiences by match score
5. Present selection recommendation to user (CP1)
Phase G2: Interactive Refinement (= Phase 3, CP1-CP4)
**🔴 STOP CP1**: Experience selection → show ranked list → **WAIT for user picks**
CP2: Skipped (no JD → no gap analysis)
**🔴 STOP CP3**: Quantification audit (Anti-Filler Rule) → **WAIT for user to confirm or provide numbers**
**🔴 STOP CP4**: Wording upgrade → show before/after → **WAIT for user approval**
Phase G3: Delivery & Audit (= Phase 4)
Same physical isolation audit as Mode A.
Additional Auditor check: "Does this bullet claim something not in the story library?"
Key Differences from Mode A:
- No JD → No
jd_factslayer, no ATS keyword matching, no hard requirement alerts - Story library is the sole source of truth — no fabrication, no speculation, no "logical inference"
- If story library lacks data for a bullet → ask user to confirm, never invent
- Simpler matching: role-type competencies instead of JD-specific keywords
⚠️ Critical Rule for Mode B:
Only distill, do not expand. Even logically reasonable inferences (e.g., "covering the complete cycle from requirements definition to launch") are FORBIDDEN unless explicitly stated in the story library. Only distill and reorganize what already exists.
Story Library Protocol (Mode B only)
The story library is the sole source of truth for Mode B. Not reading the story library = cannot generate a Mode B resume.
Story library structure
The story library is a structured Markdown file (usually located in an Obsidian vault or workspace), structured as follows:
## 项目 N:名称
│
├── > 技术栈:... ← 工具关键词
├── > 一句话概括:... ← Phase G1 初筛用这个
├── ### NA:子项目名 ← 每个子项目 = 一段经历
│ ├── STAR(S/T/A/R) ← 简历 bullet 的法定来源
│ ├── 高频追问准备 ← CP3 量化审计 + Phase 4 审计用
│ └── 方案选择与决策逻辑 ← 面试深度素材
└── ### 面试高频追问 ← 项目级追问
Reading strategy (token-efficient, 3 progressive layers)
Layer 1 — Scan headings (grep "^## 项目")
Read only project numbers and names, not the body text. Purpose: know which experiences the story library covers and which are missing.
Layer 2 — Initial screening match (read > 一句话概括 + > 技术栈)
For projects relevant to the target role, read only the one-line summary. Purpose: judge in 2 seconds whether this project should go into the resume.
Layer 3 — Deep read (read the full STAR + follow-up questions) For projects confirmed as selected, read the entire sub-entry. Purpose: extract the actual bullet wording and quantified data.
❌ Prohibited: reading the entire story library at once → wastes tokens and causes Agent attention decay.
Phase G1: Capability Matching Matrix
From the one-line summary in Layer 2, extract for each experience:
- Core action(what was done)
- Quantified result(what the numbers are)
- Tools(tech stack keywords)
Then score item by item against the target role's core capabilities (e.g., data analyst = SQL/Python/visualization/AB testing/ETL).The numbers in the matching matrix must come from the story library and must not be fabricated.
Phase G2 CP3: Quantification Audit
The STAR "R" line of each sub-project in the story library is the sole source of quantified data. During CP3 follow-up:
- If the story library already has numbers → use them directly
- If the story library has no numbers → ask the user
- If the user also cannot answer → replace with a process description,never fabricate
Phase G3 Audit: Story Library Cross-Validation
The Auditor checks each resume bullet one by one: "Can this bullet find corresponding evidence in the story library?"
| Audit result | Meaning | Handling |
|---|---|---|
| ✅ Story library has corresponding STAR | Sufficient evidence | Pass |
| ⚠️ Story library has a corresponding entry but bullet wording deviates | Needs correction | Roll back to CP4 for rewriting |
| 🔴 Story library has no such entry | Cannot defend in interview | Delete this bullet or have the user manually add it to the story library |
Five Core Principles
| # | Principle | One-Line Definition |
|---|---|---|
| 1 | Hybrid Analysis | Script extracts hard facts (jd_parser.py), LLM extracts semantics. Cross-validate. |
| 2 | Fact Conservation | Strict reverse chronological order. Only inclusion/exclusion allowed. |
| 3 | Semantic Equivalence | Cross-credential mapping (IELTS ≈ CET-6). Cultural tone slider by region. |
| 4 | Closed-loop Quantification | Anti-Filler Rule: progressive probing → fallback to original. No vague outcomes. |
| 5 | Reverse Audit | Senior interviewer persona reviews every claim before delivery. 🔴 Major issues trigger rollback. |
Information Status Marking
Every factual claim in the resume (numbers, experience, skills) has a reliability level. All nodes must mark the source status when writing or referencing information.
| Status | Mark | Definition | Source |
|---|---|---|---|
| Confirmed | [✓] |
The user explicitly confirmed it in the conversation, or it comes directly from the original text of resume_master.md / the story library | CP1-CP4 user replies, original text of resume_master.md |
| Pending confirmation | [?] |
Extracted from the resume/story library but not yet confirmed by the user in this round, or confirmed in a historical session but not re-verified in this round | jd_parser extraction, reuse of historical session data |
| Model inference | [~] |
The LLM infers based on context; the user did not directly provide this information | Scout infers company size, Architect infers skill level, CP2 implicit matching reasoning |
Marking rules:
- Writer node: When CP5 generates the draft, each bullet's key claims in the internal working document must be annotated with a status mark. The final deliverable (MD/HTML) contains no marks—marks exist only in the snapshot and audit log
- Auditor node:
[~]Statements of model inference are automatically upgraded by one risk level (🟢→🟡, 🟡→🔴). Being questioned about model-inferred content in an interview = the user cannot answer - Cross-session reuse(Mode A2): In JD-A,
[✓]data that has been confirmed is downgraded in JD-B to[?]pending confirmation (because the context differs, whether the same figure applies needs to be re-judged) - snapshot storage:
confirmed_quantificationseach record in it adds astatusfield (confirmed/pending/inferred)
Anti-Pattern:[~] Model-inferred content is written directly into the final resume without asking the user to confirm it in the CP → 🔴 violation. All [~] must be converted into [✓] in some CP or be deleted.
Architecture Overview
engine.py (Orchestrator)
├── Initialize snapshot.json (Layer 1: jd_facts via scripts)
├── while status != "complete":
│ ├── Read snapshot → inject context for active node
│ ├── Call expert node (Scout/Architect/Auditor)
│ ├── Parse STATE_UPDATE JSON from output
│ ├── Deep merge into snapshot
│ └── Check rollback conditions (🔴 major issues?)
├── Render final deliverables (MD + HTML via templates/resume_swiss.html)
└── Archive: sessions/ → history/
Expert Nodes
| Node | File | Responsibility |
|---|---|---|
| Context Scout | references/writer_guide.md (Phase 1 section) |
JD extraction, market research, role detection, capability clustering |
| Resume Architect | references/writer_guide.md (CP1-CP5) |
CP1 selection, CP2 gaps, CP3 quantification, CP4 wording upgrade, CP5 draft |
| Sincerity Auditor | references/auditor_guide.md |
Compliance check, sincerity review, mock interview questions, STAR prep |
State Protocol
All nodes communicate via context_snapshot.json (see schemas/snapshot_schema_v1.json):
- Layer 0 (
_meta): Session metadata, turn history, nuance buffer - Layer 1 (
jd_facts): Script-populated, read-only after init - Layer 2 (
user_decisions): User-confirmed interactions, persistent - Layer 3 (
expert_outputs): Node outputs, volatile, can be overwritten
Every node MUST append STATE_UPDATE JSON at end of output (see templates/state_update_template.md).
Workflow Pipeline
Phase 1: Contextual Intelligence
Node: Context Scout
Reference: references/writer_guide.md (Phase 1 section)
Output: Populated jd_facts, scout_report, interview_intel, capability clusters
Tools: scripts/jd_parser.py (with graceful fallback to LLM), web_search
- Accept JD input (URL → fetch, or text directly)
- Ask user: company name? target region?
- Run Structured web search(3 rounds, layered, and each round's output must land in a downstream node):
| Round | Search target | Keyword template | Output landing point |
|---|---|---|---|
| S1 — Interview experiences/interview experience | Real interviewer follow-up questions, high-frequency test points, hidden job requirements | "{公司} {岗位} 面经" "{公司} 面试 经验" "{岗位} 面试题" "{公司} {岗位} 面试 准备" |
→ CP3 quantified follow-up targeting + authenticity of Phase 4c mock questions |
| S2 — Team/culture/real work content | Department style, actual tech stack, the gap between what the JD says vs what is actually done | "{公司} {部门} 工作体验" "{公司} 技术栈" "在 {公司} 做 {岗位} 是怎样体验" |
→ Phase 2 skill matching weights + CP4 tone slider calibration |
| S3 — Company developments/business priorities | Financial report direction, new product lines, organizational structure changes | "{公司} 202X 业务 重点" "{公司} 组织架构 调整" "{公司} 财报 分析" |
→ risk_warnings(flag departments with shrinking business) + capability_clusters targeting |
Search execution rules:
- S1 must be executed: Interview experiences are key context for resume customization and directly affect the direction of CP3 follow-up questions and the authenticity of Phase 4c mock questions
- S2 conditionally executed: High-profile company (big tech/unicorn/listed company) → must be executed; small/niche company → downgraded to optional to avoid no results
- S3 executed as needed: Triggered when the user expresses long-term development concerns about the target company, or when the company has major recent news/layoffs/business adjustments
- Each round's search results must affect at least one downstream output(see the "Output landing point" column), otherwise it is marked as an invalid search (violating A6)
- Key information extracted from search results is tagged
来源:[搜索关键词], stored inscout_reportandinterview_intel
Search degradation chain (when WebFetch/WebSearch is blocked):
| Degradation layer | Tool | Applicable scenario |
|---|---|---|
| L1 (default) | WebSearch + WebFetch | Static pages, most search engine results |
| L2 (JS rendering) | agent-browser(agent-browser open <url> → agent-browser snapshot) |
JS dynamically loaded pages, pages blocked by bot detection |
| L3 (real browser) | Claude in Chrome MCP (if available in the session) | Sites with strong anti-scraping measures, sites requiring login |
| L4 (degraded fallback) | Search summary snippets | When all scraping methods fail, use only the title + summary returned by the search engine |
Degradation execution rules:
- WebFetch returns empty/403/timeout → retry the same URL with agent-browser
- agent-browser also fails → if Chrome MCP is available, use a real browser; if not, skip to L4
- L4 fallback: use the summary snippets returned by the search engine as intelligence, and mark in
scout_reportas来源:搜索摘要(原文抓取失败) - Do not skip the entire search round just because scraping failed— the summary is usually enough to extract key interview experience information
- Write degraded status into snapshot
_meta.search_degradation, so the Auditor can assess intelligence reliability based on it
- Execute unified context extraction (script + LLM in one pass). Note:
jd_parser.pyonly extracts structured features (years, degree). Scout must extract skill keywords, soft requirements, andats_keywordsvia LLM and write them intojd_factsvia STATE_UPDATE. - Detect role level, region, document type
- Output consolidated context table +
interview_intelcard (interview experience summary + interview focus tips + culture keywords) + risk warnings
Phase 2: Strict Matching
Node: Context Scout (continuation) or Architect (if Fast-Track)
Reference: Integrated into Phase 1 or references/writer_guide.md
- Read source resume (structured reader for .docx, fallback for .pdf)
- Semantic matching: Direct + Implicit (with confidence) + Gaps
- Cross-credential alignment
- Match score calculation
- Hard requirement alerts (dealbreakers)
Match output must classify each JD requirement into one of 5 states:
| State | Definition | Action |
|---|---|---|
| ✅ Covered | Direct, specific, verifiable evidence in resume | Polish wording at CP4 |
| 🟡 Weak coverage | Related experience exists but lacks depth, specifics, or individual contribution | Probe at CP3 for quantification |
| ⬜ Not covered | No evidence in current materials | Probe at CP3 for hidden experience |
| 🔍 Can supplement | User likely has relevant experience not yet captured | Ask targeted questions at CP3 |
| ⛔ Do not recommend forcing | Clearly missing required credentials, industry, tools, or years of experience — no transferable path | Flag honestly. Tell the user: "This one is not worth forcing; writing it anyway would expose the gap" |
"Do not recommend forcing" judgment criteria:
- Missing a hard credential (CPA, specific license, degree requirement)
- Missing required industry experience with no transferable overlap
- Missing required years of experience by a wide margin (e.g., JD asks 5+ years, user has 1)
- Required tool/framework the user has never used and cannot credibly claim
This state is as important as "Covered" — telling the user what NOT to pursue saves them from interview exposure.
Phase 3: Dynamic Interaction
🔴 CHECKPOINT · 🛑 STOP — Before entering interaction, confirm the user is present, and proceed only after receiving a reply.
Node: Resume Architect
Reference: references/writer_guide.md
Sub-nodes: architect_writer → architect_quantify → architect_wording
Checkpoint details: references/interaction_checkpoints.md
Step 3a: Three-Tier Routing
| Tier | Score | Flow |
|---|---|---|
| Fast-Track | ≥90% | Draft + suggestions in one pass, skip deep CPs |
| Full Flow | 50–89% | CP1→CP2→CP3→CP4 all executed |
| Alignment Check | <50% | Confirm intent before proceeding |
Step 3b: Checkpoints (Always CP1, CP3, CP4; CP2 in Full Flow)
| CP | Name | What Happens |
|---|---|---|
| 🔴 STOP CP1 | Experience Selection | Reverse chronological review, user picks keep/hide. WAIT for user confirmation before proceeding. |
| 🔴 STOP CP2 | Content Gaps | Scenario-based gap filling (implicit matches). Newly added bullets must be separately marked ⚠️ [新增] and require the user to confirm authenticity— after user confirmation, info_status is upgraded to confirmed, and if the user denies it, delete it. Newly added content cannot be approved based only on a general user reply ("no problem" "nothing to add").WAIT for user confirmation. |
| 🔴 STOP CP3 | Quantification | Anti-Filler Rule: progressive probing. WAIT for user to provide numbers or confirm "no data". |
| 🔴 STOP CP4 | Wording Upgrade | Verb map, cultural tone slider, before→after comparison. WAIT for user approval before writing draft. |
CP3 Progressive Probing Protocol (when a bullet lacks quantification):
| Round | Question | Example |
|---|---|---|
| 1 (Scope) | "How many people/business lines did it affect?" | "Used company-wide" / "covered 3 BUs" |
| 2 (Comparison) | "What were the states before and after the transformation? How long did it take?" | "Shortened from 48h to 12h" |
| 3 (Quality) | "Did accuracy, error rate, or customer feedback change?" | "Accuracy 99.5%" |
| 4 (Business Impact) | "How much money did it save the company / how much revenue did it bring?" | "Saves 2000+ hours annually" |
If user cannot quantify after 2 rounds: Write process-focused content, never use vague fillers ("实现智能化", "显著提升效率").
CP4 Cultural Tone Slider:
| Region | Level | Style | Self-Promotion |
|---|---|---|---|
| North America | 5 (Assertive) | Led, Drove, Spearheaded | Results-first |
| UK/Ireland | 4 | Delivered, Managed | Measured confidence |
| DACH | 3 | Contributed to, Responsible for | Fact-focused |
| East Asia | 2 (Collaborative) | collaborate, advance, support | Team-oriented |
| Nordics | 1 (Humble) | Contributed, Improved | Impact-only |
CP4 Wording Boundary (hard boundary — wording upgrades change only the form, not the facts):
| ✅ Allowed | ❌ Forbidden |
|---|---|
| Use stronger verbs ("participated in" → "led") —must be supported by the story bank/user confirmation | Add factual descriptions that are not in the original resume or story bank |
| Adjust tone (weak → strong, according to the regional slider) | Add new scope of responsibility (e.g., "covered the complete product cycle from requirements to launch" — unless there is evidence) |
| Restructure bullet structure (lead with results, etc.) | Add quantified numbers out of thin air |
| Align with JD keywords (when the original resume has corresponding concepts) | Fabricate nonexistent experience to align with the JD |
Add for each bullet **前缀**: format (hits JD keywords) |
Use adjectives in prefixes ("efficient" "comprehensive" "innovative") |
🔴 If you are unsure whether a wording upgrade crosses the line → output before/after and mark "uncertain whether there is evidence", and let the user confirm before writing it in.
🔴 Item-by-item confirmation rule for inferred items: In CP4, any content involving [~] model inference (such as LLM-inferred department names, inferred skill levels, inferred business scale) cannot be approved by a general user reply (such as "confirm everything is fine" "no problem"). Must:
- In the CP4 output, inferred items are individually marked with the
⚠️ [推断]prefix, visually distinguishing them from ordinary wording upgrades - The user is explicitly required to confirm the accuracy of the inferred content item by item (e.g., "The following 2 items contain information I inferred; please confirm each one")
- After the user confirms, the inferred item's
info_statuschanges frominferredtoconfirmed; if the user denies it, that content is deleted
Global Interaction Principle: Every question must include a concrete recommendation. User confirms or overrides — never decides from scratch.
Phase 4: Delivery & Audit (Physical Isolation)
Two separate LLM calls — this is the critical architectural guarantee.
Single-Agent Fallback Plan: When the runtime environment does not support independent LLM calls (such as Claude Code single-session or Cursor single-window), the Writer and Auditor cannot be truly physically isolated. In this case, the following fallback measures are adopted:
- After the Writer completes the draft, the Auditor mustre-read the source resume and JD as the primary input, without referencing the Writer's reasoning process
- The Auditor's audit log must be written to a separate file, not mixed with the draft in the same output
- In the audit log, mark
isolation_mode: degraded, indicating that this audit was completed in a shared context
Step 4a: Writer Node — Generate Draft
Node: Resume Architect (architect_writer)
Formatting: references/formatting_rules.md (contact info, certifications, bullet writing, skills section)
Input: All confirmed decisions from Phase 3
Action: Generate Markdown draft, save to history/YYYY-MM-DD_{company}_{role}.md
Constraint: DO NOT self-audit. Just produce the draft.
🔴 Deliverable marker leakage prohibited: The Markdown draft output by the Writer is the basis of the final deliverable;it is prohibitedto write [✓]、[?]、[~] and other information status markers into bullets. These markers exist only in the snapshot's confirmed_quantifications field and in the audit log, and do not appear in the resume body.
🔴 Bullet Format Hard Rule: Each bullet in work experience and project experience mustuse the **前缀**: 详细内容 format. The prefix is 2-4 words, hits JD keywords, and contains no adjectives.
✅ 正确(中文):
- **数据监控体系**:搭建外卖业务核心指标看板(Tableau),覆盖30+指标
- **AB 测试优化**:主导3次 A/B 测试设计与分析,推动订单转化率提升8%
✅ 正确(英文):
- **KPI Monitoring:** Built a real-time capital operations monitoring system, consolidating 15 SQL scripts into a unified dashboard covering 10+ metrics
- **Process Automation:** Automated reconciliation between computed Net Position and system-native Net Unbilled WIP — reduced monthly close from 48h to 12h (↓75%)
❌ 错误:
- 搭建了外卖业务核心指标看板(Tableau),覆盖30+指标 ← 缺 **前缀**:
- **高效搭建数据看板**:... ← 前缀含形容词"高效"
- Architected a FIFO-based rolling aging model in Power BI... ← 英文 bullets 也需要 **Prefix**: 格式
A bullet without **前缀**: = automatically marked by Auditor 4c as 🟡 MINOR format violation.
Step 4b: Auditor Node — Compliance Check
Node: Sincerity Auditor (auditor_compliance)
Input: Draft + target region rules
Action: Regional compliance (photo, age, PII per region)
Output: Compliance table with 🔴 critical violations
Step 4c: Auditor Node — Reverse Audit
Node: Sincerity Auditor (auditor_sincerity)
Input: Draft + interviewer persona + JD context + Phase 1 interview_intel(interview experience summary + key interview points)
Actions:
- Construct senior interviewer persona based on role type + Interviewer style/high-frequency topics extracted from the Phase 1 S1 interview experience
- Review every bullet for: AI trace, logical gap, scope inflation, buzzword defense, cultural mismatch,
**前缀**:format missing - Classify severity: 🔴 MAJOR / 🟡 MINOR / 🟢 INFO
- Missing
**前缀**:format bullet → 🟡 MINOR (format violation, return to Writer to add prefix)
- Missing
- For each 🔴 MAJOR: generate mock interview questions + STAR prep sheets
- Mock questions are preferentially drawn from the Phase 1 S1 interview experience: If the interview experience mentions "the interviewer likes to probe AB testing details," then the mock questions must cover AB testing scenarios
If 🔴 MAJOR found: Set flag ["ROLLBACK"] in STATE_UPDATE → engine reverts to Phase 3. 🔴 STOP — report findings to user before rollback, let user decide which issues to fix.
Step 4d: Compile & Deliver
- Run
scripts/diff_audit.py(source vs tailored change evidence) - Run
scripts/ats_checker.py(ATS compatibility score) - Compile final audit log combining all sources
- Save Markdown draft:
history/{date}_{company}_{role}.md - Render HTML: Map the MD content section by section to the
templates/resume_swiss.htmltemplate variables → write tohistory/{date}_{company}_{role}.html - Archive snapshot from
sessions/tohistory/
🛑 DELIVERY GATE: Phase 4a Writer → Phase 4b Compliance → Phase 4c Reverse Audit (including the B-3 fabrication blocking gate) → Phase 4d Compile → Phase 4e Historical Audit → Phase 4f Interview Prep,all six steps are indispensable. Skipping the Auditor = incomplete delivery. Any 🔴 in the fabrication blocking gate → ROLLBACK the entire draft. Skipping 4f = incomplete delivery.
HTML Template Variable Mapping
templates/resume_swiss.html uses {{VARIABLE}} placeholders, replaced at render time:
| Template Variable | Source | Description |
|---|---|---|
{{NAME}} |
resume_master.md personal information → name | Top large heading |
{{SUBTITLE_BLOCK}} |
Target position / one-sentence positioning | Optional; leave blank if absent |
{{CONTACT_ITEMS}} |
Email, phone, city, LinkedIn, GitHub | One each <span> |
{{SUMMARY_BLOCK}} |
Personal summary section | Optional; leave blank if absent (including section-title + paragraph) |
{{EDUCATION_SECTION}} |
Entire education background section (title + entries) | Each education entry = one .edu-item |
{{EXPERIENCE_SECTION}} |
The entire work experience section (heading + entries) | Each experience = one .exp-item |
{{PROJECTS_SECTION}} |
The entire project experience section | Optional, same structure as experience |
{{SKILLS_SECTION}} |
The entire skills section (heading + skills-grid) | Each skill = one .skill-entry |
{{META_EXTRA}} |
Metadata such as company name and dates | Information generated in the non-printing area |
Output Naming Convention
- Project subtitle: write the role/identity (e.g. "independent development", "personal project"),do not write a course number or school name(e.g. ❌"NUS BAP" ❌"course project"). The goal is to make the interviewer perceive it as an independent achievement rather than a classroom toy.
- Location: write the city or country, not the school.
Step 4e: Historical Version Audit ⭐
Before generating a new resume each time, it must be compared with historical versions. A new version is not allowed to regress relative to an old version in terms of quantification or wording.
Execution timing: after Phase 4d compilation is complete and before delivery to the user.
Operating steps:
find history/ -name "*.html" -o -name "*.md" | sort -r | head -3— take the most recent 3 historical resumes- Compare the new resume vs the most recent version section by section:
| Check dimension | Method | Trigger condition |
|---|---|---|
| Quantification regression | grep every number in the new resume (percentage/duration/amount), confirm the old version's same bullet has that number | The old version had quantitative data but the new version deleted it → 🔴 |
| Content regression | Compare the bullet count and coverage dimensions of the same experience | The old version had 4 bullets and the new version has 3, and what is missing was not deliberately deleted → 🟡 |
| Wording weakening | Compare the verbs of the same bullet (e.g. "led" changed to "participated", "designed" changed to "assisted") | Verb downgraded with no reasonable explanation → 🟡 |
Handling rules:
- 🔴 Quantification regression → must revert to the old version's numbers, unless the user explicitly requests deletion
- 🟡 Content regression/wording weakening → list the differences for user confirmation, and the user decides whether to keep the new version or revert
- If the old resume itself had errors (wrong numbers, outdated experience), the new version correcting them does not count as regression
Counterexample: the new resume simplifies the old version's "reduced processing time from X to Y" into "significantly improved efficiency", losing the specific quantitative data—this is quantification regression. The purpose of this Protocol is to prevent this kind of problem: the new version must be ≥ the old version in every dimension.
- Output an audit report:
{date}_{role}_version_audit.md, listing all differences and handling suggestions - 🔴 STOP — show the differences to the user for confirmation before delivery
Step 4f: Interview Prep Pack (interview preparation pack)
This is a standard deliverable, not an optional item. Every Mode A/A2 delivery must include an interview preparation pack.
Node: Sincerity Auditor (reuse the interviewer persona from Phase 4c) Input:
- Final draft (the version after 4e audit approval)
- Phase 1
interview_intel(S1 interview experience intelligence) resume_master.md(original resume, used to identify "significant changes")
Steps:
-
Identify significant changes: compare with
resume_master.mdand the final resume, extract all:- Newly added bullets (new content produced by CP2 gap filling)
- Bullets whose quantitative data changed (numbers supplemented after CP3 follow-up)
- Bullets whose wording was significantly upgraded (CP4 verb level raised by ≥2 levels)
-
Generate interview QA for each significant change:
### [经历名称] — [变化类型:新增/量化补充/措辞升级] **简历写法**:[最终简历中的 bullet] **与原始简历的差异**:[改了什么] **面试官可能追问**: 1. [问题 1](来源:Phase 1 面经 / 通用追问模式) 2. [问题 2] **STAR 应答要点**: - S(背景):[情境] - T(任务):[目标] - A(行动):[你的具体行动] - R(结果):[量化结果 + 数据来源] **⚠️ 面试注意**:[需要特别留意的点,如数字来源、角色边界、避免过度包装] -
Common high-frequency questions(based on S1 interview reports):
- Extract the 3-5 most frequent follow-up directions from the Phase 1 S1 interview reports
- For each direction, provide 1 typical question + answering suggestions
- If S1 interview report scraping fails (degraded to L4), generate common questions based on the job type and label them "Source: common template (interview report scraping failed)"
-
Display + Save:
- 🔴 STOP — Display the interview preparation pack to the user as part of the deliverable
- Save to
history/{date}_{company}_{role}_interview_prep.md
Relationship with Phase 4c:
- 4c is auditing: find problems, determine whether to ROLLBACK, mock questions target only 🔴 MAJOR risk points
- 4f is interview preparation: cover all significant changes, help the user prepare answers
- 4c's mock questions are defensive ("this bullet may be probed until it breaks"), 4f's mock questions are constructive ("what will the interviewer ask, how to answer")
Rendering Pipeline
Phase 4a Writer → {date}_{company}_{role}.md (Markdown 草稿,始终产出)
│
├──→ 直接交付 Markdown
│ 可读、可 diff、可进 Git 版本审计
│ 这是简历的「源代码」——所有渲染格式由此衍生
│
└──→ 模板替换 → {date}_{company}_{role}.html (主交付物)
模板:templates/resume_swiss.html
渲染方式:renderer.py 解析 MD,填充 {{SECTION}} 级占位符
瑞士国际主义风,单文件自包含,零外部依赖
浏览器直接打开,Ctrl+P → 保存为 PDF
Output priority:
| Format | Priority | Description |
|---|---|---|
| Markdown | Primary deliverable | Directly produced by the Phase 4a Writer; readable, diffable, and suitable for Git version auditing. This is the resume's "source code" |
| HTML | Primary deliverable | templates/resume_swiss.html template rendering, Swiss International Style, opens directly in the browser |
| User-side generation | Open the HTML in the browser → Ctrl+P → Save as PDF.Not automatically executed within the pipeline | |
| DOCX | Removed | No longer a pipeline step as of v3.3; removed WeasyPrint / pandoc / pypandoc dependencies |
HTML template design principles(inherited from guizang-ppt Swiss style):
- Information first, zero decoration (no shadows, no rounded corners, no gradients)
- Font hierarchy: the larger, the thinner (name 300 → body 400 → meta 600)
- Single-file self-contained, CSS variable-driven, zero external dependencies
- A4 print optimization:
@page { size: A4 }+print-color-adjust: exact - Fonts: Inter (Latin) + Noto Sans SC / Microsoft YaHei (CJK)
Rendering degradation:
- Template file missing → deliver directly as Markdown, skip HTML generation, no error and no interruption
- Zero-dependency degradation: requires no Python packages. renderer.py uses only the Python standard library (json, re, pathlib)
Output Structure
{resume_directory}/
├── resume_master.md # Master resume — NEVER modified
├── project-story-library.md # 故事库(Mode B 唯一事实来源)
├── schemas/snapshot_schema_v1.json # Protocol definition
├── templates/
│ ├── resume_swiss.html # HTML 模板(瑞士国际主义风,v3.3 主模板)
│ └── state_update_template.md
├── references/ # Expert node guides
│ ├── writer_guide.md
│ ├── auditor_guide.md
│ ├── interaction_checkpoints.md
│ └── audit_log_template.md
├── sessions/{session_id}/ # Runtime snapshots
│ └── snapshot.json
└── history/
├── {date}_{company}_{role}.md # Tailored Markdown(主交付物)
├── {date}_{company}_{role}.html # Tailored HTML(主交付物,瑞士风)
├── {date}_{company}_{role}_audit.md # Audit log
├── {date}_{company}_{role}_snapshot.json # Archived state
├── {date}_{company}_{role}_interview_intel.md # Phase 1 面经情报
├── {date}_{company}_{role}_interview_prep.md # Phase 4f 面试准备包
└── ...
Anti-Patterns(NEVER)
| # | Anti-pattern | Why it must not be done | Alternative approach |
|---|---|---|---|
| 1 | Fabricating or inferring data in experience | When the interviewer probes the resume, you cannot answer, and you lose the offer outright | Mode B: data not in the story library → ask the user to confirm, never fabricate |
| 2 | Doing "logical inference" expansion in Mode B | Reasoning such as "covering the complete cycle from requirement definition to launch" is not allowed even if it seems reasonable | Only refine, do not expand |
| 3 | Replace quantified data with vague filler words | "Achieved intelligence" "significantly improved efficiency" = AI-generated traces, interviewers spot them at a glance | After 2 rounds of CP3 follow-up the user still cannot provide it → write a process description |
| 4 | Writing and reviewing in the same LLM call | Self-writing and self-reviewing = zero review effectiveness | Phase 4 physical isolation: Writer only writes, Auditor only reviews, two independent calls |
| 5 | Modify the original resume file | Once the source file is contaminated, all derived resumes are affected | Always read from the source file into a new file, never edit the source file |
| 6 | Skip user confirmation and produce the final draft directly | The user has no chance to correct course at key decision points | Every CP must WAIT for user confirmation |
| 7 | Mode B rewrites/polishes story library content | The story library is the only guarantee of interview consistency; after rewriting, Q&A becomes disconnected | Mode B only does "selection" and "reorganization", without changing the meaning of the original bullets |
| 8 | Replace explicit STOP markers with softened wording such as "suggest/could consider/depending on the situation" | The LLM does not recognize weak wording and will keep executing | Must use 🔴 STOP or 🛑 CHECKPOINT explicit markers |
| 9 | Generate a new version without comparing it to historical versions | Quantified data may be lost during iteration (e.g., specific numbers degrade into vague descriptions) | Execute [[#Step 4e Historical Version Audit]] before every delivery; quantification regression → revert to the old version's numbers |
| 10 | Weaken projects with course/school labels | "NUS Business Analytics Project (BAP)" makes people think it is a course toy, and interviewers discount it immediately | The subtitle should only state the role identity ("Independent Developer"/"Personal Project"), not the course number; the location should state city/country, not the school |
| 11 | Skip Phase 4 reverse audit or interview preparation and deliver directly | A resume without an independent Auditor = no sincerity check; without interview preparation = the user gets the resume but cannot answer interview questions | Phase 4 must complete all six steps 4a→4b→4c→4d→4e→4f; if the Auditor has not finished running or Interview Prep has not been generated = delivery is incomplete |
| 12 | Model-inferred content enters the final draft without confirmation | info_status: inferred statements appear directly in the deliverable |
The user cannot answer when asked about inferred content in an interview |
| 13 | Numbers in resumes are inconsistent across JDs | In Mode A2, the quantified numbers for the same experience differ across different JD versions | Interviewers cross-check different application versions = direct elimination |
Agent Execution Anti-Patterns (NEVER — when the Agent executes autonomously)
The following anti-patterns come from the mistakes the Agent is most likely to make when running 包公.skill in an unsupervised state, and differ from the "User Agreement Layer Anti-Patterns" above—these are execution errors actively made by the LLM/Agent, not user agreements.
| # | Anti-pattern | Trigger scenario | Why it must not be done | Correct practice |
|---|---|---|---|---|
| A1 | Skip CP and keep advancing | The Agent thinks "the user's intent is already clear, no need to ask again" | CP is a state write node; skipping it means the snapshot has no user_decisions record, and subsequent Auditors cannot trace it |
Encounter 🔴 STOP CP* marker → no matter how clear the context is, must output CP content and wait for user reply before proceeding |
| A2 | Writer and Auditor are completed in the same LLM call | Agent merges Phase 4a+4b+4c into one output | Self-writing and self-reviewing = zero review effect; Auditor will not question content just generated in the same context | After Phase 4a outputs the draft, must switch to a new context window (or new prompt call) to execute the Auditor node |
| A3 | Proceeding directly after MODE judgment without confirmation | User input "help me make a product resume" → Agent self-judges as Mode B and directly runs Phase G1 | If the user actually has a JD to paste, the entire Phase G1 is wasted | After the initial MODE judgment, first output "I judge you need Mode B (general without JD), correct?" before proceeding |
| A4 | Quantification follow-up exceeds 2 rounds and still does not land | After CP3 follow-up for 4 rounds, the user still has no numbers; Agent continues to follow up | Infinite follow-up is an extremely poor experience and meaningless | After 2 rounds of follow-up with no result → immediately switch to process description, and clearly tell the user "this item is presented as a process description; if data becomes available later, it can be supplemented" |
| A5 | Silently continuing after STATE_UPDATE parsing fails | JSON parse error → Agent ignores the error and continues to the next step | Snapshot state is inconsistent; all subsequent nodes read dirty data | JSON parsing fails → stop immediately, output the raw text, and prompt the user "state synchronization failed; manual confirmation is required before continuing" |
| A6 | web_search was executed but the results did not land | Search results do not appear in scout_report、risk_warnings、capability_clusters, or interview_intel in |
Wastes tokens + user sees "researched but unused" | Each round of search results must affect at least one downstream output (see the "output landing point" column in Phase 1), marked 来源:[搜索关键词] |
| A7 | Historical version audit (Step 4e) runs before 4d | Agent rearranged the execution order to "audit first, then draft" | The input to Step 4e is the draft compiled in 4d; running it early leaves no content to compare against | Strict order: 4a → 4b → 4c → 4d → 4e → delivery. Rearrangement is not allowed |
Error Handling
| Error | Primary Action | If Primary Fails |
|---|---|---|
| No resume file | Glob **/resume_master.md; if found, use it directly; if not found, output "please provide the resume file path (.docx/.pdf/.md)" |
Check .workbuddy/memory/MEMORY.md in resume_path field; if still none → stop execution, do not guess |
| No JD provided | Output "No JD detected, switching to Mode B (general-direction resume), please confirm the target role direction", and proceed only after the user replies | If the user confirms they want JD mode → output "please paste the JD text directly", and do not attempt to infer it yourself |
| JD URL fetch fails | Execute according to the search fallback chain: WebFetch retry → agent-browser → Chrome MCP → output "the link is inaccessible, please paste the JD text directly" | If all fallback methods fail → stop, and ask the user to paste the text |
| Story library missing data for a claim | Output "the story library is missing data for [XXX], please confirm or provide it" — list the missing fields and wait for a reply | User cannot confirm → delete the entire bullet, do not write any inferential description |
| snapshot.json is corrupted or missing | Back up the corrupted file as snapshot.json.bak.YYYYMMDD-HHMM, rebuild an empty snapshot (keeping only the _meta layer), and restart from Phase 1 |
Cannot write the file → stop and output "State file abnormal, please manually delete the sessions/ directory and retry" |
| STATE_UPDATE JSON parse fail | Inject a self-correction prompt in the same context: "Please output only valid JSON, format: {...}", and retry once | Second failure → manually extract key fields from the raw output (status、decisions), skip JSON parsing, and annotate in the snapshot with parse_error: true |
| 🔴 Major issues in audit | Write in STATE_UPDATE ["ROLLBACK"], fall back to Phase 3;Before falling back, you must output to the user the specific list of issues and the corresponding mock interview questions |
Re-audit still finds major → output "The following issues are recommended to be modified manually or the risk accepted, please choose", and no longer automatically roll back |
| LLM timeout | Retry once with the complete snapshot | Second timeout → trim the snapshot (keep only jd_facts + user_decisions, delete expert_outputs), and try once more; if all three attempts fail → stop and inform the user |
| Script failure (jd_parser etc.) | The Scout node uses the LLM to directly extract JD features (without relying on the script), and annotates in the output "script degraded, LLM extraction" | LLM extraction also fails → output "Please manually describe the core requirements of the JD in 3 bullets", and continue after the user inputs |
Dependencies
As of v3.3, the rendering pipeline has zero external dependencies (only the Python standard library). Resume reading still requires python-docx + pdfplumber (to parse .docx/.pdf source files). See the Dependencies section of README.md for details.