2026-02-04 · AI
32
AI · 2026-02-04

用 BDD 驯服 vibe coding:Go + 大模型的最小可行实践

先把话说清:vibe coding 是什么

vibe coding 指的是一种强依赖大模型的编程方式:你用自然语言描述目标,模型生成代码,你更多依赖运行结果而不是逐行理解代码。这个说法来自 Andrej Karpathy 在 2025 年初的公开描述,随后被社区广泛引用。(Wikipedia: Vibe coding)

它的好处是速度快、试错成本低;问题是行为不稳定、回归成本高。你写得很快,但不知道系统到底“保证了什么”。

为什么 BDD 反而在这个时代更重要

BDD 的核心是“可执行的行为规格”。它把需求变成 Given / When / Then 这样的场景,不只是文档,而是能跑的验收标准。Dan North 在 2006 年把这一套从 TDD 里抽出来,强调“行为”比“测试”更有用,需求本身也应该是可执行的验收标准。(Introducing BDD)

Gherkin 规范把这套结构标准化:Given 是前置状态,When 是动作,Then 是可观察结果。(Gherkin Reference)

对 vibe coding 来说,这等于给“模型生成代码”配了一条安全带:

实战:Go + Godog + LLM 的最小工作流

Go 里最主流的 BDD 实现是 Cucumber 官方维护的 Godog。(cucumber/godog)

1) 写行为规格(Gherkin)

features/discount.feature

Feature: discount

  Scenario: VIP gets 10% off
    Given a user is VIP
    And the cart total is 200
    When I calculate the price
    Then the final price should be 180

这不是测试代码,这是需求。任何人都能看懂。

2) 让 LLM 生成步骤定义(你可以直接用下面的提示)

你是 Go 工程师。基于以下 Gherkin 场景生成 godog 步骤定义:
- 每个 Step 用正则匹配
- 使用一个上下文结构体保存状态
- Then 阶段断言计算结果
输出 Go 代码:add_test.go

模型会生成类似下面的结构。你只要把业务逻辑补进去即可。

3) 步骤定义(Go + Godog)

add_test.go

package calc

import (
    "fmt"
    "testing"

    "github.com/cucumber/godog"
)

type ctx struct {
    isVIP bool
    total int
    final int
}

func (c *ctx) userIsVIP() error {
    c.isVIP = true
    return nil
}

func (c *ctx) cartTotalIs(total int) error {
    c.total = total
    return nil
}

func (c *ctx) calcPrice() error {
    discount := 0.0
    if c.isVIP {
        discount = 0.1
    }
    c.final = int(float64(c.total) * (1.0 - discount))
    return nil
}

func (c *ctx) finalShouldBe(expect int) error {
    if c.final != expect {
        return fmt.Errorf("expected %d, got %d", expect, c.final)
    }
    return nil
}

func TestFeatures(t *testing.T) {
    c := &ctx{}
    godog.TestSuite{
        ScenarioInitializer: func(s *godog.ScenarioContext) {
            s.Step(`^a user is VIP$`, c.userIsVIP)
            s.Step(`^the cart total is (\d+)$`, c.cartTotalIs)
            s.Step(`^I calculate the price$`, c.calcPrice)
            s.Step(`^the final price should be (\d+)$`, c.finalShouldBe)
        },
        Options: &godog.Options{
            Format:   "pretty",
            Paths:    []string{"features"},
            TestingT: t,
        },
    }.Run()
}

这套结构与官方 README 一致(godog.TestSuite + ScenarioInitializer)。(cucumber/godog)

4) 运行

go test -test.v -test.run ^TestFeatures$

关键点:用 BDD 驯服 LLM,而不是让它决定行为

在 vibe coding 里,最大的问题不是“代码能不能跑”,而是“行为是否稳定”。BDD 的实用价值就是把“可执行行为”前置,让模型围绕行为去产出。

一个可落地的流程是:

这能显著降低“生成代码很爽,但后期维护很崩”的风险。

结尾:vibe coding 不是答案,行为才是

vibe coding 会让你更快做出东西,但只有行为规格能让东西“可持续”。

如果你不想被模型牵着走,就用 BDD 先定义边界,再让模型去填细节。


参考资料:
Vibe coding(Wikipedia)
Introducing BDD(Dan North)
Gherkin Reference(Cucumber)
cucumber/godog(GitHub)

目录 最新
← 左侧翻上一屏 · 右侧翻下一屏 · 中间唤出菜单