这是 resume-generator 最有意思的设计模式。AI 不是"直接"生成 Word 文件,而是走了一条间接路线:

第 7 课:代码生成模式


什么是"代码生成模式"?

这是 resume-generator 最有意思的设计模式。AI 不是"直接"生成 Word 文件,而是走了一条间接路线:

graph LR subgraph "普通思路(做不到)" P1["AI"] -. "直接输出" .-> P2["resume.docx"] end subgraph "实际做法(很聪明)" R1["AI"] --> R2["写一段 JS 代码"] --> R3["执行这段代码"] --> R4["代码输出 resume.docx"] end

为什么不能直接生成?因为 .docx 本质上是一个 ZIP 压缩包,里面是一堆 XML 文件。AI 没法直接"吐"出一个二进制文件。但 AI 可以写代码,而代码可以生成二进制文件。

代码生成的完整流程

graph TD A["AI 搜集资料(WebSearch + WebFetch)"] -->|"搜集到了人物背景信息"| B["AI 读取技能文件(Skill + Read)<br>学会 docx 库的用法"] B -->|"知道了怎么用代码生成 Word"| C["AI 写一段 JavaScript 代码(Write 工具)<br>generate_resume.js"] C -->|"代码写好了"| D["AI 执行这段代码(Bash 工具)<br>node generate_resume.js"] D -->|"代码运行,生成了文件"| E["resume.docx - 最终产出"]

AI 写的代码长什么样?

当你运行 resume-generator 后,打开 agent/custom_scripts/generate_resume.js,你会看到 AI 自动生成的代码。大致结构是这样的(每次运行可能不同):

code
const { Document, Paragraph, TextRun, Packer, HeadingLevel,
        AlignmentType, LevelFormat } = require('docx');
const fs = require('fs');

// AI 把搜集到的信息硬编码进了代码
const doc = new Document({
  styles: {
    default: {
      document: { run: { font: "Arial", size: 20 } }  // 10pt
    }
  },
  numbering: {
    config: [{
      reference: "bullets",
      levels: [{
        level: 0,
        format: LevelFormat.BULLET,
        text: "•",
        alignment: AlignmentType.LEFT,
        style: { paragraph: { indent: { left: 720, hanging: 360 } } }
      }]
    }]
  },
  sections: [{
    properties: {
      page: {
        margin: { top: 720, right: 720, bottom: 720, left: 720 }  // 0.5 inch
      }
    },
    children: [
      // 名字(24pt 居中)
      new Paragraph({
        alignment: AlignmentType.CENTER,
        children: [
          new TextRun({ text: "Elon Musk", bold: true, size: 48 })  // 24pt
        ]
      }),

      // 联系信息
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [
          new TextRun({ text: "CEO, SpaceX & Tesla | ...", size: 20 })
        ]
      }),

      // 职业简介
      new Paragraph({
        children: [
          new TextRun({ text: "PROFESSIONAL SUMMARY", bold: true, size: 24 })
        ]
      }),
      new Paragraph({
        children: [
          new TextRun({
            text: "Visionary entrepreneur and engineer...",
            size: 20
          })
        ]
      }),

      // 工作经历(最多 3 份,每份 2-3 个要点)
      // ...

      // 教育背景
      // ...

      // 技能列表
      // ...
    ]
  }]
});

// 导出为 .docx
Packer.toBuffer(doc).then(buffer => {
  fs.writeFileSync(
    __dirname + '/resume.docx',
    buffer
  );
  console.log('Resume generated successfully!');
});

注意几个关键点:

  1. AI 严格遵守了系统提示词的约束:0.5 inch margins(720 DXA),24pt 名字,10pt 正文
  2. AI 正确使用了 docx 库的 API:因为它读了 docx-js.md 这份参考手册
  3. AI 把搜集到的真实信息编码进了代码:工作经历、教育背景等都是搜出来的
  4. AI 遵守了 "不用 \n 换行" 的规则:每一行都是单独的 Paragraph

为什么要用"AI 写代码"这个模式?

原因一:AI 不能直接生成二进制文件

Word 文档是二进制格式,AI 只能输出文本。但代码是文本,代码可以生成二进制文件,所以"AI 写代码 → 代码生成文档"是一个巧妙的间接方案。

原因二:代码可以精确控制排版

直接让 AI "输出一段排版好的内容"很难精确。但用代码,你可以精确到每个字号、每个间距:

code
// 精确控制:名字 24pt,标题 12pt,正文 10pt
new TextRun({ text: "Name", size: 48 })    // 48 半磅 = 24pt
new TextRun({ text: "Header", size: 24 })  // 24 半磅 = 12pt
new TextRun({ text: "Body", size: 20 })    // 20 半磅 = 10pt

原因三:可验证、可调试

AI 生成的代码你可以看、可以改。如果简历排版不对,你可以看 generate_resume.js 找原因,甚至手动修改后重新运行。

code
# 看看 AI 写的代码
cat agent/custom_scripts/generate_resume.js

# 手动修改后重新运行
node agent/custom_scripts/generate_resume.js

"代码生成模式"的通用公式

这个模式不只是用在简历生成上。通用公式是:

python
任何 "AI 没法直接输出" 的格式,都可以用这个模式:

AI 搜集/分析信息
    ↓
AI 写一段代码(利用对应的库)
    ↓
执行代码 → 产出目标文件

例子:
  Word 文档 → AI 写 JS 代码(用 docx 库)
  Excel 表格 → AI 写 Python 代码(用 openpyxl 库)
  PDF 文件 → AI 写代码(用 reportlab 库)
  PPT 演示 → AI 写代码(用 python-pptx 库)
  图表图片 → AI 写代码(用 matplotlib 库)

错误处理:代码执行失败怎么办?

AI 写的代码不一定能一次跑通。好消息是,AI 有多轮操作机会(maxTurns: 30),所以它可以:

bash
第 1 次尝试:
  AI 写代码 → Bash 执行 → 报错!

AI 看到错误信息:
  "TypeError: Cannot read property 'BULLET' of undefined"

第 2 次尝试:
  AI 修改代码(import LevelFormat)→ Bash 执行 → 成功!

这就是 maxTurns 留余量的好处。AI 有"试错 → 修复"的空间。

本课小结

  • "代码生成模式":AI 不直接输出目标文件,而是写代码 → 执行代码 → 产出文件
  • 这么做是因为 AI 不能直接生成二进制文件,但代码可以
  • AI 写的代码质量取决于 Skill 技能文件和系统提示词
  • 这个模式可以推广到所有"需要用代码来生成"的文件格式
  • maxTurns 给了 AI 试错修复的空间

课后练习

  1. 运行一次后,打开 agent/custom_scripts/generate_resume.js,看看 AI 的代码风格
  2. 故意在 SYSTEM_PROMPT 里把 "Body 10pt" 改成 "Body 8pt",看 AI 是否会遵守
  3. 试着手动修改 generate_resume.js(比如换个名字),然后 node generate_resume.js 重新运行

沿着当前专题继续,或返回课程目录重新整理阅读顺序。

返回课程目录