Notes on code & AI-assisted development.
A working log of lessons from backend, big-data, and Go engineering, plus what actually helps (and hurts) when pairing with AI assistants.
AI 让代码迁移变快之后,质量保障反而更重要了
读 Anthropic 大规模代码迁移实践:当写代码变便宜,瓶颈转向工程控制 — AI 写代码的速度越快,工程师越不能只关注代码本身。真正稀缺的能力,正在从“写对每一行代码”转向“设计一套能持续生产正确代码的系统”:用规则约束生成、用小规模实验验证规则、用对抗性 Agent 主动找问题、用编译器和测试当裁判。这篇是我读 Anthropic《How Anthropic runs large-scale code migrations with Claude Code》后的整理与思考。 最近读了 Anthropic 发布的一篇文章:《How Anthropic runs large-scale code migrations with Claude Code》。 文章分享了他们如何利用 Claude Code 和多个...
Once AI Makes Code Migration Fast, Quality Assurance Matters More, Not Less
Reading Anthropic's large-scale migration playbook: when writing code gets cheap, the bottleneck moves to engineering control — The faster AI writes code, the less an engineer can afford to focus on the code itself. The scarce skill is shifting from “getting every line right” to...
Coding Agent 的知识管理:不是塞更多上下文,而是构建可复利的工作流
Index → Route → Body 的按需加载纪律 — Coding Agent 时代,知识管理的核心不是“记住更多”,而是“按需加载”。真正重要的不是 context size,而是 context routing:让正确的知识,在正确的阶段,被正确加载;让每个判断都有证据;让重复经验逐步变成自动化检查。这也是从 prompt engineering 走向 agent system engineering 的关键一步。 最近在思考一个问题:Coding Agent 的开发流程里,知识应该怎么管理? 很多团队在使用 agent 时,第一反应是给它更多上下文:更多文档、更多 memory、更多规则、更多历史案例。 但实际效果不一定更好。因为 agent 不是人。上下文给得越多,它不一定越聪明,反而可能出现几个问题: 读到过期信息 被历史 case 误导...
Knowledge Management for Coding Agents: Stop Stuffing Context, Build a Compounding Workflow
The Index → Route → Body discipline for on-demand loading — In the Coding Agent era, the core of knowledge management is not “remember more.” It is “load on demand.” What matters is not context size, but context routing:...
推荐一个 149K Star 的 AI Coding 宝藏仓库:Skills
真正值得学习的不是 Prompt,而是 Workflow — 最近看到一个很有意思的开源项目:Skills。截至 2026-06-28,我通过 GitHub API 查到它已经有 149,182 stars。作者 Matt Pocock 在前端和 TypeScript 圈很有影响力,但这个仓库让我更感兴趣的地方,不是某个具体 prompt,而是它把优秀工程师的工作流程沉淀成了一套套可复用的 Agent Skill。 今天重点推荐其中一个我觉得很值得学习的 Skill:improve-codebase-architecture。 一、这个 Skill 是做什么的 简单说,它会让 Agent 对一个代码仓库做一次架构诊断。 它不是上来就让模型“给我一些重构建议”,而是先规定了明确流程: 读取项目里的 CONTEXT.md 和 ADR,理解已有领域语言和历史决策...
A 149K-Star AI Coding Gem: Skills
What matters is not the prompt, but the workflow — I recently came across an interesting open-source project: Skills. As of 2026-06-28, the GitHub API showed 149,182 stars. Its author, Matt Pocock, is well known in the frontend...
让 Coding Agent 不再跑偏的 Goal 写法
从一份「写给 AI 读」的 spec 里偷来的消歧纪律 — 给 Claude Code / Cursor 派活,效果不好往往不是 agent 笨,而是 Goal 描述只在我们自己脑子里才不歧义。读自己写的字时,大脑会自动用已有的上下文把空缺补满,于是你永远看不见那些空缺;agent 没有那份上下文,遇到同一个空缺只会补成别的东西。OpenAI 开源的 Symphony Service Specification 给了一套现成解药——它明知读者是 AI,于是把「消歧」做成了第一性设计。这篇把它的六个装置拆出来,变成你下次写 Goal 就能直接用的纪律。 一个被误判的因果 我们复盘 agent 写崩的活,第一反应常是「这模型不行」。但更多时候,真正的问题在上游:Agent 跑偏,多半不是它笨,是你的 Goal 只在你自己脑子里才不歧义。 这是两件「从内部看一模一样」的事——一份对作者清晰的 Goal,和一份对缺少作者上下文的读者也无歧义的...
Writing Goals That Keep Coding Agents on Track
Disambiguation discipline stolen from a spec written to be read by AI — When Claude Code or Cursor produces bad work, it’s usually not that the agent is dumb — it’s that the Goal was only unambiguous inside your own head....
当 agent 写掉 99% 的代码,工程师的护城河挪去哪了
读 Augment《如何招聘 AI 原生工程师》之后的一点个人思考 — 做了十年软件工程师,我从没遇到过哪次技术变革像现在的 agent coding 这样,直接冲着「职业」本身来——而且就发生在过去三个月内。最近读到 Augment 那篇《我们现在如何招聘 AI 原生工程师》,它把人的角色重新定义为「从作者转向架构师和编辑者」。它真正刺到我的是一句话:纯粹的编码能力,已经不再是区分工程人才的首要因素。这篇是我读完之后的个人思考——不是复述原文,原文值得你自己读。 一个让我有点被刺到的问题 Augment 这篇文章(作者 Alex Ding、Alyah Sablan、Chris Marty、Vinay Perneti)开篇就抛出一个问题:当 agent 写掉 99% 的代码,你该怎么招工程师? 原文链接放在文末,强烈建议读原版。 我被刺到的点很私人:我这十年攒下的核心资本,恰好就是那个正在被商品化的东西——「写代码写得又快又对」。所以我下意识的焦虑,不是「我不会写代码了」,而是更难回答的那个——我的差异化到底还剩什么? 这背后是两件过去十年被捆在一起、现在正在分叉的事:擅长写代码,和擅长决定该写什么、并把人加 agent 这套系统 driving 到正确结果。在「他是个好工程师」这句话里,这两者一直感觉是一回事;只有当代码变得便宜,你才看出来——一个在贬值,一个在升值。 当写代码的成本趋零,最贵的错误就变成了「构建了错误的东西」——你的护城河也跟着从「写得多快」挪到了「选得多对」。...
When Agents Write 99% of the Code, Where Did the Engineer's Moat Go?
A few personal thoughts after reading Augment's 'How We Hire AI-Native Engineers Now' — Ten years as a software engineer, and I’ve never met a technical shift that aimed straight at the profession itself the way agent coding does — and it...
Agent Harness 新实践:Claude Code 动态工作流
从 prompt 驱动走向 workflow 驱动 — Anthropic 最近发布了 Claude Code Dynamic Workflows:Claude Code 不再只是单个 agent 在一个上下文里干活,而是可以为当前任务临时写一套专属 harness——一个 JavaScript workflow,用来调度多个子 agent 协作。我读完原文又试了一下,最大的体会是:过去写进 prompt 里的那些”请仔细检查”“别漏测试”,正在变成结构化的执行流程。本文是一篇功能梳理 + 我自己的思考。原文:A harness for every task: Dynamic Workflows in Claude Code。...
A New Agent-Harness Practice: Claude Code Dynamic Workflows
From prompt-driven to workflow-driven — Anthropic recently shipped Claude Code Dynamic Workflows: instead of a single agent working in one context, Claude Code can write a bespoke harness for the task at hand...
GPT-5.5、Gemini 3.5 Flash、Claude Fable 5 方案能力对比
模型能扩展思路,但命名约束仍是工程师的事 — 给三个最强模型同一道工程题,它们一开始都推荐了同一个”最佳实践”——而那个方案恰好踩中项目里一个没人提起的隐藏约束。模型能扩展思路、能调研、能整理方案,但它只能对你说出口的约束做推理。这次 Atlas → Looker 的同步调研让我确信:AI 已经是极好的方案副驾,却还不能替工程师做最终架构判断。真正高效的不是盲信某个模型,而是用多个模型扩展思路、用工程师经验命名关键约束、再让最强模型收敛。 本文基于一次真实工程方案调研,比较 GPT-5.5、Gemini 3.5 Flash 和 Claude Fable 5 在复杂技术问题上的方案设计能力。调研目标是:如何把 Apache Atlas 中维护的元数据,同步到 Google Cloud Looker,让客户在 Looker 中看到最新的字段描述。 一、背景:从 Atlas 同步字段描述到 Looker 我们有一个元数据管理平台...
GPT-5.5 vs Gemini 3.5 Flash vs Claude Fable 5 on Solution Design
Models can broaden your options, but naming the constraints is still the engineer's job — I handed three of the strongest models the same engineering problem, and all three opened with the same “best practice” — one that happened to step right onto...
Golang fallthrough keyword
practice — Background Golang语言中关于流程控制的关键不多,常用的有break continue,fallthrough 也是其中之一,但是较为少用,借此文档,探讨其常见用法 Official Doc https://go.dev/ref/spec#FallthroughStmt A "fallthrough" statement transfers control to the first statement of the next case clause in an expression "switch" statement. It may...
Golang's fallthrough keyword
practice — Background Go has only a handful of control-flow keywords. The everyday ones are break and continue; fallthrough is another, but it shows up far less often. This note...
Clickhouse集成kafka流数据的不足
避免踩坑 — Background Clickhouse提供了集成kafka的解决方案,从而使在clickhouse中集成流数据变为可能,但是如果要使用在生产环境中,有以下几个方面的问题不得不考虑。 消费Kafka数据的语义是at least once, 消费的数据会有重复 维护的成本与job监控 扩展性 EOS support 官方文档并未说明kafka engine消费Clickhouse的语义,但是从插件原作者维护的[文档|https://altinity.com/blog/clickhouse-kafka-engine-faq] 中可见详细的说明: Duplicates are theoretically possible, since current implementation ensures the at-least-once contract. That should not happen...
Clickhouse集成kafka流数据实践
实时数据导入 — Background 最近的项目中,有业务场景用到导入实时数据到Clickhouse的需求,再实践的过程中,由于clickhouse本身文档的一些不完善,有些经验和教训值得记录下。 Clickhouse的介绍可以参考 https://clickhouse.tech/docs/en/ ClickHouse is a column-oriented database management system (DBMS) for online analytical processing of queries (OLAP). 具备参考价值的文档: 官方文档,kafka engine是一种特殊的table engine https://clickhouse.tech/docs/en/engines/table-engines/integrations/kafka/ 插件作者维护的文档: https://altinity.com/blog/2020/5/21/clickhouse-kafka-engine-tutorial 介绍了很多官方文档没有提及的用例,已经一些FAQ问题,非常有用。 头条的实践分享:...
Go fallthrough关键字 and label break
Go语法 — fallthrough and loop 在看Go的源码的时候,经常发些loop 关键字,最近工作中也发现有代码使用fallthrough关键字,正好之前对于这两个关键字了解不多,趁机熟悉下相关用法。 先看看官方的解释 fallthrough To fall through to a subsequent case, use the fallthrough keyword https://github.com/golang/go/wiki/Switch#fall-through v := 42 switch v { case 100: fmt.Println(100)...
在二进制binary的Azkaban job 之前传递参数
Azakaban job paramter 传递 — 背景介绍与需求分析 需求 最近工作中需要用Azakaban进行任务调度,一共有3个job(A->B->C),如果A满足一定条件的话,去触发B,B完成之后去触发C。 如果A的条件没有满足,就取消B,C的运行 现状 官方文档(https://azkaban.github.io/azkaban/docs/latest/ ) 真是够精简的,很多内容不够详尽。首先我大致读了下官方文档,我的job是通过 type=command ,常用的参数传递方式即是通过job之前的运行时环境变量的方式设置的。 要调度的job A,B,C都是一个二进制的binary,传递参数给binary是比较容易的,要从binary的运行结果中获取参数是比较费劲的。我需要传递的参数是可变,就没有办法简单在job文件里面通过设置运行环境变量的方式去传递参数了。 解决办法 从官方文档里面看到下面一句话 Parameter Output Properties can be exported to be passed to its dependencies. A second...
Hive 查询优化的几种方法(转载)
bloom filter, index and statistics — HIVE OPTIMIZATIONS WITH INDEXES, BLOOM-FILTERS AND STATISTICS This blog post describes how Storage Indexes, Bitmap Indexes, Compact Indexes, Aggregate Indexes, Covering Indexes/Materialized Views, Bloom-Filters and statistics can increase...
linux find * 和 *? 的区别
linux find 默认正则语法规则 — 问题描述 在使用find朝查找东西的时候,使用* 或者 *?的时候,会匹配多多个字符,举个例子: !1018 $ ls total 0 0 a--bb-d.txt 0 a-bb-cccc-d.txt eng@rpt-re01:~/test · 04:05 AM Tue Oct 23 · !1019 $ find ./ -name "a-*-*-d.txt" ./a--bb-d.txt...
Golang Mysql数据map到自定义结构体
通用函数 — 为什么需要一个通用函数 在项目过程中,经常会碰到读取数据库数据的需求,针对不同的数据库数据集,如果直接用mysql package本身的query-scan方法,每个不同的数据集都需要几乎类似的数据处理流程,这样有两个明显的缺点 数据处理逻辑和查询行为耦合在一起 代码重复度高,不利于UT 我们看一个官方的mysql package的示例代码(https://golang.org/pkg/database/sql/#example_DB_QueryContext) func queryName(db *sql.DB, query string, args interface{}) { rows, err := db.Query(query, args...) if err != nil { log.Fatal(err) } defer...
写Golang UT的几种方法
native way — 怎么样在Golang里面写UT UT test是测试中的最小测试单元,一般而言,需要fake 输入,compare预期输出,最理想或者最简单的情况是输入特别易于fake,看下面的例子 建设我们有一个实现➕1功能的函数 sum.go // sum.go package sum func addOne(a int) int { return a + 1 } 如果你要为这个函数写UT,你需要创建一个测试文件 sum_test.go,这样当你运行命令 go test xxx时, go 会自动运行package下面的所有的 *_test.go...
GOROOT,GOPATH,GOVENDOER
区别于使用 — GOPATH与GOROOT 在工作过程中,经常碰到GOPATH与GOROOT设置引起的环境变量错误,所以总结下它们的区别于用法。 可以通过 go env 查看下当前机器的环境变量有哪些 ```!571 $ go env GOARCH=”amd64” GOBIN=”” GOEXE=”” GOHOSTARCH=”amd64” GOHOSTOS=”darwin” GOOS=”darwin” Stack Overflow上有个讨论特别有用 https://stackoverflow.com/questions/7970390/what-should-be-the-values-of-gopath-and-goroot 下面的例子可以说明问题 directory for go related things: ~/programming/go directory for...
golang cron包源码解析
第三方golang代码库源码阅读 — GO Cron库源代码阅读 项目中用到了GO的一个第三方库,内置实现了cron调度的功能,学习一下其设计与实现 项目地址: https://github.com/robfig/cron.git 首先看下官方文档的 https://godoc.org/github.com/robfig/cron 的简单用例 c := cron.New() c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") }) c.AddFunc("@hourly", func()...
GRPC Gateway在response中忽略默认值
solution — GPRC的RESTFUL API返回结果中忽略默认值或者空值 问题描述 在升级proto2到proto3的过程中,因为结构体的类型从指针变成了属性本身,导致到grpc gateway返回reponse的时候,由于某些属性的值是默认值,导致respose中缺失该属性。 // proto 2 type B { b *int json:"b,omitempty" } type A { a *string json:"Aa,omitempty" b *B json:"Ab,omitempty" } respA := A{a:...
Golang Interface{} 与 nil
interface{}的实现 — interface{}与nil的对比 在写代码的过程中,发现一个interface{} 参数与nil对比的一个奇怪的地方 先来看一段代码 https://play.golang.org/p/6_gUBSS57P_E package main import ( "fmt" "reflect" ) func test(i interface{}) { fmt.Printf("i=%v\n", i) fmt.Printf("isNil = %v\n", reflect.ValueOf(i).IsNil()) if i == nil { fmt.Println("i...