
Claude Code로 페르소나를 설정하면 TypeScript는 어떻게 변하는가: 타입, 명명, 코드량 관점의 정량 검증
요약
Claude Code에 시니어/신입, 엄격/친근함의 4가지 페르소나를 부여했을 때 TypeScript 코드 작성 방식의 변화를 정량적으로 분석한 케이스 스터디입니다. 페르소나에 따라 코드량, 타입 사용법, 주석 스타일 및 작성 패턴에서 유의미한 차이가 발생함을 확인했습니다.
핵심 포인트
- 페르소나 설정 시 코드량 차이가 최대 약 4.6배까지 발생함
- 신입/친근함 페르소나에서 'any' 타입 사용이 관측됨
- 시니어는 배열 메서드를, 신입은 for 루프를 선호하는 경향을 보임
- 성격 축에 따라 TSDoc 중심 또는 친근한 말투의 주석 스타일 차이 발생
- 라이브러리 선정(zod 등)은 페르소나와 관계없이 일관됨
Claude Code를 업무에서 사용하다 보면 문득 궁금한 점이 생긴다.
"실제 인간처럼 AI에게도 성격을 부여하면 코드 작성 방식도 변할까?"
CLAUDE.md에 프로젝트 방침을 작성하는 운용 방식은 일반적이지만,
**페르소나(Persona, 인격 설정)**를 이용하여 운용하는 팀이나 기사는 그리 많이 보이지 않는다.
이에 본 기사에서는 Claude Code에 대해 **「시니어 / 신입」 × 「엄격 / 친근함」**의 4가지 종류의 페르소나를 주입하고, 동일한 과제를 TypeScript로 풀게 하여 결과를 비교했다.
관찰 포인트는 다음과 같다.
코드량・장황함 (행수, 함수 수, 중첩 깊이)
명명(Naming)・주석 스타일 (변수명의 길이, 주석의 말투)
타입(Type) 사용법 (any의 출현, interface vs type, 제네릭(Generic)의 밀도) ← TS만의 관점
작성 방식의 선택 (for vs 배열 메서드, 화살표 함수 vs function, async/await vs .then)
"왠지 다를 것 같다"라는 느낌을 "숫자로 이렇게 다르다"까지 가져가는 것이 본 기사의 목표이다.
⚠️ 주의: 본 기사는 한정된 시행 횟수에 기반한 케이스 스터디입니다. LLM의 출력에는 변동성이 있으므로, 결론은 "절대적인 경향"이 아닌 "한 사례"로 읽어 주시기 바랍니다. 재현성에 대해서는 「실험의 한계」 섹션에서 다룹니다.
페르소나를 주입했을 때,
3개 태스크 합계 코드량은 최대 약 4.6배의 차이가 발생했다 (신입×친근함: 456%, 시니어×엄격: 108%, Baseline=100%)
any의 출현은 신입×친근함에서만 관측되었으며, 그 외에는 제로(타입 레벨 포함)
작성 방식은 시니어=배열 메서드, 신입=for 루프 vs 배열 메서드 for/reduce로 명확히 나뉘었다
주석의 말투는 성격 축(엄격/친근함)에 따라 뚜렷하게 갈렸다 (엄격=TSDoc 중심, 친근함="미래의 독자에게" 유형의 본문 주석)
라이브러리 선정은 불변하지 않았다: Baseline은 망설임 없이 zod를 도입했지만, 4가지 페르소나 모두가 "의존성 추가를 피하고 수동 검증(hand-written validation)을 수행"하는 것을 선택했다
페르소나에 의한 "과잉 반응": 신입×친근함은 사양 외의 unhandledRejection 핸들러를 추가하고, 신입×엄격은 1행 함수에 대해서도 template literal type을 작성하는 등 예상치 못한 파생이 빈번하게 발생했다
다음의 5가지 패턴을 준비했다. 프롬프트는 재현성을 위해 전문을 공개한다.
CLAUDE.md 자체를 두지 않은 순수 상태.
# 당신에 대하여
당신은 10년 이상의 경력을 가진 시니어 TypeScript 엔지니어입니다.
팀원들에게는 따뜻하게 대하며, 리뷰에서는 "왜 그렇게 했는지"를
...
# 당신에 대하여
당신은 10년 이상의 경력을 가진 시니어 TypeScript 엔지니어입니다.
타협을 허용하지 않으며, 명명・설계・타입・에러 핸들링(Error Handling) 모두에 엄격한 기준을 가집니다.
...
# 당신에 대하여
당신은 입사 1년 차의 주니어 TypeScript 엔지니어입니다.
배운 것을 정성스럽게 주석으로 남기며, 자신이 나중에 읽어도 알 수 있도록 작성합니다.
...
# 당신에 대하여
당신은 입사 1년 차의 주니어 TypeScript 엔지니어이지만,
베스트 프랙티스(Best Practice)를 따르는 것에 강한 집착을 가지고 있습니다.
...
페르소나가 작용하는 레이어를 바꾸기 위해 3단계로 준비했다.
| # | 태스크 | 예상되는 차이 발생 가능성 |
|---|---|---|
| T1 | snake_case → camelCase 변환 함수 | 명명・주석・타입 주석・배열 처리 |
| T2 | JSON API를 호출하여 정형화하는 CLI (Node.js) | async/await, 에러 핸들링, 타입 정의의 입도 |
| T3 | 간이 TODO REST API (Hono) | 파일 분할, 미들웨어 설계, 타입 공유 |
T3에서 Hono를 채택한 것은 현대적인 프레임워크에서의 관찰 사례를 남기기 위해서이다.
Express를 선택하지 않는 것 자체가 "공격적인 선택"이 되므로, 페르소나가 선정에 영향을 미치는지도 관찰 포인트가 된다.
(실험에서는 Hono를 지정하여 내부 구현의 차이점을 확인한다).
| 카테고리 | 지표 |
|---|---|
| 코드량 | 총 행 수 (LOC), 주석 행 수, 주석 비율 |
| 타입 | any 출현 횟수, as 캐스팅 횟수, interface / type 비율, 제네릭 (Generics) 사용 위치 |
| 작성 방식 | for vs map/filter/reduce 비율, 화살표 함수 (Arrow function) vs function 비율 |
| 비동기 | async/await vs .then 비율, try/catch 수 |
| 방어 | 입력 검증 (Input validation) 위치 수, 조기 반환 (Early return) 수 |
실험의 편차를 줄이기 위해 다음 사항을 고정했다.
- 모델: Claude Sonnet 4.6 (Claude Code 경유)
- TypeScript 설정:
tsconfig.json에서strict: true,noUncheckedIndexedAccess: true를 설정하고 나머지는 기본값 사용 - 포맷팅 도구: Prettier / ESLint는 사용하지 않음 (페르소나의 순수한 출력을 보기 위함)
- Node.js: v22 LTS
- 의존성: T2/T3에 필요한 최소한의 라이브러리만 포함 (Hono,
undici등) - 생성 방식: 각 패턴 × 각 태스크별로 1회씩 생성 (변동성에 대해서는 '실험의 한계'에서 논의)
- 프롬프트: "Tn의 코드를 작성해 주세요"라고만 입력. 추가 제약 조건은 주지 않음
function snakeToCamel(input: string): string {
return input.replace(/_([a-zA-Z0-9])/g, (_, char: string) => char.toUpperCase());
}
짧은 함수 선언, 주석 없음. function을 사용함. 사양(Specification)은 필요 충분함.
/**
* snake_case 문자열을 camelCase로 변환한다.
* ...
*/
27행. Baseline보다 사양이 늘어남 (앞뒤 언더스코어 보존, 연속 언더스코어 대응). 주석은 미래의 독자를 위해 "왜 그렇게 했는지"를 작성하는, 전형적인 시니어(Senior)의 태도.
export const snakeToCamel = (input: string): string =>
input.replace(/_([a-z0-9])/g, (_, c: string) => c.toUpperCase());
2행. 주석 제로. 화살표 함수의 식(Expression) 형식 ( { return ... } 조차 생략). Baseline보다 더욱 짧아지는 현상. "불필요한 주석은 쓰지 않는다"가 극단에 달하면 이 정도로 줄어듦.
// snake_case 문자열을 camelCase로 변환하는 함수
// 예: "user_name" -> "userName"
// "first_name_last_name" -> "firstNameLastName"
// ...
85행. any로 인자를 받고, null/undefined/타입 체크를 수행하며, split을 for로 돌리고, try/catch로 감싸며, console.warn/error로 기록함 ── "실무에서 본 적 있는 신입의 코드"가 그대로 튀어나옴. 함수명도 convertSnakeCaseToCamelCase로 매우 김. Baseline(3행)의 약 28배.
/**
* 文字列が `snake_case` 形式から `camelCase` 形式に変換された型を表します。
*
...
```ts
* type Result = SnakeToCamelCase<"hello_world">; // "helloWorld"
* ```
*/
export type SnakeToCamelCase<S extends string> =
S extends `${infer Head}_${infer Tail}`
...
```ts
* snakeToCamelCase("hello_world"); // "helloWorld"
* snakeToCamelCase("user_id"); // "userId"
* snakeToCamelCase("foo_bar_baz"); // "fooBarBaz"
* snakeToCamelCase("already_camel"); // "alreadyCamel"
* snakeToCamelCase(""); // ""
* ```
*/
export function snakeToCamelCase<S extends string>(input: S): SnakeToCamelCase<S> {
const segments: readonly string[] = input.split("_`);
...
53행. T1에서 제네릭과 template literal type이 나온 것은 예상 밖이었다. SnakeToCamelCase<S extends string>
타입까지 만들고, 반환값을 as SnakeToCamelCase<S>
으로 캐스팅하고 있다. '교과서대로'라는 집착이 과도한 설계로 변하기 쉬운 좋은 예시.
| 패턴 | LOC | 주석 행 | 식별자 평균 길이 | any |
|---|---|---|---|---|
| Baseline | 3 | 0 | 짧음 (5~7) | 0 |
| ... | ||||
| 관찰: '시니어×엄격'은 Baseline보다 짧아졌다. '신입×친근'은 Baseline의 약28배. 같은 한 줄 함수 요청에서 이 차이는 예상 이상이었다. |
URL을 인수로 받아, fetch로 GET하고, JSON을 pretty-print하며, 에러 시 비제로 exit한다.
#!/usr/bin/env node
const main = async (): Promise<void> => {
const url = process.argv[2];
...
41행. async function main()
으로 묶고, 3단 try/catch.
주석은 없다. unknown의 올바른 사용법.
#!/usr/bin/env node
// JSON API를 호출하여 pretty-print만 하는 얇은 CLI.
// 사양이 단순할 때는, 의존성도 추상화도 추가하지 않는 것이 읽기 좋다.
...
40행. die
헬퍼로 실패 경로를 집약한다. 최상위 레벨 await을 망설임 없이 사용한다.
주석은 '왜 이 설계인지'만 적는다. Baseline(41행)과 거의 같은 규모를, 사고의 흔적을 남기면서 유지하고 있다는 점에 주목한다.
const [, , url] = process.argv;
if (!url) {
console.error("usage: cli.ts <url>");
...
26행. die
같은 추상화조차 만들지 않는다. Baseline(41행)의 약 2/3.
그래도 URL의 사전 파싱 검증만은 넣어온다 (엄격).
너무 길어서 일부 발췌 (전체 124행). 초반부 방어 코드가 상징적이다.
process.on("unhandledRejection", (reason: any) => {
console.error("예상치 못한 에러(unhandledRejection)가 발생했습니다:", reason);
process.exit(1);
...
요청되지 않은 unhandledRejection / uncaughtException
핸들러를 추가해 온다.
'팀에 폐를 끼치지 않도록'이 역효과를 낸 예시. any는 5개 이상, try/catch
는 5중 중첩(nesting)에 해당한다.
155행. 가장 큰 특징은 ExitCode enum과 함수 분할에 있다.
const ExitCode = {
Success: 0,
InvalidArguments: 1,
...
#!/usr/bin/env node를 JSDoc의 @file 블록으로 감싸고, 함수 하나에 @param/@returns/@remarks/@throws를 풀(full)로 기술.
테스트 용이성(testability)을 위해
process.exit
을 main의 반환값(return value)을 통해 분리하는 철저함. 사양(80행이면 작성 가능)에 대한 열정이 과도하다.
| 패턴 | LOC | 주석 행 | any | try/catch 수 | 함수 분할 |
|---|---|---|---|---|---|
| Baseline | 41 | 0 | 0 | 3 | main 1개 |
| A | 40 | 17 | 0 | 1 | die 1개 + top-level |
| B | 26 | 0 | 0 | 2 | top-level만 |
| C | 124 | 30+ | 8+ | 5+ | main + process 핸들러 |
| D | 155 | 40+ | 0 | 4 | 6개 함수 + ExitCode 정의 |
이 부분이 가장 차이가 났다. zod를 넣을지, 파일을 어떻게 나눌지, 검증(validation)을 어떻게 작성할지.
src/types.ts // Todo 타입만
src/store.ts // Map 기반의 스토어
src/app.ts // Hono + zod로 라우팅
...
zod와 @hono/zod-validator를 채택
const createSchema = z.object({
title: z.string().min(1).max(200),
completed: z.boolean().optional(),
...
store.ts를 함수군(모듈)으로 작성한다. 검증은 zod를 넣지 않고 수동으로 구현하고 있다.
// src/validation.ts에서 발췌
// 외부 라이브러리를 늘리고 싶지 않으므로 수동 검증.
// Zod를 넣을 정도의 규모는 아니라는 판단. 스키마가 늘어나면 재검토함.
...
라우팅 계층에서도 Location 헤더 부여 등 REST의 관례를 적용
app.post("/todos", async (c) => {
const body: unknown = await c.req.json().catch(() => undefined);
if (body === undefined) return c.json({ error: "invalid JSON body" }, 400);
...
판단 근거("Zod를 넣을 정도는 아니다", "Location은 REST의 관례다")가 곳곳에 적혀 있다.
class TodoStore + # 프라이빗 필드(private field). zod 없음. 주석은 극도로 적음
// src/store.ts에서 발췌
export class TodoStore {
readonly #todos = new Map<string, Todo>();
...
app.ts도 짧다
export const createApp = (store: TodoStore = new TodoStore()): Hono => {
const app = new Hono();
app.get("/todos", (c) => c.json(store.list()));
...
의존성 주입(Dependency Injection)을 위한 인자(store = new TodoStore())만은 넣어두는 것이 시니어답다.
모든 패턴 중 압도적인 최대치. app.ts 단독으로 285행에 달한다. 모든 핸들러가 이중 try/catch로 감싸져 있다.
// src/app.ts에서 발췌 (POST /todos만)
honoApplication.post("/todos", async (honoContext: AnyHonoContext) => {
try {
...
주목해야 할 점은, Hono의 타입을 포기하고 any로 회피하는 부분이 있다는 것이다.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AnyHonoContext = Context<any, any, any>;
페르소나에 너무 충실하다.
5가지 패턴 중 디렉토리가 가장 세밀하게 나누어져 있다.
src/types/todo.ts // 타입 정의 (readonly + TSDoc 완비)
src/repositories/todo-repository.ts // class TodoRepository
src/validators/todo-validator.ts // validateCreateTodoInput 등
...
tsconfig.json까지 직접 작성하며, exactOptionalPropertyTypes나 noImplicitOverride를 활성화한다.
{
"compilerOptions": {
"strict": true,
...
리포지토리 패턴 (Repository Pattern) + 검증층 (Validator Layer) + 라우터층 (Router Layer) + 애플리케이션층 (Application Layer)으로, 교과서적인 4계층 구성이다.
각 클래스·함수에 @param / @returns / @remarks가 모두 붙는다. Number.parseInt로 PORT를 읽으면서 범위를 벗어나는 값을 걸러내는 등, 과도한 검증 (Validation)을 수행한다.
| 패턴 | LOC | 파일 수 | any | Zod 사용 | 주석 비율 | 레이어 수 |
|---|---|---|---|---|---|---|
| Baseline | 139 | 4 | 0 | ✔ | 낮음 | 3 (types/store/routes) |
| ... | 4 (types/repo/validator/routes) |
T1+T2+T3를 합산한 총 LOC (실측)
| 패턴 | T1 | T2 | T3 | 합계 LOC | Baseline 대비 |
|---|---|---|---|---|---|
| Baseline | 3 | 41 | 139 | 183 | 100% |
| A: 시니어 × 프렌들리 | 27 | 40 | 212 | 279 | 152% |
| B: 시니어 × 엄격 | 2 | 26 | 169 | 197 | 108% |
| C: 신입 × 프렌들리 | 85 | 124 | 625 | 834 | 456% |
| D: 신입 × 엄격 | 53 | 155 | 513 | 721 | 394% |
시각화
Baseline: ████████ (100%)
A 시니어×프렌들리: ████████████ (152%)
B 시니어×엄격: █████████ (108%)
...
「신입」 페르소나는 코드량이 4배 전후로 불어났다.
가설에서는 「신입×프렌들리: 170%, 신입×엄격: 155%」로 예측했으나, 실측치는 그 약 2.5~2.7배였다. LLM에 「주니어 (Junior)」 역할을 부여하면, 상상 이상으로 「정중한 방어 코드」, 「설명적인 명명 (Naming)」, 「장황한 계층 분리」로 치닫는다.
| 패턴 | any 출현 | as 캐스트 | 제네릭 (Generics) 사용 |
|---|---|---|---|
| Baseline | 0 | 0 | 필요한 곳에 사용 |
| A: 시니어 × 프렌들리 | 0 | 1 (명확한 의도) | 절제됨 |
| ... | 9+ (any 타입 주석 + @ts-ignore 급의 Context<any,any,any>) | 0 | 사용 안 함 |
| D: 신입 × 엄격 | 0 | 1 (반환값 타입 지정 보조) | 과도함 (T1에서 template literal type을 새로 만듦) |
특기할 만한 점은 D가 T1(작은 함수)에 대해서도 SnakeToCamelCase<S extends string>라는 타입 레벨 변환을 도입했다는 것이다. 「엄격하게 작성하라」는 지시를 문자 그대로 받아들이면 이렇게 된다.
| 패턴 | for 사용 | 배열 메서드 (Array methods) | 화살표 함수 (Arrow function) | 클래스 (Class) 사용 |
|---|---|---|---|---|
| Baseline | ✘ | ✔ (Array.from + sort) | 부분적 | ✘ |
| A | ✘ | ✔ | ✔ (모듈 함수) | ✘ |
| B | ✘ | ✔ | ✔ (모듈 함수) | ✔ (class TodoStore) |
| C | ✔ (T1에서 for 부활) | △ | △ | ✘ |
| D | ✘ | ✔ (reduce) | △ | ✔ (class TodoRepository) |
신입×친근함(Friendly)은 배열 메서드를 사용할 수 있는 상황임에도 for를 선택하는 경향.
| 패턴 | try/catch 수 (T2) | async/await | 에러 핸들러 추가 |
|---|---|---|---|
| Baseline | 3 | ✔ | ✘ |
| A | 1 (die 헬퍼로 집약) | ✔ | ✘ |
| B | 1 | ✔ | ✘ |
| C | 5 이상 | ✔ | unhandledRejection / uncaughtException을 독자적으로 추가 |
| D | 4 (카테고리별로 분리) | ✔ | main의 .then(_, _)에서 집약 |
사전 가설에서는 "라이브러리 선택은 페르소나에 의존하지 않는다"라고 생각했으나, T3에서 모든 페르소나가 Baseline과 다른 선택을 했다.
| 패턴 | T3의 검증 (Validation) 계층 |
|---|---|
| Baseline | zod + @hono/zod-validator |
| A | 수동 작성 (isNonEmptyString 등의 자체 가드) — "Zod를 도입할 정도의 규모는 아니다"라고 명시 |
| B | 수동 작성 (isRecord + 개별 가드) |
| C | 수동 작성 ("사실은 zod를 쓰고 싶지만..."이라는 TODO 주석) |
| D | 수동 작성 (validateTitle / validateDescription을 분리) |
페르소나를 설정하면, 의존성 추가에 대한 보수적인 편향(Bias)이 강해진다.
이는 표층적인 스타일이 아니라 설계 판단에 관한 이야기이며, 당초의 "페르소나는 표층에만 영향을 미친다"라는 가설에 대한 반례가 된다.
A (친근함): "미래의 독자에게 보내는 편지"를 실천 ──
// 사양이 단순할 때는 의존성도 추상화도 추가하지 않는 것이 읽기 편하다
B (엄격함): 애초에 주석을 쓰지 않음
C (친근함): 일본어로 "~라고 생각한다", "~인 것 같다" 등이 섞임 ──
// 개수도 함께 반환해 주면, 프론트엔드에서 페이지네이션을 할 때 편리함
D (엄격함): TSDoc을 기계적으로 풀 장착 (@param / @returns / @remarks / @throws / @typeParam / @example)
페르소나에서 관측된 행동의 대부분은 규약(Convention)으로 직접 작성해도 재현할 수 있을 것이다.
다음 단계로, 페르소나 대신 다음과 같은 규약만을 작성한 CLAUDE.md를 제공하고, B (시니어×엄격함)의 출력과 비교하는 실험을 예정하고 있다.
# 코딩 규약
- 변수명은 짧게, 문맥으로 의미를 파악할 수 있는 범위 내에서 생략한다
- 주석은 TSDoc 형식만 사용. 본문 주석은 원칙적으로 금지
...
가설
- LOC,
any수, 주석 스타일은 B에 상당히 가까워진다 - 단, 규약에 다 적을 수 없는 판단의 미묘한 차이 ("Zod를 도입할 정도의 규모는 아니다"와 같은 추상적인 태도)는 나타나기 어렵다
검증은 다음 기사로 미루겠다.
사전 가설에서는 "페르소나는 표층 스타일에만 영향을 미치며, 라이브러리 선정이나 데이터 구조와 같은 설계 판단은 불변한다"라고 생각했다.
하지만 실측 결과:
- T3에서 모든 페르소나가 Zod를 버렸다 ── Baseline은 망설임 없이
zod를 도입했으나, 4개의 페르소나 모두 수동 검증(Manual Validation)을 선택했다. - 파일 분할의 깊이가 페르소나에 따라 달라졌다 ── D는
repositories/,validators/,routes/의 4계층으로 나누었고, B는 최소한의 3계층, C는 계층은 얕지만 각 계층이 비대해졌다. - 클래스(Class) vs 함수 모듈(Function Module)의 선택도 페르소나에 의존했다 ── B/D는
class, A는 함수 모듈, Baseline과 C는 그 중간 형태를 보였다.
페르소나는 표층 스타일(Surface Style)에 머물지 않고, **「의존성 추가에 대한 보수성」, 「추상화의 무게」, 「OOP/함수형 선호도」**와 같은 설계 판단에도 명확하게 영향을 미친다. 이는 「인격 설정은 코스메틱(Cosmetic)일 뿐이다」라는 소박한 가정에 대한 반례다.
신입 페르소나는 코드량을 약 4배로 부풀리지만, 비대해진 내용물을 살펴보면 다음과 같다.
- C:
unhandledRejection/uncaughtException핸들러를 요청받지 않았음에도 추가 - C:
Context<any, any, any>를eslint-disable과 함께 도입 - D: T1(한 줄 함수)에 template literal type을 신설
- D:
ExitCodeenum을 T2의 CLI에 도입 - D:
PORT의 범위 체크(0~65535)를 임의로 구현
즉, 「친절함」, 「교과서적임」이라는 라벨은 사양 외 기능의 추가 트리거가 되기도 한다. 코드 리뷰 교재로서 「신입이 저지르기 쉬운 오버엔지니어링 (Over-engineering)」 샘플 생성에는 유용해 보인다.
실용적인 관점에서 가장 컴팩트하고 정확한 것은 B: 시니어 × 엄격이다. T1=2행, T2=18행으로 Baseline보다 더욱 짧다. T3는 169행으로 Baseline(139행)을 약간 상회하지만, 이는 Baseline이 zod를 채택하여 검증(Validation) 계층을 압축한 것에 반해, B는 의존성을 늘리지 않고 직접 손으로 작성(Hand-written)했기 때문이다. 직접 작성하면서도 Baseline과 비슷한 규모로 정리했다고 해석하는 것이 타당하며, 실용적인 면에서는 오히려 높은 평가를 줄 만하다. any 제로, as 제로, 불필요한 추상화 없음. 짧은 프롬프트로 이 정도 결과가 나오는 것은 비용 대비 효율이 높다.
같은 「엄격함」이라도, D(신입 × 엄격)는 B의 약 4배에 달하는 코드량이 되었다. 차이의 정체는 다음과 같다.
- 경험은 「무엇을 쓰지 않을 것인가」를 알고 있지만, 엄격함은 「쓸 수 있는 한 다 쓴다」 쪽으로 기울기 쉽다.
- 신입 페르소나는 TSDoc의 필드를 모두 채우지만, 시니어는 「쓸 가치가 있는 곳에만」 작성한다.
「엄격함」만을 CLAUDE.md에 적으면 D에 가까워지고, 「시니어」만을 적으면 과잉 설계 회피 쪽으로 기울며, 두 가지를 조합해야 비로소 B와 같이 짜임새 있는 코드에 도달한다.
실험을 통해 드러난 것은 다음과 같다.
CLAUDE.md를 활용하는 것은 비용 대비 효율이 극도로 높다. 약 150자 정도의 작성만으로 LOC(Lines of Code)를 대폭 줄일 수 있다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기