V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
yukinotech
V2EX  ›  程序员

请教一个 openspec 问题

  •  
  •   yukinotech · 2 天前 · 1190 次点击

    不太懂 openspec ,最近了解了一下。自己在某个仓库使用 openspec 写了一次需求,也观察了一下 openspec 自身是怎么使用的,发现 openspec 的 spec 似乎就是在用自然语言描述代码逻辑行为的各种 case 。以 openspec 仓库自身的 spec 为例,发现 spec.md 文件本身是在描述代码的行为逻辑。比如 openspec 的某个 spec.md 对应行为就是这个文件: https://github.com/Fission-AI/OpenSpec/blob/8332a098118a6584a7104ccfe8e46669a1c24b7d/src/utils/change-utils.ts#L112spec.md 本身贴在末尾

    我的问题是:

    1. 这样的 spec 存下来有什么意义?因为我理解存下来是为了后续有其他需求迭代时给 ai 看的,那为什么不直接让 ai 去读代码来理解现有的逻辑呢?我理解大型项目让 ai 工作是需要知识库的,但是 openspec 的 spec 更像一个细节说明书,而不是类似纲领的知识库。是不是说在 openspec 的工作流里面 spec 才是代码仓库的行为核心准则,理论上基于 spec.md 可以随时生成一套具体实现可能不一致,但行为一致的代码。
    2. openspec 的工作流程是先让 AI 进行 plan ,然后迭代 plan ,直到 AI 给出 plan 满意了,然后 AI 开始进行 coding 。这个 plan 的流程现在 antigravity 等也能做到。感觉 plan 并不是 openspec 的重点,spec.md 才是重点是吗?如果说期望的流程是先和 ai 讨论出充满细节的 spec ,再让 ai 开始 coding ,有种变成了自然语言描述写代码的感觉,这个感觉非常怪。
    3. 基于 1 的末尾提出的“spec 才是代码仓库的行为核心准则”的想法,假设需要落地到一个前端项目,那按照这个 spec 粒度,我感觉每个 tsx 文件都需要一个 spec 去描述它的规范行为。这个感觉就更怪了

    有没有实践比较多的朋友能给一些输入,分享一些经验,或者思考?

    附上的 spec.md

    change-creation 规范

    目的( Purpose )

    提供用于以编程方式创建和校验 OpenSpec change 目录的工具函数。


    需求( Requirements )

    需求:Change 创建( Change Creation )

    系统 必须( SHALL ) 提供一个函数,用于以编程方式创建新的 change 目录。

    场景:创建 change

    • 当( WHEN ) 调用 createChange(projectRoot, 'add-auth')
    • 那么( THEN ) 系统会创建 openspec/changes/add-auth/ 目录

    场景:拒绝重复的 change

    • 当( WHEN ) 调用 createChange(projectRoot, 'add-auth'),且 openspec/changes/add-auth/ 已存在
    • 那么( THEN ) 系统抛出一个错误,表明该 change 已存在

    场景:必要时创建父目录

    • 当( WHEN ) 调用 createChange(projectRoot, 'add-auth'),且 openspec/changes/ 不存在
    • 那么( THEN ) 系统创建完整路径,包括所有必要的父目录

    场景:拒绝非法的 change 名称

    • 当( WHEN ) 使用非法名称调用 createChange(projectRoot, 'Add Auth')
    • 那么( THEN ) 系统抛出一个校验错误

    需求:Change 名称校验( Change Name Validation )

    系统 必须( SHALL ) 校验 change 名称符合 kebab-case 规范。

    场景:合法的 kebab-case 名称被接受

    • 当( WHEN ) 校验一个类似 add-user-auth 的名称
    • 那么( THEN ) 校验返回 { valid: true }

    场景:允许数字后缀

    • 当( WHEN ) 校验一个类似 add-feature-2 的名称
    • 那么( THEN ) 校验返回 { valid: true }

    场景:允许单个单词

    • 当( WHEN ) 校验一个类似 refactor 的名称
    • 那么( THEN ) 校验返回 { valid: true }

    场景:拒绝大写字母

    • 当( WHEN ) 校验一个类似 Add-Auth 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }

    场景:拒绝空格

    • 当( WHEN ) 校验一个类似 add auth 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }

    场景:拒绝下划线

    • 当( WHEN ) 校验一个类似 add_auth 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }

    场景:拒绝特殊字符

    • 当( WHEN ) 校验一个类似 add-auth! 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }

    场景:拒绝以连字符开头

    • 当( WHEN ) 校验一个类似 -add-auth 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }

    场景:拒绝以连字符结尾

    • 当( WHEN ) 校验一个类似 add-auth- 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }

    场景:拒绝连续连字符

    • 当( WHEN ) 校验一个类似 add--auth 的名称
    • 那么( THEN ) 校验返回 { valid: false, error: "..." }
    6 条回复    2026-01-21 17:20:45 +08:00
    FarAhead
        1
    FarAhead  
       2 天前
    就当个人或小团队开发对齐的工具吧,感觉相当于 Antigravity 的 Plan -> Task -> Walkthrough 流程标准化了
    BeautifulSoap
        2
    BeautifulSoap  
       1 天前   ❤️ 3
    了解下 spec 驱动开发这个概念,引用我另一处的看法

    ------------------------
    Spec 驱动开发绝对不是 ai 开发的未来。真做过项目的就知道 Spec 这东西本质上就是一个项目的详细设计书(尤其日本 it 开发喜欢这一套。开发项目先确定需求,然后做完整的系统的设计,这种设计可能详细到每个小功能逻辑步骤,然后开发照着设计书实现代码)
    大部分是你用了 Spec 驱动开发,往往结果如下

    1. 对于一个复杂功能,生成的 spec 过度复杂
    2. 虽然能拆分功能 spec ,但是功能的复杂度是改变不了的,spec 的复杂和 ai 生成的大量 spec 结果就是根本懒得去看
    3. spec 详细到了代码细节实现,review spec 本质上和 review 伪代码没区别,到后来就和 2 一样懒得去详细看 spec 了
    4. spec 对各自的功能模块只适合功能变化不大、较为稳定的情况。当你的设计书经常动不动就发生大的变化(实际上开发中经常遇到),spec 也会经常会发生巨大变动,如何将最新的变动融入已经写下去的 spec 并且更新到代码也是个问题。而且每个 spec 之间都互相依赖,牵一发动全身。
    maolon
        3
    maolon  
       1 天前   ❤️ 1
    1. 文档即代码,是的你的理解没错

    2. spec 主要是充当计划的文件化索引。
    你的 agent 开始工作的时候一般都会启动一个 planner 然后开始计划并拆分的任务,当前 agent 驱动的大模型上下文太短,所以我们会在工程化里大量使用 compact 系统(包含 tool compact, history summrization 这些功能),这些 compact 系统会压缩上下文,导致信息丢失,(比如一开始 planner 详细的规划了要实现哪些细节需求,而在多次 compact 后这些细节丢失了),然后 agent 就会开始自由发挥。
    如果我们了解 compact 的工作原理就会发现,比如 tool compact 是将 tool 返回的结果存在一个文件里(比如 xxx.log )然后将上下文里 tool 调用的那一条 message 改为 {is_compacted:true, file_path:"xxx.log"},那么如果 agent 需要重新查看之前的结果,他就能通过读取 file 无损的调用回 tool 的返回内容。
    spec 也是同理,它充分利用了 agent 的 compact 系统会最大程度保留文件 path 的特性,从一开始就文件化了 planner 输出的细节,在多次 compact 后虽然需求被多次压缩损失,但是只要这个文件索引地址还在,agent 就能在需要的时候重新读取细节,从而保证在多任务,很长的工作流程里,细节和讨论的一致性,这就是 spec 的目的

    3. 这是自主性的问题,你希望 agent 拥有多少自主权利,比如你允许他部分 design 一些页面的组件吗,还是你一点自主性都不允许,这是你对项目的预期和控制问题,不是 spec 的问题
    liminany1
        4
    liminany1  
       1 天前 via Android   ❤️ 1
    QingmuSanren
        5
    QingmuSanren  
       1 天前   ❤️ 1
    我是在存量的项目中使用 openspec, 我使用一段时间后,整个使用体验是很好的,opspec 把提案和 task 规划的分厂好。
    但是有一个问题卡在我这里,就是 archive 命令的使用上遇到了问题。
    按我最开始的理解,任务完成后,我就 执行 archive 把任务归档。但是经常遇到 archive abort 的问题。后来去翻了文档,官方说只有 add 类型的 spec 才能回档。这跟我最开始的理解不一致。
    spec 就像当前当前任务的一个场景快照,我认为用处并不是特别大,openspec 的最大优点应该是帮助开发者把 需求对齐(黑话,笑)。
    yukinotech
        6
    yukinotech  
    OP
       1 天前
    @BeautifulSoap 感谢分享。我也是比较认同这个观点的
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2508 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 15:51 · PVG 23:51 · LAX 07:51 · JFK 10:51
    ♥ Do have faith in what you're doing.