AI CLI工具项目复盘从Python脚本到跨平台分发包的产品化之路一、从给我写个脚本到可以公开发布一切从一句帮我写个脚本开始每天需要把本地Markdown文件中的Mermaid图表自动渲染为PNG并嵌入文档。Python脚本15分钟写完能用。但很快需求扩展——需要支持批量处理、自定义主题、导出PDF。脚本从50行膨胀到400行开始在同事之间传阅。某天有人问这玩意能不能brew install这句话开启了从脚本到产品的产品化过程。技术本质没变——调用mermaid-cli渲染图表。但用户体验的期望从我能跑变成了我能install、我能配置、我能CI集成。二、从Python脚本到独立二进制第一步PyPI发布 —— 让Python用户能装将脚本改造成标准的Python包结构mmd-render/ setup.py mmd_render/ __init__.py cli.py renderer.py themes/ README.md# setup.py from setuptools import setup, find_packages setup( namemmd-render, version0.1.0, packagesfind_packages(), install_requires[click, playwright], entry_points{ console_scripts: [ mmd-rendermmd_render.cli:main, ], }, python_requires3.9, )发布到PyPI后用户只需pip install mmd-render即可使用。但问题随之而来有些用户没有Python环境或Python版本不对系统自带Python 3.7需要3.9。这工具很好但我装不上——这是用户的原话。第二步PyInstaller打包 —— 消除Python依赖PyInstaller能将Python脚本打包为独立可执行文件包含Python解释器和所有依赖pip install pyinstaller pyinstaller --onefile --name mmd-render cli.py生成的单个二进制文件约25MB主要是Playwright的浏览器内核但不需要任何Python环境。在GitHub Release中为三个平台提供下载mmd-render-darwin-amd64mmd-render-darwin-arm64mmd-render-linux-amd64第三步包管理器分发 —— 消除下载zip的摩擦curl下载→chmod→移动到PATH的三步安装在开发者社区是不容忽视的摩擦。接入包管理器# Homebrew Formula class MmdRender Formula desc Render Mermaid diagrams from Markdown files homepage https://github.com/user/mmd-render url https://github.com/user/mmd-render/releases/download/v0.2.0/mmd-render-darwin-arm64 sha256 abc123... version 0.2.0 def install bin.install mmd-render-darwin-arm64 mmd-render end test do system #{bin}/mmd-render, --version end endbrew install mmd-render——一行命令搞定安装。安装量从PyPI的约200次/月增长到brewPyPI合计约1200次/月。三、CLI的用户体验设计命令设计的渐进式暴露# 简单路径零配置即可用 mmd-render docs/ # 中级路径常用参数 mmd-render docs/ --theme dark --output-dir rendered/ --watch # 高级路径配置文件 mmd-render docs/ --config mmd-render.yml配置文件支持.mmd-render.yml或mmd-render.ymltheme: dark output_format: png scale: 2 watch: true # CI模式——非交互失败即退出 ci: false # 排除模式 exclude: - **/node_modules/** - **/.git/**错误信息的友好化# 用户犯错时不报Python Traceback而是给出清晰的诊断 def validate_input(path: str): if not os.path.exists(path): click.echo(f错误: 路径 {path} 不存在, errTrue) click.echo(提示: 检查路径是否正确或使用 --help 查看用法) sys.exit(1) mermaid_files glob.glob(os.path.join(path, **/*.md), recursiveTrue) if not mermaid_files: click.echo(f警告: 在 {path} 中未找到Markdown文件, errTrue) sys.exit(0)四、产品化过程中的坑坑1Playwright依赖的大小问题。mermaid-cli依赖Playwright的Chromium内核约150MB。PyInstaller打包后二进制从3MB膨胀到25MBGitHub Release的单文件限制2GB虽然没触及但用户下载体验明显变差。方案将Chromium作为外部依赖——如果系统已安装Chromium则复用否则提示安装。坑2Homebrew Formula的审核流程。提交Homebrew Formula需要满足严格的审核标准必须有test do块、依赖声明完整、无网络请求、无sudo。第一次提交因为缺少test do被拒。坑3版本管理的语义化。早期版本号随意0.1.2→0.1.3a→0.1.3b导致用户和CI脚本难以追踪。引入SemVer 自动发布Git Tag → GitHub Actions → 构建→ PyPI GitHub Release。五、总结从脚本到产品的产品化过程核心经验包管理器分发brew/pip/npm是CLI工具分发的最佳方式——一行命令安装是准入门槛独立二进制消除了Python版本依赖——打包后的25MB对用户的便利性是值得的CLI设计遵循渐进式暴露——零配置可用高级功能可配CI模式可脚本化错误信息不要暴露Traceback——用户要的是诊断不是调试信息SemVer 自动发布是可持续维护的基础最大的教训从脚本到产品最大的工作量不在代码400行Python扩展到了约800行而在分发。PyPI搭建、Homebrew Formula编写、GitHub Actions CI配置、多平台测试——这些非代码工作约占总工期的60%。如果知道最终要公开发布应该从一开始就按标准Python包组织代码避免后续重构。