RedInk 源码拆解:把小红书图文生成做成一条可自部署流水线

导读基于 HisMax/RedInk 的 README、Dockerfile、Flask/Vue 源码、提示词和配置模板,拆解它如何把小红书图文生产从一句主题变成大纲、封面、批量内容页、历史记录和重绘下载的完整流程。

RedInk 封面

如果你做过小红书图文,就知道最累的地方不是“写一句标题”,而是把一个想法拆成 6 到 12 页:封面怎么抓人,内容页怎么分层,每一页的字能不能放进图里,整组图片风格会不会跑偏,生成失败后怎么重来。

HisMax/RedInk 解决的正是这段流水线。它不是一个简单的图片生成壳子,而是把“小红书图文”拆成了几个明确步骤:先让文本模型生成大纲,再让用户编辑每页内容,随后调用图片模型批量生成封面和内容页,最后把历史记录和图片保留下来,方便重绘、下载和复用。

我看完 README、Dockerfile、前后端源码和配置模板后,最想强调一句:RedInk 的价值不在“AI 会不会画得更漂亮”,而在它把一个容易失控的内容生产过程做成了可配置、可回滚、可自部署的工具。

先看项目状态

几个可验证信息先放在前面:

  • 仓库:HisMax/RedInk
  • GitHub 描述:基于 Nano Banana Pro 的一站式小红书图文生成器,主打 “One Sentence, One Image”
  • 主要语言:Python,后端是 Flask;前端是 Vue 3 + TypeScript + Vite + Pinia
  • 本次 GitHub API 查询:约 5.3k+ stars、1.0k+ forks、16 个 open issues
  • 最新浅克隆提交:7413ddb fix: outline auto-save now works when recordId is missing (closes #47)
  • License 文件写的是 CC BY-NC-SA 4.0,并额外声明商业使用需要联系作者授权
  • Docker 镜像:README 使用 histonemax/redink:latest

这几个点决定了它的适用边界:个人、学习、内部试验很合适;如果你要把它直接放进商业内容工厂,先处理授权问题。

它真正做了什么

普通图片生成工具回答的是:“给我一句提示词,我给你一张图。”

RedInk 更像在回答:“给我一个选题,我帮你拆成一组能发布的小红书图文,并且每页都能编辑、重绘和保存。”

RedInk 工作流

源码里的路径很清楚:

  1. frontend/src/views/HomeView.vue 收集主题和最多 5 张参考图,调用 /api/outline
  2. backend/routes/outline_routes.py 解析表单或 JSON,交给 backend/services/outline.py
  3. backend/prompts/outline_prompt.txt 要求模型用 <page> 分割页面,并标注 [封面][内容][总结]
  4. frontend/src/views/OutlineView.vue 允许编辑、删除、插入、拖拽每一页,并自动保存。
  5. backend/services/image.py 先生成封面图,再把封面作为后续页面的参考图,尽量保持整组风格一致。
  6. /api/generate 通过 SSE 返回生成进度;失败的页面可以单独 retry 或 regenerate。
  7. backend/services/history.py 把记录写入 history/index.json 和单条 JSON,图片也保存在 history/<task_id>/ 下。

这就是它和“套个壳调用图片 API”的差别。RedInk 把“图文组”当成一个任务,而不是把每张图当成互不相关的请求。

源码里最值得借鉴的 4 个设计

1. 大纲先行,而不是直接出图

outline_prompt.txt 很强硬:第一页必须是封面;内容控制在 6 到 12 页;每页用 <page> 分割;每页开头必须标注类型。OutlineService._parse_outline() 再把模型返回解析成 pages 数组。

这个设计看似普通,其实很关键。因为小红书图文最容易翻车的地方是“每页各说各话”。先有页面级大纲,再出图,至少能让主题、页数和节奏先固定下来。

坏做法是:拿一个标题连发 9 次图片生成,让模型自己猜每页应该写什么。

好做法是:先把 9 页内容写清楚,再让图片模型只负责把每页变成视觉表达。

2. 封面作为风格锚点

backend/services/image.py 里,生成流程先处理封面页。成功后,它会读取封面图片并压缩到约 200KB,然后作为后续内容页的 reference_image。完整 prompt 里也写明:如果当前页面不是封面,要参考封面样式,保持配色、排版、字体和装饰元素一致。

这比单纯在 prompt 里写“风格统一”更可靠。模型至少看到了一个具体视觉锚点。

3. 配置分成文本模型和图片模型

RedInk 没有假设所有模型来自同一个供应商。配置模板明确分成两份:

配置阶梯

  • text_providers.yaml:用于大纲、标题、文案、标签,支持 openai_compatiblegoogle_gemini
  • image_providers.yaml:用于图片生成,支持 google_genaiimage_api

前端设置页会读写 /api/config,后端 config_routes.py 写入 YAML 时还会保留原有 API Key,并把返回给前端的 key 脱敏。这一点很实用:用户可以在 Web UI 里改模型、改 base_url、改 active_provider,而不用每次进服务器改文件。

4. 历史记录不是装饰功能

README 更新日志里提到 v1.4.1 修过“大纲生成后立即保存,编辑时自动保存”。这次浅克隆的最新提交也和 recordId 缺失时的大纲自动保存有关。

为什么这重要?因为图片生成是慢任务,而且可能因为限流失败。没有历史记录,用户刷新页面就丢;有历史记录,至少可以回到某个任务,查看大纲、重绘单张图、下载整组图片。

history_routes.py 里还提供了 /history/<record_id>/download,会把任务图片打成 zip。这是面向真实使用场景的细节。

5 分钟跑通:推荐先用 Docker

如果只是试用,不建议一上来本地装 Python、Node、pnpm、uv。README 推荐 Docker,一行就能启动:

部署命令卡片

docker run -d -p 12398:12398   -v ./history:/app/history   -v ./output:/app/output   histonemax/redink:latest

然后打开:

http://localhost:12398

进入设置页,先配两类服务:

# text_providers.yaml 的思路
active_provider: openai
providers:
  openai:
    type: openai_compatible
    api_key: sk-xxx
    base_url: https://api.openai.com/v1
    model: gpt-4o

# image_providers.yaml 的思路
active_provider: gemini
providers:
  gemini:
    type: google_genai
    api_key: AIza...
    model: gemini-3-pro-image-preview
    high_concurrency: false

新手先别开高并发。README 明确提醒:GCP 300 美元试用账号不建议启用 high_concurrency,可能触发速率限制。等你确认单组图文能稳定生成,再考虑调并发。

本地开发怎么跑

如果你想改源码,可以走本地开发路径:

git clone https://github.com/HisMax/RedInk.git
cd RedInk

cp text_providers.yaml.example text_providers.yaml
cp image_providers.yaml.example image_providers.yaml

uv sync
cd frontend
pnpm install

手动启动:

# 后端,项目根目录
uv run python -m backend.app
# 默认 http://localhost:12398

# 前端,frontend 目录
pnpm dev
# 默认 http://localhost:5173

也可以直接运行项目提供的一键脚本:Linux/macOS 用 ./start.sh,Windows 用 start.bat

一次完整使用建议

第一次使用,我建议不要从“大而全”的选题开始。用一个窄一点、可以判断好坏的题目,例如:

为一款 Java 后端学习路线生成 8 页小红书图文,风格简洁,少 emoji,重点突出学习顺序和避坑。

按这个顺序走:

  1. 输入主题,可选上传 1 到 3 张参考图。
  2. 先看大纲,不满意就改每页文字。尤其要检查封面标题是否过长。
  3. 点击生成前确认已经保存历史记录。
  4. 如果接口容易限流,先关闭高并发。
  5. 生成后先看封面,再看内容页是否风格统一。
  6. 只重绘失败或明显跑偏的页面,不要整组重来。
  7. 从历史记录下载 zip,保留原图。

小红书图文很吃文字可读性。模型生成的图如果文字太小、错字、漏字,再漂亮也不能直接发。RedInk 能把流程串起来,但最终审核还是要人来做。

适合谁,不适合谁

适合:

  • 经常做小红书封面、知识卡片、课程图文的人。
  • 想把“选题 → 大纲 → 成组图片 → 下载”做成固定流程的自媒体团队。
  • 想研究 Flask + Vue + AI API 编排的开发者。
  • 有多模型接口,希望自己控制配置和历史数据的人。

不适合:

  • 只想偶尔生成一张海报的人,用通用生图工具更快。
  • 对商用授权不敏感的人。这个项目的 License 不是宽松 MIT,而是 CC BY-NC-SA 4.0,商业使用要单独确认。
  • 没有稳定图片模型额度的人。RedInk 的体验高度依赖图片生成接口质量和限流策略。
  • 希望“完全自动发小红书”的人。RedInk 生成的是图文素材,不负责平台发布,也不替你做内容审核。

工程角度的几个坑

第一,Docker 部署一定要挂载 historyoutput。否则容器重建后,历史和产物很可能丢掉。

第二,配置文件不要提交到公开仓库。模板里虽然写了假 key,但真实 text_providers.yamlimage_providers.yaml 会保存 API Key。

第三,图片生成失败不一定是代码问题。401/403/404/429 在源码里都有明确报错分支,先看是不是 key、权限、模型名、base_url 或速率限制。

第四,高并发不是越高越好。ImageServiceThreadPoolExecutor 并发生成内容页,但供应商不支持时,只会把失败变多。

第五,生成图文之后还要人工校对。尤其是中文图片文字,错字和断句比普通文章更显眼。

我的判断

RedInk 最值得借鉴的不是“生成小红书图”这个表层卖点,而是它把一个内容生产动作拆成了稳定的工程流程:大纲是结构,封面是风格锚点,SSE 是进度反馈,历史记录是容错,配置页是模型抽象。

如果你只是想玩一下 AI 生图,它可能显得有点重;但如果你每周都要做成组图文,或者想给团队搭一个可控的素材生成台,RedInk 值得拉下来跑一遍。

别把它当魔法按钮。把它当一条流水线,效果会更接近真实生产。

参考

  • GitHub 仓库:https://github.com/HisMax/RedInk
  • 官方体验站:https://redink.top
  • Docker 镜像:histonemax/redink:latest
  • 关键源码:backend/routes/*backend/services/image.pybackend/prompts/*.txtfrontend/src/views/*frontend/src/stores/generator.ts