
第200个端点
用氛围编程构建SaaS。一开始很快。5张表,12个端点——20分钟就能跑起来。
但超过50个端点后,奇怪的事情开始发生。AI今天产生的模式和昨天的矛盾。超过100个,现有功能悄然崩溃。超过200个,添加一个新功能的成本是最初10个的10倍。
不是模型太笨。
决策与实现
源代码中混杂着三样东西:
- 用户决策 — 这个列是
BIGINT,这个端点仅所有者可访问,分页采用游标方式。 - 业务逻辑 — 定价策略、工作流、生命周期规则。
- 实现细节 — 变量名、库调用顺序、错误包装。
AI阅读代码时,无法分辨哪行是决策、哪行是细节。于是在"重构"或"整理"时,它把决策误认为细节,悄悄覆盖掉。用户在行为已经出错之后才发现。
这就是氛围编程在200个端点处崩溃的原因。更大的模型也解决不了。因为媒介(原始代码)本身不保留决策。 所有模型最终都会撞上同一面墙。
龙骨
造船时最先铺设的骨架是龙骨。它承载船体重量,防止左右摇晃,所有其他结构都建在龙骨之上。没有龙骨的船在平静水面上能浮,但浪来了就会变形。
用氛围编程构建的SaaS也是如此。小的时候能浮。大了就变形。
yongol就是AI编程SaaS的龙骨。
将决策从代码中分离
yongol的核心很简单。将决策从代码中分离出来。
10个声明式规范(SSOT)各负责一个关注点:
| SSOT | 职责 |
|---|---|
| features.yaml | 功能目录 — 构建什么 |
| manifest.yaml | 项目配置 — 认证、中间件、基础设施 |
| OpenAPI | API契约 — 路由、参数、响应 |
| SQL DDL + sqlc | 数据模型 — 表、列、约束、查询 |
| SSaC | 服务流程 — 端点内部的决策顺序 |
| Rego | 授权策略 — 谁能做什么 |
| Mermaid stateDiagram | 状态转换 — 实体生命周期 |
| FuncSpec | 自定义函数 — 无法用CRUD表达的逻辑 |
| Hurl | 测试场景 — 运行时验证 |
| STML | 前端 — 页面结构与数据绑定 |
10种中有8种是行业标准(OpenAPI、SQL、sqlc、Rego、Mermaid、Hurl、YAML)。只有SSaC和STML是yongol创建的DSL。AI需要从零学习的内容被最小化。
每个SSOT只包含决策。没有实现细节。AI编辑SSOT,yongol generate从中渲染代码。决策永久存在于SSOT中,代码是一次性投影。
强制一致性
决策分散在10个文件中,矛盾随之可能出现。DDL写的是 BIGINT,OpenAPI写的是 string?SSaC声明了 @auth,但Rego中没有对应规则?状态图有转换,但SSaC没有对应函数?
矛盾的SSOT就是被污染的决策。代码再干净,决策冲突了,行为就是错的。
yongol validate捕获这些问题。
✓ manifest ✓ openapi_ddl ✓ ssac_rego
✓ openapi ✓ openapi_ssac ✓ ssac_authz
✓ ddl ✓ hurl_openapi ✓ ssac_sqlc
✓ query ✓ hurl_statemachine ✓ ddl_statemachine
✓ ssac ✓ hurl_manifest ✓ ddl_rego
✓ statemachine ✓ openapi_manifest ✓ rego_manifest
✓ rego ✓ ssac_ddl ✓ stml_openapi
✓ hurl ✓ ssac_statemachine
✓ funcspec ✓ ssac_func
0 errors, 0 warnings
先单独验证每个SSOT,再执行跨层交叉验证。约287条规则检查所有10个SSOT之间的每个符号引用。只要存在一个矛盾,就拒绝编译。
AI自由编写。偏离轨道,validate立即捕获。轨道上的自由。
operationId是基石
如何将10个层绑定在一起?用一个PascalCase标识符。
输入operationId ExecuteWorkflow:
── Feature Chain: ExecuteWorkflow ──
OpenAPI api/openapi.yaml POST /workflows/{id}/execute
SSaC service/workflow/execute_workflow.ssac @get @empty @auth @state @call @publish @response
DDL db/workflows.sql CREATE TABLE workflows
DDL db/execution_logs.sql CREATE TABLE execution_logs
Rego policy/authz.rego resource: workflow
StateDiag states/workflow.md diagram: workflow → ExecuteWorkflow
FuncSpec func/billing/check_credits.go @func billing.CheckCredits
FuncSpec func/billing/deduct_credit.go @func billing.DeductCredit
FuncSpec func/worker/process_actions.go @func worker.ProcessActions
FuncSpec func/webhook/deliver.go @func webhook.Deliver
Hurl tests/scenario-happy-path.hurl scenario: scenario-happy-path.hurl
从API规范到数据库模式,从授权策略到状态转换,从函数实现到测试场景——一个功能的完整拓扑一屏可见。几十次grep被一条命令取代。
operationId之所以是基石,是因为在全栈应用中,功能的单位是API端点。用户按下按钮,API被调用,这个API贯穿所有其他层。一个名称将10个层物理地串联在一起。
基准测试:ZenFlow
ZenFlow — 多租户工作流自动化SaaS。Claude Sonnet 4.6编写SSOT,yongol负责验证。
| 阶段 | 内容 | 时间 | 累计 |
|---|---|---|---|
| 初始构建 | 多租户、认证、状态机、6张表、10个端点 | 23分钟 | 23分钟 |
| + 版本管理 | 工作流克隆、版本列表、INSERT…SELECT操作复制 | 16分钟 | 39分钟 |
| + Webhook | 事件发布、Webhook CRUD、队列后端 | 8分钟 | 47分钟 |
| + 模板市场 | 游标分页、跨组织克隆、公开端点 | 7分钟 | 54分钟 |
| + 文件附件 | 执行报告、文件后端 | 7分钟 | 61分钟 |
| + 调度 | 基于会话的cron调度、TTL | 10分钟 | 71分钟 |
| + 审计日志 | 缓存后端、分页、过滤 | 6分钟 | 77分钟 |
| + 仪表板 | 聚合API、关系连接、详情视图 | 14分钟 | 91分钟 |
| + 批量操作 | 批量保存操作、JSON序列化 | 10分钟 | 101分钟 |
| + 外部API集成 | 地理编码API导入、坐标存储 | 14分钟 | 115分钟 |
| + 条件更新 | 自动分配、置信度评分、条件分支 | 16分钟 | 131分钟 |
最终结果:30个端点、12张表、64个测试请求。全部通过。
依次添加了10个功能。添加功能从未变慢。现有测试从未崩溃。200端点的墙不存在。
用Opus运行同一规范:30个端点,73个测试请求,约76分钟。模型变了,轨道不变。
为什么更大的模型不是答案
“等GPT-6出来就好了。”
不会好的。问题不在模型智能,而在媒介。
代码作为媒介不区分决策和实现。无论哪个模型读代码,看到的都是决策与细节交织的文本。模型再聪明,媒介不提供区分,模型就无法区分。
yongol改变媒介。将AI编辑的对象从代码移到声明式规范。规范中只有决策没有实现细节,AI永远不会把决策误认为细节。决策的存续与模型大小无关。
小型LLM只编辑SSOT,validate在每次失误时提供精确反馈,就能维持与大模型编辑原始代码相同水平的决策完整性。yongol弥合了这个差距。
开始使用
npx skills add park-jun-woo/yongol
将yongol skill安装到你的AI智能体(Claude Code、Cursor、Copilot等)。安装后智能体自动学习工作流程。
直接使用CLI:
go install github.com/park-jun-woo/yongol/cmd/yongol@latest
git clone https://github.com/park-jun-woo/yongol && cd yongol
yongol validate examples/zenflow
0 errors, 0 warnings.
在这些规范上让AI添加功能试试。validate铺设轨道,AI在轨道上奔跑。没有墙。
相关文章
- SSaC — Service Sequences as Code — yongol的基石DSL。声明端点内部的决策。
- Feature Chain — 用一个operationId追踪全栈 — 通过单个operationId贯穿8个层。
- Ratchet Pattern — 让智能体完成任务的方法 — validate向智能体反馈的结构的理论基础。