Quick comparison
Quick comparison
Where Canva is a better fit
Where Reactive Resume is a better fit
Which should you choose?
Reactive Resume limitations in this comparison
Sources
其中竞品优势一节的标题必须形如 `## Where {竞品} is a better fit`(竞品名不能写成 Reactive Resume),这一条被整群验证脚本用正则强制检查。`Sources` 节列出第一手来源链接,并紧跟时效标记 `Last checked: July 28, 2026`;页面最后是唯一 CTA 卡片,例如 Canva 页的:
```mdx
<Card title="Try a resume-specific editor" icon="arrow-right" href="https://rxresu.me">
Use structured resume sections and keep the option to export or self-host when you do not need a general design canvas.
</Card>
CTA 的 title 全集群不得重复。已发布的 Canva 对比页 完整体现了该契约:开头一句给出结论,Quick comparison 用六行表格对比主工作流、设计控制、导出、数据可携带性、部署方式与套餐边界,并在正文中嵌入指向 exporting-your-resume、license、Docker 自托管 的内部链接。
分批验证:每批交付后的固定动作
Step:Markdown lint(每批)。对当批文件运行 markdownlint-cli2,期望退出码 0:
pnpm exec markdownlint-cli2 \
docs/comparisons/reactive-resume-vs-canva.mdx \
docs/comparisons/reactive-resume-vs-adobe-express.mdx \
docs/comparisons/reactive-resume-vs-overleaf.mdx
Step:批次内容契约断言(Task 1 示例)。用内联 Node 脚本检查每个文件是否包含全部必需小节、时效标记和 CTA 链接:
node - <<'NODE'
const fs = require("node:fs");
const files = [
"docs/comparisons/reactive-resume-vs-canva.mdx",
"docs/comparisons/reactive-resume-vs-adobe-express.mdx",
"docs/comparisons/reactive-resume-vs-overleaf.mdx",
];
for (const file of files) {
const text = fs.readFileSync(file, "utf8");
for (const required of [
"## Quick comparison",
"## Where Reactive Resume is a better fit",
"## Which should you choose?",
"## Reactive Resume limitations in this comparison",
"## Sources",
"Last checked: July 28, 2026",
'href="https://rxresu.me"',
]) {
if (!text.includes(required)) throw new Error(`${file}: missing ${required}`);
}
}
console.log("Task 1 content contract passed");
NODE
期望输出 Task 1 content contract passed。之后按批次提交(如 docs: compare Reactive Resume with design editors、docs: compare mainstream resume builders 等),保证每个内容批次一个 commit。
各批次的「内容要求」同样写得很细,例如:
- Task 2 要求保留关键产品边界差异:Resume.com 支持免费 PDF 与纯文本下载;MyPerfectResume、Resume-Now、Zety 的免费下载仅 TXT;Resume.io 当前仅其 Vancouver 模板可免费下载 PDF 加 TXT,其他模板/功能需付费流程——并且不得引用任何套餐价格。
- Task 3 要求把一切 ATS/结果类表述视为厂商定位而非已证实结果;只有当官方页面明确文档化了 checker、分数、关键词定向流程或职位描述分析时,才可陈述该功能存在。
- Task 4 要求只描述有文档依据的产品行为,不复述面试结果承诺、ATS 保证、评论评分或用户数量。
Task 5:导航接入与全量验证
插入导航组。在 docs/docs.json 的 Documentation tab 中、Use Cases 分组之后插入名为 Comparisons 的分组,页面顺序与文章批次对齐,且不新增 hub 页:
{
"group": "Comparisons",
"pages": [
"comparisons/reactive-resume-vs-canva",
"comparisons/reactive-resume-vs-adobe-express",
"comparisons/reactive-resume-vs-overleaf",
"comparisons/reactive-resume-vs-resume-com",
"comparisons/reactive-resume-vs-myperfectresume",
"comparisons/reactive-resume-vs-resume-now",
"comparisons/reactive-resume-vs-resume-io",
"comparisons/reactive-resume-vs-zety",
"comparisons/reactive-resume-vs-kickresume",
"comparisons/reactive-resume-vs-resumegemini",
"comparisons/reactive-resume-vs-jobscan",
"comparisons/reactive-resume-vs-resumod",
"comparisons/reactive-resume-vs-rezi",
"comparisons/reactive-resume-vs-careercircle",
"comparisons/reactive-resume-vs-novoresume",
"comparisons/reactive-resume-vs-livecareer",
"comparisons/reactive-resume-vs-freesumes"
]
}
全量内容契约验证。这是计划中最核心的验证脚本:它同时校验 docs.json 的导航路径与顺序、每页 frontmatter 的 title/description 存在且全局唯一、七个必需片段存在、竞品优势小节存在且主语不是自己、CTA 标题全局唯一:
node - <<'NODE'
const fs = require("node:fs");
const paths = [
"canva",
"adobe-express",
"overleaf",
"resume-com",
"myperfectresume",
"resume-now",
"resume-io",
"zety",
"kickresume",
"resumegemini",
"jobscan",
"resumod",
"rezi",
"careercircle",
"novoresume",
"livecareer",
"freesumes",
].map((slug) => `comparisons/reactive-resume-vs-${slug}`);
const config = JSON.parse(fs.readFileSync("docs/docs.json", "utf8"));
const docsTab = config.navigation.tabs.find((tab) => tab.tab === "Documentation");
const group = docsTab.groups.find((entry) => entry.group === "Comparisons");
if (!group) throw new Error("Missing Comparisons navigation group");
if (JSON.stringify(group.pages) !== JSON.stringify(paths)) {
throw new Error("Comparison navigation paths or order do not match the approved set");
}
const titles = new Set();
const descriptions = new Set();
const ctas = new Set();
for (const pagePath of paths) {
const file = `docs/${pagePath}.mdx`;
const text = fs.readFileSync(file, "utf8");
const frontmatter = text.match(/^---\n([\s\S]*?)\n---/);
if (!frontmatter) throw new Error(`${file}: missing frontmatter`);
const title = frontmatter[1].match(/^title: "(.+)"$/m)?.[1];
const description = frontmatter[1].match(/^description: "(.+)"$/m)?.[1];
if (!title || !description) throw new Error(`${file}: missing title or description`);
if (titles.has(title)) throw new Error(`${file}: duplicate title`);
if (descriptions.has(description)) throw new Error(`${file}: duplicate description`);
titles.add(title);
descriptions.add(description);
for (const required of [
"## Quick comparison",
"## Where Reactive Resume is a better fit",
"## Which should you choose?",
"## Reactive Resume limitations in this comparison",
"## Sources",
"Last checked: July 28, 2026",
'href="https://rxresu.me"',
]) {
if (!text.includes(required)) throw new Error(`${file}: missing ${required}`);
}
const competitorFit = text.match(/^## Where (.+) is a better fit$/m)?.[1];
if (!competitorFit || competitorFit === "Reactive Resume") {
throw new Error(`${file}: missing competitor advantage section`);
}
const cta = text.match(/<Card title="([^"]+)"/)?.[1];
if (!cta) throw new Error(`${file}: missing CTA title`);
if (ctas.has(cta)) throw new Error(`${file}: duplicate CTA title`);
ctas.add(cta);
}
console.log(`Validated ${paths.length} comparison pages`);
NODE
期望输出 Validated 17 comparison pages。注意导航断言假设 Comparisons 组位于 Documentation tab 的 groups 中,且 pages 数组顺序必须与批准集合完全一致——这是刻意设计,防止有人在补页面时悄悄改动顺序破坏锚点语义。
违禁语言扫描。用 ripgrep 检查营销与结果承诺词汇:
rg -n -i \
'\b(best|winner|superior|revolutionary|seamless|guaranteed|guarantees|will pass|land an interview)\b' \
docs/comparisons
期望零命中;若某个词只出现在官方来源标题里,要改写成中性的链接文案,而不是保留宣传性标题。
Markdown 与 Mintlify 链接校验:
pnpm exec markdownlint-cli2 "docs/comparisons/*.mdx"
cd docs && pnpm dlx mint@4.2.748 broken-links --check-redirects
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