我当初做这个项目,就是因为团队里每个人都在飞书里写了一堆文档,结果一到做汇报PPT的时候,全都得手动复制粘贴、调格式,一搞就是大半天。后来我琢磨着,既然飞书文档内容都是现成的,能不能让AI直接把文档变成一套能用的PPT?试了几个月,踩了无数坑,总算把整个链路跑通了。这篇文章就是把我的完整方案、核心代码思路和踩坑记录梳理出来,给同样在搞AI工程实践、想用大模型解决办公场景问题的朋友一个参考。
1. 整体架构设计:为什么选“飞书文档 + 大模型 + 模板渲染”这条路
先讲清楚我最终定的架构,再解释为什么这么选。整个系统可以拆成三块:数据源侧(飞书开放API)、内容加工侧(大模型)、输出侧(PPT生成)。飞书文档作为内容输入,通过开放接口把文档内容拉出来;然后交给大模型做结构化拆解和文案改写;最后按预设模板渲染成PPT文件。
- 为什么不用飞书自带的导出PPT功能?飞书文档确实可以导出为PPT,但导出来的版式非常简陋,基本是文字堆砌,领导看了只会觉得你糊弄事。我们需要的是有逻辑层级、有重点强调、排版美观的汇报PPT。
- 为什么不用现成的AI PPT工具(如Gamma等)?这些工具对内容来源支持不好,没法直接读取飞书内部文档。而且企业场景下,文档往往涉及内部信息,把内容传到第三方平台本身就有合规风险。
- 为什么自己写模板渲染?PPT的本质是“内容 + 版式”的组合。让大模型直接生成完整PPT文件不现实(格式控制不住),但让大模型产出结构化内容(章节、要点、备注),再由代码按模板填充,就能兼顾内容质量和排版稳定性。
这套架构的好处是:每一层都可以单独替换。今天用飞书,明天换钉钉,只要改数据源那一层;今天用GPT,明天换国产大模型,只要改模型调用那一层;模板样式想换就换,完全不影响其他模块。
1.1 核心链路:从飞书文档到PPT文件的四步流程
整个处理流程我用一句话概括:拉取 → 清洗 → 结构化 → 渲染。
第一步,通过飞书开放API读取云文档内容。飞书文档支持导出为Markdown或纯文本格式,这是最省事的方案。第二步,把拿到的原始文本做清洗,去掉无关的引用、批注、重复内容。第三步,把清洗后的文本按照预设的Prompt模板发给大模型,让模型输出结构化的JSON,包含封面信息、章节列表、每页的标题和要点。第四步,解析JSON,用python-pptx库按照设计好的模板生成PPT文件,再通过飞书API把文件上传回飞书云空间,或者直接下载到本地。
整个链路里,最核心、也最容易翻车的,是第三步大模型输出的结构化JSON。只要这一步稳了,前后两端都是固定的代码逻辑。
2. 核心细节解析:飞书API鉴权、文档读取与内容清洗
这节我把实操层面的细节讲透,尤其是飞书开放API这块,官方文档写得不算差,但真正用起来有几个坑不踩不知道。
2.1 飞书开放API鉴权:tenant_access_token的获取
飞书API统一使用tenant_access_token做身份认证。获取方式很简单,用App ID和App Secret换:
curl -X POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal \ -H "Content-Type: application/json" \ -d '{ "app_id": "cli_xxxxx", "app_secret": "xxxxx" }'返回结果里有个tenant_access_token字段,有效期一般是2小时。建议在代码里做缓存,别每次请求都去换一次,不然高频调用时会被限流。飞书开放平台的限流策略比较严格,我实测过,同一接口的QPS超过5就会开始报错。
注意:创建应用的时候,一定要在权限管理里开通“云文档只读”权限,并且把应用发布到对应部门或全员,否则API调用时会返回
permission denied。这一步很多第一次搞的人会漏掉,卡半天不知道为什么拉不到文档。
2.2 读取飞书文档内容:导出为Markdown
飞书提供了文档导出接口,可以把云文档转换成Markdown或纯文本。用起来很简单,先发一个导出请求,然后轮询导出结果,拿到下载链接后再下载内容。
实际过程中我发现,用Markdown格式比纯文本更好,因为Markdown保留了标题层级(#、##)、列表、加粗等结构信息,这些对后续大模型理解文档结构非常有帮助。纯文本会把所有层级碾平,大模型只能靠语义猜结构,效果差不少。
2.3 内容清洗:把“文档味”变成“汇报味”
飞书文档和PPT的叙事逻辑完全不同。文档是线性的、面面俱到的;PPT是层级的、重点突出的。所以清洗环节的核心目标,就是帮大模型减负:
- 删除批注、评论、历史修改痕迹等元信息。
- 把过长的段落按语义拆成逻辑块,方便模型逐块理解。
- 去掉口语化的寒暄词,例如“我想说的是”“其实”“嗯嗯”这类无关内容。
- 如果文档里有表格,尽量保留Markdown表格语法,大模型对表格的理解能力通常不错。
清洗不是必须单独写一个复杂的NLP流程,写正则 + 基于规则的过滤就够了。
3. 核心环节实现:Prompt设计、结构化输出与模板渲染
这是全文的重头戏。我直接把我调试过很多版的Prompt模板和JSON结构放出来,你可以直接拿去改。
3.1 Prompt设计:让大模型稳定输出结构化JSON
大模型输出格式的稳定性,直接决定整个流程能不能跑通。我踩过的一个大坑是:早期让模型“自由发挥”生成PPT大纲,结果每次输出的字段名都不一样,解析代码写起来特别难受。后来我统一改成严格的JSON Schema约束 + few-shot示例,准确率从70%直接拉到95%以上。
我的Prompt核心结构长这样(已脱敏简化):
你是一名资深的商业报告撰写专家,请根据我提供的文档内容,生成一份结构清晰的PPT大纲。 要求: 1. 输出严格的JSON,不要输出任何其他文字。 2. JSON结构如下: { "title": "PPT标题", "subtitle": "副标题或一句话概述", "sections": [ { "section_title": "章节标题", "pages": [ { "page_title": "页面标题", "bullets": ["要点1", "要点2", "要点3"], "speaker_notes": "演讲者备注,一句话概括本页重点" } ] } ] } 3. 每个章节下建议3-5页,每页要点3-5条,每条不超过15个字。 4. 内容必须忠实于原文,不要杜撰数据。注意几个细节:
- bullet条数限制:限制在3~5条,是为了配合模板排版。超过5条,模板里的文本框就会溢出,很难看。
- speaker_notes字段:这是很多方案容易忽略的。PPT不仅要给观众看,还要给演讲者提供讲稿。让模型顺手生成备注,简直就是白嫖的福利。
- JSON格式约束:务必在Prompt里写明“不要输出任何其他文字”。如果模型偶尔还在JSON前后加代码块标记,解析时可以用正则把
json标记剥掉再解析。
3.2 大模型选型与调用:API还是本地部署
模型选择上,我建议分场景:
- 如果是个人项目或测试环境,直接用云厂商的API即可,省事。
- 如果是企业内部使用,且文档涉及敏感信息,建议用私有化部署的开源模型,或者走专有云上托管的模型服务。
在实际调用时,我会设置temperature=0.3。这个参数非常关键:温度太高,模型输出天马行空,字段名会乱变;温度太低,输出模板化严重,失去内容灵性。0.3是内容改写与结构稳定之间比较好的平衡点。
3.3 模板渲染:python-pptx从入门到能用
生成PPT文件这一步,我用的是python-pptx库。它不依赖Microsoft Office,可以在Linux服务器上直接运行,很适合放在后端服务里。
我的模板逻辑是:先手做一个母版页(包括公司Logo、配色、字体),然后用代码复制母版页,往里面填内容。python-pptx支持复制slide,代码大致如下:
from pptx import Presentation from pptx.util import Inches prs = Presentation("templates/company_template.pptx") slide_layout = prs.slide_layouts[0] # 标题页模板 def add_title_slide(prs, title, subtitle): slide = prs.slides.add_slide(slide_layout) slide.shapes.title.text = title slide.placeholders[1].text = subtitle要点是:不要把内容写死在代码里,而是用占位符控制位置和大小。我在实际模板里预留了标题栏、内容栏、备注栏三个区域,渲染时只需要把大模型输出的JSON字段映射到对应占位符即可。
一句话总结这部分的经验:模板决定了PPT的下限,内容决定了PPT的上限。模板花时间做好,后面渲染就是纯粹的机械操作。
4. 工程落地实践:从脚本到可用的服务
当整个流程在本地脚本跑通之后,下一步就是把它工程化,做成一个团队可以自助使用的服务。这节我讲一讲做服务化改造时的关键点。
4.1 整体服务架构:FastAPI + Celery + AI Agent
我的最终形态是一个Web服务:用户在飞书群里发一条指令(例如“把这篇文档做成PPT”),机器人收到指令后调用后台服务,后台服务异步处理,完成后把PPT文件推回群里。
技术栈上,我用FastAPI搭接口,用Celery跑异步任务(因为大模型调用可能需要几十秒,不适合同步请求),用Redis做任务队列和结果缓存。
这里顺便说一下我理解的“AI Agent”在这个服务里的意义。它不是一个花哨的概念,而是让AI具备自主执行任务的能力:接收飞书消息 → 识别文档链接 → 拉取内容 → 调用模型 → 生成文件 → 回传结果。每个节点都像一个工具,AI负责判断调用哪个工具、传递什么参数。这比单纯一个“文本转PPT”接口更接近Agent的形态。
4.2 稳定性与容错设计
生成PPT看起来是一件事,但拆开之后有七八个环节可能失败,每个环节我都加了对应的容错:
- 飞书API限流:用一个简单的token bucket做限速,避免频繁触发429。
- 大模型超时:链路里对大模型调用设置60秒超时,超时后自动重试一次,还是失败就直接报错,把错误信息推送给人。
- JSON解析失败:模型偶尔输出不合法JSON,解析失败时自动带上下文重试一次。通常情况下,把报错信息拼进Prompt里让模型“修正”输出,成功率很高。
- PPT渲染异常:python-pptx对中文字体支持不完美,如果模板里引用了服务器上没有的字体,渲染可能失败,个别文字会变豆腐块。我把常用的中文字体(思源黑体、微软雅黑)都预装到了服务器上。
工程化还有一个细节:所有处理步骤都要有日志和追踪ID。因为AI不可完全预测,出了问题如果没有日志,排查起来非常头疼。
4.3 用Spring AI替代自研调用层?我的评估
因为我团队里Java背景的人多,有一位同事提议用Spring AI把模型调用层统一起来,减少重复代码。我专门花了一周时间试了试,结论是:如果只是调用一个模型的API,没必要上Spring AI;如果要对接多家模型、做复杂的工具调用,Spring AI可以省很多事。
Spring AI的价值在于“屏蔽差异”——不管背后是OpenAI、通义千问还是文心一言,你的代码都可以用统一的ChatClient接口调。对于大型企业项目,这是一个不错的抽象层。但如果是小项目,直接封装一个简单的OpenAI SDK调用反而更轻快。技术选型永远要结合团队规模和项目复杂度,不要因为“框架流行”而盲目引入。
5. 常见问题与排查技巧实录
这一节我整理了一些在真实使用中被问得最多的问题,基本上你要是动手做,都会碰到。
5.1 文档拉取失败:权限与分享范围的坑
飞书API读取文档的前提是:应用必须有权限,并且文档必须对该应用可见。如果你用的是个人测试文档,记得在文档分享设置里,把应用添加为协作者,否则API会报document not found。
这绝对是我见过最多人踩的坑。飞书的报错提示还特别不友好,返回的错误信息是“document not found”,但实际上文档存在,只是应用没权限。
5.2 大模型“幻觉”严重:编造数据怎么办
做PPT最怕什么?最怕AI编造数据。文档里写了“营收增长15%”,AI在生成PPT时可能顺手写成“营收增长25%”,这在汇报场合会出大问题。
我的解决办法有三层:
- 在Prompt里强制声明“只能基于原文改写,不得新增事实性内容”。
- 在清洗环节,把原文中的数字、专有名词单独提取出来作为约束条件,在Prompt里再次强调。
- 生成之后,对JSON里的数值型内容做一次校验,看是否与原文匹配,不匹配就告警。
说到底,AI是话痨,它天生有“吹牛”的冲动,你做应用的时候一定要用规则给它戴上“紧箍咒”。
5.3 生成速度太慢:如何优化到大模型调用一次
早期版本里,大模型要分三次调用:先总结封面,再生成大纲,再生成每页详情,总共要40~60秒。后来我把Prompt改成“一次调用生成完整JSON”,时间直接降到15秒以下。
大模型生成的瓶颈在于输出长度。所以我的优化思路是:减少输出量,能用缩写就用缩写,只要是结构化描述,模型输出速度会有数量级提升。如果确实内容很长,可以考虑流式输出,先把第一屏内容渲染出来,后台继续生成。
5.4 模板里的中文乱码
python-pptx生成PPT时,如果模板用的是英文字体且服务器没有中文字体,生成的文件里中文就会乱码。解决方案是:手动在pptx文件里的theme中为东亚文字指定字体(比如微软雅黑),或者在代码里对每个文本框统一设置字体:
for paragraph in text_frame.paragraphs: for run in paragraph.runs: run.font.name = "Microsoft YaHei"注意:python-pptx设置中文字体时,需要同时设置run.font.name和run.font._rPr的latin与ea属性,否则在部分环境依然会乱码。这个细节我查了很久才搞定。
6. 个人经验补充:从Demo到内部工具,还要走多远
最后分享一点从“Demo能跑”到“真正能用”之间的差距。
我的第一个版本是在本地Notebook里跑通的。当时很兴奋,觉得自己搞定了。但实际放到团队里用,发现完全不是那么回事:有人发来一个几十页的超长文档,处理到一半内存爆了;有人PPT模板要求统一带部门Logo,而我的代码写死了公司Logo;还有人在飞书群里发指令时带了多余的文字,机器人理解错了意图。
后来我花了大概两周时间做稳定性优化,才勉强达到“可以给不熟悉技术的同事用”的程度。所以在动手前,一定要想清楚这个问题:你是在做一个自己用的脚本,还是在做一个给团队用的工具?两者的工程量差一个数量级。
最后说一个我觉得后续值得扩展的方向:现在PPT生成之后,只能在文档基础上做内容整理。如果接上知识库、把公司历史汇报文档都灌注进去,AI就能学到“这家公司喜欢用什么风格做汇报”,生成出来的PPT会更加贴合企业气质。这个方向我觉得才是真正的AI Agent在办公场景里的大用武之地。
以上,就是我在“AI飞书PPT”这个项目上完整的技术实践记录。希望对同样做AI应用开发、AI工程实践的朋友有帮助。如果你也在做类似的事情,欢迎交流。