feat: add 3 creative slides — tech decisions, request tracing, lessons learned
Deploy Slides / build-and-deploy (push) Successful in 1m13s
Deploy Slides / build-and-deploy (push) Successful in 1m13s
- why-not-x.md: Engineering decision rationale (Go vs Python, SQLite vs PG, etc.) - request-journey.md: Full HTTP-to-pixel request tracing with timing breakdown - lessons.md: 4 real engineering pitfalls and how they were solved - Wire all 3 new pages into slides.md in logical positions
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# 踩坑与收获
|
||||
|
||||
真实的工程教训
|
||||
|
||||
<v-clicks>
|
||||
|
||||
<Item title="🕳️ 坑 1:AI 输出不可控">
|
||||
最初没有质检节点,生成的精灵表经常缺帧、错位。**解法**:引入 QualitySupervisor + 重试机制,用视觉模型自动校验。
|
||||
</Item>
|
||||
|
||||
<Item title="🕳️ 坑 2:LLM 调用成本高">
|
||||
每次生成都调 LLM 优化提示词,API 成本飙升。**解法**:无 Key 自动回退模板生成,开发环境零成本。模板也能生成三段式结构化提示词。
|
||||
</Item>
|
||||
|
||||
<Item title="🕳️ 坑 3:并发请求重复生成">
|
||||
用户连续点两次"生成",同一个素材生成了两遍。**解法**:`hash(prompt+type+params)` 去重,相同参数直接返回已有 taskId。
|
||||
</Item>
|
||||
|
||||
<Item title="🕳️ 坑 4:Redis 挂了限流也挂了">
|
||||
一开始限流依赖 Redis,Redis 宕机时整个生成接口不可用。**解法**:fail-open 策略,Redis 不可用时自动放行,保障核心业务。
|
||||
</Item>
|
||||
|
||||
</v-clicks>
|
||||
|
||||
<div v-click class="mt-4 text-center text-gray-400 text-sm">
|
||||
<b>最大的收获</b>:AI 应用的核心不是调 API,而是工程化 — 可靠性、一致性、成本控制
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这些都是我们实际遇到的问题。做 AI 应用和做传统 Web 应用最大的区别就是:AI 的输出是不确定的,你需要用工程手段去兜底。
|
||||
-->
|
||||
@@ -0,0 +1,39 @@
|
||||
# 一次请求的完整旅程
|
||||
|
||||
从 HTTP 到像素 — 追踪一个生成请求的全链路
|
||||
|
||||
<div class="text-sm mt-2">
|
||||
|
||||
```
|
||||
POST /api/v1/generate {prompt: "像素风骑士", assetType: "sprite", style: {artStyle: "pixel"}}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<v-clicks>
|
||||
|
||||
<Item title="① Middleware 层(~1ms)">
|
||||
JWT 认证 → 解析 userID → 用户级限流检查(Redis Lua)→ 全局限流检查 → 放行
|
||||
</Item>
|
||||
|
||||
<Item title="② Handler 层(~5ms)">
|
||||
参数绑定 + 校验 → 去重检查 `hash(prompt+type+params)` → 创建 Task(DB 写入)→ 入队 TaskQueue → 返回 `taskId`
|
||||
</Item>
|
||||
|
||||
<Item title="③ Pipeline 执行(~30s)">
|
||||
goroutine 取出任务 → PromptOptimizer(风格合并 + LLM)→ AssetGenerator(文生图 API)→ QualitySupervisor(视觉模型质检,可能重试)→ FormatAdapter(精灵表拆分 + GIF)
|
||||
</Item>
|
||||
|
||||
<Item title="④ 收尾(~2s)">
|
||||
上传素材到七牛云 Kodo → 写入 Asset 表 → 更新 Task status=completed → WebSocket 推送完成通知
|
||||
</Item>
|
||||
|
||||
</v-clicks>
|
||||
|
||||
<div v-click class="mt-2 text-center text-gray-400 text-sm">
|
||||
全程异步:前端拿到 taskId 后通过 WebSocket 实时监听进度变化
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这就是一个请求的完整生命周期。注意看耗时分布:管线占了 95% 的时间,这就是为什么要做异步。
|
||||
-->
|
||||
@@ -0,0 +1,27 @@
|
||||
# 为什么不用 X?— 技术选型思考
|
||||
|
||||
每个选择背后都有取舍
|
||||
|
||||
<v-clicks>
|
||||
|
||||
<Item title="为什么不用 Python?">
|
||||
Go 的 goroutine 天然适合并发管线编排。编译型语言部署简单(单二进制),无需管理 venv / 依赖树。Eino 框架是 Go 生态。
|
||||
</Item>
|
||||
|
||||
<Item title="为什么不用 PostgreSQL?">
|
||||
gen2D 是单实例工具型应用,SQLite 零配置、单文件、ACID 足够。无需额外数据库服务,Docker 部署零依赖。
|
||||
</Item>
|
||||
|
||||
<Item title="为什么不用 Celery / RabbitMQ?">
|
||||
当前规模下 goroutine + channel 足够。TaskQueue FIFO 串行执行避免 AI API 并发限流问题。RabbitMQ 已在路线图中,按需引入。
|
||||
</Item>
|
||||
|
||||
<Item title="为什么不用 Redis 做缓存?">
|
||||
请求去重用 `sync.Map` 内存缓存即可,单实例场景无需分布式缓存。Redis 仅用于限流(需要原子操作),不在时自动 fail-open。
|
||||
</Item>
|
||||
|
||||
</v-clicks>
|
||||
|
||||
<!--
|
||||
评委可能会问:为什么不用xx?这个问题展示的是工程判断力——不是用最新的,而是用最合适的。
|
||||
-->
|
||||
@@ -57,6 +57,10 @@ src: ./pages/architecture.md
|
||||
src: ./pages/tech-stack.md
|
||||
---
|
||||
|
||||
---
|
||||
src: ./pages/why-not-x.md
|
||||
---
|
||||
|
||||
---
|
||||
section: '核心实现 — Eino 管线'
|
||||
src: ./pages/eino-graph.md
|
||||
@@ -84,6 +88,10 @@ src: ./pages/async-deep-dive.md
|
||||
src: ./pages/dedup-ws.md
|
||||
---
|
||||
|
||||
---
|
||||
src: ./pages/request-journey.md
|
||||
---
|
||||
|
||||
---
|
||||
section: '核心实现 — 分布式限流'
|
||||
src: ./pages/ratelimit-overview.md
|
||||
@@ -109,6 +117,10 @@ src: ./pages/harness.md
|
||||
|
||||
---
|
||||
section: '总结'
|
||||
src: ./pages/lessons.md
|
||||
---
|
||||
|
||||
---
|
||||
src: ./pages/highlights.md
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user