AI 内容中心开发笔记
2026-03-26,开始做 AI 内容中心项目,支持文生文、文生图、图生图三种能力。
背景需求
做一个统一的 AI 内容生成入口:
- 文生文:用户输入文字,AI 生成内容
- 文生图:用户输入文字描述,生成图片
- 图生图:用户上传图片 + 文字描述,生成新图片
图片生成使用 GRS AI 的 nano-banana 模型。
Dify 探索
为什么先试 Dify
想零代码快速搭建,Dify 的可视化编排很方便。
遇到的核心问题
Dify 不支持"一次请求多次回复"。
我想实现的效果:
- 用户发需求 → 先回复"正在生成,请稍候..."
- 几分钟后 → 自动回复生成好的图片
但 Dify 是请求-响应模型,一次工作流执行只能返回一个 answer,执行完连接就关闭了,没法在后台继续跑然后主动推送。
Chatflow vs Workflow
| 特性 | Chatflow | Workflow |
|---|---|---|
| 适用场景 | 对话交互 | 自动化处理 |
| 对话记忆 | ✅ 支持 | ❌ 不支持 |
| 会话变量 | ✅ 支持 | ❌ 不支持 |
| 多次回复 | ❌ 还是只能一次 | ❌ 只能一次 |
Chatflow 更适合交互场景,但也解决不了异步推送问题。
解决思路
要实现异步推送,需要一个外部中间件:
- Dify 提交任务 → 返回"正在生成"
- 中间件后台轮询 GRS AI
- 生成完成后,调用 Dify API 推送给用户
可选方案:
- Vercel Serverless + Cron
- ifttt / Zapier
- OpenClaw 本身当中间件(推荐,已经有现成的)
原生代码实现
既然 Dify 满足不了需求,决定用 Node.js + Express 自己写。
项目结构
content-center/
├── src/
│ ├── types/ # 类型定义
│ ├── config/ # 配置
│ ├── modules/ # 独立功能模块
│ │ ├── intent-classifier.ts # 意图分类
│ │ ├── text-generator.ts # 文生文(流式)
│ │ ├── image-generator.ts # 文生图/图生图
│ │ └── workflow.ts # 工作流编排
│ ├── middlewares/ # 中间件
│ ├── routes/ # 路由
│ └── server.ts # 入口
├── public/ # 前端测试页面
└── uploads/ # 临时上传目录核心特点
- SSE 流式输出:先发状态,再发结果,实现多次回复
- 模块化设计:改流程只改对应模块
- 支持图片上传:multipart/form-data 处理图生图
前端界面
聊天框样式:
- 单输入框,支持 Enter 发送
- 左下角上传图片按钮
- 消息气泡区分用户/AI
- 自动滚动到底部
Dify 工作流踩坑
虽然最后决定用原生代码,但在 Dify 上也踩了不少坑,记录一下:
1. DSL 版本兼容
Dify 不同版本 DSL 格式不一样,导入失败大概率是版本问题。
2. 代码节点没有 pandas
Dify 代码节点是沙箱环境,没有预装 pandas。
解决方案:
- 方案 A:只用 Python 内置库,改用 CSV
- 方案 B:让管理员在服务器上
pip install pandas openpyxl
3. YAML 语法错误
多行字符串、缩进、code: 关键字这些容易写错,导入失败先检查 YAML 语法。
4. 节点连线遗漏
Dify DSL 里的 edges 数组要完整,漏了一条就会导致节点没连线。
轮询机制设计
图片生成需要几分钟,设计了轮询机制:
| 参数 | 值 |
|---|---|
| 首次查询 | 提交后 5 秒 |
| 轮询间隔 | 2 秒 |
| 最大重试 | 50 次 |
| 总等待 | 约 1 分 40 秒 |
流程:
提交任务 → 等待 5 秒 → 查询结果
↓
未完成 → 等待 2 秒 → 继续查询
↓
完成 → 返回图片 URL后续计划
- 完成 Express 后端服务
- 集成 OpenClaw cron 实现异步推送
- 对接飞书机器人,做成完整产品
写于 2026-03-26