Initial: knowledge base

This commit is contained in:
2026-08-05 17:25:15 +08:00
commit a5632c517e
15 changed files with 2471 additions and 0 deletions
+375
View File
@@ -0,0 +1,375 @@
# -*- coding: utf-8 -*-
"""生成《三阶段软硬配置及使用指南.pptx》
核心:每个阶段 = 客户好处 + 具体工作流程 + 人操作/自动化分工
"""
import os
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
BASE = r"C:\Users\Administrator\Desktop\AI落地公司企划项目"
ASSETS = os.path.join(BASE, "assets")
OUT = os.path.join(BASE, "三阶段软硬配置及使用指南.pptx")
BG_DARK = RGBColor(0x0B,0x25,0x45)
PRIMARY = RGBColor(0x13,0x31,0x5C)
ACCENT = RGBColor(0x2E,0x93,0xF7)
HIGHLIGHT= RGBColor(0xFF,0x8A,0x3D)
LIGHT = RGBColor(0xF4,0xF7,0xFB)
GRAY = RGBColor(0x6B,0x7A,0x8F)
WHITE = RGBColor(0xFF,0xFF,0xFF)
TEXTDARK = RGBColor(0x1A,0x24,0x33)
HUMAN_C = RGBColor(0xC8,0x6A,0x1B)
AUTO_C = RGBColor(0x1E,0x6F,0xB8)
prs = Presentation()
SW, SH = Inches(13.333), Inches(7.5)
prs.slide_width, prs.slide_height = SW, SH
BLANK = prs.slide_layouts[6]
def add_bg(slide, color=LIGHT):
s = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE,0,0,SW,SH)
s.fill.solid(); s.fill.fore_color.rgb=color
s.line.fill.background(); s.shadow.inherit=False
def add_title(slide, title, page=None, subtitle=None):
bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE,0,0,SW,Inches(1.15))
bar.fill.solid(); bar.fill.fore_color.rgb=PRIMARY; bar.line.fill.background(); bar.shadow.inherit=False
st = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE,0,Inches(1.15),SW,Inches(0.06))
st.fill.solid(); st.fill.fore_color.rgb=ACCENT; st.line.fill.background(); st.shadow.inherit=False
tb = slide.shapes.add_textbox(Inches(0.55),Inches(0.16),SW-Inches(1.1),Inches(0.95))
tf = tb.text_frame; tf.word_wrap=True
p = tf.paragraphs[0]; r = p.add_run(); r.text=title
r.font.size=Pt(25); r.font.bold=True; r.font.color.rgb=WHITE
if subtitle:
p2 = tf.add_paragraph(); r2=p2.add_run(); r2.text=subtitle
r2.font.size=Pt(12); r2.font.color.rgb=RGBColor(0xBB,0xD6,0xF2)
if page is not None:
ft = slide.shapes.add_textbox(Inches(0.55),SH-Inches(0.4),SW-Inches(1.6),Inches(0.3))
fp = ft.text_frame.paragraphs[0]; fr=fp.add_run()
fr.text="三阶段软硬配置及使用指南 · 【客户名称】"; fr.font.size=Pt(9); fr.font.color.rgb=GRAY
pg = slide.shapes.add_textbox(SW-Inches(1.05),SH-Inches(0.4),Inches(0.6),Inches(0.3))
pp = pg.text_frame.paragraphs[0]; pr=pp.add_run(); pr.text=str(page)
pr.font.size=Pt(9); pr.font.color.rgb=GRAY; pp.alignment=PP_ALIGN.RIGHT
def add_bullets(slide, items, left, top, width, height, size=14, color=TEXTDARK):
tb = slide.shapes.add_textbox(left,top,width,height)
tf = tb.text_frame; tf.word_wrap=True
first=True
for it in items:
text,lvl = it if isinstance(it,tuple) else (it,0)
p = tf.paragraphs[0] if first else tf.add_paragraph()
first=False; p.level=lvl; p.space_after=Pt(8)
pre = "" if lvl==0 else " "
r = p.add_run(); r.text = pre+text
r.font.size = Pt(size if lvl==0 else size-2); r.font.color.rgb=color
def add_table(slide, data, left, top, width, height, col_widths=None, tag_col=None):
rows,cols = len(data), len(data[0])
gtbl = slide.shapes.add_table(rows,cols,left,top,width,height)
table = gtbl.table
if col_widths:
tot=sum(col_widths)
for i,cw in enumerate(col_widths):
table.columns[i].width = Emu(int(width*cw/tot))
for ri,row in enumerate(data):
for ci,val in enumerate(row):
cell = table.cell(ri,ci)
cell.margin_left=Inches(0.07); cell.margin_right=Inches(0.07)
cell.margin_top=Inches(0.03); cell.margin_bottom=Inches(0.03)
cell.vertical_anchor=MSO_ANCHOR.MIDDLE
tf = cell.text_frame; tf.word_wrap=True
p = tf.paragraphs[0]
if tag_col and ci in tag_col and ri>0:
c_left = gtbl.left + sum(table.columns[k].width for k in range(ci))
c_top = gtbl.top + sum(table.rows[k].height for k in range(ri))
c_w = table.columns[ci].width
c_h = table.rows[ri].height
badge = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE,
c_left+Emu(int(c_w*0.08)), c_top+Emu(int(c_h*0.2)),
Emu(int(c_w*0.84)), Emu(int(c_h*0.6)))
badge.fill.solid()
badge.fill.fore_color.rgb = HUMAN_C if "" in val else AUTO_C
badge.line.fill.background(); badge.shadow.inherit=False
btf = badge.text_frame; btf.word_wrap=True
bp = btf.paragraphs[0]; bp.alignment=PP_ALIGN.CENTER
br = bp.add_run(); br.text=val
br.font.size=Pt(10); br.font.bold=True; br.font.color.rgb=WHITE
cell.text = ""
continue
r = p.add_run(); r.text=val; r.font.size=Pt(11)
if ri==0:
cell.fill.solid(); cell.fill.fore_color.rgb=PRIMARY
r.font.color.rgb=WHITE; r.font.bold=True
else:
cell.fill.solid(); cell.fill.fore_color.rgb = WHITE if ri%2 else LIGHT
r.font.color.rgb=TEXTDARK
if ci==0: r.font.bold=True
return table
def add_image(slide, path, left, top, width):
slide.shapes.add_picture(path,left,top,width=width)
def notes(slide, text):
slide.notes_slide.notes_text_frame.text = text
def new_page(title, page, subtitle=None):
s = prs.slides.add_slide(BLANK); add_bg(s); add_title(s,title,page,subtitle); return s
# ============ 1 封面 ============
cov = prs.slides.add_slide(BLANK); add_bg(cov,BG_DARK)
acc = cov.shapes.add_shape(MSO_SHAPE.RECTANGLE,0,0,Inches(0.22),SH)
acc.fill.solid(); acc.fill.fore_color.rgb=ACCENT; acc.line.fill.background(); acc.shadow.inherit=False
t = cov.shapes.add_textbox(Inches(0.9),Inches(1.8),Inches(11.5),Inches(1.7))
tf=t.text_frame; tf.word_wrap=True
p=tf.paragraphs[0]; r=p.add_run(); r.text="三阶段软硬配置及使用指南"
r.font.size=Pt(42); r.font.bold=True; r.font.color.rgb=WHITE
p2=tf.add_paragraph(); r2=p2.add_run(); r2.text="数据底座 → 模型引擎 → 日常使用运维"
r2.font.size=Pt(20); r2.font.color.rgb=ACCENT
st = cov.shapes.add_textbox(Inches(0.9),Inches(3.6),Inches(11.5),Inches(0.6))
sp=st.text_frame.paragraphs[0]; sr=sp.add_run()
sr.text="每一阶段:客户能得到什么好处 | 工作流程怎么跑 | 人操作还是自动化"
sr.font.size=Pt(16); sr.font.color.rgb=RGBColor(0xBB,0xD6,0xF2)
info = cov.shapes.add_textbox(Inches(0.9),Inches(5.6),Inches(11.5),Inches(1.0))
ip=info.text_frame
for i,line in enumerate(["客户:【客户名称】 服务商:【您的公司】",
"配套文档:商业闭环运营基板 v1.9 / 硬件与部署实现方案 v1.1 / 本地模型好用落地设计 v1.0"]):
pp=ip.paragraphs[0] if i==0 else ip.add_paragraph()
rr=pp.add_run(); rr.text=line; rr.font.size=Pt(12); rr.font.color.rgb=RGBColor(0x9F,0xB6,0xCE)
notes(cov,"【讲解】这份指南解决三个问题:客户能得到什么、流程怎么跑、哪些自动化哪些要人。")
# ============ 2 目录 ============
s = new_page("目录",1)
add_bullets(s,[
"一、整体架构速览 + 人机分工总原则",
"二、阶段一:数据底座 —— 好处 / 流程 / 人机分工",
"三、阶段二:模型引擎 —— 好处 / 流程 / 人机分工",
"四、阶段三:日常使用与运维 —— 好处 / 流程 / 人机分工",
"五、人操作 vs 自动化 总表",
"六、客户好处汇总 + 你的运维节奏",
"七、心里有底 QA + 红线兜底",
], Inches(0.9),Inches(1.7),Inches(11.5),Inches(4.6),size=17)
# ============ 3 架构总览 ============
s = new_page("一、整体架构速览",2)
add_image(s, os.path.join(ASSETS,"architecture.png"), Inches(1.6),Inches(1.35),Inches(10.1))
add_bullets(s,[
"人机分工总原则:一次性配置靠人,日常运行靠自动;老板只做两件事——看报告、问数据",
], Inches(0.9),Inches(6.6),Inches(11.5),Inches(0.6),size=13,color=PRIMARY)
notes(s,"最底下硬件是一次性装机(人);数据清洗建库是定时自动;模型常驻自动路由;最上面看板/微信推送全自动。")
# ============ 4 阶段一 目标与好处 ============
s = new_page("二之一、阶段一 数据底座:目标与客户好处",3)
add_bullets(s,[
("客户好处",0),
"① 数据收拢成「一本账」:老板随时查任何月份、任何 SKU,不再等财务做表",
"② 免费工具先学会自己看数据(演示+教学,不依赖别人)",
"③ 数据资产在自己厂里,不出厂、不上云,放心",
("本阶段做什么",0),
"免费工具 + 数据清洗整理 + SQLite 建库 + Streamlit 看板",
("自动化程度",0),
"清洗入库、看板更新 = 全自动(cron 定时);老板查数据 = 人操作(浏览器打开就看)",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(5.2),size=15)
notes(s,"阶段一对应基板阶段一/二。价值锚:让老板第一次体验到「数据看得清」。")
# ============ 5 阶段一 工作流程 ============
s = new_page("二之二、阶段一 数据底座:具体工作流程",4)
add_bullets(s,[
"① 【人·老板】每月从网店后台导出 Excel/CSV,丢进共享文件夹(教一次就会)",
"② 【自动·cron】每月 1 号凌晨,清洗脚本自动运行:去重→统一格式→入库 SQLite",
"③ 【自动】看板数据自动刷新(服务常驻,无需重启)",
"④ 【人·老板】打开浏览器随时查:月度趋势 / SKU 排行 / 区域分布 / 断码热力图",
"⑤ 【人·你】每月 1 次数据对账:抽 3–5 个关键数跟老板确认,口径不变",
"⑥ 【人·你】指标口径随业务调整时维护(季度级)",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(5.0),size=15)
notes(s,"老板的日常操作只有一件事:导数据丢文件夹。其余全自动。")
# ============ 6 阶段一 人机分工表 ============
s = new_page("二之三、阶段一 人操作 vs 自动化",5)
add_table(s,[
["功能","实现方式","频率","分工"],
["安装/配置免费工具","一次性部署到你电脑/客户机","一次性",""],
["老板导出数据丢文件夹","平台后台导出","每周/每月",""],
["数据清洗+入库 SQLite","Python 脚本 + cron","每月1号自动","自动"],
["看板数据刷新","Streamlit 服务常驻","实时","自动"],
["老板查数据/看板","浏览器访问内网地址","随时",""],
["数据对账确认","抽数核对","每月1次",""],
["指标口径维护","文档+脚本更新","按需",""],
], Inches(0.7),Inches(1.7),Inches(11.9),Inches(4.6),col_widths=[2.6,3.2,1.8,2.4],tag_col=[3])
notes(s,"阶段一自动化集中在「清洗入库+看板」,人只做配置和每月对账。")
# ============ 7 阶段二 目标与好处 ============
s = new_page("三之一、阶段二 模型引擎:目标与客户好处",6)
add_bullets(s,[
("客户好处",0),
"① 数据不出厂也能 AI 分析:周报、归因、问答全在本地跑(敏感数据安全)",
"② 响应快:本地 30B MoE 推理 2535 Token/s,不用等网络",
"③ 成本固定:本地模型一次买断,不按次收费,越用越划算",
("本阶段做什么",0),
"EVO-X2+NAS 装机 → Ubuntu/ROCm → Ollama 多模型常驻 → Hermes Agent → API 混用兜底",
("自动化程度",0),
"模型加载、任务路由、云端兜底 = 全自动;装机配置 = 一次性人操作",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(5.2),size=15)
notes(s,"阶段二对应基板阶段三。核心卖点:敏感数据本地分析 + 固定成本。")
# ============ 8 阶段二 部署流程 ============
s = new_page("三之二、阶段二 模型引擎:部署流程",7)
add_bullets(s,[
"① 【人·你】POC 先行:先用云端 API 在客户真实数据上跑出周报样例,老板认可才买硬件",
"② 【人·你】装机:EVO-X2 装 Ubuntu 24.04 + ROCm 驱动(最大坑,样机先跑通)+ NAS RAID5",
"③ 【人·你】模型部署:Ollama 拉 35B MoE + 14B + bge-m3,设 keep_alive 常驻",
"④ 【人·你】Agent 配置:Hermes Agent 注册工具(查库/发消息/生成报告)+ 任务路由规则",
"⑤ 【人·你】API 混用配置:DeepSeek 兜底开关(置信度低自动转云端)",
"⑥ 【自动】之后:模型常驻、路由、兜底全部自动运行,无需人工干预",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(5.0),size=15)
notes(s,"阶段二是配置密集型:全部一次性配置做完,之后全自动。")
# ============ 9 阶段二 人机分工表 ============
s = new_page("三之三、阶段二 人操作 vs 自动化",8)
add_table(s,[
["功能","实现方式","频率","分工"],
["POC 效果验证","云端 API 跑样例给老板看","客户掏钱前",""],
["硬件装机","EVO-X2+NAS 安装调试","一次性",""],
["ROCm/驱动/系统","Ubuntu 24.04 + ROCm 配置","一次性",""],
["模型加载/常驻","Ollama keep_alive","自动运行","自动"],
["任务路由","Agent 按任务分模型","实时","自动"],
["云端 API 兜底","置信度低自动 fallback","实时","自动"],
["月度特调模型(QLoRA","27B 特调训练","3个月后按需",""],
], Inches(0.7),Inches(1.7),Inches(11.9),Inches(4.6),col_widths=[2.6,3.2,1.8,2.4],tag_col=[3])
notes(s,"阶段二 7 项里 5 项自动,人只做装机和 POC。")
# ============ 10 阶段三 目标与好处 ============
s = new_page("四之一、阶段三 日常使用运维:目标与客户好处",9)
add_bullets(s,[
("客户好处",0),
"① 每周一自动收《经营周报》:不用做表,微信直接看图文",
"② 断码/库存预警自动推送:缺货出事前就知道,不等老板发现",
"③ 随时问数据:像问助手一样「上月华东卖了多少」,秒回",
"④ 每月 4 次到岗专属服务:特调模型、问答库整理、巡检、答疑",
"⑤ 决策有依据:补货建议、现金流模拟、SKU 优化",
("自动化程度",0),
"周报/预警/问答 = 全自动(定时任务+Agent);月度到岗 = 人操作(你)",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(5.2),size=15)
notes(s,"阶段三对应基板阶段三运行期+阶段四。客户日常几乎零操作。")
# ============ 11 阶段三 功能流程 ============
s = new_page("四之二、阶段三 日常功能工作流程",10)
add_bullets(s,[
("周报(全自动)",0),
"① 每周一早 9 点 cron 触发 → ② Agent 读库 → ③ 35B MoE 生成图文简报 → ④ 微信推给老板",
("断码预警(全自动)",0),
"① 每日 08:00 扫描库存 → ② 命中断码阈值 → ③ Agent 生成预警 → ④ 微信推送",
("数据问答(半自动)",0),
"① 老板微信/看板提问 → ② Agent 查库 → ③ 本地模型组织答案 → ④ 秒回(复杂问题自动转云端)",
("月度到岗(人操作·你)",0),
"每月 4 次:特调模型优化 / A&Q 问答库整理 / 巡检备份 / 老板答疑",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(5.2),size=14)
notes(s,"周报、预警完全不需要人碰;问答是人问机答;到岗是你的服务承诺。")
# ============ 12 阶段三 人机分工表 ============
s = new_page("四之三、阶段三 人操作 vs 自动化",11)
add_table(s,[
["功能","实现方式","频率","分工"],
["经营周报推送","cron + Agent + 微信","每周一早9点","自动"],
["断码/库存预警","每日库存扫描 + 阈值触发","每日08:00","自动"],
["数据问答","Agent 查库 + 本地模型回答","随时","人问/机答"],
["月度到岗(4次)","上门服务","每月4次",""],
["备份快照","NAS 每日快照 + 异地","每日/每周","自动"],
["巡检与日志检查","远程巡检","每周1次",""],
["备份还原演练","手动演练","每月1次",""],
["模型效果抽查","抽查5条输出质量","每周1次",""],
], Inches(0.7),Inches(1.7),Inches(11.9),Inches(4.6),col_widths=[2.6,3.2,1.8,2.4],tag_col=[3])
notes(s,"核心功能全自动;人的动作集中在巡检、到岗、抽查。")
# ============ 13 总表 ============
s = new_page("五、人操作 vs 自动化 总表(一页看全)",12)
add_table(s,[
["环节","自动化的","需要人操作的","老板日常动作"],
["阶段一 数据底座","清洗入库、看板刷新(cron","安装配置、每月对账","导数据丢文件夹、看板查数"],
["阶段二 模型引擎","模型常驻、路由、API 兜底","POC、装机、特调","无(全自动)"],
["阶段三 使用运维","周报、断码预警、问答","月度到岗、巡检、抽查","看微信、问数据"],
["你(服务商)","","到岗4次/月 + 远程巡检 + 维护",""],
], Inches(0.7),Inches(1.8),Inches(11.9),Inches(3.8),col_widths=[2.2,3.4,3.6,2.8])
add_bullets(s,[
"结论:老板每周只花 10 分钟(看周报+导数据);你的日常是每周远程巡检 1 次 + 每月到岗 4 次",
], Inches(0.9),Inches(6.0),Inches(11.5),Inches(0.8),size=14,color=PRIMARY)
notes(s,"这张表是给客户看「我买了什么服务」的总图。")
# ============ 14 好处汇总 ============
s = new_page("六之一、客户得到的好处汇总(老板视角)",13)
add_table(s,[
["好处","对应功能","解决什么问题"],
["不再等财务做表","周报每周一自动推送","报表慢、人力耗"],
["数据随时看得清","看板+数据问答","看不清赚亏"],
["出事早知道","断码/异常预警","缺货、积压后知后觉"],
["敏感数据不出厂","本地模型+NAS","怕数据泄露"],
["决策有依据","补货/现金流/SKU 建议","拍脑袋备货"],
["有人全程管","月度到岗+远程运维","系统没人维护"],
], Inches(0.7),Inches(1.7),Inches(11.9),Inches(3.6),col_widths=[3.0,4.2,3.4])
add_bullets(s,[
"一句话给老板:数据留在厂里,分析自动跑,报告送到手机,出事提前提醒,决策有人给依据",
], Inches(0.9),Inches(5.6),Inches(11.5),Inches(0.8),size=15,color=HIGHLIGHT)
# ============ 15 运维节奏 ============
s = new_page("六之二、你的运维节奏(每天/每周/每月/每季)",14)
add_table(s,[
["频率","动作","耗时"],
["每天","看系统告警(模型/服务异常到你微信)","10 分钟"],
["每周","① 确认周一周报已发出 ② 抽查 5 条输出质量","20 分钟"],
["每月","4 次到岗(特调/A&Q/巡检/答疑)+ 备份还原演练 + API 用量核对","4 个半天"],
["每季度","模型效果评估 + 客户升档评估 + 特调需求评估","1 天"],
], Inches(0.7),Inches(1.7),Inches(11.9),Inches(3.4),col_widths=[1.4,6.2,2.6])
add_bullets(s,[
"单人可承受:每周合计约 1 小时远程 + 每月 4 个半天到岗 —— 这是月维护费 2000/3000 的服务边界",
], Inches(0.9),Inches(5.4),Inches(11.5),Inches(0.8),size=14,color=PRIMARY)
# ============ 16 QA ============
s = new_page("七之一、心里有底 QA(常见问题)",15)
add_table(s,[
["问题","答案"],
["机器挂了怎么办?","数据在 NAS(RAID+快照+异地),换机重装系统后还原,1 天内恢复(每月演练过)"],
["模型效果差怎么办?","按顺序调:查 RAG 检索 → 改提示词 → 换大模型 → 最后才微调;期间置信度低自动转云端,客户无感"],
["断电了怎么办?","UPS 兜底 10 分钟,来电自动恢复;NAS 有快照不怕掉盘"],
["客户要加新功能?","工具函数库加一个函数即可(模板化),半天内上线"],
["老板要查数据?","看板随时查 / 微信问一句秒回"],
["数据更新怎么进系统?","客户导出丢文件夹 → cron 自动清洗入库,不用你干预"],
["客户停缴维护费?","系统停更但已交付功能保留(威慑不撕破脸)"],
["你自己生病/忙不过来?","SOP 文档化 + 远程自动运维,关键操作留文档"],
], Inches(0.7),Inches(1.7),Inches(11.9),Inches(4.8),col_widths=[2.6,9.4])
# ============ 17 红线兜底 ============
s = new_page("七之二、红线与兜底机制",16)
add_bullets(s,[
"① 数据不出厂:NAS 只在内网,Tailscale 只放行你;云端 API 只接可脱敏任务",
"② POC 先行:客户掏钱前先用云端样例验证效果,效果好才买硬件",
"③ 验收前置:合同写明「本地完成的任务验收 = 格式正确+规则正确」,主观好坏交云端",
"④ 兜底开关:Agent 置信度低 → 自动转云端 API,客户无感切换",
"⑤ 本地主力:35B MoE 承接 8090% 任务,云端只是保险丝(月预算 <200)",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(4.6),size=15)
# ============ 18 第一周清单 ============
s = new_page("七之三、交付后第一周清单",17)
add_bullets(s,[
"☐ 免费工具装好,老板学会自己拖数据",
"☐ 数据盘点拿到(含尺码维度,鞋类客户必查)",
"☐ 清洗脚本跑通,老板点过关键数",
"☐ 一页流程图交付(含退换货流程)",
"☐ 备忘录签署(免费边界 + 3 个月保护期 + 案例转介绍)",
"☐ 约好下周:教老板拖新数据 + 提阶段二(周报 300/次)",
], Inches(0.9),Inches(1.6),Inches(11.5),Inches(4.2),size=15)
# ============ 19 封底 ============
s = prs.slides.add_slide(BLANK); add_bg(s,BG_DARK)
t = s.shapes.add_textbox(Inches(0.9),Inches(3.0),Inches(11.5),Inches(1.5))
tf=t.text_frame; tf.word_wrap=True
p=tf.paragraphs[0]; p.alignment=PP_ALIGN.CENTER
r=p.add_run(); r.text="三阶段软硬配置及使用指南 · v1.0"
r.font.size=Pt(30); r.font.bold=True; r.font.color.rgb=WHITE
p2=tf.add_paragraph(); p2.alignment=PP_ALIGN.CENTER
r2=p2.add_run(); r2.text="配置一次 · 运行自动 · 老板零操作 · 你只做维护"
r2.font.size=Pt(16); r2.font.color.rgb=ACCENT
prs.save(OUT)
print("saved:", OUT, "slides:", len(prs.slides._sldIdLst))