๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

ยฉ 2026 Molayo

Dev.toํ—ค๋“œ๋ผ์ธ2026. 05. 27. 15:57

๐Ÿค– GPT-5.4 vs Claude Sonnet 4.6 vs Gemini 3.1 Pro โ€” 4๊ฐ€์ง€ ์‹ค์ œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ์˜ ์—์ด์ „ํŠธ ์ฝ”๋”ฉ ๋Šฅ๋ ฅ ๋น„๊ต

์š”์•ฝ

GPT-5.4, Claude Sonnet 4.6, Gemini 3.1 Pro๋ฅผ ๋Œ€์ƒ์œผ๋กœ 4๊ฐ€์ง€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ์—์„œ์˜ ์—์ด์ „ํŠธ ์ฝ”๋”ฉ ๋Šฅ๋ ฅ์„ ๋น„๊ต ๋ถ„์„ํ•œ ์—ฐ๊ตฌ์ž…๋‹ˆ๋‹ค. ๋™์ผํ•œ ํ”„๋กฌํ”„ํŠธ ํ•˜์—์„œ ๋ชจ๋ธ์ด ์ฝ”๋“œ์˜ ์ •ํ™•์„ฑ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ, ์œ ์ง€๋ณด์ˆ˜์„ฑ ๋“ฑ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ์‹ค์งˆ์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํฌ์ธํŠธ

  • Go, Python, Node.js, React ๋“ฑ 4๊ฐ€์ง€ ์Šคํƒ ๊ธฐ๋ฐ˜ ๋น„๊ต
  • ์ •ํ™•์„ฑ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ, ๊ด€์šฉ์  ์Šคํƒ€์ผ ๋“ฑ ์‹œ๋‹ˆ์–ด ๋ฆฌ๋ทฐ์–ด ๊ธฐ์ค€ ํ‰๊ฐ€
  • Claude Sonnet 4.6์ด ์ƒ์„ฑ ์†๋„ ๋ฉด์—์„œ ์••๋„์ ์ธ ์„ฑ๋Šฅ ๊ธฐ๋ก
  • ๋ชจ๋ธ๋ณ„ ์‚ฌ์ „ ์ง€์‹(Priors)์— ๋”ฐ๋ฅธ ์ฝ”๋“œ ๊ตฌ์„ฑ ์ฐจ์ด ํ™•์ธ

์„ธ ๊ฐ€์ง€ ์ตœ์ฒจ๋‹จ ์ฝ”๋”ฉ ๋ชจ๋ธ์ด Go, Python, Node.js (vanilla http), ๊ทธ๋ฆฌ๊ณ  React + TypeScript๋ผ๋Š” ๋„ค ๊ฐ€์ง€ ์Šคํƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์ž‘์€ ์ œํ’ˆ(TODO REST API ๋ฐ TODO UI)์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๋Š” ์ •๋ฉด ๋น„๊ต์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํ•ฉ์„ฑ ๋ฒค์น˜๋งˆํฌ(Synthetic benchmark)๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ฐ ๋ชจ๋ธ์—๋Š” ๋™์ผํ•œ ํ‰์ดํ•œ ์˜์–ด ํ”„๋กฌํ”„ํŠธ(Prompt)๊ฐ€ ์ฃผ์–ด์กŒ์œผ๋ฉฐ, ํ•˜๋‚˜์˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ๋ฌผ์€ ์‹œ๋‹ˆ์–ด ๋ฆฌ๋ทฐ์–ด๊ฐ€ PR(Pull Request)์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ๊ธฐ์ค€์ธ ์ •ํ™•์„ฑ(Correctness), HTTP ์˜๋ฏธ๋ก (HTTP semantics), ์—๋Ÿฌ ์ฒ˜๋ฆฌ(Error handling), ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(Validation), ๊ด€์šฉ์  ์Šคํƒ€์ผ(Idiomatic style), ๊ทธ๋ฆฌ๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ(Maintainability)์„ ๋ฐ”ํƒ•์œผ๋กœ ํ‰๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ

  • ๐Ÿ—ฃ๏ธ ํ”„๋กฌํ”„ํŠธ (The Prompt)
  • โš™๏ธ ์„ค์ • (Setup)
  • ๐Ÿน ์‹œ๋‚˜๋ฆฌ์˜ค 1 โ€” Go REST API
  • ๐Ÿ ์‹œ๋‚˜๋ฆฌ์˜ค 2 โ€” Python REST API
  • ๐ŸŸจ ์‹œ๋‚˜๋ฆฌ์˜ค 3 โ€” Node.js REST API
  • โš›๏ธ ์‹œ๋‚˜๋ฆฌ์˜ค 4 โ€” React + TypeScript UI
  • ๐Ÿ† ์ข…ํ•ฉ ์Šค์ฝ”์–ด๋ณด๋“œ (Aggregate Scoreboard)
  • ๐Ÿ” ๋‚˜ํƒ€๋‚œ ํŒจํ„ด๋“ค (Patterns That Emerged)
  • ๐ŸŽฏ ๋ชจ๋ธ ์„ ํƒ์— ์ฃผ๋Š” ์˜๋ฏธ (What This Means for Picking a Model)

๐Ÿ—ฃ๏ธ ํ”„๋กฌํ”„ํŠธ (The Prompt)

๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค์˜ ๋ชจ๋“  ๋ชจ๋ธ์€ ์–ธ์–ด ํ† ํฐ๋งŒ ๊ต์ฒด๋œ ์ •ํ™•ํžˆ ๋™์ผํ•œ ํ•œ ์ค„์˜ ์ง€์นจ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค:

"100์ค„์˜ ์ฝ”๋“œ ์ด๋‚ด๋กœ todo ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” [golang / python / nodejs / reactjs] ํŒŒ์ผ์„ ์ž‘์„ฑํ•ด์ค˜"

๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. ๋ช…์„ธ(Spec)๋„, ์—”๋“œํฌ์ธํŠธ(Endpoints) ๋ชฉ๋ก๋„, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(Validation), CORS, REST ์˜๋ฏธ๋ก (REST semantics), ๋˜๋Š” ์ ‘๊ทผ์„ฑ(Accessibility)์— ๋Œ€ํ•œ ํžŒํŠธ๋„ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. 100์ค„ ์ œํ•œ์€ ์˜๋„์ ์ธ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ชจ๋ธ์ด _๋ฌด์—‡์„ ํฌํ•จํ•˜๊ณ  ๋ฌด์—‡์„ ์ƒ๋žตํ• ์ง€_์— ๋Œ€ํ•ด ์Šค์Šค๋กœ ํŒ๋‹จํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋ฉฐ, ๋ฐ”๋กœ ์ด ์ง€์ ์—์„œ ๋ชจ๋ธ์˜ ์‚ฌ์ „ ์ง€์‹(Priors)์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ์ถ”๊ฐ€ํ•  ์—ฌ์œ ๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์„ ํƒํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

โš™๏ธ ์„ค์ • (Setup)

์†Œ์Šค ์ €์žฅ์†Œ: truongpx396/gpt-5.4_claude-sonnet-4.6_gemini-3.1-pro-coding-capability โ€” ์ƒ์„ฑ๋œ ๋ชจ๋“  ํŒŒ์ผ์€ gencode_golang/, gencode_python/, gencode_node/, ๊ทธ๋ฆฌ๊ณ  gencode_reactjs/ ์•„๋ž˜์— ์ •๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์„ธ ๊ฐ€์ง€ ๊ฒฝ์Ÿ ๋ชจ๋ธ ๋ชจ๋‘ GitHub Copilot์„ ํ†ตํ•ด ์ ‘์†๋˜์—ˆ์œผ๋ฉฐ, ๊ฐ ๋ชจ๋ธ์€ ๊ธฐ๋ณธ ์ถ”๋ก (Reasoning) ์„ค์ •์œผ๋กœ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋ธ์ถ”๋ก  ๋ชจ๋“œ (Reasoning mode)์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ (Context window)์ƒ์„ฑ ์†๋„ (Generation speed)*์ ‘์† ๋ฐฉ์‹ (Access)
GPT-5.4์ค‘๊ฐ„ (๊ธฐ๋ณธ๊ฐ’)400k~24 tok/sGitHub Copilot
...
  • ๋ณธ ํ…Œ์ŠคํŠธ ์ค‘์— ์ธก์ •๋จ โ€” ๊ฐ ์ž‘์—…์€ ์•ฝ 100ํ–‰ / ์•ฝ 700๊ฐœ์˜ ์ถœ๋ ฅ ํ† ํฐ์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. Claude Sonnet 4.6์ด ์••๋„์ ์ธ ์ฐจ์ด๋กœ ๊ฐ€์žฅ ๋นจ๋ž์œผ๋ฉฐ, GPT-5.4๋ณด๋‹ค ์•ฝ 42% ๋น ๋ฅด๊ณ  Gemini 3.1 Pro๋ณด๋‹ค ์•ฝ 13% ๋นจ๋ž์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ด๋Š” 20์ดˆ ๋Œ€๊ธฐ์™€ 29์ดˆ ๋Œ€๊ธฐ์˜ ์ฐจ์ด๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, ๋‹จ์ผ ์ƒ์„ฑ (one-shot generation) ์‹œ์—๋Š” ๋ˆˆ์— ๋„์ง€๋งŒ ๊ฒฐ์ •์ ์ธ ์ฐจ์ด๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋งŽ์€ ์ˆœ์ฐจ์  ํ˜ธ์ถœ์ด ๋ฐœ์ƒํ•˜๋Š” ์—์ด์ „ํŠธ ๋ฃจํ”„ (agentic loops)์—์„œ๋Š” ์ด ์ฐจ์ด๊ฐ€ ํฌ๊ฒŒ ๋ˆ„์ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ ์ถœ๋ ฅ๋ฌผ์— ๋Œ€ํ•ด ์‹œ๋‹ˆ์–ด ๋ฆฌ๋ทฐ์–ด(senior-reviewer)๊ฐ€ ๊ฒ€ํ† ํ•˜๋Š” ๋ฐฉ์‹์˜ ํŒ๊ฒฐ ์ž์ฒด๋Š” Claude Code ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜๋Š” 1M-ํ† ํฐ ์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ๋ฅผ ๊ฐ€์ง„ Claude Sonnet 4.7์— ์˜ํ•ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ชจ๋ธ์€ ํ‰๊ฐ€ ๋Œ€์ƒ์ด ๋œ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜์ง€ ์•Š์•˜์œผ๋ฉฐ, ์˜ค์ง ์ฝ๊ณ  ์ฑ„์ ๋งŒ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฆฌ๋ทฐ ๋ชจ๋ธ์— ์ œ๊ณต๋œ ํ”„๋กฌํ”„ํŠธ๋Š” ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๋™์ผํ–ˆ์œผ๋ฉฐ, ํด๋” ์ด๋ฆ„๋งŒ ๊ต์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

"gencode_golang / gencode_python / gencode_node / gencode_reactjs ํด๋”์— ์žˆ๋Š” 3๊ฐœ์˜ ํŒŒ์ผ์„ ํ™•์ธํ•˜๊ณ , ์–ด๋–ค ์ฝ”๋“œ๊ฐ€ ๋” ๋‚˜์€์ง€ ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ด์œ ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”."

์ด ์‹คํ—˜์—์„œ "์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ (context window)" ์—ด์€ ์ƒ๊ฐ๋ณด๋‹ค ์ค‘์š”๋„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค. ๊ฐ ์ž‘์—…์€ ์ˆ˜๋ฐฑ ๊ฐœ์˜ ํ† ํฐ ๋‚ด์— ๋“ค์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  ์ด ์ง€ํ‘œ๋Š” ๊ฐ ๋ฒค๋”๊ฐ€ Copilot ๋‚ด์—์„œ ์ž์‹ ์˜ ๋ชจ๋ธ์„ ์–ด๋–ป๊ฒŒ ํฌ์ง€์…”๋‹ํ•˜๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ ๋” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. GPT-5.4๋Š” ํ—ค๋น„๊ธ‰ (heavyweight), Sonnet 4.6์€ ์›Œํฌํ˜ธ์Šค (workhorse, ์‹ค๋ฌด ์ค‘์‹ฌํ˜•), Gemini 3.1 Pro๋Š” ํ”„๋ฆฌ๋ทฐ ํ‹ฐ์–ด (preview tier)๋กœ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฉ๋ฆฌ ๋ฐ ํŽธํ–ฅ ๋ฐฉ์ง€ (Isolation & Bias Prevention)

๊ฐ ํŒŒ์ผ์€ ์ „์šฉ์˜ ๊นจ๋—ํ•˜๊ณ  ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ (dedicated, clean, fresh context) โ€” ์ฆ‰, ์ด์ „ ๋Œ€ํ™” ๊ธฐ๋ก์ด ์—†๊ณ , ๊ณต์œ ๋œ ์ฑ„ํŒ… ์„ธ์…˜์ด ์—†์œผ๋ฉฐ, ๋ชจ๋ธ ๊ฐ„์˜ ์ƒํ˜ธ ์ฐธ์กฐ๊ฐ€ ์—†๋Š” ๋ณ„๋„์˜ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ(repo)์—์„œ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ ํ›„ ๊ฐ ์ถœ๋ ฅ๋ฌผ์€ ๊ฒ€ํ† ๋ฅผ ์œ„ํ•ด ๋ณ„๋„์˜ ๋ชฉ์ ์ง€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋กœ ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ์ •์ ์œผ๋กœ, ์ƒ์„ฑ ๊ณผ์ • ์ค‘์—๋Š” ์‚ฌ์ „ ์„ค์ •๋œ ๊ทœ์น™, ์‚ฌ์šฉ์ž ์ •์˜ ์ง€์นจ (custom instructions), ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ (system prompts), ๋˜๋Š” .github/copilot-instructions.md ํŒŒ์ผ์ด ์ „ํ˜€ ์กด์žฌํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค โ€” ๋ชจ๋“  ๋ชจ๋ธ์€ ์ˆœ์ˆ˜ ๊ธฐ๋ณธ ์„ค์ • (bare defaults) ์ƒํƒœ๋กœ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค:

  • ์–ด๋–ค ๋ชจ๋ธ๋„ ์ƒ์„ฑ ์ „์ด๋‚˜ ์ƒ์„ฑ ์ค‘์— ๋‹ค๋ฅธ ๋ชจ๋ธ์˜ ์ถœ๋ ฅ์„ ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณต์œ ๋œ ์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ (Context Window)๋ฅผ ํ†ตํ•ด ๊ฒฝ์Ÿ ๋ชจ๋ธ ๊ฐ„์˜ ์Šคํƒ€์ผ, ๊ตฌ์กฐ ๋˜๋Š” ๊ฒฐ์ • ์‚ฌํ•ญ์ด ์œ ์ถœ๋  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์–ด๋–ค ์ปค์Šคํ…€ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ (Custom System Prompt)๋„ ํŠน์ • ํŒจํ„ด์„ ๋”ฐ๋ฅด๋„๋ก ๋ชจ๋ธ์„ ์œ ๋„ํ•˜๊ฑฐ๋‚˜ ๋ฉ€๋ฆฌํ•˜๊ฒŒ ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ๊ฒ€ํ† ์ž (Sonnet 4.7)๋Š” ์˜ค์ง ์›๋ณธ ํŒŒ์ผ๋งŒ์„ ์ „๋‹ฌ๋ฐ›์•˜์œผ๋ฉฐ, ์–ด๋–ค ๋ชจ๋ธ์ด ์–ด๋–ค ํŒŒ์ผ์„ ์ž‘์„ฑํ–ˆ๋Š”์ง€์— ๋Œ€ํ•œ ํžŒํŠธ๋Š” ์ „ํ˜€ ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํŒŒ์ผ ์ด๋ฆ„ ์ ‘๋ฏธ์‚ฌ (_gpt-5.4, _claude-sonet-4.6, _gemini-3.1-pro)๋Š” ๋ชจ๋“  ํŒ์ •์ด ์™„๋ฃŒ๋œ ํ›„์—๋งŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ ๋ฐ ๊ฒ€ํ†  ๋‹จ๊ณ„ ๋™์•ˆ ํŒŒ์ผ์€ ์˜ค์ง ๋ฒˆํ˜ธ๋กœ๋งŒ ์‹๋ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค (todo_1_, todo_2_, todo_3_). ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ์‚ฌํ›„์ ์œผ๋กœ ๊ท€์† ์ •๋ณด๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชฉํ‘œ๋Š” ์•ต์ปค๋ง ํŽธํ–ฅ (Anchoring Bias, ํ•˜๋‚˜์˜ ์†”๋ฃจ์…˜์„ ๋ณธ ํ›„ ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ), ์ปจํ…์ŠคํŠธ ์œ ์ถœ (Context Bleed), ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋ธ์˜ ์ž๊ธฐ ํŽธํ–ฅ (Model Self-favoritism)๊ณผ ๊ฐ™์€ ํŽธํ–ฅ์˜ ์›์ธ์„ ๊ฐ€๋Šฅํ•œ ํ•œ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿน ์‹œ๋‚˜๋ฆฌ์˜ค 1 โ€” Go REST API

์ˆœ์œ„: Sonnet 4.6 > GPT-5.4 > Gemini 3.1 Pro

๐Ÿ“„ ์ „์ฒด ํŒ์ • ๊ฒฐ๊ณผ โ†’ gencode_golang/verdict.md

์šฐ์Šน์ž: Claude Sonnet 4.6

Sonnet 4.6์€ Go 1.22+์˜ ๋ฉ”์„œ๋“œ ์ธ์‹ ๋ผ์šฐํŒ… (Method-aware Routing)์„ ๋‚˜๋จธ์ง€ ๊ธฐ๋ณธ ์‚ฌํ•ญ๋“ค๊ณผ ๊ฒฐํ•ฉํ•œ ์œ ์ผํ•œ ๋ชจ๋ธ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋ธ์€ r.PathValue("id")๋ฅผ ์‚ฌ์šฉํ•˜๋Š” mux.HandleFunc("/todos/{id}", ...)๋ฅผ ์‚ฌ์šฉํ•˜์˜€๊ณ , ์ผ๋ฐ˜์ ์ธ Content-Type / WriteHeader / Encode 3๋‹จ๊ณ„ ๊ณผ์ •์„ ์ œ๊ฑฐํ•˜๋Š” jsonResponse() ํ—ฌํผ ํ•จ์ˆ˜, ๊ตฌ์กฐํ™”๋œ JSON ์—๋Ÿฌ ๋ฐ”๋””, ๋””์ŠคํŒจ์น˜(Dispatch)๋ฅผ ์œ„ํ•œ switch r.Method, ๊ทธ๋ฆฌ๊ณ  โ€” ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ ์œผ๋กœ์„œ โ€” ๋ˆ„๋ฝ๋œ ํ•„๋“œ๊ฐ€ ์กฐ์šฉํžˆ ์ œ๋กœ ๊ฐ’(Zero value)์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š๋„๋ก ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ํฌ์ธํ„ฐ ํ•„๋“œ (Pointer Fields)๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค:

gencode_golang/todo_2_claude-sonet-4.6.go:83-97

case http.MethodPut:
    var body struct {
        Title     *string `json:"title"`
...

๋˜ํ•œ ์ฃผ๋ชฉํ•  ์ ์€ body.Title == ""๋ฅผ ๊ฒ€์ฆํ•˜๊ณ , ๊ธฐ๋ณธ mux ๋Œ€์‹  ๋ช…์‹œ์ ์ธ http.NewServeMux()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์‹ค์ œ GET /todos/{id} ๊ฒฝ๋กœ๋ฅผ ๋…ธ์ถœํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

2์œ„: GPT-5.4 โ€” ์˜ฌ๋ฐ”๋ฅธ ์˜๋ฏธ๋ก , ๊ตฌ์‹ ๋ผ์šฐํŒ…

GPT-5.4๋Š” _์˜๋ฏธ(meaning)_๋Š” ์ •ํ™•ํ•˜๊ฒŒ ํŒŒ์•…ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ํฌ์ธํ„ฐ ํ•„๋“œ๋ฅผ ํฌํ•จํ•œ PATCH ๋ฐฉ์‹, strings.TrimSpace ๊ฒ€์ฆ ๋“ฑ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Go 1.22 ์ด์ „์˜ ํŒจํ„ด์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ ํŒŒ์‹ฑ์„ ์œ„ํ•ด ์ˆ˜๋™์œผ๋กœ strings.TrimPrefix(r.URL.Path, "/todos/")๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์—๋Ÿฌ ๋ณธ๋ฌธ์„ ๊ฐ€์ง„ http.Error๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์กฐํšŒ์™€ ๋ฉ”์„œ๋“œ ๋””์ŠคํŒจ์น˜(method dispatch)๊ฐ€ ๋’ค์„ž์ธ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์น˜ 2020๋…„์˜ Go ์ฝ”๋“œ๋ฅผ ๋ณด๋Š” ๋“ฏํ•ฉ๋‹ˆ๋‹ค.

์ตœํ•˜์œ„: Gemini 3.1 Pro โ€” ํ˜„๋Œ€์ ์ธ ๊ฒ‰๋ชจ์Šต, ๋ฌด๋„ˆ์ง„ ๊ธฐ๋ณธ๊ธฐ

Gemini 3.1 Pro์˜ ์ฝ”๋“œ๋Š” ๊ฐ€์žฅ ํ˜„๋Œ€์ ์œผ๋กœ ๋ณด์˜€์ง€๋งŒ ("GET /todos" ์Šคํƒ€์ผ์˜ ๋ผ์šฐํŒ…), ๊ธฐ์ดˆ์ ์ธ ๋ถ€๋ถ„์—์„œ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค:

  • strconv.Atoi(r.PathValue("id")) ๋ฐ json.NewDecoder(r.Body).Decode(&t)์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋ฅผ ๋ฌด์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. โ†’ ์ž˜๋ชป๋œ ์ž…๋ ฅ์ด ๋“ค์–ด์˜ค๋ฉด 400 ์—๋Ÿฌ ๋Œ€์‹  id=0์ด ๋ฉ๋‹ˆ๋‹ค.
  • map[int]Todo๋ฅผ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. โ†’ GET /todos๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์•„์ดํ…œ์ด ๋ฌด์ž‘์œ„ ์ˆœ์„œ๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ API๊ฐ€ ์•„๋‹ˆ๋ผ ์Šฌ๋กฏ๋จธ์‹ ์ž…๋‹ˆ๋‹ค.
  • ์ž…๋ ฅ ๊ฒ€์ฆ(input validation)์ด ์—†์œผ๋ฉฐ, ๋นˆ ์ œ๋ชฉ์— ๋Œ€ํ•œ ๋ฐฉ์–ด ๋กœ์ง(empty-title guard)๋„ ์—†์Šต๋‹ˆ๋‹ค.
  • PUT ์š”์ฒญ ์‹œ ์ „์ฒด ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฎ์–ด์”๋‹ˆ๋‹ค. completed ํ•„๋“œ๋ฅผ ์ƒ๋žตํ•˜๋ฉด false๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค.

๊ณ ์ „์ ์ธ ์‹ค์ˆ˜ ์œ ๋ฐœ ์š”์†Œ(foot-guns)๋ฅผ ํ˜„๋Œ€์ ์ธ ๋ฌธ๋ฒ•์œผ๋กœ ๊ฐ์‹ธ๋†“์€ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

๐Ÿ ์‹œ๋‚˜๋ฆฌ์˜ค 2 โ€” Python REST API (ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ http.server)

์ˆœ์œ„: GPT-5.4 > Sonnet 4.6 > Gemini 3.1 Pro

๐Ÿ“„ ์ „์ฒด ํŒ๊ฒฐ๋ฌธ โ†’ gencode_python/verdict.md

์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” GPT-5.4๊ฐ€ ์••๋„์ ์œผ๋กœ 1์œ„๋ฅผ ์ฐจ์ง€ํ•œ ์œ ์ผํ•œ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

์šฐ์Šน: GPT-5.4 โ€” ๊ฐ€์žฅ ์•ˆ์ „ํ•œ ์ž…๋ ฅ ์ฒ˜๋ฆฌ

GPT-5.4๋Š” ์ง€๋ฃจํ•˜์ง€๋งŒ ์ค‘์š”ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ๋“ค์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ CORS ํ—ค๋”๋ฅผ ์†ก์ถœํ•˜๋Š” send() ํ—ฌํผ, Content-Length ๋ˆ„๋ฝ์— ๋Œ€ํ•ด ๋ฐฉ์–ด ๋กœ์ง์„ ๊ฐ–์ถ˜ read_json() (๋‹ค๋ฅธ ๋ชจ๋ธ๋“ค์€ int(None)์—์„œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค), UUID ID, createdAt ํƒ€์ž„์Šคํƒฌํ”„, OPTIONS ์š”์ฒญ์— ๋Œ€ํ•œ 204 No Content, ๊ธฐ๋ณธ ์š”์ฒญ ๋กœ๊ทธ ์–ต์ œ, ๊ทธ๋ฆฌ๊ณ  **์ง„์ •ํ•œ PATCH ์˜๋ฏธ๋ก (semantics)**์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค:

gencode_python/todo_1_gpt-5.4.py:21-24

def read_json(handler):
    size = int(handler.headers.get("Content-Length", "0"))
    raw = handler.rfile.read(size) if size else b"{}"
...

gencode_python/todo_1_gpt-5.4.py:52-61

def do_PATCH(self):
    todo = self.find_todo()
    if not todo:
...

์˜ค์ง ๋†“์นœ ๋ถ€๋ถ„๋งŒ: GET /todos/{id}๊ฐ€ ์—†๊ณ , ์ €์žฅ์†Œ๊ฐ€ ๋”•์…”๋„ˆ๋ฆฌ ๋Œ€์‹  ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค (O(n) ์กฐํšŒ).

์ฐจ์ƒ์œ„๊ถŒ: Sonnet 4.6 โ€” ๋” ๋‚˜์€ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ, ์•ฝํ•œ ์˜๋ฏธ๋ก 

Sonnet 4.6์€ ์˜ฌ๋ฐ”๋ฅธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ธ dict ์ €์žฅ์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” O(1) ์กฐํšŒ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ ์‚ญ์ œ ์‹œ ๊น”๋”ํ•œ dict.pop()์„ ๊ตฌํ˜„ํ–ˆ๊ณ  ์œ ์šฉํ•œ ์‹œ์ž‘ ๋ฐฐ๋„ˆ๊นŒ์ง€ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๋ฅผ **PUT**์œผ๋กœ ๋ ˆ์ด๋ธ”๋งํ–ˆ๋Š”๋ฐ, ์ด๋Š” RFC 7231์— ๋”ฐ๋ฅด๋ฉด ์˜๋ฏธ๋ก ์ ์œผ๋กœ ํ‹€๋ฆฝ๋‹ˆ๋‹ค (PUT์€ ์ „์ฒด ๊ต์ฒด ์˜๋ฏธ). ๋˜ํ•œ title์ด ๋ฌธ์ž์—ด์ด ์•„๋‹ ๊ฒฝ์šฐ body["title"].strip()์—์„œ ์ž ์žฌ์ ์ธ AttributeError๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœํ•˜์œ„๊ถŒ: Gemini 3.1 Pro โ€” ์ข‹์€ ์•„์ด๋””์–ด๋Š” ํ•˜๋‚˜, ํšŒ๊ท€(regressions)๊ฐ€ ๋งŽ์Œ

Gemini 3.1 Pro๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์ง„์ •์œผ๋กœ ์ข‹์€ ์•„์ด๋””์–ด๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ end_headers ์˜ค๋ฒ„๋ผ์ด๋“œ๋ฅผ ํ†ตํ•œ CORS ๊ตฌํ˜„์ธ๋ฐ, ์ด๋Š” ์„ธ ๋ชจ๋ธ ์ค‘ ๊ฐ€์žฅ DRYํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ทธ ์™ธ ๋ชจ๋“  ๊ฒƒ์€ ํšŒ๊ท€์ ์ž…๋‹ˆ๋‹ค: ์ „์—ญ ์นด์šดํ„ฐ์—์„œ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์ •์ˆ˜ ID, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋ถ€์žฌ (๋นˆ ๋ฌธ์ž์—ด "" ์ œ๋ชฉ์ด ์กฐ์šฉํžˆ ์ €์žฅ๋จ), Content-Length ๋ˆ„๋ฝ ์‹œ ์ถฉ๋Œ ๋ฐœ์ƒ (int(None) โ†’ TypeError), DELETE๊ฐ€ ์ธํ”Œ๋ ˆ์ด์Šค ์ˆ˜์ • ๋Œ€์‹  ์ „์—ญ ๋ฆฌ์ŠคํŠธ๋ฅผ ์žฌ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๋ฌธ์ œ (๋‹ค๋ฅธ ๋ชจ๋“  ์ฐธ์กฐ๋ฅผ ๊นจ๋œจ๋ฆผ), OPTIONS์— ์ž˜๋ชป๋œ ์ƒํƒœ ์ฝ”๋“œ (204 ๋Œ€์‹  200), ๊ธฐ๋ณธ stderr ๋กœ๊ทธ ์ŠคํŒธ.

๐ŸŸจ ์‹œ๋‚˜๋ฆฌ์˜ค 3 โ€” Node.js REST API (์ˆœ์ˆ˜ node:http)

์ˆœ์œ„: GPT-5.4 > Sonnet 4.6 > Gemini 3.1 Pro

๐Ÿ“„ ์ „์ฒด ํŒ๊ฒฐ โ†’ gencode_node/verdict.md

์šฐ์Šน์ž: GPT-5.4 โ€” ๊ฐ€์žฅ ๊น”๋”ํ•œ ์ถ”์ƒํ™”

GPT-5.4์˜ Node ๋ฒ„์ „์ด ์‹ค์ œ๋กœ ๋ฐฐํฌํ•  ๋งŒํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ESM import(์ตœ์‹  Node์™€ ์ผ์น˜), ์ถฉ๋Œ ๋ฐฉ์ง€ ID๋ฅผ ์œ„ํ•œ randomUUID() ์‚ฌ์šฉ, ์ƒํƒœ + CORS + content-type์„ ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ๋กœ ์ „์†กํ•˜๋Š” ๋‹จ์ผ send() ํ—ฌํผ, PATCH์— ๋Œ€ํ•œ ์—„๊ฒฉํ•œ ํ•„๋“œ๋ณ„ ํƒ€์ž… ๊ฒ€์ฆ, ๊ทธ๋ฆฌ๊ณ  ์ž˜๋ชป๋œ JSON์— ๋Œ€ํ•ด 400 (500์ด ์•„๋‹˜)์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ตœ์ƒ์œ„ try/catch๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

gencode_node/todo_1_gpt-5.4.js:42-48

if (url.pathname.startsWith('/todos/') && req.method === 'PATCH') {
  if (!todo) return send(res, 404, { error: 'todo not found' })
  const { text, completed } = await readBody(req)
...

typeof completed === 'boolean' ๊ฒ€์‚ฌ๋Š” ์žฅ๋‚œ๊ฐ ์ฝ”๋“œ๋ฅผ ์‹ค์ œ ์ œํ’ˆ ์ฝ”๋“œ์™€ ๊ตฌ๋ถ„ํ•˜๋Š” ์ข…๋ฅ˜์˜ ๋””ํ…Œ์ผ์ž…๋‹ˆ๋‹ค. Gemini๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์ „๊ฐœ ๋ฐ ์ž„์‹œ๋ฐฉํŽธ์  ์ ‘๊ทผ ๋ฐฉ์‹({ ...todos[index], ...data, id })์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ completed: "yes"๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋ชจ๋“  ์‚ฌ๋žŒ์„ ์œ„ํ•œ ์Šคํ‚ค๋งˆ๋ฅผ ๊นจ๋œจ๋ฆฌ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ฐจ์ˆœ์œ„: Sonnet 4.6 โ€” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ๋Š” ๊น”๋”ํ•˜์ง€๋งŒ ๋ถˆ๊ฐ€๋Šฅํ•จ

Sonnet 4.6์˜ Node ์ฝ”๋“œ๋Š” ๋ผ์šฐํŠธ๋ณ„ JSON ํŒŒ์‹ฑ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์ข‹๊ณ , DELETE ์‹œ์— ์ •ํ™•ํžˆ 204 No Content๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ CORS ํ—ค๋”๋ฅผ ์ „ํ˜€ ์ „์†กํ•˜์ง€ ์•Š์•„ ํ”„๋ก์‹œ ์—†์ด ๋ธŒ๋ผ์šฐ์ € ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. TODO ์•ฑ์˜ ๊ด€์ ์—์„œ ์ด๋Š” ์น˜๋ช…์ ์ธ ์ œํ’ˆ ๊ฒฐํ•จ์ž…๋‹ˆ๋‹ค.

์ตœํ•˜์œ„: Gemini 3.1 Pro โ€” ์žฅํ™ฉํ•˜๊ณ  ์˜๋ฏธ์ ์œผ๋กœ ํ‹€๋ฆผ

Go์™€ ๊ฐ™์€ ํŒจํ„ด์„ ๋ณด์ž…๋‹ˆ๋‹ค: PATCH๊ฐ€ ์˜๋„๋œ ๊ณณ์— PUT์ด ์‚ฌ์šฉ๋˜์—ˆ๊ณ , ์ž˜๋ชป๋œ JSON์€ 400 ๋Œ€์‹  500์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์ž…๋ ฅ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์—†๊ณ , ์ œ๋ชฉ์— trim()์ด ์—†์–ด (" "๋„ ์œ ํšจํ•œ TODO์ž„), ๊ทธ๋ฆฌ๊ณ  ESM import ๋Œ€์‹  require๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” 2025๋…„ ๋ฒ„์ „์˜ Node ์˜ˆ์ œ๋กœ๋Š” ์–ด์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ์ข‹์€ ์ ์€ ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค: for await (const chunk of req)๋Š” ์„ธ ๊ฐ€์ง€ ์ค‘ ๊ฐ€์žฅ ๊ด€์šฉ์ ์ธ ๋ฐ”๋”” ๋ฆฌ๋”์ž…๋‹ˆ๋‹ค. ์ž‘์€ ์Šน๋ฆฌ, ๋งŽ์€ ํŒจ๋ฐฐ์ž…๋‹ˆ๋‹ค.

โš›๏ธ ์‹œ๋‚˜๋ฆฌ์˜ค 4 โ€” React + TypeScript UI

์ˆœ์œ„: Sonnet 4.6 > Gemini 3.1 Pro > GPT-5.4

๐Ÿ“„ ์ „์ฒด ํŒ๊ฒฐ๋ฌธ โ†’ gencode_reactjs/verdict.md

์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋ชจ๋“  ์ฐจ์›์—์„œ ๋‹จ ํ•˜๋‚˜์˜ ์Šน์ž๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ํฅ๋ฏธ๋กœ์šด ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค. ๊ฐ ๋ชจ๋ธ์€ ๋‹ค๋ฅธ ๋ชจ๋ธ์ด ๋ถ€์กฑํ–ˆ๋˜ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณด์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

์ข…ํ•ฉ ์šฐ์Šน์ž: Sonnet 4.6 โ€” ์ตœ๊ณ ์˜ ์•„ํ‚คํ…์ฒ˜ ๋ฐ ๊ธฐ๋Šฅ ์„ธํŠธ

Sonnet 4.6์€ ๊ฐ€์žฅ ์™„์ „ํ•œ TODO ๊ธฐ๋Šฅ์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค: ์ถ”๊ฐ€(add), ํ† ๊ธ€(toggle), ์‚ญ์ œ(delete), ํ•„ํ„ฐ(์ „์ฒด/ํ™œ์„ฑ/์™„๋ฃŒ)(filter (all/active/done)), ๋‚จ์€ ํ•ญ๋ชฉ ์นด์šดํ„ฐ(items-left counter), ๋นˆ ์ƒํƒœ(empty state), ๊ทธ๋ฆฌ๊ณ  ์™„๋ฃŒ ํ•ญ๋ชฉ ์ง€์šฐ๊ธฐ(clear-completed). ๋˜ํ•œ ํ•ธ๋“ค๋Ÿฌ(handlers)๋ฅผ ์ž‘์€ ์ด๋ฆ„์ด ์ง€์ •๋œ ํ•จ์ˆ˜(named functions)๋กœ ๋ถ„๋ฆฌํ•˜์˜€๊ณ , ๋ชจ๋“  ์Šคํƒ€์ผ๋ง์„ ๋‹จ์ผ s ๊ฐ์ฒด๋กœ ๋ชจ์•„ JSX๊ฐ€ ์Šคํƒ€์ผ๋ง ๋…ธ์ด์ฆˆ๊ฐ€ ์•„๋‹Œ ๊ตฌ์กฐ์ฒ˜๋Ÿผ ์ฝํžˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•„ํ„ฐ ๋กœ์ง์€ ์ƒํƒœ(state)๊ฐ€ ์•„๋‹Œ ํŒŒ์ƒ๋œ ๊ฐ’(derived value)์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ๋Š”๋ฐ, ์ด๋Š” React์˜ ๊ด€์šฉ์ ์ธ(idiomatic) ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค:

gencode_reactjs/todo_2_claude-sonet-4.6.tsx:10-26

const add = () => {
  const text = input.trim();
  if (!text) return;
...

AI ์ž๋™ ์ƒ์„ฑ ์ฝ˜ํ…์ธ 

๋ณธ ์ฝ˜ํ…์ธ ๋Š” Dev.to AI tag์˜ ์›๋ฌธ์„ AI๊ฐ€ ์ž๋™์œผ๋กœ ์š”์•ฝยท๋ฒˆ์—ญยท๋ถ„์„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์› ์ €์ž‘๊ถŒ์€ ์›์ €์ž‘์ž์—๊ฒŒ ์žˆ์œผ๋ฉฐ, ์ •ํ™•ํ•œ ๋‚ด์šฉ์€ ๋ฐ˜๋“œ์‹œ ์›๋ฌธ์„ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.

์›๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
0

๋Œ“๊ธ€

0