Skip to content

AI 辅助模板开发

这篇教程教什么

你将用 AI 从零开发一个 Presto 模板——把 Markdown 变成精美的 PDF。上一篇教程你学会了用 AI 写 Python 小程序,这次我们用同样的方式做一件更有成就感的事:开发一个真正能用的简历模板。

  • 预计时间: 60-90 分钟
  • 最终产出物: 一个能在 Presto 中使用的自定义简历模板
  • 前置条件: 完成 AI 编程入门、已安装 Presto

准备好了吗?我们开始。


第一部分:理解模板是什么(10 分钟)

模板 = PDF 的"皮肤"

你平时写 Word 文档,内容和排版是混在一起的——字体、颜色、边距都要自己一点点调。在 Presto 里,内容和排版是分开的:

  • 你负责内容: 用 Markdown 写文字(就像写纯文本)
  • 模板负责排版: 决定标题多大、字体用什么、间距多少

换句话说,模板就是 PDF 的"皮肤"。同样一份简历内容,换个模板就能变成完全不同的风格。

详细解释见 术语表 - 模板

二进制模板 = 一个小程序

Presto 的模板不是一个样式文件(不像 Word 的 .dotx 模板),而是一个编译后的小程序。它的工作方式很简单:

  1. 吃进去 Markdown(你写的内容)
  2. 吐出来 Typst 排版指令(告诉排版引擎怎么画 PDF)

你不需要理解这个程序的内部实现,只需要知道:你给它内容,它给你排版好的 PDF。

详细解释见 术语表 - 二进制模板

效果对比

同一份 Markdown 内容,使用不同模板生成的 PDF 效果完全不同:

这就是模板的力量——你写一次内容,可以随时换"皮肤"。


第二部分:创建项目骨架(5 分钟)

我们用 Presto 官方的脚手架工具一键生成项目。打开终端,输入:

bash
npx create-presto-template

脚手架会用交互式向导问你几个问题。照着下面填就行:

text
? Template name (kebab-case): my-first-template
? Display name: 我的第一个模板
? Description: 一个简单的个人简历模板
? Language: Go (recommended)
? Category: 简历
? GitHub username: your-username
? License: MIT

✓ Created my-first-template/

你看到的界面可能略有不同(工具会更新),但问题大同小异。GitHub 用户名填你自己的就行,没有 GitHub 账号填个随意的名字也可以,不影响本地开发。

验证

bash
ls my-first-template/

你应该看到这些文件:

text
CLAUDE.md         Makefile          example.md
main.go           manifest.json     template_head.typ

看到了?项目骨架已经就位了。


第三部分:理解项目结构(10 分钟)

进入项目目录:

bash
cd my-first-template

脚手架生成了 6 个文件,每个都有明确的用途。我们快速过一遍,不用记住细节——后面用 AI 开发时会反复接触它们。

文件一句话说明
main.go模板的"大脑"——读取 Markdown,输出 Typst 排版指令
manifest.json模板的"身份证"——名称、版本、依赖字体等元数据
template_head.typ排版样式定义——页面大小、字体、间距等 Typst 设置
example.md示例文档——展示模板效果的 Markdown 文件
Makefile构建命令集合——编译、测试、预览一键搞定
CLAUDE.mdAI 开发配置——告诉 AI 助手这个项目的规则和约束

每个文件的详细说明见 模板开发者指南,这里只做概览,不重复展开。

CLAUDE.md 是什么?

上一篇教程里,你直接和 AI 对话。但 AI 不知道你的项目有什么规则(比如"不能用第三方库"、"必须用 goldmark 解析 Markdown")。CLAUDE.md 就是解决这个问题的——它是一个放在项目根目录的配置文件,AI 助手每次启动时会自动读取。

你可以把它理解成:给 AI 的一份"项目须知",让 AI 从一开始就知道该遵守哪些规则。

验证

先确认项目能正常编译和测试:

bash
make build && make test

你应该看到编译成功、测试全部通过。如果报错,检查一下 Go 是否已安装(go version)。


第四部分:用 AI 开发模板(30-40 分钟)

好了,重头戏来了。我们要把这个默认模板改造成一个个人简历模板

目标效果:

  • A4 纵向,上下左右适当留白
  • 顶部居中显示姓名(大号加粗)
  • 姓名下方一行显示联系方式(邮箱、电话)
  • 正文分"教育背景"、"项目经历"、"技能"等板块
  • 整体简洁大方,适合求职使用

我们用 AI 来完成所有编码工作。进入项目目录,启动 Claude Code:

bash
cd my-first-template
claude

第一轮对话:描述需求

👤 你:

我想把这个模板改造成一个个人简历模板。要求如下:

  1. A4 纵向页面,上下边距 2cm,左右边距 2.5cm
  2. 顶部居中显示姓名(大号黑体加粗),姓名下方一行居中显示联系方式
  3. 正文用宋体,标题用黑体
  4. 支持的板块:教育背景、项目经历、技能特长、自我评价
  5. 每个板块标题下面有一条细分隔线
  6. 请同时更新 manifest.json、template_head.typ、example.md 和 main.go

🤖 AI:

好的,我来帮你把模板改造成个人简历模板。我会按顺序修改 4 个文件。

首先更新 manifest.json

json
{
  "name": "my-first-template",
  "displayName": "我的第一个模板",
  "description": "一个简单的个人简历模板",
  "version": "0.1.0",
  "author": "your-username",
  "license": "MIT",
  "category": "简历",
  "keywords": ["简历", "求职", "resume"],
  "minPrestoVersion": "0.1.0",
  "requiredFonts": [],
  "frontmatterSchema": {
    "name": { "type": "string", "default": "请输入姓名" },
    "email": { "type": "string", "default": "example@email.com" },
    "phone": { "type": "string", "default": "138-0000-0000" }
  }
}

然后更新 template_head.typ,设置页面和字体样式:

typst
#set page(paper: "a4", margin: (top: 2cm, bottom: 2cm, left: 2.5cm, right: 2.5cm))
#set text(font: "SimSun", size: 11pt, lang: "zh")
#set par(leading: 0.8em)

#show heading.where(level: 1): it => {
  align(center, text(font: "SimHei", size: 22pt, weight: "bold")[#it.body])
}

#show heading.where(level: 2): it => {
  v(0.6em)
  text(font: "SimHei", size: 13pt)[#it.body]
  v(0.2em)
  line(length: 100%, stroke: 0.5pt + luma(180))
  v(0.3em)
}

接下来更新 example.md,写一份示例简历:

markdown
---
name: 张三
email: zhangsan@example.com
phone: 138-0000-0000
---

## 教育背景

**某某大学** | 计算机科学与技术 | 2022.09 - 2026.06

- GPA 3.8/4.0,专业排名前 10%
- 主修课程:数据结构、操作系统、计算机网络

## 项目经历

**校园二手交易平台** | 后端开发 | 2024.03 - 2024.06

- 使用 Go + Gin 框架开发 RESTful API
- 实现了用户认证、商品搜索和订单管理功能
- 部署在学校服务器,日活跃用户 200+

## 技能特长

- **编程语言:** Go、Python、JavaScript
- **工具框架:** Git、Docker、MySQL、Redis
- **语言能力:** CET-6 580 分

## 自我评价

热爱编程,善于学习新技术。有团队协作经验,能承受项目压力。

最后更新 main.go。核心修改是在转换逻辑中处理 frontmatter 中的 nameemailphone 字段,把它们渲染成顶部的居中标题和联系方式行:

go
// 在输出 template_head.typ 之后,先输出姓名和联系方式
if name, ok := frontmatter["name"]; ok {
    fmt.Fprintf(out, "#heading(level: 1)[%s]\n", typst.EscapeContent(name))
}

contacts := []string{}
if email, ok := frontmatter["email"]; ok {
    contacts = append(contacts, email)
}
if phone, ok := frontmatter["phone"]; ok {
    contacts = append(contacts, phone)
}
if len(contacts) > 0 {
    fmt.Fprintf(out, "#align(center)[%s]\n", typst.EscapeContent(strings.Join(contacts, " | ")))
    fmt.Fprintln(out, "#v(0.5em)")
}

我已经修改了这 4 个文件。你可以运行 make build && make test 来验证。

这段对话展示了一个典型的 AI 开发过程:你描述需求,AI 帮你修改所有相关文件。它不仅改了代码,还更新了配置、示例和样式——这就是 AI 编程的效率。

⚠️ AI 可能犯的错:

AI 可能会建议你安装额外的包(比如 go get some-markdown-parser)。但 Presto 模板应该只用标准库 + goldmark(一个 Go 的 Markdown 解析库,脚手架已经帮你配好了)。 如果 AI 建议安装额外依赖,告诉它:

"请只使用标准库和 goldmark,不要引入额外依赖。"

为什么有这个限制?因为模板运行在沙箱里,多余的依赖不仅增加体积,还可能带来安全风险。CLAUDE.md 里已经写了这个规则,但 AI 偶尔会忽略。

第二轮对话:编译测试和修复

现在来编译测试一下:

bash
make build && make test

如果一切顺利,你会看到测试全部通过。但现实往往没这么顺利——第一次编译报错是家常便饭。让我们看看一个常见的修复过程:

👤 你:

运行 make build 报错了,错误信息是:

text
./main.go:42:18: undefined: typst.EscapeContent

🤖 AI:

抱歉,看起来 typst 包的路径不对。让我检查一下项目结构。

找到了——Starter 项目中 Typst 转义函数在 internal/typst 包里。我需要修改 import 路径:

go
import (
    "my-first-template/internal/typst"
)

已修改,请再次运行 make build

👤 你:

编译通过了。但是 make test 有一个测试失败了:

text
FAIL: example round-trip - output contains invalid Typst

🤖 AI:

这个错误说明模板输出的 Typst 代码有语法问题。让我用示例文档测试一下,看看输出是什么:

bash
cat example.md | ./my-first-template

我看到问题了——heading 的输出格式有误,多了一层嵌套。 template_head.typ 里的 #show heading.where(level: 1) 已经处理了一级标题的样式, 但 main.go 输出的 Typst 代码中又手动设置了居中,导致冲突。

修复方案:在 main.go 中不使用 #heading(level: 1) 来输出姓名,而是直接用居中文本:

go
if name, ok := frontmatter["name"]; ok {
    fmt.Fprintf(out, "#align(center, text(font: \"SimHei\", size: 22pt, weight: \"bold\")[%s])\n",
        typst.EscapeContent(name))
}

同时从 template_head.typ 里删掉 #show heading.where(level: 1) 的规则,因为简历不需要一级标题样式了。

已修改,再试试 make test

这就是 AI 开发的真实过程——不是一次就对,而是编译 - 报错 - 修复的循环。这完全正常,专业开发者每天都在做同样的事。重要的是:你不需要自己看懂 Go 代码的每一行,你只需要把错误信息告诉 AI,AI 会帮你分析和修复。

⚠️ AI 可能犯的错:

AI 可能假设你的电脑是 amd64 架构(Intel 处理器),但你的 Mac 是 arm64(Apple Silicon)。如果 AI 给出的编译命令包含 GOARCH=amd64,那是错的——改成 GOARCH=arm64

更好的做法:直接用 make build,Makefile 会自动检测你的系统架构,你不需要手动指定。

第三轮对话:预览和迭代

测试通过后,把模板安装到 Presto 并预览效果:

bash
make preview

这个命令会编译模板、安装到 Presto 的模板目录,然后用 example.md 生成 PDF 并打开预览。

看到 PDF 了吗?但你可能觉得有些地方不满意。比如:

👤 你:

PDF 出来了,效果基本可以。但有几个问题:

  1. 姓名和联系方式之间间距太大了
  2. "教育背景"这些标题下面的分隔线颜色太深了,能不能浅一点?
  3. 项目经历里的"后端开发"这种角色信息能不能用灰色小字显示?

🤖 AI:

我来逐一调整这三个问题。

1. 减小姓名和联系方式的间距

main.go 中,姓名后面的 #v(0.5em) 改成 #v(0.2em)

go
fmt.Fprintln(out, "#v(0.2em)")

2. 浅化分隔线颜色

template_head.typ 中,把分隔线的 luma(180) 改成 luma(210)(数值越大越浅):

typst
line(length: 100%, stroke: 0.5pt + luma(210))

3. 角色信息用灰色小字

这需要在 main.go 的 Markdown 转 Typst 逻辑中识别 | 分隔的格式。当一行加粗文本后面跟着 | 分隔的内容时,把 | 后面的部分用灰色小字渲染:

go
// 识别 "**项目名** | 角色 | 时间" 格式
// 输出:#strong[项目名] #h(0.5em) #text(fill: luma(120), size: 10pt)[角色 | 时间]

已全部修改。运行 make preview 看看效果。

👤 你:

好多了!再调一个:项目经历和教育背景的板块之间间距能大一点吗?现在感觉太紧凑了。

🤖 AI:

template_head.typ 中增加二级标题上方的间距,把 v(0.6em) 改成 v(1.2em)

typst
#show heading.where(level: 2): it => {
  v(1.2em)
  text(font: "SimHei", size: 13pt)[#it.body]
  v(0.2em)
  line(length: 100%, stroke: 0.5pt + luma(210))
  v(0.3em)
}

运行 make preview 查看效果。

这种"预览 - 反馈 - 微调"的循环就是模板开发的常态。你不需要懂 Typst 语法——只要用眼睛看 PDF、用嘴巴(键盘)告诉 AI 哪里不对就行。

验证

反复 make preview 直到你满意为止。最终的简历 PDF 应该有:

  • [ ] 顶部居中的姓名(大号加粗)
  • [ ] 姓名下方的联系方式(邮箱、电话)
  • [ ] 清晰的板块分隔(教育背景、项目经历、技能、自我评价)
  • [ ] 每个板块标题下有浅色分隔线
  • [ ] 整体排版简洁大方

第五部分:测试和发布(10 分钟)

运行完整测试

bash
make test

make test 会自动检查以下内容:

  1. manifest.json 是否为有效 JSON
  2. example.md 能否被模板正确转换(round-trip 测试)
  3. --version--manifest--example 参数是否正常工作
  4. category 字段是否合法
  5. 安全检查(是否引入了禁止的包、是否有网络访问等)

全部通过就说明你的模板符合 Presto 的质量标准。

多平台构建(可选)

如果你想分享模板给其他人使用,需要为多个平台构建:

bash
make build-all    # 构建 6 个平台版本(darwin/linux/windows x arm64/amd64)

但本地开发时不需要——make build 只构建当前平台就够了。

发布

当你准备好分享模板时,可以通过 GitHub Release 发布。完整的发布流程(包括打 tag、CI 自动构建等)见 发布流程指南

验证

bash
make test

全部通过即可。


第六部分:回顾学到了什么

恭喜你完成了第一个 Presto 模板的开发!让我们回顾一下这个过程中的关键经验。

1. CLAUDE.md 帮 AI 理解项目上下文

你有没有注意到,AI 从一开始就知道"只能用标准库和 goldmark"、"输出格式是 Typst"这些规则?这是因为 CLAUDE.md 提前告诉了 AI。以后你做任何项目,都可以写一个 CLAUDE.md 让 AI 更好地理解上下文。

2. 渐进式开发:先跑通,再完善

我们没有一上来就追求完美的排版。而是先让模板能编译、能通过测试、能生成基本的 PDF,然后一步步调整细节。这种"先跑通,再完善"的方式,在 AI 辅助开发中特别有效——因为每一步都有明确的验证点。

3. AI 会犯错,但你能识别和纠正

在开发过程中,我们遇到了至少两种 AI 犯错的情况:

  • 建议安装不必要的依赖(应该只用标准库 + goldmark)
  • 假设 amd64 架构(你的 Mac 是 arm64)

这些错误不可怕。重要的是你知道项目的规则,能在 AI 犯错时及时纠正。随着经验增加,你会越来越擅长发现这类问题。

4. 编译 - 报错 - 修复是正常工作流

第一次编译就通过才是反常的。把错误信息复制给 AI、让 AI 分析和修复,这是专业开发者每天都在做的事,不是"能力不足"的表现。

想了解更多 AI 辅助开发的模式和技巧,请阅读 AI 工作流模式


下一步

恭喜你开发了第一个 Presto 模板!从一个空项目开始,你用 AI 完成了需求分析、代码修改、编译调试和排版微调——这就是真实的模板开发流程。

想继续深入?这里有一些方向:

  • 深入学习模板开发: 模板开发者指南 包含完整的技术细节,包括二进制协议、Typst 语法速查、模式食谱等
  • 了解发布流程: 发布流程指南 教你如何把模板分享给其他人使用

你已经掌握了用 AI 开发 Presto 模板的基本方法。接下来,试着用同样的方式开发一个你真正需要的模板——也许是实验报告、课程论文、或者社团活动海报。实践是最好的学习方式。

Presto — Markdown to PDF