pstack数据形状优先原则:数据结构如何决定代码设计
【免费下载链接】pstack-claudeClaude Code, Codex, Copilot, Pi, OpenCode, Gemini, and Prime Agent versions of Poteto's pstack. Rigorous agent workflows with Cursor primitives translated for other harnesses.项目地址: https://gitcode.com/GitHub_Trending/ps/pstack-claude
在 pstack 这套 Agent 工作流里,数据形状优先原则(data shape first)是贯穿所有编码任务的第一性法则:先给数据命名、定形状、选组织方式,再动手写逻辑。pstack 是一个面向 Claude Code、Codex、Pi、OpenCode 等 Agent 框架的严格工作流技能栈,把"数据结构决定代码设计"从口号落实成了可执行的规则。本文将带你快速理解这条原则的来龙去脉、常用结构选型,以及它在 pstack 中是如何被强制执行的。
快速上手:先认识 pstack
pstack 的核心入口是poteto-mode:你只需告诉它目标(例如"修复翻页时搜索条件重置的问题"),它会自动选择正确的工作流——复现、调查、委托实现、重跑验证。其中一条硬性规则直接体现了本文主题:
任何代码任务 →先命名数据形状,再按"领域建模"原则选择其组织结构。
你可以把它理解为 pstack 的"宪法级"条款,写在 poteto-mode/SKILL.md 中,并在feature与refactoring两个 playbook 里反复触发。
什么是"数据形状优先":为什么结构决定设计
pstack 把这条原则拆成两层文件来阐述:
- 地基层:principle-foundational-thinking 开宗明义——"先拿到正确的数据形状,再写逻辑。尽早定义核心类型,追踪每一个访问模式,选择与主路径匹配的结构。"
- 执行层:principle-model-the-domain 解释了为什么:散落的布尔值、跨文件重复的形状假设、铺开的分支判断,都是偶然复杂度;而一个与领域匹配的结构能让"非法状态不可表示",直接删掉分支。
一句话总结其因果链:
- 数据形状错了 → 逻辑必须不断"打补丁"(if/else 链条越来越长)
- 数据形状对了 → 逻辑变得显而易见,很多分支从类型层面消失
- 写代码时做对很便宜,事后补救则读起来像重构,于是被无限拖延
🎯 所以"数据结构如何决定代码设计"不是偏好问题,而是维护成本问题。
4 种常用数据形状技术:从布尔地狱到领域结构
principle-model-the-domain给出了一个选型清单,可以直接当作检查表使用:
| 信号(坏味道) | 优先选择的数据结构 |
|---|---|
| 散落的布尔标志、生命周期检查 | 状态机(state machine) |
| 松散参数、重复的形状假设 | 带类型的对象/模型(typed model) |
| 分支判断散布在多个文件里 | 映射表、注册表、判别联合(registry / discriminated union) |
| 临时拼凑的状态修改 | Reducer 或命令/事件模型 |
| 按"加载→校验→转换→保存"顺序组织的模块 | 围绕一个领域知识体组织的模块(执行顺序 ≠ 所有权) |
同时它明确提醒:不要强行抽象。如果当前形状已经清晰、局部、且不太可能增长,优先选择无聊但直白的代码。怀疑任何"增加了一层间接却没有删掉分支、重复规则或非法状态"的抽象。
🔍 如何自检是否跳过了这一步?两个经典信号:新功能让既有 if/else 链条多长了一个分支;或者出现第二个必须与第一个保持同步的布尔值。
类型系统纪律:让非法状态在编译期消失
数据形状要真正落地,需要类型系统做守卫。principle-type-system-discipline 把它总结为一句狠话:"类型检查器是证明助手"。对 TypeScript 项目,pstack 还有专门的 typescript-best-practices 规则表,核心几条:
- 判别联合优先:用
kind字面量区分变体,杜绝"可选字段袋子" - 构造式建模:通过形状的构造方式让非法值根本无法产生(非空列表 = 头 + 尾,而不是"长度>0 的列表")
- 品牌化原语:
UserId和OrderId底层都是字符串,但类型上不可互换 - 禁止
as强转:每一次强转都是等待发生的运行时崩溃 - 外部数据先解析:JSON、RPC 载荷、CLI 参数在边界处解析为具名领域类型,边界内信任类型
其中最有意思的自检问题是:"你能不能写一行注释来解释某个字段组合何时合法?" 如果能——说明类型太宽松,该拆成联合类型了。
5 个设计红旗:数据形状出错的典型症状
pstack 的architect技能在综合多个候选设计前,会用一份红旗清单逐一筛查,文件在 design-red-flags.md。与数据形状相关的有五个:
- 浅模块:暴露一大堆接口却几乎不隐藏复杂度——形状选错时最常见的结果
- 信息泄漏:同一个表示细节出现在多个模块,改动需要多处协调编辑
- 时间分解:按执行顺序而非知识所有权组织模块,同一套规则在每个阶段重复
- 所有权分裂:多个模块写同一份状态,规则逐渐漂移
- 直通方法:原样转发参数,只加一层间接而不隐藏任何复杂度
💡 配合 principle-separate-before-serializing-shared-state 的原则:当两个执行者可能写同一份状态时,先问"是否真的需要共享",能消灭共享就先消灭——并发冲突往往是数据形状问题的运行时表现。
如何在 pstack 中强制执行这条原则
原则之所以在 pstack 里"不是建议而是流程",靠的是三处工程化设计:
- 架构先行:architect 技能要求在写代码前就勾勒类型、函数签名、类形状与模块边界(函数体留
not implemented),实现与草图偏离时视为"信号"而非摩擦;如果反复出现同形状的绕行方案,直接推倒重来(Phase E: Scrap) - 设计空间穷尽:principle-exhaust-the-design-space 要求对没有先例的决策先做 2-3 个结构上互不相同的原型再定夺——"第一个形状的第二种口味不算数"
- 自动触发:
poteto-mode把上述原则织入了feature与refactoringplaybook,Agent 在委托子代理写代码前,必须携带"具名数据形状 + 组织结构"这一上下文,否则任务不成立
完整技能清单与斜杠命令可查阅 docs/reference.md,维护说明见 CHANGES.md。
小结:把判断前置到数据层
数据形状优先原则的价值可以用三句话带走:
- 形状错了,逻辑就是补丁堆;形状对了,很多分支根本不存在
- 用类型系统把非法状态变成"编译不过",把运行时惊喜前移为编译期报错
- 在写代码之前做结构决策最便宜——pstack 把这一点做成了强制流程,而不是口头规范
如果你正在管理一个由 Agent 参与编码的项目,这套原则同样可以直接抄作业:给数据命名、追踪访问模式、匹配主路径选结构、用类型删分支——这比任何代码规范都能更早暴露设计问题。
【免费下载链接】pstack-claudeClaude Code, Codex, Copilot, Pi, OpenCode, Gemini, and Prime Agent versions of Poteto's pstack. Rigorous agent workflows with Cursor primitives translated for other harnesses.项目地址: https://gitcode.com/GitHub_Trending/ps/pstack-claude
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考