惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
L
LangChain Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
月光博客
月光博客
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
美团技术团队
S
Security @ Cisco Blogs
人人都是产品经理
人人都是产品经理
L
LINUX DO - 热门话题
S
SegmentFault 最新的问题
D
DataBreaches.Net
C
CXSECURITY Database RSS Feed - CXSecurity.com
Microsoft Security Blog
Microsoft Security Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
N
News | PayPal Newsroom
W
WeLiveSecurity
F
Fortinet All Blogs
The Hacker News
The Hacker News
The Register - Security
The Register - Security
P
Palo Alto Networks Blog
Engineering at Meta
Engineering at Meta
T
The Exploit Database - CXSecurity.com
Vercel News
Vercel News
G
GRAHAM CLULEY
博客园 - 聂微东
P
Privacy International News Feed
P
Privacy & Cybersecurity Law Blog
Hacker News: Ask HN
Hacker News: Ask HN
Webroot Blog
Webroot Blog
G
Google Developers Blog
T
Tailwind CSS Blog
V
Vulnerabilities – Threatpost
L
Lohrmann on Cybersecurity
T
Tenable Blog
Cisco Talos Blog
Cisco Talos Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security Affairs
云风的 BLOG
云风的 BLOG
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
B
Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hugging Face - Blog
Hugging Face - Blog
T
Threatpost

鸟窝

鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 LLM 究竟是如何工作的? Go 实验特性详解 amd64 微架构级别对 Go 程序性能提升多少? Loop Engineering 实践:一次批量实现 8 个 issue,完成夔牛工具的开发 傻瓜式RDMA高性能网络开发:从零跑到 400 Gb每秒 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 百度网络监控工具开源第三弹:lidar — 不只是 pingmesh 别只盯着gopacket了,看看这个强大的网络库 大厂的内部工具居然开源了! 一窥百度物理网络秒级监控定位的秘密 如何构建你自己的 Agent 运行时 寻找你代码中的臭味:一个让 AI 帮你嗅出架构腐化的开源 Skill 套壳不丢人!我用Go+AI搓了一个Agent统一编排框架,ClaudeCode-Codex-Pi全被我包了 告别死锁和陈旧语法、告别性能瓶颈:三个开源 Skill,新手Gopher 秒变 Go 语言大神 SPEC和PRD的区别 SPEC和方案设计有什么区别 从需求到上线,让 AI 管理你的整个研发流程! antigravity-cli 使用 CLIProxyAPI, 让最新的 Codex 能够支持国内的各大模型 Clawpatch + codex-review:AI 代码审查工具链的正确打开方式 拆解Manus:沙盒架构深度解析 40+ Claude Code Tips: From Basics to Advanced Ralph 实验:构建 SQLite UI 了解 Manus Sandbox - 您的云计算机 Notex:一个开源 NotebookLM 替代方案的实现 拆解Manus:真正有用的深度报告的生成 Claude Code 使用 我给每个模型服务商『捐』了10块钱,只为了... Go之禅 - 基于Rob Pike思想的Go语言哲学 Codex CLI vs Gemini CLI vs Claude Code:谁是最佳选择? goskills:Claude Skills 功能强大,为我所用 一行代码使用 Claude Skill 和 deepseek langchain + MCP:如虎添翼 Linux 中网络包的一生 godotenv 库介绍 Codex CLI vs Gemini CLI vs Claude Code: Which is the Best? 使用Linux 30年了,我都不知道 ping 8.8 还能这么用? 从 AI 哪里挣钱? Go sync 包近两年发展综述 deepseek-v3.2-exp的闪电索引器
Loop Engineering 实践:我把 RDMA 开发库移植到 Go 语言,花费 239 块钱
smallnest · 2026-06-17 · via 鸟窝

一次几乎全自动的库开发实验:从一份 PRD 出发,15 个 issue 串成流水线,让 Agent 一路 实现 → 审查 → 记录 → 发布,最后我只在真机上验证。本文复盘整个过程,验证了Loop Engineering和实际的花费。

0. 缘起

我想要一个 Go 语言的 RDMA 库。

从去年我们做高性能网络的黑盒监控起,就开始尝试用 RDMA 做探测。但我们的技术栈是 Go,找了几个库,实现得不好也不稳定;换成 C 语言技术栈对团队同学来说成本太高;自己实现当时觉得挺有挑战,于是这件事就搁下了,最后还是退回到用普通 UDP 协议探测。

RDMA for Go 库市面上的选择不多:要么是某个公司内部、绑定很深的封装,要么是年久失修的 binding。而我要的东西很明确——地道的 Go API,封装 libibverbs + librdmacm(也就是 rdma-core 的用户态库),支持 RC/UD 两种传输、Send/Recv 和 RDMA Read/Write,再配一套对标 perftestib_send_bw/latib_write_bw/latib_read_bw/lat 的 Go 版工具。

今年不同了,AI Coding 技术飞速发展,我也有信心去做移植这件事。尤其本周 Loop Engineering 这种工作方式大家讨论得很热烈,我也在自己的 goal workflow 里加了个 loop-it 技能,实现了一个轻量级的 Loop Engineering,正好拿来试试手。

还有,大家普遍担心 Loop Engineering 实践起来 token 花费太高,我也想实际看看到底花费几何。

移植RDMA到Go生态圈是个典型的「工作量不小、但每一步都不算难」的活儿。cgo 封装 verbs 是体力活:几十个 C 结构体、状态机、字节序、资源生命周期,错一个字段编译就挂。正是这种结构清晰、可分解、可验证的任务,最适合拿来做一次 Loop Engineering 实验。

所谓 Loop Engineering,核心就一句话:不要让 Agent 一口气写完一个大项目,而是把工作拆成带依赖的小单元,让它在一个可恢复、可观测的循环里逐个吃掉,每一步都有验证关卡。

这是我的锅,实现的loop-it有问题。后来在执行过程中我发现了这个问题,修复了 loop-it


4. 补救:真正的审查发现了什么

最后我还是做了补救,让 CC「现在跑一次真正的审查」。这次 CC 调起了能用的 /code-review(high effort:多个独立角度并行找问题,再逐条对抗式验证),对已合并的全部代码做了一轮真正的 correctness 审查。

结果很扎心——8 个确认/可信的问题,其中两个是致命的编译错误:

  1. cq_linux.goc.imm_data undefined
    struct ibv_wcimm_data 在一个匿名 union 里,cgo 根本无法用 .imm_data 访问;而且它是 __be32(网络字节序)。

  2. device_linux.goibv_query_port 类型不匹配
    现代 rdma-core 把 ibv_query_port 做成 static inline,转发到一个收 _compat_ibv_port_attr* 的真实符号,cgo 直接调会类型不符。

还有 6 个运行时/逻辑问题,例如:

  1. rdma_cm 路径的 Endpoint.Peer 永远没赋值 → 所有走 -R 的 Write/Read 都会立刻报 errNoPeer
  2. write.go 的 busy-wait 没有内存屏障for buf[last] != expect {} 读的是 NIC 通过 RDMA 写入、Go 运行时看不见的内存,编译器可能把这次 load 提到循环外,造成死循环或读到陈旧值。
  3. imm_data 发送侧字节序 → 没 htonl,对端会读到字节翻转的立即数。
  4. rdma_cm 错误路径资源泄漏errno 读取时机不对setup 忽略了 -c/-d/-i/-x 参数……

最刺眼的事实是:这两个编译错误意味着,整个 cgo 核心从来没在 Linux 上编译过。我全程在 macOS 上开发,走的是 stub 路径,go build 一路绿灯,但那只证明了「桩实现能编译」,完全没碰到真正的 verbs 代码。


5. 修复阶段:一步步把真相逼出来

接下来的过程,本质上是让真实环境替我做验证。这部分非常有意思,因为它展示了 Agent 的盲区如何被一台真机一点点照亮。

我还是做了一点点额外的工作,以下是我手工触发的。

第一步,质量清理(/simplify)。4 个角度并行审查:reuse / simplification / efficiency / altitude。修了几处真问题:

  • stats.go 的延迟统计,原来每打印一行 summary 要 sort 3 次(Min/Max/Percentile 各自 sort 一遍),直方图路径甚至 5 次。改成 Stats() 一次排序算出 min/avg/max/p99。
  • 带宽测试的「保持 TxDepth 个请求在途」的循环,在 send/write/read 里三份几乎一样的拷贝 → 抽成一个 runBWPipeline(cfg, cq, post),用闭包传 opcode。
  • 4 个工具 main 里重复的 -R/UD 拒绝逻辑 → 收敛成一个 Config.RequireOneSidedTCP()
  • 删掉过时的 var _ = C.IBV_QPT_RC cgo 占位 anchor。

第二步,工程化。加了 Makefilevet/build/test/tools/cross/stub/integration/lint/fmt,硬件相关的 integrationGORDMA_HW=1 闸住),加了 make fmtmake lint

make lint 一跑,golangci-lint 报了 20 个问题:16 个 errcheck(没检查的 defer Close() 返回值等)、2 个 unused、以及 2 个 staticcheck SA5002,正是 write.go 那个 busy-wait race。静态分析工具独立地撞上了 /code-review 早就指出的内存模型 bug。

这里有个小插曲值得一记:修这个 race 时我第一反应是用 atomic.LoadUint8——结果 Go 根本没有 8 位原子操作,编译直接挂。最后改成:定位包含该字节的 4 字节对齐 word,用 atomic.LoadUint32 + CompareAndSwapUint32 只改其中一个字节(代价是要求 Size >= 4)。Agent 也会想当然,差别只在于有没有一个会立刻打脸的编译器。

第三步,真机连环打脸。用户把代码弄到一台真正的 H20 GPU 服务器上(装了 RDMA 网卡),开始跑 make

  • 第一次:fatal error: rdma/rdma_cma.h: No such file or directory,缺 librdmacm-dev。换成我的开发 docker,上面已经装好了相应依赖库。
  • 第二次:c.imm_data undefined + ibv_query_port 类型不匹配,就是 /code-review 预言的那两个编译错误,这下在真机上真实地复现了。CC 按 libibverbs 的正确用法修:给 imm_data 写 C 辅助函数 wc_imm_data()ntohl 转主机序);给 ibv_query_port 包一层 C wrapper gordma_query_port() 让 inline 在 C 里展开;发送侧 imm_datahtonl
  • 第三次:device_linux.go:67: possible misuse of unsafe.Pointergo vet 嫌弃把指针存进 uintptr 再做算术。改用 unsafe.Add,让指针运算全程保持 unsafe.Pointer 形式。

因为这些都没进 Loop,所以不适合放在循环里,而是在循环之外执行的。起始后续/simplify 也可以加在循环中。


6. 完整的提交时间线

如果把 16 个功能 PR 之后的修复也算上,整条提交线是这样的(节选):

1
2
3
4
5
6
7
8
edd44e2 docs: add badges to README
4fa8b9c fix: use unsafe.Add to walk device list (go vet unsafe.Pointer) ← 真机第3次
f0b0453 fix: cgo compile errors (imm_data, ibv_query_port) + imm byte order ← 真机第2次
d253e36 Chore/simplify cleanups (#31) ← 质量清理+工程化
f2519af docs: README usage, godoc, and CI workflow (#15) ← loop-it 最后一个 issue
...
d15513b 项目骨架:go.mod、cgo 构建配置、非 Linux stub (#1) ← loop-it 第一个 issue
56514ff Initial commit

#1#15 是 loop-it 自动跑出来的,干净利落。d253e36 之后的几个 fix,则是人把 Agent 拽回现实的痕迹。


7. 成本:那 239 块钱

说说标题里的钱。

我一直盯着Claude Code中钱的消耗,最后算下来一共花了 239 元。239 这个数字是按整轮交互(一份 PRD、15 个 issue 的实现、一轮 high-effort code-review、一轮 4 角度 simplify,外加多轮真机修复往返)的量级估的。我不想在这篇复盘里编一张逐项发票出来——那本身就违背了全文的主旨。

但即便按这个量级看,几个判断是成立的:

  • 这是「一个有经验的工程师几天的活儿」:cgo 封装整套 verbs、写 6 个 perftest 工具、跨平台 stub、CI、文档。按工时折算,几百块的 API 成本对应的是数千块的人力成本。
  • 真正贵的不是「写」,是「来回」。第一遍实现其实很快、很便宜,大约100块。烧钱的是后面那些本可以避免的往返——如果一开始就在有网卡的 Linux 上开发,那两个编译错误根本不会漏到合并之后,也不会有「真机连环打脸」的三轮修复。
  • 跳过审查省下的钱,会在后面加倍还回来。loop-it 静默降级掉的 /review-it,最终是用一轮独立的 /code-review + 多轮真机调试补回来的。省一步,赔三步。。

附:项目信息

  • 仓库:github.com/smallnest/gordma
  • 规模:52 个 Go 文件 / ~3981 行
  • 能力:Device/Context/PD/MR/CQ/QP/AH 全套 verbs;RC + UD;TCP 握手 + rdma_cm 两种建连;6 个 perftest 风格工具
  • 构建:Linux+cgo 真实实现,非 Linux/CGO_ENABLED=0 stub 实现
  • 状态:cgo 编译错误已在真机修复;硬件数据通路的端到端验证已在 RoCE v2 真机上验证