godebug代理
Go应用程序的无状态CLI调试器,专为AI代理工具调用而设计。允许对日志和测试无法提供的应用程序行为进行运行时验证。看 超越测试:AI代理的运行时验证 从随机生成到确定性工程的范式转变。您还可以使用godebug进行人工智能代理的传统调试。
概述
godebug 包裹 探究 具有输出结构化JSON的单个命令接口的调试器。每次调用运行一个命令,输出结果并退出——非常适合使用无状态命令的AI代理→ 响应模式。
┌─────────────────────────────────────────────────────────────┐
│ Delve Headless Server │
│ (persistent, maintains state) │
└─────────────────────────────────────────────────────────────┘
▲
│ JSON-RPC
│
┌─────────────────────────────────────────────────────────────┐
│ godebug start ./app │ godebug break main.go:42 │
│ godebug continue │ godebug locals │
│ (each command connects, executes, outputs JSON, exits) │
└─────────────────────────────────────────────────────────────┘安装
先决条件
- 转到1.24+
- 探究 调试器(
go install github.com/go-delve/delve/cmd/dlv@latest)
安装
go install github.com/8gears/godebug-agentic@latest快速开始
# Start debug session (returns JSON with server address)
godebug start ./cmd/myapp
# {"data":{"addr":"127.0.0.1:38697",...}}
# Use --addr for all subsequent commands
godebug --addr 127.0.0.1:38697 break main.go:42
godebug --addr 127.0.0.1:38697 continue
godebug --addr 127.0.0.1:38697 locals
godebug --addr 127.0.0.1:38697 quit文档
有关完整的命令参考、示例和工作流,请参阅Claude Code技能:
该技能用经过验证的JSON输出示例记录了所有21个命令:
- 会话管理:
start,connect,quit,status,restart - 断点:
break(与--cond对于条件句),clear,breakpoints - 执行:
continue,next,step,stepout - 检查:
locals,args,eval - 导航:
stack,frame,goroutines,goroutine - 来源:
list,sources
为什么调试?
传统调试
AI代理可以使用 godebug 对于经典的调试工作流程——查找和修复错误:
- 设置断点 在可疑地点
- 逐步执行 逐行编码
- 检查变量 了解国家
- 检查调用堆栈 追踪执行流程
- 调试goroutines 诊断并发问题
在Go中,并发性是一级公民,这尤其有价值:
- 竟态条件 取决于无法静态确定的时间
- 死锁 从跨越多个goroutine的锁排序中脱颖而出
- 渠道行为 取决于缓冲区大小和goroutine调度
- 上下文取消 以需要运行时观察的方式传播
运行时验证(测试之外)
除了bug查找,调试器还启用了一种新的范式: 验证应用程序行为 日志和测试无法捕获。
| 验证方法 | 它提供了什么 | 它错过了什么 |
|---|---|---|
| 日志 | 选择报告什么代码 | 日志语句之间的所有内容 |
| 单元测试 | 预测场景的通过/失败 | 中间状态、时间、实际路径 |
| 调试器 | 实际运行时状态 | 无-直接观察 |
核心观点: 测试验证结果,调试器验证行为.
可以检查运行时状态的AI代理不会猜测——它知道。这将代码生成从随机输出转换为经过验证的工程。
有关完整的范式转变,请参阅 超越测试:AI代理的运行时验证.
手术数据提取
随着 eval,AI可以准确地提取所需的数据,而不会产生日志垃圾邮件:
# Instead of adding print statements and re-running...
godebug --addr $ADDR eval "myStruct.InnerField.Map[\"key\"]"
godebug --addr $ADDR eval "len(users)"
godebug --addr $ADDR eval "err.Error()"优点:
- 无代码修改:在不添加打印语句的情况下检查任何表达式
- 代币高效:只获取相关数据,而不是整个日志转储
- 迭代探索:按需深入挖掘嵌套结构
上下文窗口效率
LLM的上下文窗口有限。 godebug 回报 集中、结构化的数据:
| 方法 | 令牌 | 信噪比 |
|---|---|---|
| 转储1000行日志 | ~4000 | 低(大多无关紧要) |
| 转储整个文件 | ~2000 | 中等(需要找到行) |
godebug eval | ~50 | 高(正是被问到的) |
godebug locals | ~200 | 高(仅当前范围) |
设计原则
- 无状态:没有会话文件或隐藏状态--只需传递
--addr - JSON输出:对方案消费的结构化回应
- 单个命令:每次调用都是独立的,非常适合AI代理
- 全力挖掘:通过干净的CLI实现所有调试功能
示例:调试并发错误
此示例显示了如何在中调试WaitGroup竞争条件 testdata/concurrency_bugs/waitgroup_race.
臭虫
// BUGGY: Add() races with Wait()
for i := 0; i < 10; i++ {
go func(id int) {
wg.Add(1) // May execute AFTER Wait() returns
defer wg.Done()
}(i)
}
wg.Wait() // Returns immediately if no Add() called yet调试会话
# Start debug session and capture address
ADDR=$(godebug start ./testdata/concurrency_bugs/waitgroup_race | jq -r '.data.addr')
# Set breakpoints
godebug --addr $ADDR break main.go:18 # wg.Add(1)
godebug --addr $ADDR break main.go:27 # wg.Wait()
# Continue - hits Wait() FIRST (proving the race)
godebug --addr $ADDR continue
# {"data":{"location":{"line":27}}} <- Wait() reached before Add()!
# Check WaitGroup state
godebug --addr $ADDR locals
# wg.state.v = 0 <- No Add() called yet!
# Check goroutines
godebug --addr $ADDR goroutines
# Main at Wait() (line 27), workers still at lines 17-18
godebug --addr $ADDR quit发现: 主河道河段 Wait() 在任何工人打电话之前 Add(),所以 Wait() 立即返回。
发展
先决条件
可用任务
task # Build the binary
task build # Build optimized binary to ./bin/godebug
task build:dev # Build with debug symbols
task test # Run tests with race detection
task test:cover # Run tests with coverage
task lint # Run golangci-lint
task verify # Run tidy + lint + test + build
task clean # Remove build artifacts项目结构
godebug-agentic/
├── main.go # Entry point
├── cmd/
│ ├── root.go # Cobra root, --addr/--output flags
│ ├── start.go # Start debug session
│ ├── connect.go # Connect to existing server
│ ├── quit.go # Quit debug session
│ ├── status.go # Check server status
│ ├── breakpoint.go # break, clear, breakpoints
│ ├── execution.go # continue, step, next, stepout, restart
│ ├── inspect.go # locals, args, eval
│ ├── navigation.go # stack, frame, goroutines, goroutine
│ └── source.go # list, sources
├── internal/
│ ├── debugger/
│ │ ├── client.go # Delve RPC2 client wrapper
│ │ └── launcher.go # Spawns dlv headless
│ └── output/
│ ├── response.go # JSON response envelope
│ ├── errors.go # Error types and handling
│ └── exitcodes.go # CLI exit codes
├── testdata/
│ ├── debugme/ # Basic test application
│ └── concurrency_bugs/ # Concurrency bug examples
└── .claude/
└── skills/godebug/ # Claude Code skill documentation测试数据:并发错误示例
这 testdata/concurrency_bugs/ 目录中故意包含有缺陷的Go程序,用于练习调试:
| 示例 | Bug类型 |
|---|---|
waitgroup_race/ | WaitGroup添加/等待比赛条件 |
race_counter/ | 非同步计数器增量 |
deadlock_circular/ | 循环锁排序死锁 |
closure_loop/ | 闭包中的循环变量捕获 |
mutex_copy/ | 通过值接收器复制互斥体 |
channel_nil/ | 无信道操作 |
leak_forgotten_sender/ | Goroutine从废弃的通道发送泄漏 |
select_timeout_leak/ | 定时器泄漏 time.After 在循环中 |
# Build all examples
task build:examples
# Debug an example
godebug start ./testdata/concurrency_bugs/waitgroup_race许可证
麻省理工学院
