关于文档工具的一些经验
上周五晚上十点半,我还在公司对着屏幕疯狂敲键盘。窗外是熟悉的陆家嘴夜景,而我面前的终端里正跑着一个 Rust 写的小爬虫——任务是从一堆 PDF 简历里抽取出候选人用过的技术栈,然后自动生成一份结构化的产品需求文档草稿。是的,你没看错,简历、爬虫、产品,这三个看起来八竿子打不着的东西,在我们这届互联网“牛马”的日常里,居然神奇地串在了一起。
先简单自我介绍一下:我是个有点老派的开发者,MacBook Pro 是我的主力机(Windows?那玩意儿只配用来测兼容性),住在上海张江,离公司步行十分钟,主打一个“加班回家不超半小时”。最近在啃 Rust,虽然写得慢得像树懒,但内存安全是真的香。至于为什么开始研究文档工具?说白了,就是被产品经理逼的。
事情得从上个月说起。我们组接了个新需求:要为 HR 团队开发一个“智能简历分析系统”,目标是从成千上万份投递的 PDF/DOCX 简历中自动识别候选人的技能、项目经历、工作年限,然后按岗位要求打标签。听起来高大上,其实背后全是脏活累活。更离谱的是,PM 还要求输出一份“可读性强、带图表、能直接贴进 Confluence 的产品文档”,说是方便他们向老板汇报进度。
我当时就懵了:你让我写爬虫,我认;你让我解析简历,咬咬牙也能干;但你让我顺手把产品文档也写了? 而且还是“高质量”那种?行吧,谁让我拿这份工资呢。
于是我开始调研文档生成方案。早期我试过直接用 Python 的 docxtpl 渲染 Word,结果格式一塌糊涂;后来改用 Markdown + Pandoc 导出 PDF,可 PM 说“不够炫”,非要动态图表和交互式表格。行,那上 Docusaurus?太重。VuePress?配置复杂。最后,我灵光一闪:既然简历数据已经是结构化的 JSON 了,为什么不直接用静态站点生成器 + 模板引擎,一键产出带筛选功能的 HTML 文档?
于是,我撸起袖子,用 Rust 写了个极简的文档生成器(别笑,虽然只有 300 行,但至少没内存泄漏)。核心思路很简单:
- 爬虫阶段:用
pdf-extract和docx-rs解析简历文件,提取文本; - NLP 阶段:正则 + 关键词匹配(别指望上 BERT,工期只有两周);
- 文档生成阶段:把结构化数据喂给 Handlebars 模板,渲染成带筛选器的 HTML 页面。
// 简化版伪代码,真实项目当然有 error handling(才怪)
fn generate_resume_doc(resumes: Vec<Resume>) -> Result<(), Box<dyn std::error::Error>> {
let mut handlebars = Handlebars::new();
handlebars.register_template_file("report", "templates/resume_report.hbs")?;
let data = json!({
"candidates": resumes,
"generated_at": Utc::now().to_rfc3339(),
"total_count": resumes.len()
});
let output = handlebars.render("report", &data)?;
fs::write("docs/resume_analysis.html", output)?;
Ok(())
}
模板里我还加了个小 trick:用 <details> 标签折叠每个候选人的完整简历,主页面只展示技能标签云和岗位匹配度柱状图(用 Chart.js 动态生成)。PM 看完 demo 后居然说:“这个可以,下周站会上用它做汇报!”
当然,过程不可能一帆风顺。最大的坑出现在跨平台字体渲染上。我在 Mac 上跑得好好的 PDF 解析,在 Windows 测试机上直接乱码——因为某些简历用了嵌入字体,而 pdf-extract 在 Windows 下默认不加载字体表。折腾了整整一个周末,最后靠 Docker 容器统一环境才解决。那一刻我深刻体会到:“一次编写,到处运行”大概率是骗人的,除非你把所有依赖都打包进容器。
另一个教训是关于文档版本管理。初期我把生成的 HTML 直接扔进 Git,结果每次更新都是一堆二进制 diff,PR 里根本没法 review。后来学乖了:只提交源数据(JSON)和模板,CI 流水线里自动 build 并 deploy 到内部 S3。这样既保证可追溯,又避免污染代码库。
说到 CI,我们还搞了个骚操作:每当 HR 上传新一批简历到指定目录,GitHub Actions 就自动触发爬虫 + 文档生成流程,完成后发个 Slack 通知。运维同事看到后直呼“内卷”,但测试团队倒是挺开心——因为他们终于不用手动核对 Excel 了。
那么,到底哪些文档工具值得用?结合这次踩坑经验,我整理了一个粗略对比:
| 工具 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| Pandoc + Markdown | 轻量、格式转换强大 | 图表支持弱,交互性差 | 技术文档、API 手册 |
| Docusaurus | React 生态、插件丰富 | 启动慢,学习曲线陡 | 开源项目官网 |
| 自研静态生成器(如本次) | 完全可控、性能高 | 开发成本高 | 数据驱动型报告 |
| Notion API | 实时协作、UI 友好 | 无法离线、权限复杂 | 团队知识库 |
如果你只是写 API 文档,我强烈推荐坚持手写 Markdown + 自动化部署——文档的价值在于内容,而不是花里胡哨的动画。但如果你的数据本身就是产品(比如我们的简历分析结果),那就值得投入精力做一套端到端的生成流水线。
回头想想,这次折腾其实暴露了一个行业通病:我们总在重复造轮子,却没人愿意好好写文档。 很多团队把文档当成“交付物”而不是“产品”,结果要么烂尾,要么写成天书。而真正高效的团队,会把文档当作用户界面的一部分——就像我们这次,把枯燥的简历数据变成了产品经理能直接讲给 CEO 听的故事。
顺便说一句,这套系统上线后,HR 团队效率提升明显,连带着我们组的 KPI 都沾了光。上周站会上,PM 居然主动给我们点了奶茶(虽然是最便宜的那种)。那一刻我觉得,哪怕再保守,也该拥抱点自动化——只要它能让我不用手动 copy-paste 一百份简历。
最后,如果你也在上海做 Rust 或文档工程相关的工作,欢迎约咖啡聊聊(我请,反正省下的加班时间够喝十杯)。至于跳槽?暂时不考虑,毕竟刚搞定这套系统,简历还没来得及更新呢 😏

评论 0