Trama 发布:在写代码前把智能体的改动画成状态机
Trama – See your agent's changes as state machines before any code
Trama 是一个 VS Code 与 Cursor 扩展,让智能体先把应用写成状态机地图,再据此生成代码。地图以纯 Markdown 存放在仓库的 .trama/ 目录,由模型、需求、提案、任务和漂移组成,图表自动生成且只读。
Tasks · Requirements · Analysis · Map · Agents
你的 AI agent 写代码很快。Trama 确保它写的是你想要的那份代码。
当大部分代码都由 agent 编写时,很容易搞不清你的软件到底在做什么。每一次提示都会加入没人看过的行为。
Trama 为你和你的 agent 提供一份共享的应用地图:它能处于的每一种状态,以及是什么把它从一种状态推进到下一种。agent 用纯文本编写这份地图,Trama 据此自动绘制出图表,且始终是最新的。你永远不用拖拽方框或画箭头。agent 在写下一行代码之前会先读这份地图。
看看实际效果
让我们给一个小型网店加上退货功能:就是 Trama 自带的那个 商店示例。
1. 说出你想要什么
像跟同事说话那样写下来。一行就够了,也可以写满一整页。从标签页的菜单里发送;关闭标签页也会发送。
你的 agent 会立刻在你已经在用的聊天或终端里接手,并开始阅读地图。
2. 回答几个问题
agent 只问它自己无法决定的事。对于退货,它问了九个问题,第一个是如何对一次配送建模,因为 14 天是从配送开始算的。每个问题都预先选好了 agent 的建议,所以大多数时候你只需确认。跳过你不在乎的那些:agent 会采用它的建议,并把它列为一条假设供你核对。
3. 在任何代码存在之前就看到改动
当 agent 完成后,在地图上选中它的 Proposal:新增部分为蓝色,删除部分为红色。在这里,退货引入了一个新的 Actor——时间,它负责关闭退货窗口。侧边面板汇总了每一项决策和每一条假设。
在看板上,Proposal 列出了它触及的每一个文件。批准它,或者附上备注拒绝它。
4. 看着它被构建出来
批准后,agent 会对照代码检查改动了什么,每个 Machine 一个子 agent,并行进行。
随着 agent 准备任务,任务会出现在看板上。
退货设计变成了九个 Task,归在它下面。
点击 Run this design,agent 会逐一处理它们,而你可以全程跟进。
5. 知道代码和地图何时不一致
当代码做了地图没有说明的事,或违反了你的一条规则时,Trama 称之为 Drift。
Drift 不是 bug 报告。它只是说代码和地图不再讲述同一个故事,而且它不判定哪一个是对的:
- 代码可能是错的。 agent 误读了一个 Task,或者一次快速的手动修复漏掉了一种情况:这是个 bug。
- 地图可能过时了。 你在写代码时改了主意,或者代码处理了一种没人想到要画出来的情况:代码是对的,地图应该跟上。
- 两者可能都合理。 对地图从未提出的一个问题,有两种都成立的答案:这是只有你能做的决定。
那些既不改变图表也不改变你任何规则的细枝末节不算 Drift:只有当行为本身不同时,Trama 才会提出一个。
每个 Drift 都会显示发生了什么、应该发生什么,以及两到五种修复代码的方式,agent 的建议排在最前面。你选一个。或者你保持代码原样,地图随之更新以匹配。在你决定之前,agent 不会启动任何涉及应用那部分的 Task,所以不会有新东西建立在摇摇欲坠的地基上。
6. 一次性设定规则
技术栈、设计、数据、业务规则:写一次,放在地图旁边,agent 会在每个任务中遵循它们。
规则随地图一起生长。退货设计也加了自己的规则:窗口在交付后第 14 天的 23:59 结束,退货覆盖整个订单,退款为全额。每条规则都绑定到地图上它所适用的确切部分,就像 order/Delivered。
是的,它比原始的 vibe coding 慢
Trama 仍然是 vibe coding:你描述你想要什么,agent 来写代码。改变的是中间发生的事。
用原始的 vibe coding,你输入一个提示,代码就出现了。用 Trama,你回答问题、在地图上查看变更、批准它,然后 agent 才写代码。每个功能都需要更多步骤,你会感受到这一点。
这些时间没有浪费。它花在了最划算的地方:
- 在构建之前做决定。现在回答一个问题,比以后重建一个功能更便宜。在地图上改一行只需一秒;拆掉走错方向的代码要花一下午。
- 永远不用解释两次。地图和你的规则留在仓库里。每个新会话、每个 agent、每个队友都从已经决定好的内容开始,而不是从空白的聊天开始。
- 在错误还小的时候抓住它。Drift 会在扫描时立即标记出偏离地图的代码,趁更多功能还没堆到它上面。
- 让 agent 并行工作。因为每个 Task 都绑定到地图上清晰的部分,多个 agent 可以同时构建而不会互相干扰。
第一个功能更慢。第五十个不会,因为应用仍然是你理解的那个。
如果你在做一个周一就会扔掉的周末原型,原始的 vibe coding 就够了。Trama 是为你想长期保留的软件准备的。
已经有项目了?
把 Trama 指向你现有的代码。agent 会绘制出你的应用今天所做的事情的地图,并在此过程中标记出任何看起来不对的地方。
名字的含义
Trama 在意大利语中是 weft(纬线):织工在织机上来回穿梭的线,直到图案出现。布一旦织成,图案就固定了。你无法通过拉扯一根线来改变它:一根线被拉偏会立刻显现,而新的图案必须有意地织出来。
这就是 Trama 背后的理念。你的 agent 是一个极快的织工,而地图就是图案。对设计的每一次更改都是有意识地织入的,作为你批准的 Proposal,而代码中一根被拉偏的线会显示为 Drift。
在意大利语中,trama 也是故事的 plot(情节):发生了什么、以什么顺序、为什么。你的应用可能处于的每个状态、以及推动它前进的每个事件的地图,正是如此。
这些字母拼出了其中的内容:
- Tasks:agent 接手的工作,在一个你可以跟踪的看板上。
- Requirements:你的应用必须如何构建,写一次,每次都遵循。
- Analysis:agent 将你的代码与地图进行比较,并告诉你它们在哪里不一致。
- Map:你的应用可能处于的每种情况,为你绘制成图表。
- Agents:与你已经在用的那个配合使用:Copilot Chat、Cursor、Claude Code 或 omp。
试试看
Trama 在 VS Code 和 Cursor 中运行,支持 Linux(x64)和 macOS(Apple silicon)。
-
安装扩展。从 Releases 下载适合你平台的
.vsix,然后从命令面板运行 Extensions: Install from VSIX…,或者:code --install-extension trama-<platform>-<version>.vsix
trama命令行包含在扩展中,所以无需安装其他东西。 -
在初始化项目之前,先在 Settings(
trama.agent)中选择你的 agent:chat(默认):VS Code 中的 Copilot Chat,或 Cursor 中的聊天。claude:终端中的 Claude Code。同时将trama.skillsDir设为.claude/skills,以便 Claude Code 找到 Trama 的技能。omp:终端中的 omp。
终端 agent 必须已安装并位于你的
PATH中。 -
打开你的项目并运行 Trama: Open。
-
选择 Initialize Project 从头开始,或选择 Import from Code 用于现有应用。
-
点击 Design… 并描述你的第一个功能。
Settings
对于 Claude Code、使用意大利语写作,典型设置如下:
| 设置 | 默认值 | 作用 |
|---|---|---|
trama.agent |
chat |
Trama 将指令发送到哪里:chat、claude 或 omp。 |
trama.skillsDir |
.agents/skills |
Initialize Project 将 agent 技能安装到哪里。Claude Code 请使用 .claude/skills。 |
trama.language |
空 | agent 所写文本(描述、Proposals、Tasks、Drifts)的语言,例如 Italian。代码、名称、标题和 ID 保持英文。 |
trama.terminalLocation |
panel |
终端 agent 在哪里打开:panel(终端区域,后台)或 editor(代码旁边的标签页)。 |
trama.analysis |
空 | 用于设计请求、Drift 解决和导入的模型。 |
trama.scan |
空 | 用于扫描的模型,包括比较每个 Machine 的子 agent。 |
trama.execution |
空 | 用于实现 Tasks 的模型。 |
trama.autoScan |
true |
在你批准 Proposal 后,扫描它更改的内容并创建 Tasks。 |
trama.autoExit |
true |
agent 的终端完成后立即关闭。 |
trama.maxParallelAgents |
20 |
agent 可以同时运行多少个子 agent。 |
trama.submitWhileRunning |
disabled |
enabled 让你在另一个运行进行中时启动一个运行。 |
trama.driftAutoPilot |
disabled |
让 agent 自行解决 Drifts:enabled 用于非关键项,yolo 用于所有项。 |
对于这三个模型设置,请按你的 agent 接受的方式填写模型名称,或留空以使用 agent 的默认值。在聊天中,它们选择新对话的模型:在 Copilot 中,是使用该名称的模型;在 Cursor 中,是对话的起始模型。除 trama.autoScan、trama.skillsDir、trama.language 和 trama.submitWhileRunning 之外的每个设置都只存在于你的用户设置中,因此无法按工作区覆盖。所有细节都在 扩展 README 中。
工作原理
flowchart LR
subgraph repo[".trama/ in your repo"]
M[Model]
R[Requirements]
W[Proposals · Tasks · Drifts]
end
E[Editor extension] -->|reads, renders| repo
E -->|sends instructions| A[Your agent]
A -->|loads| S[Skills]
A -->|explores, writes through| C[trama CLI]
C --> repo
R -.->|generated into| S
A -->|writes| Code[Your code]
Loading
一切都是你仓库中的纯 Markdown。.trama/ 与你的代码放在一起并随其进行版本控制:model/ 中的 Model、requirements/ 中的 Requirements,以及 proposals/、tasks/ 和 drifts/ 中的工作。没有数据库,没有云服务,没有账户。
Model 是一组状态机。一个 System 被拆分为 Features。每个 Feature 将 Machines 分组,每个 Machine 是一个文件,列出其 States、推动它变化的事件(Events),以及每次变化导向何处,条件以纯文本形式书写。States 可以嵌套。Machines 从不互相调用:它们对 Events 做出反应,这些 Events 由其他 Machines 或 System 外部的 Actors(用户、支付提供商、时间)发出。Diagram 由这些文件生成并自动布局。它是只读的:要更改它,你向 agent 请求一个 Proposal,这样文件始终是唯一事实来源。文件格式。
需求变成技能。 需求被分组到 Area(ui、tech、quality、data、rules 或你自己的)中,再拆分成片段。每个 Area 和片段都会说明 agent 何时需要它,而每个 section 适用于整个 System 或某个 Feature、Machine 或 State。每当 Requirement 文件发生变化,Trama 都会将它们重新生成为 agent 技能(trama-req-<area>-<fragment>),并以那个“何时”作为技能描述。agent 自己的技能加载器随后只会拉取与当前任务相关的规则。超过大小预算后,每个 Area 会改为一个索引技能,因此庞大的规则手册永远不会淹没 agent 的上下文。
Agent 通过 CLI 操作。 trama CLI 是一个随扩展一起打包的单一二进制文件。agent 用它来探索 Model(trama machine order、trama paths order Draft Shipped、trama search refund)、检查它(trama validate、trama analyze),并创建 Proposal、Task 和 Drift。它从不读取你的代码:将 Model 与代码进行比较是 agent 的工作。
技能驱动工作流。 trama init 会将五个 agent 技能安装到你的项目中,每个技能对应循环中的一步:
| 技能 | 作用 |
|---|---|
trama-design |
分轮向你提问,然后编写一个 Proposal |
trama-scan |
将 Model 和 Requirements 与代码进行比较;提交 Task 和 Drift |
trama-implement |
将 Task 转化为代码;当无法遵循 Model 时提交一个 Drift |
trama-resolve-drifts |
询问你如何解决每个 Drift,然后将你的选择记录在一个 Proposal 中 |
trama-import |
将现有代码描述为 Proposal |
没有你,什么都不会改变。 一个 Proposal 包含它所触及的每个文件的完整新版本,并且在你看到它之前必须通过针对整个 Model 的验证。在你批准之前,什么都不会改变。批准、拒绝或解决 Drift 等决定由你做出:agent 只会在你明确要求时执行这些操作。未解决的 Drift 会阻止关于 Model 同一部分的所有 Task,直到你解决它。
为并行 agent 而构建。 一次扫描会将每个 Machine 分配给各自的子 agent。实现运行会按组分配 Task,这些组触及 Model 的不同部分。在你批准一个 Proposal 后,只会再次扫描它所更改的内容。
编辑器从不调用模型。 该扩展渲染 Diagram、Board 和 Requirements,在自己的面板中显示 agent 的问题,并将指令发送给你选择的 agent。所有推理都在你的 agent 中、使用你的订阅进行。
了解更多
许可证
Trama 是在 GNU AGPL v3 下开源的:使用它、修改它并分享它,只要你的更改也保持开源。
想在闭源产品中使用 Trama?联系我们 获取商业许可证。
Copyright © 2026 Luca Soda
来源:Hacker News · github.com








