yongol — AI 编程 SaaS 的龙骨

第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项目配置 — 认证、中间件、基础设施
OpenAPIAPI契约 — 路由、参数、响应
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调度、TTL10分钟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在轨道上奔跑。没有墙。


相关文章

代码:github.com/park-jun-woo/yongol