AI에게 현대 바둑 가르치기: ‘Stuck-in-the-Past’ 문제를 Antigravity로 해결하기
Source: Dev.to
문제: 구식 기본값
LeetCode – 1. Two Sum
func TwoSum(nums []int, target int) []int {
seen := make(map[int]int)
for i, num := range nums {
comp := target - num
if idx, ok := seen[comp]; ok {
return []int{idx, i}
}
seen[num] = i
}
return nil
}
에이전트에게 write benchmark for TwoSum function 를 요청하면 보통 다음과 같은 벤치마크가 생성됩니다:
func BenchmarkTwoSum(b *testing.B) {
// Create a larger input for benchmarking
nums := make([]int, 1000)
for i := 0; i < 1000; i++ { // Old‑style loop
nums[i] = i
}
target := 1997
b.ResetTimer()
for i := 0; i < b.N; i++ { // Old‑style benchmark loop
TwoSum(nums, target)
}
}
문제점
- 최신
for i := range 1000대신 고전적인for i := 0; i < 1000; i++루프를 사용합니다. - Go 1.24에서 도입된 새로운
b.Loop()메서드 대신b.N을 수동으로 사용합니다.
해결책: 에이전트 규칙
Antigravity에서 Rule 은 에이전트에 대한 제약, 선호도 및 스타일 가이드를 정의하는 Markdown 파일입니다.
(설정 방법은 문서를 참고하세요.)
1. 벤치마크 현대화 (benchmark.md)
// benchmark.md
The `b.Loop` method is now the preferred way to write benchmarks in Go 1.24+.
func BenchmarkExample(b *testing.B) {
// ... setup ...
for b.Loop() {
// ... code to measure ...
}
// ... cleanup ...
}
Always use b.Loop() instead of b.N in benchmarks.
2. 루프 현대화 (loops.md)
// loops.md
Each iteration creates a new instance of the variable. There is no need to declare `v := v` inside the loop for closure safety.
for _, v := range data {
go func() {
// safe to use v here directly
}()
}
// Integer ranges are now supported.
for i := range 10 {
fmt.Println(10 - i)
}
결과
규칙 파일을 추가하고 Reload Rules 버튼을 클릭한 뒤, 에이전트는 새로운 관례를 따르게 됩니다. 다시 요청하면:
write benchmark for TwoSum function
다음과 같은 계획을 제시합니다:
[NEW] search_test.go
* Create `search_test.go`.
* Implement `BenchmarkTwoSum`.
* Use `b.Loop()` structure.
* Construct a large slice of integers and a target that tests worst/average cases.
업데이트된 벤치마크
func BenchmarkTwoSum(b *testing.B) {
nums := make([]int, 1000)
for i := range 1000 {
nums[i] = i
}
target := 1997
for b.Loop() {
TwoSum(nums, target)
}
}
코드가 최신 Go 사양을 따르며 전체적으로 더 깔끔해졌습니다.
더 나아가기: 스타일 가이드 적용
규칙은 보다 넓은 스타일 가이드도 강제할 수 있습니다. 예를 들어 전체 Uber Go Style Guide 를 가져오거나 자체 규칙을 정의할 수 있습니다.
예시: 오류 래핑 적용 (errors.md)
// errors.md
Do not simply `return err`. Always wrap errors using `github.com/cockroachdb/errors` to provide stack traces and context. Use `Wrap(error, string)` or `Wrapf(error, string, ...interface{})`.
func getUser(id int) error {
if err := someDatabaseCall(id); err != nil {
// Wrap the original error with added context
return errors.Wrapf(err, "some database call id %d", id)
}
return nil
}
이와 같은 규칙을 정의하면 LLM이 구식 패턴으로 돌아가는 것을 방지하고, 생성된 코드가 팀의 도구와 스타일에 맞도록 할 수 있습니다. 규칙은 LLM의 지식과 실제로 원하는 코드 사이의 격차를 메워 줍니다.