<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel xmlns:content="http://purl.org/rss/1.0/modules/content/"><title>요즘IT » 개발 » 피드</title><link>https://yozm.wishket.com/magazine/list/develop</link><description>쉽고 재미있는 IT 이야기를 다룹니다. 업계 전문가들이 전하는 IT 트렌드, 기획, 디자인, 개발, 인사이트 소식들이 가득합니다.</description><atom:link href="https://yozm.wishket.com/magazine/list/develop/feed/" rel="self"/><language>ko-kr</language><lastBuildDate>Wed, 22 Apr 2026 09:34:33 +0000</lastBuildDate><item><title>유니온 타입에서 막히는 순간, 타입 좁히기가 필요하다</title><link>https://yozm.wishket.com/magazine/detail/3719</link><description>타입스크립트를 쓰다 보면 하나의 변수가 여러 타입을 가질 수 있는 상황을 자주 만나게 됩니다. 함수의 매개변수가 string일 수도, number일 수도 있고, API 응답이 성공 데이터일 수도, 에러 객체일 수도 있습니다. 이처럼 다양한 가능성을 안고 있는 변수를 다룰 때, 타입스크립트는 꽤 보수적으로 반응합니다. 해당 변수가 “어떤 타입인지 아직 모르겠으니” 특정 타입 전용 메서드를 사용하지 못하도록 막아버리는 것입니다. 이 문제를 해결하는 방법이 바로 타입 좁히기(Type Narrowing)입니다. 타입 좁히기란 조건문 등을 활용해 넓은 타입을 더 구체적인 타입으로 확정해가는 과정을 말합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3719</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;타입스크립트를 쓰다 보면 하나의 변수가 여러 타입을 가질 수 있는 상황을 자주 만나게 됩니다. 함수의 매개변수가 string일 수도, number일 수도 있고, API 응답이 성공 데이터일 수도, 에러 객체일 수도 있습니다. 이처럼 다양한 가능성을 안고 있는 변수를 다룰 때, 타입스크립트는 꽤 보수적으로 반응합니다. 해당 변수가 “어떤 타입인지 아직 모르겠으니” 특정 타입 전용 메서드를 사용하지 못하도록 막아버리는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 문제를 해결하는 방법이 바로 타입 좁히기(Type Narrowing)입니다. 타입 좁히기란 조건문 등을 활용해 넓은 타입을 더 구체적인 타입으로 확정해가는 과정을 말합니다. 복잡하게 들릴 수 있지만, 사실 우리가 자바스크립트에서 이미 자연스럽게 하고 있던 방어적 코딩 패턴을 타입스크립트가 인식하고 활용해주는 것에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 타입 좁히기가 왜 필요한지부터 실무에서 자주 쓰이는 핵심 패턴까지 단계별로 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul&gt;&lt;li&gt;타입 좁히기란 조건문 등을 활용해 넓은 타입을 더 구체적인 타입으로 확정해가는 과정을 말합니다.&lt;/li&gt;&lt;li&gt;유니온 타입의 변수에는 모든 구성 타입이 공통으로 갖고 있는 프로퍼티와 메서드만 사용할 수 있기 때문입니다.&lt;/li&gt;&lt;li&gt;타입 가드는 조건문 등을 활용하여 타입의 범위를 좁혀나가는 표현들을 말하며 실무에서 자주 쓰이는 패턴입니다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;타입 좁히기가 필요한 이유&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;타입 좁히기가 왜 필요한지 이해하려면, 먼저 유니온 타입의 한계부터 살펴봐야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 유니온 타입만으로는 부족하다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;유니온 타입은 여러 타입 중 하나가 될 수 있는 변수를 정의할 때 사용합니다. 예를 들어, 문자열과 숫자를 모두 받을 수 있는 함수를 만든다고 해봅시다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function printValue(value: string | number) {
  console.log(value.toUpperCase()); // ❌ 오류
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 코드는 에러가 발생합니다. value가 string일 수도, number일 수도 있기 때문에 타입스크립트는 string 전용 메서드인 toUpperCase()를 호출하지 못하게 막는 것입니다. 반대로 number 전용 메서드인 toFixed()도 마찬가지로 쓸 수 없습니다. 유니온 타입의 변수에는 모든 구성 타입이 공통으로 갖고 있는 프로퍼티와 메서드만 사용할 수 있기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;그렇다면 어떻게 해야 할까요? 이 변수가 string인지 number인지를 먼저 확인하고, 확인된 상태에서 해당 타입의 기능을 사용하면 됩니다. 바로 이것이 타입 좁히기입니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 조건문으로 타입을 좁히면?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;아래처럼 typeof를 사용한 조건문을 추가해 봅시다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function printValue(value: string | number) {
  if (typeof value === "string") {
    console.log(value.toUpperCase()); // ✅ string 타입으로 확정
  } else {
    console.log(value.toFixed(2)); // ✅ number 타입으로 확정
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;if 블록 안에서 typeof value === "string" 조건을 통과했다면, 타입스크립트는 해당 블록 안의 value를 string 타입으로 확정합니다. else 블록에서는 string이 아닌 나머지, 즉 number 타입으로 확정됩니다. 별도의 타입 단언(as)을 쓰지 않아도, 조건문만으로 타입을 안전하게 구분할 수 있는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3719/%EA%B7%B8%EB%A6%BC1__3_.png"&gt;&lt;figcaption&gt;&amp;lt;출처 : 작가, Claude AI 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 조건문 등을 활용하여 타입의 범위를 좁혀나가는 표현들을 타입 가드(Type Guard)라고 부릅니다. 타입 좁히기를 실현하는 구체적인 도구가 바로 타입 가드인 셈입니다. 이제 실무에서 자주 쓰이는 타입 가드 패턴들을 하나씩 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;타입 좁히기 기본 패턴&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;타입스크립트에서 제공하는 타입 가드는 여러 종류가 있습니다. 상황에 따라 적합한 패턴이 다르기 때문에, 각 패턴의 특성과 사용 시점을 정리해두면 유용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) typeof 가드&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;typeof는 가장 기본적이고 자주 사용되는 타입 가드입니다. 자바스크립트의 typeof 연산자가 반환하는 문자열을 기준으로 타입을 구분합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function formatInput(input: string | number | boolean) {
  if (typeof input === "string") {
    return input.trim();
  } else if (typeof input === "number") {
    return input.toLocaleString();
  } else {
    return input ? "참" : "거짓";
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;typeof는 "string", "number", "boolean", "undefined", "object", "function", "symbol", "bigint" 중 하나를 반환합니다. 주의할 점은 typeof null이 "object"를 반환한다는 것입니다. 따라서 null과 객체를 동시에 다루는 경우에는 typeof만으로는 정확하게 구분하기 어렵습니다. null 체크를 별도로 추가하거나, 다른 타입 가드를 함께 사용해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function process(value: string | null) {
  if (typeof value === "string") {
    return value.toUpperCase(); // ✅ null이 아님이 보장됨
  }
  return "빈 값";
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;typeof는 원시 타입을 구분할 때 유용하지만, 객체의 구체적인 종류(Date인지, Array인지, 커스텀 클래스인지)를 구분하기에는 적합하지 않습니다. 객체는 typeof로 확인하면 전부 "object"가 반환되기 때문입니다. 이런 경우에는 다음에 소개할 instanceof를 사용해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) instanceof 가드&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;instanceof는 어떤 값이 특정 클래스의 인스턴스인지를 확인하는 연산자입니다. 주로 Date, Error 같은 내장 클래스나 직접 정의한 클래스의 인스턴스를 구분할 때 사용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function formatDate(value: string | Date) {
  if (value instanceof Date) {
    return `${value.getFullYear()}년 ${value.getMonth() + 1}월 ${value.getDate()}일`;
  }
  return value;
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;에러 처리에서도 자주 쓰입니다. try-catch 블록에서 catch한 에러가 어떤 종류인지 구분할 때 instanceof가 유용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function handleError(error: unknown) {
  if (error instanceof TypeError) {
    console.log("타입 에러:", error.message);
  } else if (error instanceof RangeError) {
    console.log("범위 에러:", error.message);
  } else {
    console.log("알 수 없는 에러");
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 instanceof는 클래스 기반 타입에만 사용할 수 있습니다. 인터페이스나 타입 별칭 그 자체는 컴파일 과정에서 제거되어 런타임에 남지 않으므로, 이를 직접 instanceof로 검사할 수는 없습니다. 즉, 자바스크립트로 변환된 코드에는 인터페이스에 대한 정보가 남아있지 않으므로 instanceof로 비교할 대상 자체가 없는 것입니다. 물론 해당 인터페이스를 구현한 클래스가 있다면, 그 클래스를 기준으로 instanceof 검사를 하는 것은 가능합니다. 하지만 인터페이스 자체를 직접 검사할 수 없다는 점은 동일합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) in 연산자&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;in 연산자는 객체에 특정 프로퍼티가 존재하는지를 확인하는 방식으로 타입을 좁힙니다. 인터페이스나 타입 별칭으로 정의한 서로 다른 객체 타입을 구분할 때 특히 유용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;interface Dog {
  name: string;
  bark: () =&amp;gt; void;
}

interface Cat {
  name: string;
  meow: () =&amp;gt; void;
}

function greetPet(pet: Dog | Cat) {
  if ("bark" in pet) {
    pet.bark(); // ✅ Dog 타입으로 확정
  } else {
    pet.meow(); // ✅ Cat 타입으로 확정
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Dog에는 bark가 있고 Cat에는 없기 때문에, "bark" in pet 조건으로 두 타입을 구분할 수 있습니다. 이처럼 in 연산자는 타입마다 고유하게 존재하는 프로퍼티를 기준으로 분기할 때 효과적입니다. 다만, 두 타입이 완전히 동일한 프로퍼티 구조를 갖고 있다면 in만으로는 구분이 어렵습니다. 이런 경우에는 뒤에서 다룰 판별된 유니온 패턴이 더 적합합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기본 패턴을 정리하면 다음과 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3719/%EA%B7%B8%EB%A6%BC2__3_.png"&gt;&lt;figcaption&gt;&amp;lt;출처 : 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실무에서 자주 쓰는 고급 패턴&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;앞서 살펴본 기본 패턴만으로도 많은 상황을 커버할 수 있지만, 실무에서 마주하는 타입 분기는 조금 더 복잡한 경우가 많습니다. 여러 종류의 응답 객체를 구분하거나, 타입스크립트가 자동으로 추론하지 못하는 상황을 직접 처리해야 할 때가 있습니다. 이런 경우에 활용할 수 있는 고급 패턴들을 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 판별된 유니온(Discriminated Union)&lt;/strong&gt;&lt;/h4&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3719/%EA%B7%B8%EB%A6%BC3__2_.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude AI 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실무에서 가장 많이 쓰이는 타입 좁히기 패턴입니다. 유니온을 구성하는 각 타입이 공통적으로 가지고 있는 리터럴 타입 필드를 기준으로 분기하는 방식입니다. 보통 type, status, kind 같은 필드가 이 역할을 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;API 응답 처리를 예로 들어보겠습니다. 대부분의 API는 성공과 실패 시 응답 구조가 다릅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;interface SuccessResponse {
  status: "success";
  data: {
    id: number;
    name: string;
  };
}

interface ErrorResponse {
  status: "error";
  errorCode: number;
  message: string;
}

type ApiResponse = SuccessResponse | ErrorResponse;&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 status 필드가 판별자(discriminant) 역할을 합니다. 이 필드의 값이 "success"인지 "error"인지에 따라 타입이 자동으로 확정됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function handleResponse(response: ApiResponse) {
  if (response.status === "success") {
    console.log(response.data.name); // ✅ SuccessResponse로 확정
  } else {
    console.log(`에러 ${response.errorCode}: ${response.message}`); // ✅ ErrorResponse로 확정
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;switch문과 결합하면 더 깔끔하게 분기할 수 있습니다. 상태가 세 가지 이상으로 나뉘는 경우에 특히 유용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;interface LoadingState {
  status: "loading";
}

interface SuccessState {
  status: "success";
  data: string[];
}

interface ErrorState {
  status: "error";
  message: string;
}

type FetchState = LoadingState | SuccessState | ErrorState;

function renderUI(state: FetchState) {
  switch (state.status) {
    case "loading":
      return "로딩 중...";
    case "success":
      return state.data.join(", ");
    case "error":
      return `오류: ${state.message}`;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;판별된 유니온의 장점은 코드의 의도가 명확하다는 것입니다. status 필드 하나만 보면 어떤 타입인지 바로 알 수 있기 때문에 가독성이 좋고, 새로운 상태가 추가되더라도 switch문에 case만 추가하면 되므로 확장도 용이합니다. 또한 never 타입을 활용한 exhaustive check를 함께 쓰면, 누락된 분기를 컴파일 단계에서 바로 잡아낼 수 있어 더 안전합니다. 리액트에서 API 호출 상태를 관리하거나, Redux 같은 상태 관리 도구에서 액션을 구분할 때도 이 패턴이 자주 사용됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 사용자 정의 타입 가드(is 키워드)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;지금까지 살펴본 패턴들은 타입스크립트가 조건문을 분석해서 자동으로 타입을 좁혀주는 경우였습니다. 하지만 타입스크립트가 자동으로 추론하지 못하는 상황도 있습니다. 예를 들어, 복잡한 조건을 별도 함수로 분리하면, 그 함수의 반환값이 boolean일 뿐 타입 좁히기로 연결되지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function isString(value: unknown): boolean {
  return typeof value === "string";
}

function process(value: string | number) {
  if (isString(value)) {
    value.toUpperCase(); // ❌ 여전히 string | number
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;위 코드에서 isString 함수는 분명히 문자열 여부를 확인하고 있지만, 타입스크립트 입장에서는 그냥 boolean을 반환하는 함수일 뿐입니다. 조건문 안에서의 타입 좁히기가 작동하지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이런 상황에서 is 키워드를 사용하면 됩니다. 반환 타입을 value is string 형태로 선언하면, 이 함수가 true를 반환할 때 해당 매개변수가 특정 타입임을 타입스크립트에 알려줄 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function isString(value: unknown): value is string {
  return typeof value === "string";
}

function process(value: string | number) {
  if (isString(value)) {
    value.toUpperCase(); // ✅ string 타입으로 확정
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 패턴은 반복적으로 사용되는 타입 체크 로직을 함수로 분리할 때 특히 유용합니다. 여러 곳에서 동일한 타입 확인 조건을 작성하는 대신, 타입 가드 함수 하나를 만들어두면 코드의 중복을 줄이면서도 타입 안전성을 유지할 수 있습니다. 배열에서 null이나 undefined를 걸러내는 필터링 패턴에서도 자주 활용됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function isNotNull&amp;lt;T&amp;gt;(value: T | null): value is T {
  return value !== null;
}

const items = ["사과", null, "바나나", null, "딸기"];
const filtered = items.filter(isNotNull);
// filtered의 타입: string[]&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Array.filter에 일반적인 boolean 반환 함수를 넘기면 타입스크립트가 null이 제거되었다는 것을 대부분 인식하지 못해 (string | null)[] 타입이 유지되는데, is 키워드를 사용한 타입 가드를 넘기면 string[]으로 정확하게 추론됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 타입 좁히기 사용 시 주의할 점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;타입 좁히기는 강력한 기능이지만, 실무에서 사용하다 보면 몇 가지 실수하기 쉬운 지점이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;먼저 첫 번째로 주의할 것은 타입 단언(as)의 남용입니다. 타입 좁히기 대신 as로 강제 변환하면 코드가 짧아지는 것처럼 보이지만, 타입 안전성을 포기하는 것입니다. 실제 런타임 값이 해당 타입이 아닐 경우, 타입스크립트는 에러를 잡아주지 못합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;// ❌ 위험: 실제로 string이 아닐 수 있음
const value = someFunction() as string;
console.log(value.toUpperCase()); // 런타임 에러 가능

// ✅ 안전: 실제로 string인지 확인 후 사용
const value = someFunction();
if (typeof value === "string") {
  console.log(value.toUpperCase());
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="margin-left:36pt;text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 콜백 함수 안에서 좁혀진 타입이 풀리는 경우입니다. 바깥 스코프에서 타입을 좁혀놨더라도, 콜백 안에서는 이 정보가 유지되지 않을 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function process(value: string | null) {
  if (value !== null) {
    // 여기서는 string 타입으로 좁혀짐
    setTimeout(() =&amp;gt; {
      console.log(value.toUpperCase()); // ✅ 이 경우는 동작함
    }, 100);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="margin-left:36pt;text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;위 예시처럼 재할당 가능성이 없고 제어 흐름상 안전하다고 판단되는 경우에는 콜백 안에서도 좁혀진 타입이 유지될 수 있습니다. 하지만 let으로 선언된 변수는 콜백이 실행되기 전에 다른 값이 할당될 수 있기 때문에, 타입스크립트의 제어 흐름 분석이 클로저 경계를 넘어서까지 안전하다고 보장하지 못하는 경우가 있습니다. 이런 상황에서는 좁혀진 값을 별도의 const 변수에 담아두는 방법이 안전합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;let value: string | null = getString();

if (value !== null) {
  const confirmed = value; // string 타입으로 확정된 값을 별도 변수에 저장
  setTimeout(() =&amp;gt; {
    console.log(confirmed.toUpperCase()); // ✅ 안전
  }, 100);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 타입스크립트의 타입 좁히기에 대해 살펴보았습니다. 코드를 작성하다 as를 사용하고 싶은 순간이 오면, 잠시 멈추고 타입 좁히기로 해결할 수 있는지 먼저 떠올려보세요. 대부분의 경우 조건문 한두 줄이면 충분하고, 그렇게 작성한 코드가 더 안전하고 읽기 쉬운 코드로 이어집니다. 타입 좁히기에 익숙해질수록 타입스크립트를 더 자신 있게 다룰 수 있게 될 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>에이전트 하네스 완전 해부</title><link>https://yozm.wishket.com/magazine/detail/3718</link><description>이 글은 AI 에이전트 시스템에서 모델을 감싸는 인프라, 즉 '하네스(Harness)'의 개념을 정의하고, 파일시스템·샌드박스·메모리·컨텍스트 관리 등 핵심 구성 요소를 모델의 한계에서 역추적하여 도출하는 과정을 담고 있습니다. LangChain이 자사 코딩 에이전트의 하네스만 변경하여 Terminal Bench 2.0에서 Top 30에서 Top 5로 끌어올린 사례를 포함해, 하네스 엔지니어링의 현재와 미래를 구체적으로 소개합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3718</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;본문은 요즘IT가 Vivek Trivedy(비벡 트리베디) 님의 글&amp;lt;&lt;a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/"&gt;&lt;u&gt;The Anatomy of an Agent Harness&lt;/u&gt;&lt;/a&gt;&amp;gt;를 번역한 글입니다. 필자는 LangChain의 프로덕트 매니저로, 에이전트·하네스·평가(Evals)를 담당하며 오픈소스 에이전트 프레임워크 개발을 이끌고 있습니다. 이전에는 AWS에서 과학자(Scientist)로 근무하며 Temple University에서 컴퓨터 과학 박사 학위를 취득했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글은 AI 에이전트 시스템에서 모델을 감싸는 인프라, 즉 '하네스(Harness)'의 개념을 정의하고, 파일시스템·샌드박스·메모리·컨텍스트 관리 등 핵심 구성 요소를 모델의 한계에서 역추적하여 도출하는 과정을 담고 있습니다. LangChain이 자사 코딩 에이전트의 하네스만 변경하여 Terminal Bench 2.0에서 Top 30에서 Top 5로 끌어올린 사례를 포함해, 하네스 엔지니어링의 현재와 미래를 구체적으로 소개합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;필자에게 허락을 받고 번역했으며, 글에 포함된 링크는 원문에 따라 표시했습니다.&lt;/span&gt;&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;누가 "하네스"를 좀 정의해줄래요?&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;에이전트 = 모델 + 하네스(harness)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;모델이 아닌 모든 것이 하네스입니다.&lt;/strong&gt; 하네스란 모델 그 자체가 아닌 모든 코드, 설정, 실행 로직을 말합니다. 날것의 모델(raw model)은 에이전트가 아닙니다. 하지만 하네스가 모델에게 상태(state), 도구 실행, 피드백 루프, 강제 가능한 제약 같은 것들을 부여하는 순간, 모델은 에이전트가 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;구체적으로 하네스는 다음과 같은 것들을 포함합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;시스템 프롬프트&lt;/li&gt;&lt;li style="text-align:justify;"&gt;도구(Tools), 스킬(Skills), MCP와 그 설명들&lt;/li&gt;&lt;li style="text-align:justify;"&gt;번들링된 인프라(파일시스템, 샌드박스, 브라우저)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;오케스트레이션 로직(서브에이전트 생성, 핸드오프, 모델 라우팅)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;결정론적 실행을 위한 훅/미들웨어(compaction, continuation, lint check)&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;에이전트 시스템에서 모델과 하네스의 경계를 나누는 방법은 여러 가지고, 꽤 지저분합니다. 하지만 제 생각에 위 정의가 가장 깔끔합니다. 왜냐하면 이 정의는 &lt;strong&gt;모델의 지능(intelligence)을 중심에 두고 시스템을 설계하도록&lt;/strong&gt; 강제하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글의 나머지 부분에서는 하네스의 핵심 구성 요소들을 하나씩 살펴보면서, 모델이라는 핵심 프리미티브(primitive)에서 출발해 각 구성 요소가 왜 존재해야 하는지를 역으로 도출해보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;왜 하네스가 필요한가: 모델의 관점에서&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;우리가 에이전트에게 시키고 싶은 일들 중에는, 모델이 그 자체로는 할 수 없는 것들이 있습니다. 바로 이 지점에서 하네스가 등장합니다. 모델은 (대체로) 텍스트, 이미지, 오디오, 비디오 같은 데이터를 입력받아 텍스트를 출력합니다. 그게 전부입니다. 모델은 기본적으로 다음을 할 수 없습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;상호작용 간에 지속 가능한 상태 유지&lt;/li&gt;&lt;li style="text-align:justify;"&gt;코드 실행&lt;/li&gt;&lt;li style="text-align:justify;"&gt;실시간 지식 접근&lt;/li&gt;&lt;li style="text-align:justify;"&gt;작업 완수를 위한 환경 세팅 및 패키지 설치&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이것들은 모두 하네스 레벨의 기능입니다. LLM이라는 구조 자체가, 유용한 일을 시키려면 모델을 감싸는 어떤 기계 장치를 필요로 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, "대화하기"라는 제품 UX를 만들려면 이전 메시지들을 추적하고 새 사용자 메시지를 덧붙이기 위해 모델을 while 루프로 감싸야 합니다. 이 글을 읽고 있는 분이라면 이미 이런 종류의 하네스를 써본 셈입니다. 핵심은, 우리가 원하는 에이전트의 행동을 하네스의 실제 기능으로 변환한다는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3718/image2.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;원하는 에이전트 행동에서 하네스 엔지니어링으로 역산하기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;하네스 엔지니어링은 인간이 에이전트의 행동을 유도하기 위한 유용한 사전 지식(prior)을 주입하는 일입니다. 그리고 모델이 더 똑똑해질수록, 하네스는 이전에는 불가능했던 작업을 완수하도록 모델을 정교하게 확장하고 교정하는 용도로 쓰이고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;모든 하네스 기능을 빠짐없이 다루지는 않을 겁니다. 목표는 "모델이 유용한 일을 하게 돕는다"는 출발점에서 일련의 기능들을 도출해보는 것입니다. 다음과 같은 패턴을 따라가 보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;우리가 원하는(또는 고치고 싶은) 행동 → 모델이 그것을 달성하게 돕는 하네스 설계&lt;/strong&gt;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3718/image3.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;지속적 저장과 컨텍스트 관리를 위한 파일시스템&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;우리는 에이전트가 실제 데이터와 상호작용하고, 컨텍스트에 담기지 않는 정보를 덜어내고, 세션을 넘나들며 작업을 지속하도록 하고 싶습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;모델은 컨텍스트 윈도우 안의 지식에 대해서만 직접 작업할 수 있습니다. 파일시스템이 도입되기 전에는 사용자가 모델에게 내용을 복사·붙여넣기 해야 했습니다. UX가 번거롭고, 자율 에이전트에는 적용할 수도 없습니다. 세상은 이미 작업을 위해 파일시스템을 쓰고 있었고, 덕분에 모델은 파일시스템 사용법을 수십억 토큰으로 자연스럽게 학습한 상태였습니다. 그래서 자연스러운 해결책은 이것이 됐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;하네스는 파일시스템 추상화와 파일 시스템 작업(fs-ops)용 도구를 기본 탑재합니다.&lt;/strong&gt; 파일시스템은 아마도 가장 근본적인 하네스 프리미티브일 것입니다. 다음과 같은 것들을 가능하게 하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;에이전트에게 데이터, 코드, 문서를 읽을 수 있는 작업 공간이 생깁니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;모든 것을 컨텍스트에 붙들고 있는 대신, 작업을 점진적으로 더하거나 덜어낼 수 있습니다. 중간 산출물을 저장하고, 한 세션을 넘어서는 상태를 유지할 수 있습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;파일시스템은 자연스러운 협업 표면입니다. 여러 에이전트와 인간이 공유된 파일을 통해 협업할 수 있습니다. 에이전트 팀(Agent Teams) 같은 아키텍처가 이 위에서 돌아갑니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;Git을 더하면 파일시스템에 버전 관리가 붙어, 에이전트가 작업을 추적하고, 에러를 롤백하고, 실험을 브랜치로 나눌 수 있게 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;파일시스템은 뒤에서 다시 등장합니다. 알고 보면 이것이 다른 여러 기능의 기반이 되는 핵심 하네스 프리미티브이기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;범용 도구로서의 Bash와 코드&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;우리는 인간이 모든 도구를 미리 설계하지 않아도 에이전트가 자율적으로 문제를 해결하기를 원합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;오늘날 에이전트 실행의 주류 패턴은 &lt;a href="https://docs.langchain.com/oss/python/langchain/agents?ref=blog.langchain.com&amp;amp;_gl=1*1cg3aey*_gcl_au*MTI0NzU3OTgzNi4xNzc1ODEwMDcy*_ga*NjMwMzc2MzQ2LjE3NzU4MTAwNzM.*_ga_47WX3HKKY2*czE3NzY0MTE2NDQkbzkkZzAkdDE3NzY0MTE2NDQkajYwJGwwJGgw"&gt;&lt;u&gt;ReAct 루프&lt;/u&gt;&lt;/a&gt;입니다. 모델이 추론하고, 도구 호출로 행동하고, 결과를 관찰하고, 이를 while 루프 안에서 반복하는 방식입니다. 하지만 하네스는 자기가 로직을 갖고 있는 도구만 실행할 수 있습니다. 사용자에게 가능한 모든 행동에 대한 도구를 일일이 만들라고 요구하는 건 좋은 해결책이 아닙니다. 더 나은 방법은 에이전트에게 bash 같은 범용 도구를 주는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;하네스는 bash 도구를 기본 탑재해, 모델이 코드를 작성하고 실행하며 자율적으로 문제를 풀 수 있게 합니다.&lt;/strong&gt; Bash와 코드 실행은 모델에게 컴퓨터를 쥐여주고 나머지는 알아서 하게 하는 방향으로 가는 큰 도약입니다. 모델은 미리 설정된 고정된 도구 세트에 갇히지 않고, 코드를 통해 즉석에서 자신만의 도구를 설계할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하네스는 여전히 다른 도구들도 함께 제공하지만, 코드 실행은 자율적 문제 해결의 기본 전략으로 자리 잡았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;작업을 실행하고 검증하기 위한 샌드박스와 도구&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;에이전트는 안전하게 행동하고, 결과를 관찰하며, 진전을 이룰 수 있는 적절한 기본 환경이 필요합니다. 모델에게 저장 공간과 코드 실행 능력을 줬지만, 이 모든 것이 &lt;strong&gt;어딘가에서&lt;/strong&gt; 일어나야 합니다. 에이전트가 만든 코드를 로컬에서 그대로 실행하는 건 위험하고, 단일 로컬 환경은 대규모 에이전트 워크로드에는 적합하지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;샌드박스는 에이전트에게 안전한 실행 환경을 제공합니다. 로컬 대신, 하네스가 샌드박스에 연결해 코드를 실행하고, 파일을 살펴보고, 의존성을 설치하고, 작업을 완료합니다. 이 방식은 격리된 안전한 코드 실행을 가능하게 합니다. 보안을 더 강화하려면, 하네스에서 허용 명령어를 화이트리스트로 지정하고 네트워크 격리를 강제할 수도 있습니다. 샌드박스는 확장성도 열어줍니다. 필요할 때 환경을 생성하고, 여러 작업에 병렬로 뿌리고, 끝나면 정리할 수 있기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;좋은 환경은 좋은 기본 도구들과 함께 옵니다. 하네스는 에이전트가 유용한 일을 할 수 있도록 도구를 구성할 책임이 있습니다. 언어 런타임과 패키지 사전 설치, git과 테스트용 CLI, 웹 상호작용 및 검증용 &lt;a href="https://github.com/vercel-labs/agent-browser?ref=blog.langchain.com"&gt;&lt;u&gt;브라우저&lt;/u&gt;&lt;/a&gt; 등이 여기 포함됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;브라우저, 로그, 스크린샷, 테스트 러너 같은 도구는 에이전트가 자기 작업을 관찰하고 분석할 수 있게 해줍니다. 이를 통해 에이전트는 자기 검증 루프를 만들 수 있습니다. 애플리케이션 코드를 작성하고, 테스트를 돌리고, 로그를 살펴보고, 에러를 고치는 식으로요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;모델은 기본적으로 자기 실행 환경을 스스로 구성하지 않습니다. 에이전트가 어디서 동작할지, 어떤 도구를 쓸 수 있을지, 무엇에 접근할 수 있을지, 어떻게 작업을 검증할지는 모두 하네스 수준의 설계 결정입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;지속적 학습을 위한 메모리와 검색&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;에이전트는 이전에 본 것을 기억해야 하고, 학습 시점에는 존재하지 않았던 정보에도 접근할 수 있어야 합니다. 모델은 가중치와 현재 컨텍스트에 담긴 것 외에는 추가 지식이 없습니다. 모델 가중치를 수정할 수 없는 상황에서, "지식을 추가"하는 유일한 방법은 컨텍스트 주입입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;메모리 측면에서도 파일시스템이 다시 핵심 프리미티브로 등장합니다. 하네스는 &lt;a href="http://agents.md"&gt;&lt;u&gt;AGENTS.md&lt;/u&gt;&lt;/a&gt; 같은 메모리 파일 표준을 지원하고, 에이전트 시작 시 이를 컨텍스트에 주입합니다. 에이전트가 이 파일을 추가하고 수정하면, 하네스는 업데이트된 내용을 다음 컨텍스트에 불러옵니다. 이는 일종의 &lt;a href="https://www.ibm.com/think/topics/continual-learning?ref=blog.langchain.com"&gt;&lt;u&gt;지속적 학습&lt;/u&gt;&lt;/a&gt;입니다. 에이전트가 한 세션에서 얻은 지식을 지속 가능하게 저장하고, 그 지식을 이후 세션에 주입하는 방식이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지식 컷오프(knowledge cutoff) 때문에, 모델은 사용자가 직접 제공하지 않는 한 새로 업데이트된 라이브러리 버전 같은 데이터에 직접 접근할 수 없습니다. 최신 지식을 위해서는 웹 검색과 &lt;a href="https://context7.com/?ref=blog.langchain.com"&gt;&lt;u&gt;Context7&lt;/u&gt;&lt;/a&gt; 같은 MCP 도구들이 에이전트가 학습 이후에 등장한 정보, 예컨대 최신 라이브러리 버전이나 최신 데이터에 접근하도록 도와줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;웹 검색과 최신 컨텍스트 조회 도구는 하네스에 내장할 만한 유용한 프리미티브들입니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;컨텍스트 부패와 싸우기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;작업이 진행될수록 에이전트 성능이 나빠져서는 안 됩니다. &lt;a href="https://research.trychroma.com/context-rot?ref=blog.langchain.com"&gt;&lt;u&gt;컨텍스트 부패(context rot)&lt;/u&gt;&lt;/a&gt;는 컨텍스트 윈도우가 채워질수록 모델이 추론과 작업 수행에서 나빠지는 현상을 말합니다. 컨텍스트는 귀중하고 희소한 자원이기 때문에, 하네스는 이를 관리할 전략이 필요합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;오늘날의 하네스는 사실상 좋은 컨텍스트 엔지니어링을 전달하는 수단입니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;Compaction&lt;/strong&gt;은 컨텍스트 윈도우가 가득 차려 할 때 무엇을 할지의 문제를 다룹니다. compaction이 없으면 대화가 컨텍스트 윈도우를 초과했을 때 어떻게 될까요? 한 가지 선택지는 API가 에러를 내는 것입니다. 좋지 않죠. 하네스는 이런 상황을 위한 전략이 필요합니다. compaction은 기존 컨텍스트를 똑똑하게 덜어내고 요약해서, 에이전트가 계속 작업할 수 있게 해줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;도구 호출 오프로딩(Tool call offloading)&lt;/strong&gt;은 큰 도구 출력이 유용한 정보 없이 컨텍스트를 어지럽히는 문제를 줄여줍니다. 하네스는 일정 토큰 수 이상인 도구 출력에 대해 앞뒤 토큰만 남기고, 전체 출력은 파일시스템에 옮겨두어 필요할 때만 모델이 접근할 수 있게 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;스킬(Skills)&lt;/strong&gt;은 에이전트 시작 시 너무 많은 도구나 MCP 서버가 컨텍스트에 로드되어, 일을 시작하기도 전에 성능이 떨어지는 문제를 해결합니다. 스킬은 점진적 공개(progressive disclosure)를 통해 이 문제를 푸는 하네스 수준의 프리미티브입니다. 모델이 시작 시 스킬의 front-matter를 컨텍스트에 싣겠다고 선택한 건 아니지만, 하네스가 이를 지원함으로써 모델을 컨텍스트 부패로부터 보호할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;장기 자율 실행&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;우리는 에이전트가 복잡한 작업을, 자율적으로, 정확하게, 긴 시간에 걸쳐 완수하기를 원합니다. 자율적인 소프트웨어 생성은 코딩 에이전트의 성배입니다. 하지만 오늘날의 모델들은 조기 종료(early stopping), 복잡한 문제 분해의 어려움, 여러 컨텍스트 윈도우를 넘어갈 때의 일관성 붕괴 같은 문제들을 겪습니다. 좋은 하네스는 이 모든 것을 설계에 반영해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서부터는 앞서 다룬 하네스 프리미티브들이 복리처럼 작동하기 시작합니다. 장기 작업은 여러 컨텍스트 윈도우를 넘어 작업을 지속하기 위해 지속 가능한 상태, 계획, 관찰, 검증을 모두 필요로 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;세션을 가로지르는 작업 추적을 위한 파일시스템과 git&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;에이전트는 긴 작업 동안 수백만 토큰을 만들어내기 때문에, 파일시스템이 작업을 지속 가능하게 담아 시간에 따른 진전을 추적합니다. 여기에 git을 더하면, 새로 시작한 에이전트가 프로젝트의 최신 상태와 히스토리를 빠르게 따라잡을 수 있습니다. 여러 에이전트가 함께 일할 때도 파일시스템은 공유된 작업 원장(ledger) 역할을 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;작업을 이어가기 위한 Ralph Loop&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://ghuntley.com/loop/?ref=blog.langchain.com"&gt;&lt;u&gt;Ralph Loop&lt;/u&gt;&lt;/a&gt;은 모델이 종료하려는 시도를 훅으로 가로채, 깨끗한 컨텍스트 윈도우에 원래 프롬프트를 다시 주입해 완료 목표를 향해 계속 일하게 하는 하네스 패턴입니다. 이 패턴이 가능한 건 파일시스템 덕분입니다. 각 반복은 새 컨텍스트로 시작하되, 이전 반복의 상태를 파일에서 읽어오기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;궤도를 유지하기 위한 계획과 자기 검증&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;계획(planning)은 모델이 목표를 여러 단계로 분해하는 일입니다. 하네스는 좋은 프롬프트와, 파일시스템의 계획 파일 사용법에 대한 리마인더 주입을 통해 이를 지원합니다. 각 단계를 완료한 뒤, 에이전트는 자기 검증(self-verification)을 통해 작업의 정확성을 점검할 때 더 잘 동작합니다. 하네스의 훅이 사전 정의된 테스트 스위트를 실행하고, 실패 시 에러 메시지를 담아 모델로 다시 루프를 돌릴 수도 있고, 모델이 스스로 자기 코드를 평가하도록 프롬프트를 설계할 수도 있습니다. 검증은 해결책을 테스트에 뿌리내리게 하고, 자기 개선을 위한 피드백 신호를 만들어냅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;하네스의 미래&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;모델 학습과 하네스 설계의 결합&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;오늘날 Claude Code나 Codex와 같은 에이전트 제품들은 모델과 하네스가 루프 안에 포함된 상태로 사후 학습(Post-trained)됩니다. 이를 통해 모델은 하네스 설계자가 의도한 동작(파일 시스템 조작, Bash 실행, 계획 수립, 하위 에이전트 병렬화 등)을 기본적으로 더 잘 수행하게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 과정에서 유용한 프리미티브가 발견되어 하네스에 추가되고, 이는 다시 다음 세대 모델 학습에 사용되는 피드백 루프가 형성됩니다. 이 사이클이 반복되면서, 모델은 자기가 학습된 하네스 안에서 점점 더 유능해집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 이 공진화(co-evolution)는 일반화 측면에서 흥미로운 부작용을 낳습니다. 도구 로직을 바꾸면 모델 성능이 떨어지는 현상 같은 것들이죠. 좋은 예가 &lt;a href="https://developers.openai.com/cookbook/examples/gpt-5/codex_prompting_guide/?ref=blog.langchain.com#apply_patch"&gt;&lt;u&gt;Codex-5.3 프롬프팅 가이드&lt;/u&gt;&lt;/a&gt;에 나오는, 파일 편집용 apply_patch 도구 로직에 관한 내용입니다. 진정으로 지능적인 모델이라면 패치 방식을 바꾸는 정도로 문제를 겪을 리 없지만, 하네스를 루프에 넣은 학습은 이런 식의 과적합을 만듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그렇다고 해서 모델이 사후 학습될 때 사용된 하네스가 반드시 여러분의 작업에 최적인 것은 아닙니다.&amp;nbsp; &lt;a href="https://www.tbench.ai/leaderboard/terminal-bench/2.0?ref=blog.langchain.com"&gt;&lt;u&gt;Terminal Bench 2.0 리더보드&lt;/u&gt;&lt;/a&gt;가 좋은 예입니다. Claude Code 안에서의 Opus 4.6은 다른 하네스에서의 Opus 4.6보다 한참 낮은 점수를 받습니다. &lt;a href="https://x.com/Vtrivedy10/status/2023805578561060992?s=20&amp;amp;ref=blog.langchain.com"&gt;&lt;u&gt;이전 글&lt;/u&gt;&lt;/a&gt;에서 저희는 코딩 에이전트의 Terminal Bench 2.0 순위를 하네스만 바꿔 Top 30에서 Top 5로 끌어올린 과정을 공유한 적이 있습니다. 여러분의 작업에 맞게 하네스를 최적화하는 일에는 아직 짜낼 수 있는 즙이 많이 남아 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3718/image1.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;하네스 엔지니어링은 어디로 가는가&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;모델이 더 유능해질수록, 지금 하네스에 있는 일부 기능은 모델 안으로 흡수될 것입니다. 모델은 기본적으로 계획 수립, 자기 검증, 장기 일관성 유지 등을 더 잘하게 될 것이고, 결과적으로 컨텍스트 주입과 같은 필요성은 줄어들 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이는 시간이 흐를수록 하네스의 중요성이 낮아질 것임을 시사합니다. 하지만 프롬프트 엔지니어링이 지금도 여전히 가치 있는 것처럼, 하네스 엔지니어링도 좋은 에이전트를 만드는 데 계속 유용할 가능성이 큽니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하네스는 모델의 부족한 점을 보완하기도 하지만, 무엇보다 &lt;strong&gt;모델의 지능을 중심으로 시스템을 설계하여 효율성을 극대화&lt;/strong&gt;하기 때문입니다. 잘 구성된 환경, 적절한 도구, 영구적인 상태, 그리고 검증 루프는 모델의 기초 지능 수준과 상관없이 더 효율적인 에이전트를 만듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하네스 엔지니어링은 저희가 LangChain에서 하네스 구축 라이브러리 &lt;a href="https://docs.langchain.com/oss/python/deepagents/overview?ref=blog.langchain.com&amp;amp;_gl=1*1dmk3yc*_gcl_au*MTI0NzU3OTgzNi4xNzc1ODEwMDcy*_ga*NjMwMzc2MzQ2LjE3NzU4MTAwNzM.*_ga_47WX3HKKY2*czE3NzY0MTE2NDQkbzkkZzAkdDE3NzY0MTE2NDQkajYwJGwwJGgw"&gt;&lt;u&gt;deepagents&lt;/u&gt;&lt;/a&gt;를 개선하며 계속 연구하고 있는 매우 활발한 영역입니다. 아래는 저희가 현재 탐색하고 있는 문제들입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;공유 코드베이스 위에서 수백 개의 에이전트가 병렬로 일하도록 오케스트레이션하기&lt;/li&gt;&lt;li style="text-align:justify;"&gt;자기 트레이스를 분석해 하네스 수준의 실패 패턴을 찾아내고 고치는 에이전트&lt;/li&gt;&lt;li style="text-align:justify;"&gt;미리 설정해두는 대신, 주어진 작업에 맞춰 적절한 도구와 컨텍스트를 적시에(just-in-time) 동적으로 조립하는 하네스&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글은 하네스가 무엇인지 정의하고, 우리가 모델에게 원하는 작업에 따라 하네스가 어떻게 형성되는지 고찰해 보는 과정이었습니다. &lt;strong&gt;모델은 지능을 품고, 하네스는 그 지능을 유용하게 만드는 시스템입니다&lt;/strong&gt;. 더 나은 하네스, 더 나은 시스템, 더 나은 에이전트를 향해.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&amp;lt;원문&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/"&gt;&lt;u&gt;The Anatomy of an Agent Harness&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>“이걸 누가 관리하나요?” GEO 자동화가 필요한 이유</title><link>https://yozm.wishket.com/magazine/detail/3713</link><description>최근 GEO는 AI 검색 시대의 핵심 전략으로 빠르게 자리 잡고 있습니다. ChatGPT, Gemini, Perplexity와 같은 생성형 AI 서비스는 더 이상 단순히 웹 페이지 링크를 나열하지 않습니다. 대신 사용자의 질문에 대해 직접 “답변 문장”을 생성하며, 이 과정에서 특정 웹 콘텐츠를 인용하여 재구성합니다. 많은 기업이 기존의 SEO뿐만 아니라, GEO를 위한 구조화 정보, 특히 JSON-LD 기반 태그를 활용해 자사 콘텐츠가 AI 답변에 포함되도록 최적화를 시도하고 있습니다. 그러나 실제 서비스 환경에서는 곧 하나의 근본적인 질문과 마주하게 됩니다. “이걸 누가, 어떻게 계속 관리할 것인가?”</description><guid>https://yozm.wishket.com/magazine/detail/3713</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;GEO가 필요한데, 어떻게 적용할 것인가?&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최근 GEO(Generative Engine Optimization)는 AI 검색 시대의 핵심 전략으로 빠르게 자리 잡고 있습니다. ChatGPT, Gemini, Perplexity와 같은 생성형 AI 서비스는 더 이상 단순히 웹 페이지 링크를 나열하지 않습니다. 대신 사용자의 질문에 대해 직접 “답변 문장”을 생성하며, 이 과정에서 특정 웹 콘텐츠를 인용하여 재구성합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;이로 따라 많은 기업이 기존의 SEO(Search Engine Optimization)뿐만 아니라, GEO를 위한 구조화 정보, 특히 JSON-LD 기반 태그를 활용해 자사 콘텐츠가 AI 답변에 포함되도록 최적화를 시도하고 있습니다. 그러나 실제 서비스 환경에서는 곧 하나의 근본적인 질문과 마주하게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;“이걸 누가, 어떻게 계속 관리할 것인가?”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;정적인 웹 사이트라면 한 번의 작업으로도 어느 정도 유지가 가능하겠지만 포털, 뉴스, 전자상거래, 커뮤니티, SaaS 문서 플랫폼처럼 콘텐츠가 지속적으로 생성되고 수정되며, 때로는 삭제되는 환경에서 웹 페이지마다 지속적으로 구조화 데이터를 관리하는 것이 사실상 불가능합니다.&lt;br&gt;&lt;br&gt;이 글에서는 이러한 문제를 해결하기 위해 현재 사내에서 실험 중인 GEO 자동화 아키텍처를 기반으로, 다음 내용을 알아보고자 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;GEO는 더 이상 전략 문제가 아니라 운영 문제이며, 자동화를 통해 확장할 수 있습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;AI를 활용하면 콘텐츠 분석부터 구조화 데이터 생성까지 전 과정을 자동화할 수 있습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;CDN 엣지와 서버리스(Serverless)를 결합하면 서비스 수정 없이 GEO를 적용할 수 있습니다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;GEO 전략을 실제 서비스에 적용할 때 마주하는 문제&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;GEO 개념 자체는 비교적 명확합니다. AI가 이해하기 쉬운 구조로 콘텐츠를 제공하고, 이를 통해 인용 가능성을 높이는 것입니다. 그러나 이를 실제 서비스에 적용하는 순간, 문제의 본질은 기술이 아니라 운영으로 이동합니다.&lt;br&gt;&lt;br&gt;첫 번째 문제는 &lt;strong&gt;콘텐츠 규모&lt;/strong&gt;입니다. 하루 수십, 수백 개의 페이지가 생성되는 서비스에서는 페이지마다 적절한 구조화 데이터를 작성하는 것이 불가능합니다. 특히 전자상거래 상품 페이지나 뉴스 기사처럼 데이터가 지속적으로 업데이트되는 환경에서는 메타데이터의 최신성을 유지하는 것 자체가 큰 비용으로 이어집니다.&lt;br&gt;&lt;br&gt;두 번째 문제는 &lt;strong&gt;콘텐츠의 다양성&lt;/strong&gt;입니다. 단순 블로그 글이 아니라 상품, 리뷰, FAQ, 기술 문서 등 다양한 형태의 콘텐츠가 존재할 때, 각각에 맞는 스키마 구조를 설계하고 유지하는 것도 쉽지 않습니다. 이는 단순 반복 작업이 아니라 도메인 이해를 요구하는 작업이기 때문입니다.&lt;br&gt;&lt;br&gt;세 번째 문제는 &lt;strong&gt;조직 구조&lt;/strong&gt;입니다. 대부분의 엔터프라이즈 환경에서는 웹 애플리케이션 코드 수정이 매우 엄격하게 통제됩니다. JSON-LD를 추가하는 단순 작업조차도 배포 승인 프로세스를 거쳐야 하며, 이로 따라 GEO 적용 속도는 조직 구조에 의해 제한됩니다.&lt;br&gt;&lt;br&gt;네 번째 문제는 &lt;strong&gt;효과 측정&lt;/strong&gt;입니다. 기존 SEO는 클릭 수, 클릭 확률, 순위 등 명확한 지표가 존재했습니다. 그러나 GEO는 “인용”이라는 새로운 지표를 중심으로 움직이며, 이는 정량화하기 어렵고 플랫폼별로 측정 방식도 다릅니다.&lt;br&gt;&lt;br&gt;결국 GEO는 “어떻게 잘 만들 것인가”보다 “어떻게 지속적으로 운영하고 개선할 것인가”가 더 중요한 문제로 전환됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;AI 기반 구조화 데이터 생성 파이프라인&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;위에서 언급한 문제의 해결을 위해 사내에서는 AI를 활용한 GEO 자동화 파이프라인을 실험적으로 구축하고 있습니다. 핵심 아이디어는 사람이 직접 GEO 태그를 작성하는 대신, AI가 콘텐츠를 읽고 구조화 데이터를 자동으로 생성하도록 만드는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3713/image2.png"&gt;&lt;figcaption&gt;GEO를 위한 태그 생성 및 제공 프로세스 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;먼저 GEO 태그 생성 프로세스는 크게 네 단계로 구성됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 &lt;strong&gt;콘텐츠 수집 단계&lt;/strong&gt;입니다. CMS, 내부 API, 혹은 HTML 크롤링을 통해 웹 페이지의 본문 자료를 수집합니다. 이때 중요한 것은 단순 HTML이 아니라 “의미 있는 텍스트”를 추출하는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는&lt;strong&gt;크롤링한 콘텐츠의 클렌징 및 MD 형식으로의 변환 단계&lt;/strong&gt;입니다. HTML 내의 광고, 내비게이션, 불필요한 태그 등을 제거하고 LLM이 이해하기 쉬운 형태로 데이터를 변환합니다. 이 단계는 결과 품질에 매우 큰 영향을 미치면서도 사용하는 사용할 소비 토큰을 줄여주는 효과도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;세 번째는 &lt;strong&gt;AI 분석 단계&lt;/strong&gt;입니다. AI 모델은 MD 파일을 분석하여 제목, 작성자, 발행일, 핵심 주제, 키워드, 엔티티 등을 추출합니다. 특히 엔티티 추출은 GEO에서 매우 중요한 역할을 하며, 이는 AI가 콘텐츠를 “지식 단위”로 이해하는 데 도움을 줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;네 번째는 &lt;strong&gt;구조화 데이터 생성 단계&lt;/strong&gt;입니다. 추출된 정보를 기반으로 schema.org 표준에 맞는 JSON-LD를 생성하고, 이를 CDN 엣지 플랫폼 내의 KV 스토어 데이터베이스에 저장합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;다음은 특정 페이지 내용을 태그 생성 프로세스를 통해 저장한 JSON-LD의 예제 일부입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;{
  "@context": "https://schema.org",
  "@graph": [

    {
      "@type": "WebSite",
      "@id": "https://learn-ai.brandonkang.org/#website",
      "url": "https://learn-ai.brandonkang.org/",
      "name": "Learn AI",
      "description": "Learn AI is a practical knowledge hub covering AI fundamentals, large language models, GPU infrastructure, inference optimization, and Kubernetes-based AI systems.",
      "inLanguage": "en",
      "publisher": {
        "@id": "https://learn-ai.brandonkang.org/#person"
      }
    },

    {
      "@type": "Person",
      "@id": "https://learn-ai.brandonkang.org/#person",
      "name": "Brandon Kang",
      "url": "https://learn-ai.brandonkang.org/",
      "jobTitle": "Technical Solutions Architect",
      "knowsAbout": [
        "Artificial Intelligence",
        "Large Language Models",
        "GPU Computing",
        "AI Inference",
        "Kubernetes",
        "Cloud Infrastructure"
      ]
    },
…&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 중요한 사항은 “완벽성”이 아니라 “일관성”입니다. 일부 필드가 완벽하지 않더라도, 모든 페이지에 일정 수준의 구조화 데이터가 지속적으로 제공되는 것이 GEO 관점에서는 훨씬 더 중요합니다. 또한 이 파이프라인은 이벤트 기반 혹은 주기적 배치 방식으로 동작하여, 콘텐츠가 업데이트될 때 자동으로 메타데이터가 재생성됩니다. 이는 GEO를 단발성 작업이 아닌 데이터 파이프라인으로 전환하는 핵심 요소입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;CDN 엣지 기반 GEO 자동 삽입 아키텍처&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이제 위에서 생성한 데이터를 실제 사용자에게 전달되는 HTML에 포함하는 GEO 태그 제공 프로세스가 필요합니다. 많은 기업에서는 원본 웹 서버나 CMS를 자주 수정하는 것이 쉽지 않습니다. 최종 테스트 및 검수와 배포 프로세스를 지켜야 하기 때문입니다. 그래서 CDN 플랫폼을 활용한 쉬운 배포 방식을 선택했습니다. 사실 이 방식 때문에 동일한 CDN의 엣지에 배포된 KV 스토어를 사용하여 데이터 이동 시간을 최소화한 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI 에이전트가 웹 페이지를 요청하면 CDN 엣지 서버에서 구동하는 서버리스 함수는 원본 HTML 응답을 가로채고, 사전에 생성된 JSON-LD 데이터를 가져와 해당 페이지의 &amp;lt;head&amp;gt; 태그 내 삽입하여 최종 전달합니다. 아래는 그 과정을 수행하는 함수 예제입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;#rewrite.js
import { HtmlRewritingStream } from 'html-rewriter';
import { httpRequest } from 'http-request';
import { createResponse } from 'create-response';
import { EdgeKV } from 'edgekv';

export async function responseProvider(request) {

  // 1. 원본 HTML 요청
  let htmlResponse = await httpRequest(request);
  if (!htmlResponse.ok) {
    return createResponse(500, {}, `Failed to fetch doc: ${htmlResponse.status}`);
  }

  // 2. EdgeKV 초기화
  const edgeKv = new EdgeKV({
    namespace: "geo",
    group: "jsonld"
  });

  // 3. URL → key
  const url = new URL(request.url);
  const key = url.pathname.replace(/\/$/, "") || "/";

  let jsonLd = null;

  try {
    jsonLd = await edgeKv.getText({ item: key });
  } catch (e) {
    jsonLd = null;
  }

  let rewriter = new HtmlRewritingStream();
  let injected = false;

  // 4. 기존 JSON-LD 체크 (중복 방지)
  rewriter.onElement('script[type="application/ld+json"]', el =&amp;gt; {
    injected = true;
  });

  // 5. &amp;lt;head&amp;gt;에 GEO 블록 삽입
  rewriter.onElement('head', el =&amp;gt; {
    if (!injected &amp;amp;&amp;amp; jsonLd) {
      el.append(`
        &amp;lt;!-- GEO / Structured Data --&amp;gt;
        &amp;lt;script type="application/ld+json"&amp;gt;${jsonLd}&amp;lt;/script&amp;gt;
      `);
    }
  });

  // 6. 응답 반환
  return createResponse(200, {}, htmlResponse.body.pipeThrough(rewriter));
}

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 수정된 HTML은 짧은 주기 동안 CDN 캐시에 저장되어 다음 AI 에이전트의 요청부터는 별도의 삽입 과정 없이 빠르게 전달됩니다. 원본 콘텐츠가 변경되는 경우 어차피 웹 사이트 관리자는 CDN 캐시를 무력화하는 명령을 수행하기에 새로운 GEO 태그가 적용될 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3713/image3.png"&gt;&lt;figcaption&gt;최종적으로 페이지에 적용된 JSON-LD 태그&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 방식의 가장 큰 장점은 원본 시스템을 전혀 수정하지 않고, 사용자 주변에 가장 가까운 곳에 위치한 CDN에서 모든 작업을 수행한다는 점입니다. 결과적으로 원본 서버의 애플리케이션 코드, CMS, 데이터베이스에 영향을 주지 않으면서 GEO를 적용할 수 있습니다. 오히려 사용자와 가까운 위치에서 캐싱된 응답이 전달되기에 체감 성능이 개선되는 경우도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;이 접근은 GEO를 “콘텐츠 레벨”이 아니라 “플랫폼 레벨”에서 적용하는 방식이라고 볼 수 있습니다. 즉, 웹 사이트 개발팀이 아니라 인프라팀에서 GEO 태그를 통제할 수 있게 되는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;GEO 적용 이후 무엇을 확인해야 하는가?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;GEO를 적용한 이후 가장 중요한 질문은 “그래서 효과가 있는가?”입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3713/image1.png"&gt;&lt;figcaption&gt;GEO 적용 이후 구글 사이트에서의 테스트 예제 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;현재 프로토타입에서는 이를 검증하기 위해 세 가지 관점에서 자료를 수집하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 &lt;strong&gt;크롤링 패턴&lt;/strong&gt;입니다. AI 에이전트들이 어떤 페이지에 얼마나 자주 접근하는지를 CDN 로그 기반으로 분석합니다. 이는 AI가 어떤 콘텐츠를 “관심 있게 보는지”를 간접적으로 보여줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;두 번째는 &lt;strong&gt;인용 여부&lt;/strong&gt;입니다. 특정 질문에 대해 AI가 자사 콘텐츠를 실제로 인용하는지를 반복적으로 테스트합니다. 이는 기존 SEO의 순위 확인과 유사하지만, 훨씬 더 실험적인 접근이 필요합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;세 번째는 &lt;strong&gt;사용자 행동 변화&lt;/strong&gt;입니다. AI 기반 유입이 실제 트래픽 증가나 브랜드 인지도 향상으로 이어지는지를 분석합니다. 특히 AI 답변을 통한 간접 유입은 기존 분석 도구로는 포착하기 어려운 경우도 많아, 새로운 지표 설계가 필요합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;br&gt;&lt;strong&gt;JSON-LD가 전부는 아니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;한 가지 중요한 사항은 GEO 태그가 적용되었다고 해서 반드시 AI 검색 결과에 바로 반영되는 것은 아니라는 점입니다. 구조화 데이터는 중요한 정보지만, 실제 AI 답변 생성 과정에서는 그것만으로 인용 여부가 결정되지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 많은 조직에서 GEO를 “JSON-LD를 잘 넣는 작업”으로 이해하는 경우가 있는데, 구조화 데이터는 콘텐츠의 의미를 명확하게 전달하는 데 도움을 주는 보조적인 신호일 뿐이며, AI가 실제로 인용할지를 결정하는 핵심 요소는 결국 콘텐츠 자체입니다. 검색 엔진의 AI는 구조화 데이터보다도 본문에 포함된 정보의 명확성, 질문과의 직접적인 연관성, 그리고 문장의 재사용 가능성을 더 중요하게 판단합니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반대로 생각해 보면, 구조화 데이터가 다소 부족하더라도, 특정 질문에 대해 명확하게 답하는 문장이 잘 정리되어 있고, 콘텐츠의 구조가 논리적으로 구성되어 있다면 AI는 해당 콘텐츠를 충분히 활용할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3713/image4.png"&gt;&lt;figcaption&gt;AEO, GEO 적용을 위한 모범 사례 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 중요한 것은 “AI가 이해하기 쉬운 콘텐츠를 만드는 것”입니다. 구조화 데이터는 그 과정을 돕는 도구일 뿐이며, 이를 과도하게 의존하기보다는 콘텐츠 자체의 품질과 구조를 먼저 설계하는 접근이 필요합니다. 이러한 구조를 고려하면, GEO에서 구조화된 메타데이터는 “필수 조건”이 아니라 “가속 장치”에 가깝습니다. 구조화 데이터가 잘 되어 있으면 AI가 콘텐츠를 더 빠르고 정확하게 이해할 수 있지만, 결국 인용 여부를 결정하는 것은 콘텐츠 자체의 품질과 맥락 적합성입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결과적으로 GEO는 더 이상 엔지니어링 팀만의 영역이 아닙니다. 구조화 데이터를 적용하는 기술적인 작업을 넘어, 웹 콘텐츠를 기획하고 작성하는 단계부터 AI가 이해하기 쉬운 형태로 정보를 구성하는 것이 중요해졌습니다. 즉, 콘텐츠 제작자 역시 GEO가 선호하는 정보 구조와 서술 방식, 그리고 문맥(Context)을 고려해야 하는 시대가 된 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이는 단순히 키워드를 잘 배치하는 수준을 넘어, 질문에 직접적으로 답할 수 있는 문장 구조, 명확한 정보 단위, 그리고 AI가 재사용하기 쉬운 콘텐츠 형태를 만드는 방향으로 콘텐츠 전략 자체가 변화하고 있음을 의미합니다. 좀 더 자세한 내용은 기존 요즘IT 글 “&lt;a href="https://yozm.wishket.com/magazine/detail/3654/"&gt;&lt;u&gt;AI 시대 콘텐츠 생존 전략: GEO를 위한 SIFT 프레임워크&lt;/u&gt;&lt;/a&gt;”를 참고하시기 바랍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;GEO는 이제 콘텐츠 전략을 넘어선 플랫폼 전략&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI 검색 환경에서는 어떤 콘텐츠가 “검색되는가”가 아니라, 어떤 콘텐츠가 “인용되는가”가 더 중요한 시대가 되었습니다. 콘텐츠 규모가 커질수록 이를 수작업으로 관리하는 방식은 한계를 가질 수밖에 없습니다. 따라서 앞으로 기업이 고민해야 할 질문은 GEO를 어떻게 자동화하고 운영할 것인가로 바뀔 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;본문에서 소개한 AI 기반 콘텐츠 분석, 서버리스 컴퓨팅, CDN 엣지 아키텍처를 결합한 접근은 이러한 문제를 해결할 수 있는 현실적인 방법 중 하나입니다. 이러한 흐름에 맞춰 구조화 데이터 생성, 콘텐츠 최적화, AI 인용 분석을 자동화하는 전문 도구와 서비스들이 속속 등장하고 있으며, GEO를 하나의 운영 체계로 관리하려는 시도도 점점 늘어나고 있습니다. 앞으로는 단순히 콘텐츠를 잘 만드는 것을 넘어, AI가 이해하고 활용하기 좋은 형태로 콘텐츠를 설계하고 이를 지속적으로 최적화하는 역량이 기업 경쟁력의 중요한 기준이 될 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>4계층 문서 체계로 만드는 AI Driven 쿠버네티스 운영 표준</title><link>https://yozm.wishket.com/magazine/detail/3710</link><description>바이브 코딩(Vibe Coding)이 자연어로 코드를 생성하는 것이라면, 바이브옵스(VibeOps)는 자연어로 인프라를 운영하는 것입니다. 실제로 진행한 대규모 인프라 변경 프로젝트에서 AI 코파일럿인 Claude Code를 열심히 활용하며 발견한 문제들과 이를 해결하기 위해 자연스럽게 만들어진 4계층 문서 체계(Four-Layer Document Architecture)와 Command Guardrails 패턴을 소개할 예정입니다. 이 구조는 처음부터 설계된 것이 아닙니다. AI와 함께 일하면서 부딪힌 한계를 하나씩 보완한 결과물입니다. AI에게 단순히 명령을 시키는 것이 아니라, AI가 올바르게 행동하도록 구조를 설계하는 방법에 대해 말해 보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3710</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;바이브 코딩&lt;span style="color:#757575;"&gt;(Vibe Coding)&lt;/span&gt;이 자연어로 코드를 생성하는 것이라면, 바이브옵스&lt;span style="color:#757575;"&gt;(VibeOps)&lt;/span&gt;는 자연어로 인프라를 운영하는 것입니다. &lt;a href="https://yozm.wishket.com/magazine/detail/3325/"&gt;이전 글&lt;/a&gt;에서 바이브옵스의 기본 개념과 제미나이 CLI, 클로드 코드를 활용한 기본적인 사용법을 다뤘는데, 이번 글에서는 조금 다른 이야기를 해보려고 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 진행한 대규모 인프라 변경 프로젝트에서 AI 코파일럿인 Claude Code를 열심히 활용하며 발견한 문제들과 이를 해결하기 위해 자연스럽게 만들어진 &lt;strong&gt;4계층 문서 체계&lt;/strong&gt;&lt;span style="color:#757575;"&gt;(Four-Layer Document Architecture)&lt;/span&gt;와 &lt;strong&gt;Command Guardrails 패턴&lt;/strong&gt;을 소개할 예정입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 구조는 처음부터 설계된 것이 아닙니다. AI와 함께 일하면서 부딪힌 한계를 하나씩 보완한 결과물입니다. 따라서 누구나 자신의 환경에서 점진적으로 도입할 수 있다는 것이 핵심입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;AI에게 단순히 명령을 시키는 것이 아니라, AI가 올바르게 행동하도록 구조를 설계하는 방법&lt;/strong&gt;에 대해 말해 보겠습니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;문제 인식: 제한된 리소스의 제약&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;앞서도 저는 이와 유사한 프로젝트를 진행한 적이 있습니다. 24시간 무중단으로 운영하는 중요한 플랫폼의 대규모 변경 작업이었습니다. V1에서 V2로 넘어가는 차세대 프로젝트로 예정된 일이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기에 제약 조건까지 있었습니다. 리소스가 제한적이어서 &lt;strong&gt;DevOps/SRE 1명이 DEV와 PROD를 동시에 구축&lt;/strong&gt;할 뿐만 아니라 운영에 필요한 모든 요소의 배포 설정을 진행해야 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;쿠버네티스 기반의 플랫폼이었기 때문에, 할 일로는 다수의 노드와 수백 개의 파드, 다수의 Helm 릴리스에 Kafka, Redis 같은 데이터 계층의 전환, 옵저버빌리티 스택 전체 재구축, 수십 개의 알림 규칙과 알림 경로까지 포함되어 있었습니다. 단순 복제가 아니라 아키텍처 현대화를 포함하는 전면 재설계 작업이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;전통적 접근의 한계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;전통적인 DevOps/SRE 워크플로우는 Wiki를 읽고, 터미널에서 수작업을 하고, 결과를 다시 Wiki에 기록하는 순서로 진행됩니다. 그런데 여기에는 문제가 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;IaC&lt;span style="color:#757575;"&gt;(Infrastructure as Code)&lt;/span&gt;는 선언적이지만 상황에 따른 판단은 하지 못합니다. 한편 Runbook은 상황마다 달라서 그대로 실행하기 어렵고, 자동화 스크립트는 그 자체의 유지보수가 또 다른 부담이 됩니다. 그래서 이런 질문을 던졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;만약 runbook을 이해하고, 상황에 맞게 판단하고, 실행까지 하는 동료가 있다면 어떨까?&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그에 대한 답으로 Claude Code를 전면에 활용하기로 결정했습니다. 규모가 큰 프로젝트라서 AI를 쓴 것이 아니라 &lt;strong&gt;제한된 리소스라는 제약 속에서 AI를 동료로 삼는 방법을 찾아야 한 것&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;4계층 문서 체계의 탄생&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이러한 협업을 위해 만든 4계층 문서 체계는 처음부터 설계된 것이 아닙니다. 단계마다 AI의 한계를 발견하고, 그 한계를 보완하기 위한 계층을 하나씩 추가하면서 자연스럽게 진화한 결과입니다. 각 계층이 왜 필요해졌는지를 순서대로 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Layer 1: work-plans, 사람이 읽는 계획서&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;가장 먼저 만든 것은 사람이 읽고 판단하기 위한 상세 계획서입니다. 한국어로 쓰며, 각 컴포넌트의 Why, How, 트레이드오프를 문서화합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;work-plans/
├── 00-main/&amp;nbsp;             # 마스터 플랜 + DEV/PROD 런북
├── 10-infrastructure/&amp;nbsp;   # EKS, 스토리지, AWS 연동
├── 20-platform/&amp;nbsp;         # Prometheus, Loki, Tempo, ArgoCD
├── 30-data/&amp;nbsp;             # Valkey, Kafka, Kafka Streams
├── 40-transition/&amp;nbsp;       # 무중단 전환, Weighted Routing
└── 90-future-projects/&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 문서를 AI에게 그대로 주면 어떻게 될까요? 너무 길고, 맥락이 많고, 한국어와 영어가 섞여 있으니, AI가 핵심을 놓치거나 엉뚱한 부분에 집중하는 현상이 발생했습니다. &lt;strong&gt;사람이 보는 문서와 AI가 보는 문서는 달라야 한다는 것을 깨달았습니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Layer 2: claude-context, AI를 위해 증류한 문서&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;그래서 work-plans의 핵심만을 영어로, 최소한 증류(distill)한 문서를 만들었습니다. AI가 프로젝트 상태를 즉시 파악하는 대시보드 역할을 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;claude-context/
├── 00-project-summary.md     # 프로젝트 1페이지 요약
├── 01-environment-values.md&amp;nbsp; # 모든 환경 값 (복붙 가능)
├── 02-document-map.md&amp;nbsp;       # 문서 네비게이션 맵
├── 03-current-status.md&amp;nbsp;     # 현재 배포 상태 (라이브)
└── 99-execution-guide.md     # 실행 순서 + 체크리스트&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;work-plans가 교과서라면 claude-context는 시험 범위 요약노트에 가까운 느낌입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 여전히 문제는 있었습니다. AI가 맥락은 이해하는데, 실행할 때 자기 나름대로 명령어를 만들어냈습니다. 예를 들어 “Loki 설치해줘”라고 하면 AI가 &lt;code&gt;helm install&lt;/code&gt; 명령을 자체 생성하는데, 버전이 다른데다 values는 누락되고 네임스페이스가 틀리는 일까지 발생했습니다. &lt;strong&gt;AI가 이해하는 것과 올바르게 실행하는 것은 다른 문제였습니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Layer 3: command-guardrails, AI의 행동 제어&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이 계층이 이 글의 핵심인 Command Guardrails 패턴입니다. 각 파일은 단계별 실행 가이드로, 마크다운 안에 bash 블록을 포함하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;command-guardrails/
├── dev/
│   ├── 00-prerequisites/&amp;nbsp;   # KMS, S3, EFS
│   ├── 10-infrastructure/   # EKS, 노드그룹, 애드온
│   ├── 20-platform/         # Helm (Prometheus, Loki...)
│   ├── 30-data/             # Valkey, Kafka
│   ├── 40-transition/       # 알림, 도메인, 트래픽 전환
│   └── 80-rollback/         # 롤백 절차
└── prod/
    └── (동일 구조, PROD 값 + DEV 교훈 반영)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;핵심 설계 원칙은 이렇게 잡았습니다. 기존 V1을 보호하며, get, describe, logs만 허용하고, 순서를 00에서 10, 20, 30, 40으로 강제합니다. 즉, &lt;strong&gt;AI 시대의 인프라 문서는 사람이 읽는 문서가 아니라, AI가 실행하는 문서라고 정의한 것&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 문제는 하나 더 있었습니다. Guardrail에 helm upgrade prometheus-stack만 적으면 AI가 &lt;code&gt;--set&lt;/code&gt; 플래그를 창의적으로 만들어냈습니다. 경우의 수가 폭발하니 재현할 수 없는 배포가 되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Layer 4: helm-values, IaC에 가까워진 계층&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이 계층은 실제 사고를 2건 겪고 나왔습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;사고 1: Mimir 버전 업그레이드&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;guardrail 문서에 helm upgrade mimir만 적고 --version을 지정하지 않은 일이 있었습니다. AI는 지시를 그대로 실행했고, chart 5.8.0 환경에서 최신 6.0.5로 자동 업그레이드가 됐습니다. Mimir 6.0에는 Kafka 기반 ingest storage 기본 활성화, Nginx 제거 후 Unified Gateway 교체, Rollout-operator 웹훅 기본 활성화라는 세 가지 breaking change가 있어서 기존 5.x의 --set 값들이 6.x 스키마와 맞지 않으면서 ingester, distributor 파드가 전부 CrashLoopBackOff에 빠졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이에 맞춰 다시 6.0으로 올리려면 ingest storage 구성, gateway 마이그레이션, CRD 사전 설치까지 한꺼번에 해야 하는데, 1인 DevOps/SRE가 DEV+PROD 동시 구축하는 상황에서 감당할 수준이 아니었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 helm rollback으로 복구한 다음 5.8.0으로 버전을 고정하고 진행했습니다. 이 사고에서 얻은 교훈이 Layer 4입니다. --version 5.8.0, -f helm-values/mimir.yaml로 버전도 값도 파일로 고정해서 AI에게 해석의 여지를 없앴습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;사고 2: 알림 규칙의 false alarm&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;AI에 “CPU 사용률 80% 넘으면 알림 만들어줘”라고 지시했더니, Grafana alert rule의 &lt;code&gt;relativeTimeRange&lt;/code&gt;을 600초&lt;span style="color:#757575;"&gt;(쿼리 범위 10분)&lt;/span&gt;, for를 5분&lt;span style="color:#757575;"&gt;(조건 지속 시간)&lt;/span&gt;으로 설정했습니다. 10분 범위 안에 순간 스파이크가 하나만 찍혀도 조건이 충족되고, 그 스파이크가 윈도우 안에 남아 있는 동안 5분이면 바로 firing이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;배포 직후 파드 스케일링 때마다 CPU가 잠깐 튀면서 새벽에도, 배포할 때도 알림이 울렸습니다. 게다가 AI가 같은 패턴으로 알람을 생성했기 때문에, 7개 규칙이 전부 같은 문제를 가지고 있었습니다. 문제를 해결하기 위해 &lt;code&gt;relativeTimeRange&lt;/code&gt;을 300초로 줄이고, for를 10분으로 늘리고, 쿼리를 &lt;code&gt;avg_over_time&lt;/code&gt;으로 바꿔서 수정했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 얻은 교훈은, 알림 파라미터도 Guardrail 본문에 쓰면 안 된다는 겁니다. AI는 합리적으로 보이는 값을 만들어내지만, 그게 운영 환경에서 맞는지는 별개 문제이기 때문입니다. 그래서 알림 임계값, 평가 주기, for 기간 같은 파라미터를 전부 helm-values 파일로 빼서 관리하게 됐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최종적으로 helm 명령어는 다음과 같은 형태가 되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;helm upgrade loki grafana/loki \
  --version 6.30.0 \&amp;nbsp;       # 버전 고정
  -f helm-values/loki.yaml \ # 값 고정 (IaC)
  -n monitoring \&amp;nbsp;           # 네임스페이스 고정
  --wait --timeout 10m       # 동작 고정&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 4개의 계층이 완성되었습니다. 정리하면 위에서 아래로 갈수록 추상에서 구체로, 자유도는 감소하되 재현성은 증가하는 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3710/image1.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Tip. 왜 AI를 위한 문서는 영어로 증류해야 하는가&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;4계층 체계에서 주목할 점 가운데 하나는 Layer 2&lt;span style="color:#757575;"&gt;(claude-context)&lt;/span&gt;가 영어로 작성된다는 것입니다. 이는 단순히 AI가 영어를 더 잘 이해하기 때문만은 아닙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫째, &lt;strong&gt;토큰 효율성&lt;/strong&gt; 문제입니다. 한국어는 영어 대비 동일한 내용을 표현하는 데 더 많은 토큰을 소비합니다. Claude Code의 컨텍스트 윈도우는 유한하기 때문에, 같은 정보를 더 적은 토큰으로 전달하는 영어가 효율적입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;둘째, &lt;strong&gt;기술 용어의 일관성&lt;/strong&gt; 문제입니다. 쿠버네티스 생태계의 용어는 대부분 영어 기반입니다. “노드그룹”과 “nodegroup”, “네임스페이스”와 “namespace”가 혼재되면 AI가 매칭에 실패하는 경우가 있습니다. AI가 읽을 문서에서 기술 용어를 영어로 통일하면 이러한 혼선을 방지할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;셋째, &lt;strong&gt;명령어와의 직접 연결&lt;/strong&gt;입니다. AI가 context 문서를 읽고 바로 셸 명령어를 생성해야 하는데, 한국어 설명에서 영어 명령어로 전환하는 과정에서 오류가 발생할 확률이 높습니다. 영어로 작성된 context는 명령어 생성까지의 경로를 짧게 만들어 줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 이러한 제약으로, 모든 문서를 영어로 써야 한다는 의미는 아닙니다. Layer 1&lt;span style="color:#757575;"&gt;(work-plans)&lt;/span&gt;은 사람이 의사결정을 위해 읽는 문서이므로 한국어가 적합합니다. 즉, &lt;strong&gt;“누가 읽느냐”에 따라 언어를 구분하는 것&lt;/strong&gt;이 핵심입니다.&lt;/p&gt;&lt;hr&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;CLAUDE.md: AI가 가장 먼저 읽는 행동 규칙&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;4계층 문서 체계 외에 한 가지 더 중요한 요소가 있습니다. 바로 &lt;strong&gt;CLAUDE.md&lt;/strong&gt; 파일입니다. 이 파일은 Claude Code가 프로젝트 디렉터리에 진입했을 때 가장 먼저 읽는 파일로, AI의 행동 규칙&lt;span style="color:#757575;"&gt;(Ground Rules)&lt;/span&gt;을 정의합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/detail/3334/"&gt;이전 글&lt;/a&gt;에서 제미나이 CLI의 GEMINI.md를 다룬 적이 있는데, CLAUDE.md도 동일한 역할을 합니다. 차이가 있다면 4계층 문서 체계와 결합되어 더 구조적으로 동작한다는 점입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, 실제 운영 환경에서 사용되는 CLAUDE.md는 다음과 같은 규칙을 포함합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;# Ground Rules

## 허용되는 명령어
- kubectl get / describe / logs 만 허용
- helm list / helm status 만 허용

## 금지되는 명령어
- kubectl delete / apply / patch 금지
- helm install / upgrade / uninstall 금지

## 문서 참조 순서
1. memory/MEMORY.md를 먼저 읽을 것
2. claude-context/에서 현재 상태 파악
3. command-guardrails/에서 실행 가이드 확인
4. guardrail에 없는 명령은 실행하지 말 것&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 적어 두면 AI가 자기 마음대로 명령어를 만들어내는 것을 막을 수 있습니다. 특히 &lt;strong&gt;“guardrail에 없는 명령은 실행하지 말 것”&lt;/strong&gt;이라는 규칙이 중요한데, 이는 AI가 할 수 있는 행동의 범위를 명확하게 제한해 줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;settings.local.json&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;여기에 더해서 &lt;strong&gt;.claude/settings.local.json&lt;/strong&gt;을 설정하면 V1 보호를 도구 수준에서 강제할 수 있습니다. CLAUDE.md가 자연어로 된 규칙이라면, settings.local.json은 실제로 명령어 실행 자체를 허용하거나 차단하는 설정입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;{
  "permissions": {
    "allow": [
      "Bash(kubectl --context=sysnet4admin-v1 get *)",
      "Bash(kubectl --context=sysnet4admin-v1 describe *)",
      "Bash(kubectl --context=sysnet4admin-v1 logs *)",
      "Bash(kubectl --context=sysnet4admin-v2 *)",
      "Bash(helm --kube-context=sysnet4admin-v2 *)",
      "Bash(aws * --profile sysnet4admin *)",
      "Bash(eksctl * --profile sysnet4admin *)"
    ],
    "deny": [
      "Bash(kubectl --context=sysnet4admin-v1 apply *)",
      "Bash(kubectl --context=sysnet4admin-v1 delete *)",
      "Bash(kubectl --context=sysnet4admin-v1 patch *)",
      "Bash(kubectl --context=sysnet4admin-v1 edit *)",
      "Bash(kubectl --context=sysnet4admin-v1 scale *)",
      "Bash(kubectl --context=sysnet4admin-v1 exec *)",
      "Bash(helm --kube-context=sysnet4admin-v1 install *)",
      "Bash(helm --kube-context=sysnet4admin-v1 upgrade *)",
      "Bash(helm --kube-context=sysnet4admin-v1 uninstall *)",
      "Bash(helm --kube-context=sysnet4admin-v1 delete *)"
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;V1&lt;span style="color:#757575;"&gt;(sysnet4admin-v1)&lt;/span&gt;에는 &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;describe&lt;/code&gt;, &lt;code&gt;logs&lt;/code&gt;만 허용하고, &lt;code&gt;apply&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt; 같은 변경 명령은 전부 차단합니다. 반면 V2&lt;span style="color:#757575;"&gt;(sysnet4admin-v2)&lt;/span&gt;에는 모든 명령을 허용해서 자유롭게 작업할 수 있도록 합니다. 이렇게 하면 CLAUDE.md에서 자연어로 안내하는 규칙을 설정 파일이 실제로 강제하게 되므로, AI가 실수로라도 V1 프로덕션에 변경을 가하는 것을 방지할 수 있습니다.&lt;/p&gt;&lt;hr&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;4계층 문서에 기반한 운영 전략과 도입 방법&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이처럼 계층 문서 기반으로 인프라 관리에 접근하다 보니 다양한 변화를 만날 수 있었습니다. AI와 함께 일하며 확장할 수 있는 방향성과 실제 도입 과정에서 느낀 것을 정리했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. GitAIOps&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이렇게 만들어진 4계층 문서 체계를 Git으로 관리하면 재미있는 부분이 생깁니다. AI를 위해 만든 문서가 동시에 팀 전체의 운영 표준이 되는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3710/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-04-14_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_2_20_53.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 개념을 &lt;strong&gt;GitAIOps&lt;/strong&gt;라고 부릅니다. GitOps가 선언적 인프라에서 Git을 Single Source of Truth로 삼는 것이라면, GitAIOps는 여기에 AI가 문서를 이해하고 실행하는 계층을 추가한 것입니다. 누가 실행해도 같은 결과가 나오니 일관성이 보장되고, 변경 이력이 남으니 감사 추적이 가능합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. AI에게 맡기는 것의 경계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;4계층 문서 체계를 구축했다고 해서 모든 것을 AI에게 맡길 수 있는 것은 아닙니다. 오히려 이 체계를 운영하면서 AI에게 맡기기 좋은 것과 사람이 판단해야 하는 것의 경계가 더 명확해졌습니다. 무엇보다 AI는 자동 운전이 아니라 운전 보조라는 것을 잊지 말아야 합니다. &lt;strong&gt;핸들은 사람이 잡되, 사각지대를 AI가 잡아준다&lt;/strong&gt;는 느낌으로 써야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3710/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-04-14_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_2_21_05.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. DEV에서 PROD로: Guardrail 재사용 패턴&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;4계층 체계가 가장 효과적인 부분은 &lt;strong&gt;DEV에서 PROD로 넘어갈 때&lt;/strong&gt;입니다. DEV에서 검증된 Guardrail을 PROD에 재사용할 때, 단순 복사가 아니라 DEV에서의 교훈을 반영하는 것이 핵심입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 PROD Guardrail에는 DEV 교훈이란 섹션이 자동으로 추가됩니다. 예를 들어 DEV에서 Mimir 버전 사고가 있었다면, PROD Guardrail에는 해당 버전 고정에 대한 경고와 함께 검증된 버전 번호가 명시됩니다. DEV 환경 전체 구축에 약 2일이 걸렸다면, 이 Guardrail을 재사용하는 PROD 환경 구축은 약 1일로 단축됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 Guardrail이 축적되면 재사용할수록 구축 속도가 빨라집니다. 그리고 이 패턴은 쿠버네티스에만 적용되는 것이 아닙니다. Terraform, Ansible 등 어떤 IaC 도구를 사용하더라도 동일한 구조를 적용할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4. 생산성 변화&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;직접 AI 기반 운영을 도입하니 아래와 같은 생산성 변화가 일어났습니다. &lt;strong&gt;AI가 사람을 대체한 게 아니라, 제한된 리소스의 커버리지를 몇 배로 확장했다는 점&lt;/strong&gt;을 가장 크게 느꼈습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3710/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-04-14_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_2_21_16.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;5. 조직에 적용할 점진적 도입 로드맵&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이러한 구조를 우리 조직에 한 번에 도입할 필요는 없습니다. 그보다는 단계적으로 조금씩 접근하는 것이 현실적입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Level 0 (1주):&lt;/strong&gt;기존 runbook을 구조화된 마크다운 형식의 문서로 정리합니다. 이것만으로도 문서 가독성이 크게 향상됩니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Level 1 (2~4주):&lt;/strong&gt;Claude Code로 DEV 환경에서 실험을 시작합니다. 이전 바이브옵스 글에서 다룬 것처럼, 먼저 DEV에서 충분히 테스트하는 것이 중요합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Level 2 (1~2개월):&lt;/strong&gt;Context + Guardrails 2계층 체계를 구축합니다. 실제 운영에서 발생하는 문제들을 반영하면서 점진적으로 완성합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Level 3 (지속):&lt;/strong&gt;DEV에서 PROD로의 패턴이 정착되고, helm-values(IaC)가 추가됩니다. 이 단계에서는 guardrail이 팀의 표준 운영 절차(SOP)가 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;hr&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며: DevOps/SRE의 역할 변화&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이 글에서 다룬 4계층 문서 체계와 Command Guardrails 패턴을 보면, DevOps 엔지니어와 SRE의 역할이 바뀌고 있다는 것을 알 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;전통적인 DevOps/SRE가 kubectl을 직접 실행하는 사람이었다면, AI-Driven DevOps/SRE는 AI가 실행할 가이드를 설계하는 사람입니다. Runbook을 작성하던 역할은 Guardrails를 설계하는 역할로, 수동으로 감사하던 역할은 AI가 감사한 결과를 검증하는 역할로 바뀝니다. 반복 작업을 수행하는 대신 판단과 의사결정에 집중하게 되고, 혼자 환경 하나만 담당하던 것이 혼자 환경 N개를 커버할 수 있게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI가 잘하는 것은 최대한 활용하되, 실행에서 틀리지 않도록 구조로 잡아주는 것. 그것이 4계층 문서 체계와 Command Guardrails 패턴이 하는 일이며, 얻어가야 할 교훈입니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;부록 1: AI의 기억 관리를 위한 Memory 시스템&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;4계층 문서 체계를 운영하다 보면 자연스럽게 마주치는 문제가 하나 더 있습니다. Claude Code와 긴 대화를 나누다 보면 컨텍스트 압축(compaction)이 발생한다는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어 35개 알림 규칙을 전수 분석해서 P0/P1/P2로 분류했는데, compaction이 발생하면 원본이 사라지고 “P0/P1/P2 분류 완료”라는 요약만 남습니다. 이 상태에서 “P1 항목이 뭐였지?”라고 물으면 AI는 대답할 수 없게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 문제를 해결하기 위해 4계층과 동일한 원리를 적용한 &lt;strong&gt;memory 시스템&lt;/strong&gt;을 도입했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;memory/
├── MEMORY.md&amp;nbsp;             # 인덱스 (200줄, 자동 주입)
├── alert-gap-analysis.md&amp;nbsp; # 토픽 파일 (필요 시 로드)
├── osd-lessons.md         # 토픽 파일 (필요 시 로드)
└── argocd-lessons.md&amp;nbsp;     # 토픽 파일 (필요 시 로드)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;시스템이 하는 역할은 크게 4가지입니다. compaction에서 살아남는 &lt;strong&gt;맥락 보존&lt;/strong&gt;, “하지 마라”를 축적한 &lt;strong&gt;금지 사항 누적&lt;/strong&gt;&lt;span style="color:#757575;"&gt;(guardrail 보완)&lt;/span&gt;, 대화가 끊어져도 이어지는 &lt;strong&gt;작업 상태 추적&lt;/strong&gt;, 그리고 매 세션마다 재탐색 없이 시작하는 &lt;strong&gt;콜드 스타트 방지&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 중요한 것은 MEMORY.md의 크기 관리입니다. AI 코딩 에이전트에는 200줄을 초과하면 경고 없이 잘려나가는&lt;span style="color:#757575;"&gt;(hard truncation)&lt;/span&gt; 현상이 있고, 오래된 기억은 때로 AI가 잘못된 근거로 판단하는 원인이 됩니다. 실제로 지시 준수율이 200줄 이하에서는 92%인데, 400줄 이상이 되면 71%로 떨어지는 것을 확인했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;따라서 MEMORY.md는 인덱스만 유지하고, 상세 내용은 토픽 파일로 분리합니다. 결국 4계층과 같은 원리입니다. 증류하고, 분리해서, 필요할 때만 로드하기. 이 원칙은 문서 체계뿐 아니라 AI의 기억 관리에도 동일하게 적용됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;부록 2: 옵저버빌리티 감사 데모로 직접 해보기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이 글에서 설명한 구조를 축소해서 직접 체험해볼 수 있는 데모도 준비했습니다. 읽기 전용 감사&lt;span style="color:#757575;"&gt;(Observability Audit)&lt;/span&gt;를 수행하는 구성으로, 4계층 중 실행에 해당하는 부분만 뽑아낸 형태입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;demo/
├── CLAUDE.md&amp;nbsp;                   # AI 행동 규칙
├── claude-context/
│   └── 00-cluster-summary.md&amp;nbsp;   # 클러스터 맥락
├── command-guardrails/
│   └── observability-audit.md   # 실행 가이드
└── memory/
    └── MEMORY.md&amp;nbsp;               # 누적 기억&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;데모를 실행하면 CLAUDE.md에서 READ-ONLY만 허용하고, command-guardrails의 9단계 감사 절차를 AI가 순서대로 실행한 다음, 결과를 Audit Report 형식으로 출력합니다. 실제 감사 리포트 결과와 전체 소스는 &lt;a href="https://github.com/sysnet4admin/talks/tree/main/Byline-Network/2026-ai-era-k8s-cloud-native/demo"&gt;GitHub&lt;/a&gt;에서 확인할 수 있습니다.&lt;/p&gt;&lt;hr&gt;&lt;h4 style="margin-left:0px;text-align:justify;"&gt;&lt;strong&gt;작가&lt;/strong&gt;&lt;/h4&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;&lt;strong&gt;조훈(CNCF 앰버서더)&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;메가존에서 쿠버네티스와 컨테이너 인프라 Tech Evangelist, CoE(Center of Excellence) 역할을 맡고 있다. 클라우드 네이티브 컴퓨팅 재단(CNCF)의 글로벌 앰버서더, ‘IT 인프라 엔지니어 그룹’의 운영진, 오픈소스 컨트리뷰터로도 활동하고 있다. 인프런/유데미에서 앤서블 및 쿠버네티스에 관한 강의를 하고, 『컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커』, 『우아하게 앤서블』, 『시스템/네트워크 관리자를 위한 파이썬 실무 프로그래밍』을 집필하였으며, 요즘IT와 같은 온라인 플랫폼에 글을 기고한다.&lt;/p&gt;&lt;p style="margin-left:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;&lt;strong&gt;심근우&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;LG유플러스 CTO부문에서 대고객 비즈니스 시스템의 DevOps를 담당하는 UcubeDAX팀의 팀장으로 일하고 있다. 퍼블릭 클라우드와 프라이빗 클라우드에 걸친 쿠버네티스 클러스터를 안정적으로 운영하기 위해 노력하고 있으며, 특히 주니어 DevOps 엔지니어들의 육성에 큰 관심을 가지고 있다.&lt;/p&gt;&lt;p style="margin-left:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;&lt;strong&gt;문성주&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;글로벌 소셜 플랫폼 기업에서 Site Reliability Engineer로 재직하며, 쿠버네티스 멀티 클러스터 관리와 데이터베이스 플랫폼 운영을 주도하고 있다. 또한 ISMS-P, GDPR, CCPA 등 글로벌 보안 규제에 부합하는 데이터 라이프사이클 파이프라인을 설계·운영한 실무 경험을 가지고 있으며, 쿠버네티스 오픈소스 프로젝트에도 기여하고 있다. 더불어 국내 주요 기업과 국가 기관의 클라우드 전환, 데이터 거버넌스 컨설팅, 보안 컴플라이언스 대응을 지원하고 있다.&lt;/p&gt;&lt;p style="margin-left:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;&lt;strong&gt;이성민&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;미국 넷플릭스(Netflix) 사의 Data Platform Infrastructure 팀에서 사내 플랫폼 팀들과 데이터 사용자들을 어우르기 위한 가상화 및 도구들을 개발하는 일들을 하고 있다. 과거 컨테이너와 쿠버네티스에 큰 관심을 두고 ingress-nginx를 비롯한 오픈 소스에 참여했으며, 현재는 데이터 분야에 일하게 되면서 stateful 한 서비스들이 컨테이너화에서 겪는 어려움을 보다 근본적으로 해결하기 위한 많은 노력을 하고 있다.&lt;/p&gt;&lt;p style="margin-left:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>자바 vs. 파이썬: 더 나은 에이전트 개발 언어는?</title><link>https://yozm.wishket.com/magazine/detail/3708</link><description>많은 사람이 생성형 AI 애플리케이션을 구축할 때는 파이썬이 가장 자연스러운 언어라고 잘못 알고 있습니다. 데이터 과학도 아닌데요. 사실 이미 JVM을 사용하고 있다면, JVM에서 생성형 AI를 다루는 것이 당연합니다. 오늘은 LangGraph와 Java로 만든 프레임워크 Embabel을 비교해보려고 합니다. LangGraph는 첫 번째이자, 동시에 가장 인기 있는 파이썬 기반 생성형 AI 프레임워크인 LangChain에서 나온 확장 프레임워크입니다. 이 프레임워크는 정말 Java가 할 수 없는 것들을 할 수 있을까요?</description><guid>https://yozm.wishket.com/magazine/detail/3708</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;본문은 로드 존슨(&lt;/span&gt;&lt;a href="https://www.linkedin.com/in/johnsonroda/"&gt;Rod Johnson&lt;/a&gt;&lt;span style="color:#757575;"&gt;)의 글 &amp;lt;&lt;/span&gt;&lt;a href="https://medium.com/@springrod/build-better-agents-in-java-vs-python-embabel-vs-langgraph-f7951a0d855c"&gt;Build Better Agents in Java vs Python: Embabel vs LangGraph&lt;/a&gt;&lt;span style="color:#757575;"&gt;&amp;gt;를 번역한 글입니다. 로드 존슨은 스프링 프레임워크를 만든 것으로 유명한 개발자죠.﻿ 그는 최근 Embabel이란 프로젝트를 만들고, 에이전트 프레임워크를 개발하고 있습니다. 필자에게 허락받고 번역과 게재를 진행했습니다.&lt;/span&gt;&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;많은 사람이 생성형 AI 애플리케이션을 구축할 때는 파이썬이 가장 자연스러운 언어라고 잘못 알고 있습니다. 데이터 과학도 아닌데요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러니 이미 JVM을 사용하고 있다면, 사실 JVM에서 생성형 AI를 다루는 것이 당연합니다. 반면 둘 중 어느 쪽도 아니라면, 이제부터 보여드릴 공정한 비교 결과에 어쩌면 놀라워 할 수도 있겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이전 블로그들에서 저는 &lt;a href="https://www.crewai.com/"&gt;CrewAI&lt;/a&gt;와 &lt;a href="https://ai.pydantic.dev/"&gt;Pydantic AI&lt;/a&gt;의 예시를 가져와 Java와 &lt;a href="https://github.com/embabel/embabel-agent"&gt;Embabel&lt;/a&gt;로 다시 구현하면서, 같은 기능을 두고 더 깔끔하고 확장 가능한 코드를 만들어 본 적 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;오늘은 &lt;a href="https://www.langchain.com/langgraph"&gt;LangGraph&lt;/a&gt;의 차례입니다. LangGraph는 첫 번째이자, 동시에 가장 인기 있는 파이썬 기반 생성형 AI 프레임워크인 &lt;a href="https://www.langchain.com/"&gt;LangChain&lt;/a&gt;에서 나온 확장 프레임워크입니다. LangChain의 인기와 LangGraph의 약속은 회사를 주목받는 대상으로 만들었으며, 덕분에 회사는 &lt;a href="https://sacra.com/c/langchain/"&gt;최근 11억 달러의 평가액으로 시리즈 B 투자를 유치&lt;/a&gt;했습니다. 그 프레임워크는 이런 평가대로 정말 Java가 할 수 없는 것들을 할 수 있을까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:50%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image1.png"&gt;&lt;/figure&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;LangGraph 아키텍처&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;LangGraph는 코드를 이용하여 다수 에이전트를 사용하는 업무 프로그램을 구현할 수 있게 합니다. 이 프레임워크는 유한 상태 기계(Finite State Machine)를 사용하여 작업 순서를 정렬합니다. 노드(상태)는 함수이고, 엣지(전이)는 자동으로 결정되거나 함수 호출 결과에 따라 동적으로 결정되기도 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이러한 노드와 엣지들은 긴 흐름을 여러 단계로 나누어 실행을 더 결정론적으로 만들고 작업 흐름을 이해하기 쉽게 만듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;무엇보다 상태 기계는 작업 흐름을 정의하는 가장 명확한 방법이므로 이 개념을 가장 먼저 적용한 LangChain이 현재의 시장 위치를 차지하는 것이 놀랄 일은 아닙니다. 빠른 시장 출시에 따른 것이지요. 하지만 이것이 최선의 모델일까요, 아니면 아직 명확히 드러나지 않은 더 나은 해결책이 있을까요? 최근 저희는 여러 번 상태 기계를 구축한 끝에&amp;nbsp; &lt;a href="https://medium.com/@springrod/ai-for-your-gen-ai-how-and-why-embabel-plans-3930244218f6"&gt;목표 지향 행동 계획(GOAP)&lt;/a&gt;을 기반으로 하는 새로운 접근법을 정착시켰습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;때때로 먼저 움직이지 않고 다른 사람들의 성공과 실패에서 배우는 것이 최선일 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;패턴 대결&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;저는 오랫동안 Embabel과 LangGraph 사이의 체계적인 비교를 하고 싶었습니다. 공정을 기하기 위해 제가 만든 예시를 선택하지 않았고, 대신 Hamza Boulahia의 ‘&lt;a href="https://pub.towardsai.net/agentic-design-patterns-with-langgraph-5fe7289187e6?gi=4b6d27acb0b5"&gt;LangGraph 에이전트 디자인 패턴&lt;/a&gt;’에 관한 최근 블로그의 내용을 다시 구현했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지난 몇 년간 AI 시스템을 구축하면서 배운 것이 있다면 패턴이 중요하다는 사실입니다. 전통적인 소프트웨어를 설계하든 대형 언어 모델(LLM) 에이전트로 실험하든, 작업 흐름을 구성하는 방식이야말로 결과물이 얼마나 견고하고 유연하며 확장 가능한지를 결정합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Boulahia는 6가지 에이전트 디자인 패턴을 시연합니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;프롬프트 사슬 구성&lt;/strong&gt;: 복잡한 일들을 관리할 수 있는 단계로 나누기&lt;/li&gt;&lt;li style="text-align:justify;"&gt;제어 흐름을 위한 &lt;strong&gt;경로 설정&lt;/strong&gt;(routing)과 &lt;strong&gt;병렬화&lt;/strong&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;리플렉션(Reflection)&lt;/strong&gt;: 에이전트가 결과를 비판적으로 살피고 개선&lt;/li&gt;&lt;li style="text-align:justify;"&gt;외부 시스템과 통합하기 위한 &lt;strong&gt;도구 사용&lt;/strong&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;계획 수립(Planning)&lt;/strong&gt;: 목적을 명확하게 실행 가능한 순서로 구조화&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;여러 에이전트의 협업&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;각 패턴을 하나씩 살펴보면서 자바 프로그램에서 Embabel을 사용해 표현력을 올리는 방식들을 보여드리겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;프롬프트 사슬 구성&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;프롬프트 사슬 구성은 필수적인 패턴으로 한 모델의 결과가 다른 모델의 입력이 되는 구조입니다. 이렇게 하면 일의 흐름을 예측하기 좋습니다. 이제 다룰 예제에서 에이전트는 사용자 입력을 기반으로 주제를 제안하고 각 주제에 대해 여러 개의 블로그 제목을 생성할 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;LangGraph 구현&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;예제는 LLM을 호출할 때 기본 LangChain API를 사용하며, 작업 흐름 관리를 위해서 LangGraph를 사용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여타 작업 흐름 엔진(workflow engine)처럼 LangGraph를 사용하면 LangChain 만 사용할 때와 달리 프로세스 상태를 유지하기만 해도 좋습니다. 이를 State 클래스로 표현합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;작업 흐름은 노드와 엣지를 통해 정의됩니다. LLM을 호출하는 Python 메서드가 노드가 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image3.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;작업 흐름은 코드로 구현합니다. 노드는 메서드에 매핑되고 엣지가 메서드를 연결합니다. 예제에서 엣지는 간단하게 다음 상태로 전환하게 만듭니다. 작업 흐름이 하드코딩된 문자열로 표현되기 때문에 컴파일 할 때 유효성 검사가 거의 이루어지지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image2.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;작업 흐름의 실행은 아래와 같은 코드로 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image5.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실행한 결과는 다음과 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image4.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;Embabel 구현&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;사소한 부분이긴 하지만, 사실 위의 예시 일부는 좋지 않은 설계이기 때문에 이를 그대로 구현하기는 어렵습니다. 특히, 지금의 예시는 도메인에 대한 모델링 부족하다 할 수 있습니다. 파이썬으로 생성형 AI를 다룰 때는 도메인 모델링을 과소평가하는 경향이 있는데, 이는 &lt;a href="https://medium.com/@springrod/context-engineering-needs-domain-understanding-b4387e8e4bf8"&gt;심각한 실수&lt;/a&gt;입니다. State 클래스의 모든 필드는 문자열로 모델링되어 있으므로 구조가 있어야 합니다. 특히 주제를 하나로 문자열로 표현하는 일은 오해를 낳기 쉽습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 문제를 해결하는 형태로 최소한의 변경을 했습니다. 도메인 모델과 행위 그리고 목적으로 표현된 Embabel 구현 방식을 택했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;도메인 객체는 Java 레코드이며, 요구사항에서 암시된 구조를 올바르게 나타냅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image7.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;코드를 좀 더 자세히 해설해 보겠습니다. 우선 @Agent 애노테이션은 클래스가 Spring에 의해 생성되고 주입되며, Embabel이 처리하게 합니다. @Action 메서드는 단계를 나타내고, 목적은 원하는 출력입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Actor 필드는 하이퍼파라미터를 주고 LLM 모델을 선택하는 일과 명령어를 결합합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;extractTopics와 generateBlogTitles 메서드는 LangGraph 노드 메서드에 해당합니다. 그러나 작업 흐름은 매우 다르게 구성되어 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이처럼 Embabel에서는 코드에서 작업 흐름을 지정할 필요가 없습니다. 프레임워크 스스로&amp;nbsp; 코드를 분석하여 실행 경로를 계획합니다.&amp;nbsp; 특히 실행 로직은 타입의 흐름에서 올바른 실행 계획을 추론할 수 있습니다. 예를 들어, 작업 흐름 범위에서 Topics와 BlogTitles 객체를 사용할 수 있어야만 마찬가지로 목적을 달성할 수 있다는 것을 알 수 있습니다. 그에 따라 메서드 호출 순서를 올바르게 결정할 수 있습니다. 이와 같은 계획 단계는 결정론적입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;마지막으로, generateBlogTitles 단계를 병렬 작업으로 모델링하여 요구사항을 더 자연스럽게 반영하고 LLM과의 상호 작용을 더 간결하고 집중력있게 만듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;출력 결과는 다음과 같습니다. LangGraph 예제 출력과 달리 요구사항을 정확하게 반영한 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image6.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;비교&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;두 구현 모두 흐름을 작고 초점이 분명한 단계로 나누어 예측을 쉽게 합니다. 다만, Embabel 버전에는 코드가 조금 더 많습니다. 다중성cardinality을 올바르게 모델링하려는 코드가 추가됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 대신 Embabel 구현은 여러 측면에서 우수하다고 느껴집니다. 먼저, 타입 안전성 측면이 그렇습니다. 오용 가능성이 있는 문자열과 대비되는 제대로 된 도메인 모델이 있어 테스트하기 쉬워집니다. 그리고 추가할 수 있는 구조 때문에 병렬 작업도 가능합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 외에도 Embabel 구현에서는 사소하지만 LangGraph 보다 나은 몇 가지 개선 사항이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;LLM 선택과 페르소나 외부화: Embabel과 Spring을 사용하면, Actor 정의를 application.yml 파일로 간단하게 외부화할 수 있습니다. 파이썬에 부족한 복잡한 옵션 구성이 가능합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;주제와 블로그 제목 유지: 적절히 구조화된 도메인 객체가 있기 때문에, 원할 때 쉽게 내용을 유지할 수 있습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;경로 선택(Routing)&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;또 다른 기본 패턴은 작업 흐름 안에서의 경로 선택입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;LangGraph 구현&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;여기 LangGraph 구현이 있습니다. 먼저 감정 분석을 수행한 다음 응답을 생성하기 위해 적절한 함수를 선택합니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image9.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;LangGraph에서 항상 그렇듯이 작업 흐름은 확인할 수 없는 문자열로 구축됩니다. 예제 코드에서 “classification”에 오타가 났는데, 전부 같이 틀렸기 때문에 다행히 문제는 없습니다. 그래도 이렇게 취약할 때는 타이핑이 매우 중요해집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다음 예시는 함수의 출력을 다음 상태 이름에 매핑하는 식의 더 정교한 LangGraph 상태 전환을 보여주는데, 여기서도 역시 오류가 발생하기 쉬운 마법 문자열이 보너스로 더해집니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image8.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다음과 같은 코드로 이를 실행합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image12.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;Embabel 구현&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;노드와 엣지를 명시적으로 연결하는 일은 이렇게 간단한 일을 너무 복잡하게 만듭니다. 좀 더 자연스러운 방식으로 단계를 표현해 봅시다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이때는 단계가 다르기 때문에 LLM과 관련된 공통 시스템 메시지가 아니라 매번 초점이 맞춰진 프롬프트를 사용할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;먼저 Sentiment의 타입을 만들겠습니다. 이는 흐름을 데이터 타입으로 표현할 수 있게 도와줍니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image10.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 우리는 classify 메소드가 Sentiment 객체를 반환 하도록 구현을 시작할 수 있습니다. Embabel은 스스로 Sentiment가 하위 타입을 갖는지 알아차리며,그에 맞춰 적절한 경로를 계획합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;한편 Encourage와&amp;nbsp; help 메소드는 각각 하나의 Sentiment 하위 유형을 취합니다. 파이썬 함수와 마찬지로 LLM을 호출하여 응답을 생성하는 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image11.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;비교&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;Embabel을 이용해 데이터 타입을 통해 실행 경로를 정의하는 것이 LangChain 상태 머신보다&amp;nbsp; 자연스럽고 오류가 적다고 생각합니다. 다시 한번, Embabel 내부에서 스스로 계획하는 기능이 흐름을 파악하기 때문에 직접 흐름을 정의할 필요가 없습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;병렬화&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;LLM 상호 작용이 일어나면, 동작이 느려질 수 있습니다. 따라서 병렬화는 생성형 AI 애플리케이션에서 중요합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;LangGraph는 “평행 엣지(parallel edges)”를 통해 작업을 병렬화할 수 있게 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image13.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Embabel에서는 병렬화를 위해 두 가지 선택이 가능합니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;블로그 제목 예시에서 본 parallelMap 메서드를 사용한 프로그래밍 방식.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;자동 구조도 있습니다. embabel.agent.platform.process-type=CONCURRENT를 설정하면, Embabel 스스로 계획하여 서로 의존하지 않는 작업을 대상으로 현재 목표를 달성하기 위해 필요한 경로를 병렬 실행합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;리플렉션(Reflection)&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;리플렉션은 다양한 이름으로 불리는 중요한 보편적 패턴입니다. 앤트로픽은 “&lt;a href="https://www.anthropic.com/engineering/building-effective-agents"&gt;Building Effective Agents”&lt;/a&gt;에서 이 패턴을 Evaluator-optimizer라고 부릅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;패턴의 핵심 아이디어는 LLM 호출을 한 차례 사용하여 다른 LLM의 출력에 대한 피드백을 제공하고 결과가 만족스러울 때까지 반복하는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기 LangGraph 구현이 있습니다. 사용자가 지정한 작업에 응답하여 텍스트를 초안하고 만족스러울 때까지 비판합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image14.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;패턴의 가치에 빗대어 볼 때 이상적인 구현과는 거리가 멉니다. 일단, 종료를 보장할 수 없습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개발자 관점에서 이런 류의 상태 머신은 일반적인 작업흐름을 표현하는데 이상적이지 않습니다. 공정하게 따지면, Embabel의 GOAP 계획도 마찬가지입니다. FSM이나 GOAP을 쓴다면 조잡한 계획에 잘 맞지만, 세밀한 작업을 정의할 수 있다면 정교한 프레임워크 지원으로 더 쉽게 할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;따라서 Embabel은 일반적인 패턴에 대해 바로 직접 만들지 않고 가져다 쓸 수 있도록 구현하는 방식을 제공합니다. (물론 자신만의 것을 만들 수도 있습니다.) 구현을 원하는 경우 GOAP 계획을 내보내는 fluent API&lt;span style="color:#757575;"&gt;*&lt;/span&gt;를 제공하기 때문에 표준적인 방식으로 단계를 관리할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;*fluent API: 메서드 체이닝으로 코드를 자연어처럼 읽히게 만드는 API 설계 패턴&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;RepeatUntilAcceptableBuilder를 사용하여 프로그래밍 방식으로 Agent를 만들고 @Configuration 클래스에서 Spring bean으로 노출하면, Embabel이 자동으로 배포합니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image15.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;자바로 작성한 Embabel 코드는 LangGraph를 사용한 파이썬 코드보다 훨씬 적은 코드를 가지고 있습니다. 그 덕분에 타입을 보장하고 많은 도구를 활용할 수 있어 흐름을 망칠 일이 없습니다. 만일 maxIterations를 초과하면 루프가 종료되고, 지금까지 본 최고 점수의 결과를 반환합니다. 또한, RepeatUntilAcceptableBuilder가 매개변수화되어 있고 타입을 보장하기 때문에 자신의 결과 타입과 피드백 타입을 사용할 수 있습니다. 이 시나리오에서 LangGraph는 매우 좋지 않은 성능을 보여준다고 할 수 있겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;도구 사용&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;도구 사용은 모든 생성형 AI 프레임워크의 필수 요소이며 쉬워야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;LangGraph를 사용하면 Python에서 도구를 정의하고 LLM에 바인딩할 수 있습니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image16.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;간단한 예시입니다. 다만, 이 예시는 생성된 Python 코드를 샌드박스 없이 실행하기 때문에 위험할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Embabel로 같은 처리를 한다면 매 번 PromptRunner를 사용하여 간단하게 도구를 추가할 수 있습니다. MCP가 지원하는 잘 알려진 도구 그룹을 정의하거나 Java 객체로 지정할 수 있습니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image17.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://medium.com/@springrod/domain-tools-direct-access-zero-ceremony-9a3e8d4cf550"&gt;도구 객체를 사용하는 기능&lt;/a&gt;은 특히 중요합니다. 이들은 데이터베이스에서 검색한 도메인 객체 또는 스프링으로 에이전트에 주입한 서비스일 수 있습니다. 파이썬에서도 그렇게 할 수 있지만, 자바 객체의 경우가 유용한 비즈니스 기능을 가질 가능성이 더 높다는 점에서 중요한 차이가 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Embabel은 또한 LlmReference와 같은 개념으로 도구 그룹화를 제공하며, 이는 도구를 프롬프트 요소와 결합하여 런타임에 정교한 구성을 가능하게 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;계획 수립&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;계획을 수립하는 과정을 다룬 LangGraph 블로그 예시는 이전 두 단계의 실행에 따라 최종 단계가 달라지는 형태를 포함합니다. 이것은 작업흐름 구축 과정에서다음과 같이 표현됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image18.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Embabel에서는 두 데이터 타입을 모두 사용하는 메서드를 간단히 정의합니다:&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3708/image19.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 방식이 제가 느끼기에 더 명확하고 타입 활용에 안전하며 테스트하기 쉽습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;LangChain 예시는 또한 계획의 단계를 하드코딩하지만, 그 코드는 LLM이 만들 수 있다고 언급합니다. Embabel에서 역시 LLM이 명령 객체를 인스턴스화하도록 하여 이를 구현할 수 있습니다. 그러나 LLM에 의존하여 계획을 수행하면 흐름 예측이 훨씬 어려워지므로 주의깊게 수행해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;다중 에이전트 협업&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;마지막 패턴은 감독자 노드에서 다른 에이전트로의 전달 예시입니다. 이것은 Google ADK와 같은 프레임워크에서 흔한 패턴입니다. 상태 머신이나 GOAP 액션을 통해 단계를 표현하는 것보다 덜 결정론적이므로, 우리가 권장하는 경향이 없는 패턴입니다. 이러한 동작을 달성하기 위해 Embabel은 에이전트를 도구로 사용할 수 있게 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;전체 코드&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;전체 코드는 &lt;a href="https://github.com/embabel/langgraph-patterns"&gt;Embabel langgraph-patterns 저장소&lt;/a&gt;에서 찾을 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;누군가는 &lt;a href="https://pub.towardsai.net/agentic-design-patterns-with-langgraph-5fe7289187e6"&gt;원본 블로그&lt;/a&gt;가 LangGraph 사용을 제대로 보여준 것이 아니라고 주장할 수 있습니다. 하지만 이 글은 제가 보기에 에이전트에 대한 건전한 이해를 바탕으로 한 잘 쓴 글이며, 미디엄Medium에서 수백 개의 박수를 받았습니다. 다른 LangGraph 애플리케이션에서 동일한 결함을 찾기는 어렵지 않으며, 문제가 저자가 아니라 프레임워크, 언어 및 생태계에 있음을 시사합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이제 자바 커뮤니티는 파이썬 기반 에이전트의 성장을 따라잡아야 한다는 강박을 멈추고, 생성형 AI 에이전트를 구축하기 위한 해결책뿐만 아니라 모든 플랫폼에서 최고의 해결책을 가지고 있음을 보여줄 때입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;파이썬 프레임워크가 보여주는 평범한 아이디어 아래 안주하는 것을 멈추고 우리가 써온 언어를 기반으로 생각할 때입니다. 파이썬은 황제들만 갖출 수 있는 옷을 입지 않았습니다. 여러분이 JVM 개발자이지만, 상사가 파이썬으로 에이전트를 작성하라고 말하면, 비즈니스 애플리케이션, 생성형 AI 또는 기타 분야의 플랫폼으로서 파이썬의 약점을 지적할 준비를 하세요. 그리고 일반적인 패턴을 그대로 쓰면서도 파이썬보다 자바가 나아 보일 수 있는 방법을 보여줄 준비를 하세요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;파이썬은 모든 개발자가 능숙하게 쓰면 좋은 중요한 언어입니다. 많은 작업에 훌륭한 성능을 보여줍니다. 다만, 이 언어는 꽤 중요한 비즈니스 애플리케이션을 구축할 때 인기 있는 언어가 아니었으며, 여기에는 그럴만한 이유가 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;JVM의 견고성은 잘 알려져 있습니다. 생태계 — 특히 파이썬에서는 대안이 없는 Spring이 — 이러한 견고함을 강력하게 뒷받침합니다. Embabel은 이를 바탕으로 하며, 모든 파이썬 프레임워크보다 우수한 개념을 제공한다고 저는 믿습니다. 나머지는 여러분에게 달려 있습니다. 오늘 자바 에이전트 템플릿에서 첫 번째 에이전트를 만들어 보세요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>AI, 개발 말고 요구사항부터 써야 하는 이유</title><link>https://yozm.wishket.com/magazine/detail/3707</link><description>AI 열풍이 조금씩 식어가고 있습니다. 대부분의 기업은 이미 개발자에게 코파일럿, 코드 어시스턴트 같은 AI 도구를 쥐여주며 개발 속도를 높였는데요. 그런데도 여전히 뭔가 빠진 느낌입니다. AI가 우리가 기대했던 만큼 일하고 있다는 확신이 들지 않죠. ROI 향상, 10배의 생산성 개선, 그 기대했던 순간이 아직도 오지 않은 것 같습니다. 그런데 사실, 그 순간은 이미 와 있습니다. 지금 당장 활용할 수 있죠. 먼저 짚고 싶은 건, AI를 개발에 활용하는 것만으로는 부족하다는 점입니다. 개발 전 단계부터 이후까지, 전체 흐름이 함께 빨라져야 하거든요. 10배의 생산성과 더 나은 AI 투자 수익은 결국 가장 느린 단계를 얼마나 빠르게 끌어올리느냐에 달려 있습니다. </description><guid>https://yozm.wishket.com/magazine/detail/3707</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;본문은 요즘 IT와 번역가 Yuna가 함께 &lt;a href="https://www.linkedin.com/in/jakubgiza/"&gt;야쿠브 기자(&lt;u&gt;Jakub Giza&lt;/u&gt;&lt;/a&gt;)의 글 &lt;a href="https://medium.com/@giza.jakub/how-to-leverage-ai-for-better-it-requirements-and-process-improvements-in-your-company-2695ecc2507f"&gt;&amp;lt;&lt;u&gt;How to leverage AI for better IT requirements and process improvements in your company&lt;/u&gt;&lt;/a&gt;&amp;gt;을 번역한 글입니다. 필자는 25년 이상의 기업 IT 경력을 보유한 전문가로, 통신, 디지털 플랫폼, 대규모 혁신 프로젝트 등 다양한 분야에서 글로벌 개발 프로그램을 이끌어왔습니다. 현재는 AI 실험 단계를 넘어 실제 조직 안에서 AI를 체계적으로 실행할 수 있도록 돕는 데 집중하고 있으며, 인간과 AI의 협업 프레임워크인 HyperVe의 창시자이기도 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글은 AI 도입 후에도 기대했던 ROI가 나오지 않는 이유를 짚고 그 해결책을 제시합니다. 개발 속도만 높이는 것으로는 부족하며, 요구사항을 정의하는 방식 자체를 AI 시대에 맞게 바꿔야 한다고 설명합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#999999;"&gt;필자에게 허락을 받고 번역했으며, 글에 포함된 링크는 원문에 따라 표시했습니다.&lt;/span&gt;&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;p style="text-align:justify;"&gt;AI 열풍이 조금씩 식어가고 있습니다. 대부분의 기업은 이미 개발자에게 코파일럿, 코드 어시스턴트 같은 AI 도구를 쥐여주며 개발 속도를 높였는데요. 그런데도 여전히 뭔가 빠진 느낌입니다. AI가 우리가 기대했던 만큼 일하고 있다는 확신이 들지 않죠. &lt;strong&gt;ROI 향상, 10배의 생산성 개선&lt;/strong&gt;, 그 기대했던 순간이 아직도 오지 않은 것 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 사실, 그 순간은 이미 와 있습니다. 지금 당장 활용할 수 있죠. 먼저 짚고 싶은 건, AI를 개발에 활용하는 것만으로는 부족하다는 점입니다. 개발 전 단계부터 이후까지, 전체 흐름이 함께 빨라져야 하거든요. 10배의 생산성과 더 나은 AI 투자 수익은 결국 가장 느린 단계를 얼마나 빠르게 끌어올리느냐에 달려 있습니다. 그리고 지금 그 병목은 개발 이전으로 옮겨갔습니다. 무엇을 만들지 정의하고 검증하는 단계가 빨라진 개발 속도를 따라가지 못하고 있는 거죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;상황은 더 심각합니다. AI 시대에는 불명확한 의도, 부족한 맥락, 검증되지 않은 비즈니스 가정이 단순히 속도를 늦추는 문제가 아닙니다. 잘못된 것을 더 빠르게 만들게 되고, 그만큼 조직의 위험도 커지죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;해결책은 무엇일까요? &lt;strong&gt;비즈니스 요구사항을 정의하고 프로세스를 개선하는 속도와 정확도를 AI 개발 속도에 맞춰야 합니다. 코딩에만 AI를 쓸 게 아니라, 비즈니스 활동 전반에 AI를 녹여야 한다는 뜻입니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;AI 투자 수익이 낮은 건 개발 속도 문제가 아닙니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;개발이 빨라지면 그 이전 단계가 새로운 병목이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;불명확한 의도: "포털이 필요합니다…" 같은 두루뭉술한 요청&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;부족한 맥락: 실제 업무가 어떻게 돌아가는지 모르는 상태&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;부실한 검증: 이게 정말 가치를 만들어낼지 확인하지 않는 상태&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;숨겨진 제약: 법무, 운영, 시스템 의존성, 데이터 품질 등 미처 파악 못 한 것들&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;느린 합의: 회의로만 요구사항을 정리하려는 관행&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;결국 무엇을 만들지 정의하고 검증하는 단계가 AI로 빨라진 개발 속도를 따라가지 못하는 겁니다&lt;/strong&gt;. AI가 기대만큼의 성과를 내지 못하는 이유가 바로 여기 있죠. 더 빠르게, 때로는 더 잘 만들지만 정작 필요하지 않은 것을 만드는 경우가 너무 많습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;잘못된 방향에 빠른 실행이 더해지면, 빠르게 망합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;"더 나은 프롬프트"는 답이 아닙니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;많은 분들이 이렇게 반응합니다. "더 좋은 프롬프트가 필요해." 그럴듯하게 들리지만 잘못된 처방입니다. 프롬프트가 근본 문제가 아니거든요. 프롬프트는 이미 더 앞 단계에서 망가진 흐름의 마지막 단계일 뿐이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;진짜 문제는 대부분의 조직이 요구사항을 다루는 방식이 아직도 그대로라는 점입니다. 문서 하나, 티켓 하나, 인수인계 하나, 한 번 쓰고 끝나는 산출물로 취급하죠. 개발이 느렸을 때는 그래도 됐습니다. 하지만 지금처럼 개발이 빠른 시대엔 통하지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI 시대에 요구사항은 이래야 합니다.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;협업: 이해관계자와 AI가 함께 만들어가야 합니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;실제 맥락: 회사와 시장에 대한 구체적인 지식에서 출발해야 합니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;지속적인 개선: 한 번 쓰고 끝나는 게 아니라 계속 다듬어져야 합니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;추적 가능성: 처음 의도부터 최종 결과까지 가치를 검증할 수 있어야 합니다.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;새로운 요구사항 정의 시스템, VOS의 등장&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;그렇다면 실제로 무엇이 필요할까요? &lt;strong&gt;개발이 시작되기 전, 팀이 비즈니스 의도를 실행 가능한 형태로 바꿀 수 있도록 돕는 무언가가 필요합니다. 거버넌스, 맥락, 팀 간 합의를 잃지 않으면서요&lt;/strong&gt;. 다시 말해, 의도, 맥락, 가정, 아이디어, 논의, 결정을 하나로 엮어주는 시스템이 필요한 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 등장한 새로운 개념이 바로 &lt;a href="https://medium.com/@giza.jakub/the-end-of-project-management-tools-the-ai-era-runs-on-value-orchestration-systems-vos-1ff8f4434629"&gt;&lt;u&gt;VOS(Value Orchestration System, 요구사항 정의 시스템)&lt;/u&gt;&lt;/a&gt;이죠. VOS는 백로그 도구도, 챗봇도, 문서 저장소도, 티켓 시스템도 아닙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3707/image1.png"&gt;&lt;figcaption&gt;HyperVe Loop — Value Orchestration System&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;VOS는 AI가 팀의 일을 늘리기 전에, 먼저 질을 높이도록 돕는 시스템입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;이제 업무 흐름은 요청에서 프롬프트, 개발 순입니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;기존 개발 방식에서는 "요구사항"에서 "구현"으로 넘어가는 흐름을 따랐는데요. 일반적인 소프트웨어 개발 생명주기, SDLC가 그것입니다. AI 네이티브 업무에서는 흐름이 다릅니다. 더 단순하고, 더 명확하고, 더 솔직하죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://medium.com/@giza.jakub/the-end-of-typical-agile-frameworks-and-the-rise-of-the-request-prompt-delivery-rpd-framework-e4671b2e359d"&gt;&lt;u&gt;요청하고, 프롬프트를 만들고, 개발합니다.&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://medium.com/@giza.jakub/request-the-successor-to-user-stories-in-ai-native-work-3111bdddee3b"&gt;&lt;strong&gt;&lt;u&gt;요청&lt;/u&gt;&lt;/strong&gt;&lt;/a&gt;: 비즈니스 의도, 기대 결과, 제약 조건, 성공 기준을 명확히 정의합니다.&lt;/li&gt;&lt;li&gt;&lt;a href="https://medium.com/@giza.jakub/prompt-the-new-specification-layer-for-ai-native-teams-cc7047be0921"&gt;&lt;strong&gt;&lt;u&gt;프롬프트&lt;/u&gt;&lt;/strong&gt;&lt;/a&gt;: 추측이 아닌 회사의 실제 상황을 담아 구체적인 지침을 만듭니다.&lt;/li&gt;&lt;li&gt;&lt;a href="https://medium.com/@giza.jakub/delivery-has-changed-forever-ai-doesnt-wait-for-sprints-cb60daaf45b1"&gt;&lt;strong&gt;&lt;u&gt;개발&lt;/u&gt;&lt;/strong&gt;&lt;/a&gt;: 사람과 AI가 함께 실행하되, 처음 의도와 일치하는지 언제든 확인할 수 있습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 흐름이 실제로 이루어지려면 그에 맞는 공간이 필요합니다. 협업, 검증, 거버넌스가 기본으로 갖춰진 작업 공간이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;AI가 우리 회사를 알아야 제대로 작동합니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI가 일관되게 도움이 되려면 회사의 실제 상황을 알아야 합니다. 우리 조직이 어떻게 돌아가는지 AI가 파악하고 있어야 한다는 뜻이죠. 이를 위해 조직의 실제 상황을 담은 회사 정보가 필요합니다. 여기엔 이런 것들이 포함돼야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;프로세스: 업무가 어떻게 흘러가는지, 어디서 시간이 낭비되는지&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;시스템과 연동: 어떤 시스템을 쓰는지, 어디서 인수인계가 끊기는지&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;제약 조건: 보안, 법무, 운영, 데이터 저장 위치 등 반드시 지켜야 할 것들&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;기존 문서와 결정 사항: 이미 알고 있는 것, 이미 결정된 것들&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;담당자와 이해관계자: 누가 무엇을 결정하는지&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;데이터 품질 기준: 자동화가 제대로 작동하려면 어떤 조건이 갖춰져야 하는지&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3707/image3.png"&gt;&lt;figcaption&gt;HyperVe Loop System&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이런 토대 없이 요구사항을 만들면 그건 그냥 의견입니다. 이런 토대를 갖추고 요구사항을 만들면 그건 근거가 됩니다. “회의에서 나온 아이디어”가 “시스템 안에서 관리”되기 시작하는 변화입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실무에 적용해보면 다음과 같습니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;"주문에서 개통까지 걸리는 시간을 14일에서 3일로 줄이자"는 목표가 있다고 해봅시다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;대부분의 팀은 바로 해결책으로 뛰어듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;단계를 자동화한다&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;새 도구를 도입한다&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;워크플로를 다시 만든다&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;다른 플랫폼을 구매한다&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 AI 기반 요구사항 워크스페이스는 그 전에 먼저 해야 할 일을 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;올바른 질문을 던지는 거죠. 핵심을 파고드는 탐색입니다.&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;정확히 어디서 지연이 발생하는가?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;어떤 단계가 수동이고 어떤 단계가 자동화되어 있는가?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;무엇이 재작업을 유발하는가?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;어떤 제약이 자동화를 막고 있는가?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;어떤 수준의 데이터 품질이 필요한가?&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;이 질문들은 조직의 실제 정보에 기반하기 때문에 추측이 아닌 사실에서 출발합니다.&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;프로세스 흐름과 이미 파악된 병목 지점&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;관련된 시스템들&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;시스템 간 연결과 인수인계 지점&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;반복적으로 발생하는 문제 패턴&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;이전에 내려진 결정과 제약 조건&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;그리고 각 선택지를 장단점과 함께 제시합니다. 어떤 결정을 내릴지 훨씬 명확해지는 순간이죠.&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;"옵션 A는 시간을 가장 빠르게 단축하지만, 먼저 데이터 정리가 필요합니다."&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;"옵션 B는 비용이 덜 들지만 개선 효과는 20%에 그칩니다."&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;"옵션 C는 고객 경험을 높이지만 운영 방식의 변화가 필요합니다."&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;결과물은 바로 검토하고 실행할 수 있는 형태로 나옵니다.&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;구조화된 요청서&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;프롬프트로 바로 활용할 수 있는 명세서&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;목표에서 가정, 결정, 산출물까지 연결되는 추적 가능한 흐름&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 과정을 거치면 "프로세스를 개선해야 한다"는 막연한 말이 측정 가능한 결과로 이어지는 실질적인 결정이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;HyperVe Loop의 사례&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://hyperve.com/"&gt;&lt;u&gt;HyperVe Loop&lt;/u&gt;&lt;/a&gt;는 요청, 프롬프트, 개발 흐름을 중심으로 만들어진 VOS의 실제 사례입니다. 주요 기능은 이렇습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;AI 기반 협업: AI가 이해관계자들과 함께 올바른 질문을 던지고, 결정 사항을 기록하고, 새로운 아이디어를 끌어냅니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;실제 맥락 기반 대화: 추측이 아닌 회사의 프로세스, 시스템, 제약 조건, 문서, 결정 사항을 토대로 논의가 이루어집니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;개발 전 검증: 본격적인 개발에 들어가기 전에 가치, 실현 가능성, 리스크, 장단점을 먼저 따져봅니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;근거 있는 선택지 비교: ROI를 기준으로 실행 가능한 옵션을 비교해 볼 수 있습니다.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;전 과정 추적: 요청에서 프롬프트, 개발까지 모든 과정이 끊기지 않고 연결됩니다.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결과적으로 더 나은 결정, 더 빠른 합의, 그리고 불필요한 재작업이 줄어듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3707/image2.png"&gt;&lt;figcaption&gt;리더가 AI로 실질적인 성과를 내는 5가지 방법&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;다음 경쟁력은 더 명확한 의도에서 나옵니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI 네이티브 개발은 이제 당연한 것이 되어가고 있습니다. 다음 경쟁력은 비즈니스 요구사항을 정의하는 방식도 함께 바꾸는 데 있습니다. 구조화되고, 실제 맥락에 기반하고, 협업적이고, 추적 가능한 방식으로요. 개발이 빨라진 지금, 결국 중요한 건 하나입니다. 올바른 것을 만들고 있느냐는 질문이죠.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&amp;lt;원문&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://medium.com/@giza.jakub/how-to-leverage-ai-for-better-it-requirements-and-process-improvements-in-your-company-2695ecc2507f"&gt;&lt;u&gt;How to leverage AI for better IT requirements and process improvements in your company&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>[요즘IT 콘텐츠 AX] 기업 블로그 에이전트의 가능성과 한계 웨비나 오픈!</title><link>https://yozm.wishket.com/magazine/detail/3706</link><description>“AI로 콘텐츠 자동화하기” 콘텐츠를 만들어 본 분들이라면 한 번쯤은 생각해 보셨을 텐데요. 막상 해보면 글 한 편은 어떻게 완성되는데, 기획부터 발행까지 전체를 자동으로 돌리는 작업은 생각보다 훨씬 복잡합니다. 원했던 퀄리티가 나오지 않을 때도 많고요. 그래서 요즘IT가 직접 부딪혀봤습니다. 위시켓 기업 블로그를 대상으로, 콘텐츠 마케터의 워크플로우를 6단계로 나누고 각 단계에 AI 에이전트를 붙였습니다. 비개발자가 클로드 코드로 월간 12건의 콘텐츠 기획부터 발행까지 자동화한 과정, 그 한계와 가능성을 솔직하게 공유합니다. 정답이 있는, 이론을 배우는 자리는 아닙니다. 대신 직접 만들면서 겪은 것들을 있는 그대로 나눠보려고 합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3706</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;h4&gt;&lt;strong&gt;“콘텐츠 담당자를 위한 기업 블로그 에이전트 가능성과 한계” 웨비나 오픈&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“AI로 콘텐츠 자동화하기” 콘텐츠를 만들어 본 분들이라면 한 번쯤은 생각해 보셨을 텐데요. 막상 해보면 글 한 편은 어떻게 완성되는데, 기획부터 발행까지 전체를 자동으로 돌리는 작업은 생각보다 훨씬 복잡합니다. 원했던 퀄리티가 나오지 않을 때도 많고요.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 요즘IT가 직접 부딪혀봤습니다. 위시켓 기업 블로그를 대상으로, 콘텐츠 마케터의 워크플로우를 6단계로 나누고 각 단계에 AI 에이전트를 붙였습니다. 비개발자가 클로드 코드로 월간 12건의 콘텐츠 기획부터 발행까지 자동화한 과정, 그 한계와 가능성을 솔직하게 공유합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;정답이 있는, 이론을 배우는 자리는 아닙니다. 대신 직접 만들면서 겪은 것들을 있는 그대로 나눠보려고 합니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;&lt;strong&gt;[요즘IT 콘텐츠 AX 실험기 미리보기]&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://yozm.wishket.com/magazine/detail/3647/"&gt;12분 49초 만에 한 달치 기획이 나왔다: 콘텐츠 AX 실험기&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://yozm.wishket.com/magazine/detail/3695/"&gt;콘텐츠 AX, '프롬프트' 말고 '파일'을 보세요: 콘텐츠 AX 실험기 ②&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;a href="https://litt.ly/yozm_it/sale/qdteYzP"&gt;&lt;img src="https://www.wishket.com/media/news/3706/1_RlVsdEv.png"&gt;&lt;/a&gt;&lt;/figure&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;웨비나 정보&lt;/strong&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;일시&lt;/strong&gt;: 2026년 4월 17일(금) 저녁 7:00&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;형태&lt;/strong&gt;: 온라인 라이브 (Zoom)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;구성&lt;/strong&gt;: 발표 30분 + Q&amp;amp;A 20분&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;참가 비용&lt;/strong&gt;: 얼리버드 &lt;s&gt;15,000&amp;nbsp;&lt;/s&gt; ▶&lt;strong&gt;11,900원 (4/16일까지)&lt;/strong&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;신청 링크:&lt;/strong&gt;&lt;a href="https://litt.ly/yozm_it/sale/qdteYzP"&gt;&lt;strong&gt;웨비나 신청하기&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;슬라이드&lt;/strong&gt;: 참여자에게 발표 슬라이드 PDF 제공 (웨비나 전날 이메일 발송)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;녹화본&lt;/strong&gt;: 따로 제공되지 않습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;웨비나에서 이런 이야기를 다룹니다&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;01. 파이프라인 전체 구조&lt;/strong&gt;&amp;nbsp;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;콘텐츠 마케터의 워크플로우를 세분화하고, 각 단계에 에이전트를 붙인 구조. 왜 이렇게 나눴고, 어디서 사람이 개입하는지 살펴봅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;02. 시행착오 기록&lt;/strong&gt;&amp;nbsp;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;키워드 수집에서 노이즈가 터진 일, 기존 글과 중복 판정이 안 맞았던 일, GEO 최적화와 브랜드 톤이 충돌한 일. 실제 겪은 문제들과 대응 과정을 살펴봅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;03. 도메인 지식의 벽&lt;/strong&gt;&amp;nbsp;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;기업 담당자만 아는 비즈니스 맥락을 AI에 주입하는 것이 왜 어렵고, 어디까지 가능했는지 알아봅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;04. 생성 품질의 현실&lt;/strong&gt;&amp;nbsp;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AI가 쓴 글이 "사람이 읽을 만한 글"이 되려면 무엇이 필요한지. 현재 수준은 어디이고, 무엇이 부족한지 알아봅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;05. 직접 만들 때 알아야 할 것&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;에이전트가 정확히 뭔지, 어떻게 만드는지, 어디까지 자동화되고 어디서 사람이 판단해야 하는지 살펴봅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;발표자&lt;/strong&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;장대청(요즘IT 그로스 파트 리드 · 위시켓)&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;비개발자. 코드를 직접 짜지 않고, 업무 매뉴얼을 자연어로 정의하면 클로드 코드가 코드를 짜는 방식으로 파이프라인을 구축했습니다. 위시켓 기업 블로그 자동화 프로젝트의 설계와 실행을 담당하고 있습니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;span style="background-color:rgb(255,255,255);color:rgb(49,49,49);"&gt;&lt;strong&gt;이런 분들께 추천해요&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;기업 블로그나 콘텐츠 마케팅을 담당하면서 AI 자동화를 검토 중인 분&lt;/li&gt;&lt;li style="text-align:justify;"&gt;에이전트가 궁금한데, 실제 사례를 먼저 보고 싶은 분&lt;/li&gt;&lt;li style="text-align:justify;"&gt;직접 파이프라인을 만들어보고 싶은데, 전체 그림이 안 잡히는 분&lt;/li&gt;&lt;li style="text-align:justify;"&gt;코드는 나오지 않습니다. 구조와 판단 과정, 시행착오 중심으로 이야기합니다. 사전 등록자의 77%가 비개발자(PM, 기획자, 콘텐츠 마케터)였습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;자주 묻는 질문&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Q. 비개발자인데 이해할 수 있나요?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;네. 사전 등록자의 77%가 비개발자(PM, 기획자, 콘텐츠 마케터, 경영진)입니다. 코드는 나오지 않습니다. 구조와 판단 과정, 시행착오 중심으로 이야기합니다.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;strong&gt;Q. 웨비나를 듣고 바로 자동화를 구축할 수 있나요?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이 웨비나는 정답이나 성공 공식을 알려주는 자리가 아닙니다. 에이전트로 블로그를 자동화한다는 것이 실제로 어떤 것인지, 클로드 코드로 그것을 어떻게 시작하는지, 그 과정에서 부딪히는 문제들은 무엇인지, 직접 해본 사람의 경험과 시행착오를 공유합니다. 되는 것과 안 되는 것의 경계를 이해하고, 스스로 판단 기준을 세울 수 있도록 돕는 자리입니다.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;strong&gt;Q. 우리 회사에도 적용 가능한가요?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;기업 블로그 콘텐츠를 정기 발행하는 팀이라면 파이프라인 구조 자체는 적용 가능합니다. 다만 도메인 지식을 AI에 주입하는 과정이 핵심 과제이며, 이 부분의 현실적인 난이도를 웨비나에서 다룹니다.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;strong&gt;Q. 녹화본이 제공되나요?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;녹화본은 제공되지 않습니다. 참여자에게 발표 슬라이드 PDF를 웨비나 전날 이메일로 발송해드립니다.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;strong&gt;Q. 환불이 가능한가요?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;웨비나 당일 전까지 환불 요청 시 전액 환불됩니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;강의가 아니라 경험담을 나누는 자리입니다. 잘 된 것도, 막혔던 것도, 아직 안 되는 것도, 모두 있는 그대로 공유합니다. "우리 팀도 해볼 수 있을까?"라고 고민하고 계신 분들께 도움이 되길 바랍니다. 그럼 4/17일 웨비나에서 만나요!&lt;/p&gt;&lt;hr&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;a href="https://litt.ly/yozm_it/sale/qdteYzP"&gt;&lt;img src="https://www.wishket.com/media/news/3706/3.png"&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 style="text-align:center;"&gt;&lt;strong&gt;[→&lt;/strong&gt;&lt;a href="https://litt.ly/yozm_it/sale/qdteYzP"&gt;&lt;strong&gt;웨비나 신청하기&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>AI 에이전트가 슬랙을 떠난 이유: 웹으로 이사한 곰곰이</title><link>https://yozm.wishket.com/magazine/detail/3705</link><description>요즘 기업들의 AI 도입 사례를 부쩍 자주 보게 됩니다. 특히 자연어로 데이터를 분석하는 Text-to-SQL 에이전트 사례가 눈에 띄게 늘었는데요. 그런데 흥미로운 점이 있습니다. 많은 초기 도입 사례에서 AI 에이전트가 슬랙봇의 형태로 소개된다는 것입니다. 저도 그랬습니다. 곰곰이도 처음엔 슬랙 채널에서만 활동했고, 덕분에 빠르게 프로토타이핑하여 동료들에게 선보일 수 있었습니다. 하지만 얼마 전 곰곰이를 웹앱으로 이사시켰습니다. LLM과 AI의 잠재력을 슬랙이라는 작은 그릇에 계속 가둬둘 수 없다고 판단했기 때문입니다. 이 글에서는 제가 왜 그런 결정을 내렸는지, 그리고 웹으로 이사 이후 무엇이 달라졌는지 풀어보려 합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3705</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;이번 글은 &lt;a href="https://yozm.wishket.com/magazine/detail/3697/"&gt;반복적인 SQL 업무를 자동화하는 AI 에이전트 '곰곰이'&lt;/a&gt;의 후속입니다. 아직 읽지 않으셨다면 먼저 읽고 오시는 걸 추천합니다.&amp;nbsp;&lt;br&gt;&lt;br&gt;요즘 기업들의 AI 도입 사례를 부쩍 자주 보게 됩니다. 특히 자연어로 데이터를 분석하는 Text-to-SQL 에이전트 사례가 눈에 띄게 늘었는데요. 그런데 흥미로운 점이 있습니다. 많은 초기 도입 사례에서 &lt;strong&gt;AI 에이전트가 슬랙봇의 형태로 소개된다&lt;/strong&gt;는 것입니다. 저도 그랬습니다. 곰곰이도 처음엔 슬랙 채널에서만 활동했고, 덕분에 빠르게 프로토타이핑하여 동료들에게 선보일 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 얼마 전 &lt;strong&gt;곰곰이를 웹앱으로 이사시켰습니다.&lt;/strong&gt; LLM과 AI의 잠재력을 슬랙이라는 작은 그릇에 계속 가둬둘 수 없다고 판단했기 때문입니다. 이 글에서는 제가 왜 그런 결정을 내렸는지, 그리고 웹으로 이사 이후 무엇이 달라졌는지 풀어보려 합니다. 슬랙봇으로 AI 에이전트를 운영하고 있거나 고민 중인 분이라면, 저의 사례가 작은 힌트가 됐으면 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;목차&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;슬랙은 AI의 잠재력을 담을 수 없다&lt;/li&gt;&lt;li style="text-align:justify;"&gt;웹 전환으로 달라진 것들&lt;/li&gt;&lt;li style="text-align:justify;"&gt;커맨드와 예약: 반복 분석을 자동화하다&lt;/li&gt;&lt;li style="text-align:justify;"&gt;곰곰이 제작자의 생각&lt;/li&gt;&lt;li style="text-align:justify;"&gt;앞으로 남은 여정&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;슬랙은 AI의 잠재력을 담을 수 없다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;곰곰이가 슬랙봇으로 시작한 건 당연한 선택이었습니다. 슬랙은 동료들이 하루 종일 켜놓는 업무용 메신저입니다. 새로운 환경을 따로 세팅하거나 배울 필요 없이 곰곰이를 바로 써볼 수 있었고, 데이터 분석 결과를 동료들에게 공유하는 것도 쉬웠습니다. 빠르게 프로토타이핑하고 동료들의 반응을 확인하기엔 슬랙만한 환경이 없었습니다. 그런데 &lt;strong&gt;쓰면 쓸수록 불편한 지점들이 생겼습니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 &lt;strong&gt;보안&lt;/strong&gt;입니다. 슬랙에서 회사 정보를 공유하는 건 이미 익숙한 일입니다. 그런데 DB와 연결된 AI가 슬랙 위에서 데이터를 조회하고 분석한다는 건 왠지 찝찝합니다. 보안 통제가 높은 조직이라면 더욱 그렇습니다. 데이터 조회와 반출에 대한 사용자별 권한 체계가 있는 곳이라면, 곰곰이가 슬랙에서 자유롭게 데이터를 분석하는 것 자체가 허락되지 않을 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;가독성&lt;/strong&gt;입니다. 아래 사진은 슬랙에서 곰곰이의 데이터 분석 답변입니다. 표는 줄이 맞지 않아 읽기가 어렵습니다. 그래프를 그리는 것은 아예 불가능하고, 굵게나 밑줄 같은 마크다운 기본 포맷도 제대로 렌더링되지 않습니다. 곰곰이가 데이터 분석 과정에서 도구를 선택하고 생각하는 흐름인 ReAct 추론 과정을 보여주는 것도 마찬가지입니다. 슬랙으로는 데이터 분석 결과를 보여주기에 충분하지 않았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/1.webp" alt="슬랙 곰곰이"&gt;&lt;figcaption&gt;슬랙 곰곰이 답변의 시원치 않은 모습&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;세 번째는 &lt;strong&gt;확장성&lt;/strong&gt;입니다. 슬랙은 채팅 앱으로서 훌륭하고 SDK나 플러그인도 잘 갖춰져 있습니다. 하지만 직접 만든 웹앱과 비교하면 기능을 추가하고 커스텀 할 때 발목이 잡힙니다. 개인화된 대화, 보고서 이미지 다운로드, 로그인과 권한 관리, 어드민 기능 같은 것들은 슬랙에서 만들 수 없습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;슬랙이 나쁘다는 게 아닙니다. 다만 곰곰이의 잠재력을 전부 끌어내려면 제가 원하는 대로 만들 수 있는 환경이 필요했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;웹 전환으로 달라진 것들&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;저는 백엔드에 익숙한 개발자입니다. 데이터 설계, 인프라 구축, API 개발은 늘 하던 일이라 부담이 없습니다. 그런데 버그 없이 잘 동작하는 웹앱을 만드는 건 솔직히 자신이 없었습니다. 하지만 그것도 몇 달 전 이야기입니다. &lt;strong&gt;AI 코딩 에이전트 덕분에 이제 퀄리티 높은 웹앱도 직접 만들 수 있게 되었습니다.&lt;/strong&gt; 슬랙봇 개발도 쉬운 편이긴 한데 AI의 도움이 잘 닿지 않는 부분들이 있습니다. 반면 AI 코딩 에이전트로 직접 웹앱을 만들면 빠르게 원하는 데로 모두 만들 수 있어 슬랙봇 보다 웹앱 개발이 더 쉬워진 상황이 됐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 AI 에이전트의 족쇄가 되는 슬랙을 벗어나 직접 웹앱을 만들어 곰곰이가 능력을 더 자유롭게 보여줄 수 있는 브라우저 환경으로 이사시켰습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/2.webp" alt="곰곰이 웹앱 브라우저"&gt;&lt;figcaption&gt;새 채팅 화면&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;가장 먼저 달라진 건 &lt;strong&gt;개인화&lt;/strong&gt;입니다. 회원가입과 로그인으로 접근하게 되면서 채팅을 공유 환경뿐만 아니라 나만의 공간으로도 쓸 수 있게 됐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/3.webp" alt="곰곰이 웹앱 브라우저"&gt;&lt;figcaption&gt;곰곰이 웹을 보고 만약 무엇인가 떠올랐다면, 맞습니다. 저는 스탯을 개발에만 찍어서 디자인 능력이 없거든요.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;나의 데이터 분석 채팅을 나만 볼 수 있는 게 생각보다 꽤 중요합니다. 곰곰이의 고객인 사내 동료들은 아직 데이터를 직접 다루는 습관이 충분히 쌓이지 않은 분들이 많습니다. &lt;strong&gt;내가 한 질문이 누군가에게 바보 같아 보이지 않을까 하는 마음이 곰곰이 사용을 주저하게 만들 수 있거든요.&lt;/strong&gt; 나만 볼 수 있는 대화가 생기니까 자유롭게 질문하고 시도해 볼 수 있습니다. 아직 만들진 않았지만 유저나 그룹별로 접근 가능한 데이터 종류를 제어하는 권한 관리도 웹이기 때문에 가능한 것들입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/4.webp" alt="곰곰이 웹앱 브라우저"&gt;&lt;figcaption&gt;바보 같은 질문 하는 채팅&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;답변의 표현도 훨씬 풍부해졌습니다. 곰곰이가 마크다운으로 답변하도록 만들고 브라우저에서 렌더링하니까 표, 코드, 텍스트 포맷이 제대로 보입니다. 슬랙과 웹에서 곰곰이의 답변을 비교하면 답변의 가독성이 더 좋다는 것을 바로 알 수 있죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/5.webp" alt="곰곰이 웹앱 브라우저"&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 한 발 더 나가면 마크다운과 잘 호환되는 Mermaid 문법으로 답변하게 할 수 있는데, &lt;strong&gt;그러면 순서도, 막대, 꺾은선, 파이 그래프 같은 시각화를 코딩 없이 프롬프트만으로 보고서에 바로 넣을 수 있습니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/6.webp" alt="곰곰이 차트"&gt;&lt;figcaption&gt;곰곰이가 그려준 차트들&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;곰곰이가 데이터를 분석하는 ReAct 추론 과정을 채팅에서 바로 볼 수 있다는 것도 생각보다 유용합니다. 보고서가 어떤 과정으로 만들어졌는지 빠르게 파악할 수 있거든요. 동료들이 질문한 결과가 예상과 다르다고 확인을 요청해 올 때 추론 과정을 같이 들여다보면 어디서 어떻게 틀렸는지 바로 찾을 수 있습니다. 덕분에 “이 부분에서 이렇게 접근하면 됩니다” 같은 구체적인 피드백을 주기가 훨씬 수월해졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/7.webp" alt="곰곰이의 사고과정"&gt;&lt;figcaption&gt;곰곰이의 사고 과정 엿보기&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;직접 만든 웹앱이니까 원하는 기능을 그냥 만들면 됩니다. 당연한 말 같지만 이게 생각보다 큰 차이입니다. 데이터 분석 보고서를 HTML 렌더링된 형태 그대로 이미지로 저장할 수 있고, 좋아요 버튼을 누르면 대화 내용을 요약해서 곰곰이의 장기 기억에 넣을 수 있습니다. 뒤에서 설명할 커맨드와 예약도 웹 인터페이스 안에서 생성, 수정, 삭제가 가능합니다. 슬랙에서는 시도조차 못 했던 것들입니다. 우리가 웹앱에서 당연하게 기대하는 경험들을 이제 곰곰이도 갖추게 됐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/8.webp" alt="곰곰이 웹앱 브라우저"&gt;&lt;figcaption&gt;좋아요를 누르면 곰곰이가 대화를 기억해 준다.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;마지막으로 대시보드 이야기를 빼놓을 수 없습니다. 전통적으로 데이터를 받아보는 방식은 두 가지였습니다. 새로운 정보나 가끔 필요한 분석은 데이터 분석가에게 요청해서 보고서로 받고, 자주 봐야 하는 정해진 지표들은 대시보드로 봤습니다. 곰곰이 채팅이 전자를 담당해 주고 있다면, 후자는 여전히 대시보드가 필요합니다. 채팅 분석만으로는 그 경험을 대체하기 어렵습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;옵저버빌리티처럼 데이터도 한곳에 모여 있어야 시너지가 난다&lt;/strong&gt;고 생각해서 데이터 대시보드도 같은 웹에 직접 개발했습니다. (Chart JS 사용) 차트는 곰곰이가 만드는 게 아니라, 코딩 에이전트의 도움을 받아 사람이 직접 만들고 있습니다. 곰곰이를 웹으로 이사시켰기 때문에 채팅과 대시보드를 한곳에서 제공할 수 있게 됐고, 두 가지가 만들어낼 시너지를 기대하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/9.webp" alt="곰곰이 대시보드"&gt;&lt;figcaption&gt;대시보드를 보고 바로 채팅으로 물어 볼수 있다.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;커맨드와 예약: 반복 분석을 자동화하다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;곰곰이로 데이터 분석을 잘하려면 순차적으로 질문하는 게 좋습니다. 예를 들면 이런 식입니다. “지금 진행 중인 투표가 있어?” → “해당 투표 후보자의 득표 Top3를 알려줘.” → “Top3 후보가 붙었던 다른 투표 모두 알려줘.” → “회차별 투표수 그래프를 포함해서 보고해줘.” 물론 이걸 한 번에 요청해도 곰곰이는 높은 확률로 맞는 답변을 만들어냅니다. 하지만 LLM의 특성상 단계적으로 접근할수록 결과의 품질이 올라가는 건 사실입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/10.webp" alt="곰곰이 커맨드"&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;문제는 매주 같은 분석이 필요할 때입니다. &lt;strong&gt;이 과정을 매번 반복해야 한다면 귀찮습니다.&lt;/strong&gt; 동료들의 곰곰이 사용 빈도도 자연스럽게 떨어질 것이고요. 그래서 만든 게 커맨드 기능입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;만족스러운 대화가 있으면 곰곰이에게 &lt;strong&gt;“이거 커맨드로 만들어줘”&lt;/strong&gt;라고 하면 됩니다. 곰곰이가 대화를 분석해서 사용자에게 확인받아야 하는 입력 정보, 데이터 분석 SQL, 분석 방법, 보고서 작성 형식 등을 프롬프트로 정리하여 저장합니다. 다음부터는 &lt;code&gt;/vote-weekly-report&lt;/code&gt; 같은 커맨드 하나로 동일한 보고서를 받을 수 있습니다. 커맨드 검색, 수정, 삭제 같은 관리도 웹 인터페이스 안에서 바로 할 수 있습니다. 슬랙이었다면 불가능했던 것들입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/11.webp" alt="커맨드 저장 &amp;gt; 커맨드 수정 &amp;gt; 커맨드 실행"&gt;&lt;figcaption&gt;커맨드 저장 &amp;gt; 커맨드 수정 &amp;gt; 커맨드 실행&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;커맨드를 만들었다고 해도 사용자가 직접 실행하러 와야 한다면 여전히 귀찮은 일입니다. 그래서 &lt;strong&gt;예약 기능을 붙였습니다.&lt;/strong&gt; 원하는 주기와 시점에 커맨드를 예약해 두면 곰곰이가 알아서 분석을 실행하고, 핵심 내용 3줄 요약과 바로 가기 링크를 슬랙으로 보냅니다. 사용자는 알림을 받고 지표에 이상한 점이 있을 때만 웹에 들어와서 그 세션 그대로 곰곰이에게 이어서 물어보면 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/12.webp" alt="보고서 슬랙"&gt;&lt;figcaption&gt;3줄 요약된 보고서를 슬랙 알림으로 수신 &amp;gt; 추가 궁금점을 질문&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;슬랙의 접근성과 웹의 경험을 합친 것입니다.&lt;/strong&gt; 인터페이스를 직접 만들었기 때문에 가능한 조합입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;곰곰이 제작자의 생각&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;곰곰이가 생기고 나서 &lt;strong&gt;데이터 업무의 패러다임 자체가 바뀌었습니다.&lt;/strong&gt; SQL을 모르는 동료가 직접 데이터를 확인하는 게 자연스러워졌고, 데이터를 기반으로 의사결정 하는 횟수도 늘었습니다. 예약 기능 덕분에 지표의 이상을 예전보다 훨씬 빠르게 감지할 수 있게 됐고요. 기존에 없던 개념의 데이터 플랫폼을 갖게 된 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;근데 솔직히 말하면 저의 기대보다 많이 안 씁니다. 이렇게 좋은 도구인데 동료들이 각자의 이유로 자주 찾지 않습니다. 무슨 데이터가 있는지 모르겠다, 너무 바빠서 데이터까지 볼 여유가 없다, 데이터를 확인해야 한다는 생각을 못 했다, 습관이 없다. 들어보면 다 맞는 말입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 저는 이 이유들이 일단 &lt;strong&gt;곰곰이에게 물어보기 시작하면 해결된다&lt;/strong&gt;고 생각합니다. 궁금한 게 생겼을 때 ChatGPT를 켜는 것처럼요. 새로운 도구는 써보면서 익히는 수밖에 없습니다. 다만 ChatGPT랑 다른 점이 하나 있습니다. 데이터에 대해 궁금해하고 분석 결과를 이해할 수 있는 능력이 있어야 한다는 것입니다. 그게 어렵다는 건 공감합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 지금 제가 하고 있는 건 동료들에게 먼저 다가가는 것입니다. 불편한 점을 물어보고, 사용 방법을 알려주고, 기다리는 것. 시간이 해결해 주는 부분도 분명히 있을 겁니다. &lt;strong&gt;그리고 이런 부분이 AI가 아닌 사람이 필요한 지점이 아닐까요?&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3705/13.webp" alt="곰곰이"&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;앞으로 남은 여정&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;곰곰이를 처음 기획하면서 생각했던 것들은 대부분 만들었습니다. 생각보다 빨리 도달해서 스스로도 좀 놀랐습니다. 지금은 소프트웨어 개발의 대격변기니까요. 다음에 뭘 만들지 아직 계획은 없습니다. 그냥 머릿속에 있는 아이디어들을 꺼내봅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;멀티 에이전트, 다른 기업들의 사례를 보면 분야별로 에이전트를 따로 만들어 협업하게 하는 경우를 종종 봤습니다. 질문 의도를 분석하는 에이전트, 작업을 계획하고 지휘하는 에이전트, SQL만 전담하는 에이전트, 답변만 만드는 에이전트, 이런 식으로요. 흥미롭긴 한데 곰곰이는 아직 도구 수가 많지 않아서인지 단일 에이전트로도 충분히 만족스럽습니다. 언젠가는 필요할 것 같기도 한데 지금은 모르겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;어드민 API를 도구로 제공해서 채팅으로 어드민을 관리하는 것도 생각해 봤습니다. 사실 AI 에이전트의 본질은 분야가 달라도 다 똑같습니다. 요청을 받고, 생각하고, 도구를 골라 실행하고, 결과를 관찰합니다. 기존 어드민 API들을 곰곰이가 쓸 수 있는 도구로 만들어준다면 &lt;strong&gt;“곰곰아 다음 주 투표 미리 만들어놔. 가이드 문서 보고 알아서 해!”&lt;/strong&gt; 같은 것도 가능해집니다. 도구와 가이드만 주면 곰곰이가 데이터 분석가 말고도 뭐든 될 수 있는 거죠. 안 해봐서 잘 될지는 모르겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사내 모든 문서와 정보를 RAG로 넣어주는 것도 재밌는 상상입니다. 창사 이후 모든 지라 티켓, 슬랙 대화 내용들을 곰곰이에게 제공한다면 &lt;strong&gt;창업자보다 회사를 더 잘 아는 존재가 될 수도 있습니다.&lt;/strong&gt; 물론 LLM과 RAG의 한계가 있으니 기대만큼은 안 되겠죠. 역시 안 해봐서 모릅니다. &lt;span style="color:#999999;"&gt;(언젠가 곰곰이 3탄이 나올 수 있다면 좋겠네요.)&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>타입스크립트 제네릭, 실무에서 제대로 활용하기</title><link>https://yozm.wishket.com/magazine/detail/3702</link><description>타입스크립트를 쓰다 보면 제네릭을 마주치는 일이 정말 많습니다. 라이브러리의 타입 정의를 읽을 때, API 응답 타입을 만들 때, 공통 함수를 작성할 때 등 어디에서든 &lt;T&gt; 같은 꺾쇠괄호가 등장하는데요, 그런데 다른 사람이 작성한 제네릭은 대충 읽을 수 있어도, 막상 직접 작성하려면 막막한 경우가 많습니다. 이번 글에서는 제네릭이 왜 필요한지부터 실무에서 자주 만나는 패턴까지 단계별로 살펴보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3702</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;타입스크립트를 쓰다 보면 제네릭을 마주치는 일이 정말 많습니다. 라이브러리의 타입 정의를 읽을 때, API 응답 타입을 만들 때, 공통 함수를 작성할 때 등 어디에서든 &amp;lt;T&amp;gt; 같은 꺾쇠괄호가 등장하는데요, 그런데 다른 사람이 작성한 제네릭은 대충 읽을 수 있어도, 막상 직접 작성하려면 막막한 경우가 많습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 제네릭이 왜 필요한지부터 실무에서 자주 만나는 패턴까지 단계별로 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul&gt;&lt;li&gt;타입스크립트를 쓰다 보면 제네릭을 마주치는 일이 정말 많습니다, 제네릭이 왜 필요한지부터 실무에서 자주 만나는 패턴까지 단계별로 살펴보겠습니다.&lt;/li&gt;&lt;li&gt;any를 쓰면 반환 값의 타입 정보가 사라집니다, 타입의 중복도 없애고 타입 안전성도 유지할 수 있는 방법이기 때문입니다.&lt;/li&gt;&lt;li&gt;제네릭에 익숙해지면 타입스크립트가 기본으로 제공하는 유틸리티 타입(Pick, Omit, Partial 등)을 이해하는 것도 훨씬 수월해집니다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;제네릭이 필요한 이유&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;제네릭이 왜 필요한지 이해하려면, 제네릭 없이 코드를 작성했을 때 어떤 불편함이 생기는지 먼저 살펴보는 것이 좋습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 타입을 하드코딩하면 생기는 문제&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;배열의 첫 번째 요소를 반환하는 간단한 함수를 만든다고 해봅시다. string 배열이라면 이렇게 작성할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function getFirstString(arr: string[]): string {
  return arr[0];
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 number 배열도 처리해야 한다면 어떻게 해야 할까요? 같은 로직의 함수를 하나 더 만들어야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function getFirstNumber(arr: number[]): number {
  return arr[0];
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;로직은 완전히 같은데 타입만 다르다는 이유로 함수가 계속 늘어납니다. boolean 배열, 객체 배열까지 대응하려면 끝이 없어지겠죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) any를 사용하면 되지 않을까?&lt;/strong&gt;&lt;/h4&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3702/%EA%B7%B8%EB%A6%BC1__2_.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, ChatGPT로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그렇다면 매개변수 타입을 any로 바꾸면 어떨까요? 중복 문제는 해결됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function getFirst(arr: any[]): any {
  return arr[0];
}

const result = getFirst([1, 2, 3]);
result.toUpperCase(); // 에러가 안 남&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;any를 쓰면 타입 정보가 사라질뿐 아니라, 타입스크립트의 검사 자체가 대부분 우회됩니다. result가 number인데도 toUpperCase()를 호출해도 타입스크립트가 경고해 주지 않습니다. 결국 런타임에서야 에러가 터지게 되는데, 이렇게 되면 타입스크립트를 쓰는 의미가 퇴색되겠죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;바로 이런 상황에서 필요한 것이 제네릭입니다. 타입의 중복도 없애고, 타입 안전성도 유지할 수 있는 방법이기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;제네릭 기본 문법&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;제네릭의 필요성을 확인했으니, 이제 실제 문법을 살펴보겠습니다. 함수, 인터페이스, 그리고 제약 조건까지 단계적으로 알아볼게요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3702/%EA%B7%B8%EB%A6%BC2__2_.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 함수에서의 제네릭&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;제네릭 함수는 꺾쇠괄호(&amp;lt;T&amp;gt;)로 타입 매개변수를 선언합니다. T는 호출 시점에 전달되는 값에 따라 타입이 결정됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function getFirst&amp;lt;T&amp;gt;(arr: T[]): T | undefined {
  return arr[0];
}

const num = getFirst([1, 2, 3]);       // T는 number로 추론
const str = getFirst(["a", "b", "c"]); // T는 string으로 추론&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;getFirst([1, 2, 3])을 호출하면 타입스크립트가 인자를 보고 T를 number로 추론합니다. 덕분에 반환값 num도 number 타입으로 정확하게 잡히죠. 아까 any를 썼을 때와 달리, num.toUpperCase()를 쓰면 컴파일 단계에서 에러가 발생합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;타입 추론이 원하는 대로 되지 않을 때는 직접 타입을 명시할 수도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;const value = getFirst&amp;lt;string&amp;gt;(["a", "b", "c"]);&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 대부분 타입스크립트가 알아서 추론해 주기 때문에 특별한 이유가 없다면 명시하지 않아도 괜찮습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 인터페이스와 타입에서의 제네릭&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;제네릭은 함수뿐 아니라 인터페이스와 타입 별칭에도 적용할 수 있습니다. 특히 구조는 같지만 내부 데이터 타입만 달라지는 경우에 유용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;interface KeyPair&amp;lt;K, V&amp;gt; {
  key: K;
  value: V;
}

const pair1: KeyPair&amp;lt;string, number&amp;gt; = {
  key: "age",
  value: 27,
};

const pair2: KeyPair&amp;lt;string, boolean&amp;gt; = {
  key: "isActive",
  value: true,
};&lt;/code&gt;&lt;/pre&gt;&lt;p style="margin-left:36pt;text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 함수와 한 가지 다른 점이 있습니다. 제네릭 함수는 호출 시 인자를 보고 타입을 추론할 수 있지만, 제네릭 인터페이스나 타입 별칭은 함수처럼 호출 인자를 통해 즉시 추론되는 경우가 적기 때문에, 사용하는 위치에 따라 타입 인수를 직접 명시하는 경우가 많습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;타입 별칭에서도 동일하게 사용할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;type Pair&amp;lt;K, V&amp;gt; = {
  key: K;
  value: V;
};&lt;/code&gt;&lt;/pre&gt;&lt;p style="margin-left:36pt;text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 제네릭 제약 조건(extends)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;제네릭은 기본적으로 어떤 타입이든 받을 수 있습니다. 하지만 실무에서는 아무 타입이나 받으면 안 되는 경우가 많은데요, 이때 extends 키워드로 타입의 범위를 제한할 수 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function getLength&amp;lt;T extends { length: number }&amp;gt;(data: T): number {
  return data.length;
}

getLength("hello");      // ✅ string은 length 속성이 있음
getLength([1, 2, 3]);    // ✅ 배열은 length 속성이 있음
getLength({ length: 5 }); // ✅ 직접 정의한 객체도 가능
getLength(123);           // ❌ number에는 length가 없어서 에러&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;T extends { length: number }는 “T는 반드시 number 타입의 length 속성을 가져야 한다”는 제약입니다. 이 조건을 만족하지 않는 타입이 들어오면 컴파일 단계에서 에러가 발생합니다. 이처럼 제약 조건을 활용하면 제네릭의 유연함은 유지하면서도, 필요한 속성이나 메서드가 있다는 것을 보장받을 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실무에서 자주 쓰는 제네릭 패턴&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;문법을 익혔으니, 이제 실무에서 제네릭이 어떻게 쓰이는지 살펴보겠습니다. 가장 흔하게 만나는 두 가지 패턴을 소개해 보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) API 응답 타입 래퍼&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;실무에서 백엔드 API를 호출하면, 응답 구조가 보통 일정한 형태를 따릅니다. 상태 코드와 메시지는 공통이고, 실제 데이터 부분만 엔드포인트 마다 달라지는 경우가 많죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;interface ApiResponse&amp;lt;T&amp;gt; {
  success: boolean;
  statusCode: number;
  data: T;
  message: string;
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 data 부분만 제네릭으로 열어두면, 하나의 인터페이스로 모든 API 응답을 커버할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;interface User {
  id: number;
  name: string;
}

interface Post {
  id: number;
  title: string;
  content: string;
}

type UserResponse = ApiResponse&amp;lt;User&amp;gt;;
type PostListResponse = ApiResponse&amp;lt;Post[]&amp;gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3702/%EA%B7%B8%EB%A6%BC3__1_.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;ApiResponse&amp;lt;User&amp;gt;는 data가 User 타입이 되고, ApiResponse&amp;lt;Post[ ]&amp;gt;는 data가 Post[ ] 타입이 됩니다. 엔드포인트가 수십 개라도 API 응답 래퍼를 매번 새로 정의할 필요가 없습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 공통 유틸 함수에 제네릭 적용하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;프로젝트를 진행하다 보면 배열이나 객체를 다루는 공통 유틸 함수를 만들게 됩니다. 이런 함수에 제네릭을 적용하면 반환 타입까지 정확하게 추론되는 것을 확인할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;// 배열에서 특정 조건을 만족하는 첫 번째 요소 반환
function findFirst&amp;lt;T&amp;gt;(arr: T[], predicate: (item: T) =&amp;gt; boolean): T | undefined {
  return arr.find(predicate);
}

const users = [
  { name: "홍길동", age: 27 },
  { name: "김철수", age: 30 },
];

const found = findFirst(users, (user) =&amp;gt; user.age &amp;gt; 25);
// found의 타입: { name: string; age: number } | undefined&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;findFirst에 users 배열을 넘기면, 타입스크립트가 T를 { name: string; age: number }로 추론합니다. 덕분에 predicate 콜백의 user 매개변수에서도 user.age에 자동완성이 동작하고, 반환값의 타입도 정확하게 잡힙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;객체의 특정 필드를 추출하는 함수도 제네릭과 제약 조건을 조합하면 타입 안전하게 만들 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-typescript"&gt;function pluck&amp;lt;T, K extends keyof T&amp;gt;(arr: T[], key: K): T[K][] {
  return arr.map((item) =&amp;gt; item[key]);
}

const names = pluck(users, "name"); // string[]
const ages = pluck(users, "age");   // number[]&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;K extends keyof T는 “K는 T의 키 중 하나여야 한다”는 제약입니다. 덕분에 존재하지 않는 키를 넘기면 컴파일 에러가 발생하고, 반환 타입도 해당 키의 값 타입에 맞게 자동으로 추론됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 제네릭이 필요한 이유부터 기본 문법, 그리고 실무 패턴까지 살펴봤습니다. 처음에는 &amp;lt;T&amp;gt; 같은 꺾쇠괄호가 낯설게 느껴질 수 있지만, 결국 핵심은 하나입니다. 타입을 값처럼 매개변수로 전달해서 중복 없이 다양한 타입에 대응하는 것이죠. 실무에서 반복되는 타입 패턴이 보인다면, 그것이 바로 제네릭을 쓸 타이밍입니다. 특히 API응답 타입이나 공통 유틸 함수처럼 구조는 같고 데이터만 달라지는 상황에서 제네릭은 가장 큰 효과를 발휘합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;제네릭에 익숙해지면 타입스크립트가 기본으로 제공하는 유틸리티 타입(Pick, Omit, Partial 등)을 이해하는 것도 훨씬 수월해집니다. 이 유틸리티 타입들도 결국 제네릭으로 만들어진 것이기 때문입니다.&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;&amp;lt;참고&amp;gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://ts.winterlood.com/"&gt;&lt;u&gt;한 입 크기로 잘라먹는 타입스크립트&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://inpa.tistory.com/entry/TS-%F0%9F%93%98-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Generic-%ED%83%80%EC%9E%85-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0"&gt;&lt;u&gt;타입스크립트 Generic 타입 정복하기&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>시니어를 넘어 ‘백수저’ 리드 개발자로</title><link>https://yozm.wishket.com/magazine/detail/3701</link><description>개발 현장에서 시간은 누구에게나 공평하게 흐릅니다. 그렇게 연차가 쌓이고 경험이 더해지면 우리는 자연스레 시니어(Senior)라는 타이틀을 달게 됩니다. 하지만, 코드를 오래 작성했다고 해서 누구나 팀과 프로덕트를 이끄는 리드(Lead) 개발자가 되는 것은 아닙니다. 리드를 목표로 하는 것은 어쩌면 매일 하는 일의 기준을 한 단계 높여놓겠다는 뜻일지도 모릅니다. 같은 업무를 처리하더라도 “리드라면 이 상황에서 어떤 판단을 했을까?”라는 시각으로 봐야 더 높은 학습 효율을 끌어낼 수 있습니다. 주니어 시절의 방향 설정이 중요한 이유가 여기 있습니다. 주니어 레벨부터 리드 개발자의 마인드셋을 지향해야 매일의 경험을 성장의 자양분으로 환산해낼 수 있습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3701</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;주니어 개발자라도, 리드 개발자를 지향해야 하는 이유&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개발 현장에서 시간은 누구에게나 공평하게 흐릅니다. 그렇게 연차가 쌓이고 경험이 더해지면 우리는 자연스레 시니어(Senior)라는 타이틀을 달게 됩니다. 하지만, 코드를 오래 작성했다고 해서 누구나 팀과 프로덕트를 이끄는 리드(Lead) 개발자가 되는 것은 아닙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;주니어 시절부터 리드의 시선을 가지라는 조언은 단순히 빠른 승진에 야망을 품으라는 말이 아닙니다. 커리어라는 긴 흐름 속에서 표류하지 않고 앞으로 나아갈 방향을 찾는 일에 가깝습니다. 목적지를 알고 움직이는 사람은 길을 쉽게 잃지 않기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;마찬가지로 지금 당장 리드 역할을 맡으라는 것도 아닙니다. 어쩌면 매일 하는 일의 기준을 한 단계 높여놓겠다는 뜻일지도 모릅니다. 같은 업무를 처리하더라도 “리드라면 이 상황에서 어떤 판단을 했을까?”라는 시각으로 봐야 더 높은 학습 효율을 끌어낼 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;주니어 시절의 방향 설정이 중요한 이유가 여기 있습니다. 주니어 레벨부터 리드 개발자의 마인드셋을 지향해야 매일의 경험을 성장의 자양분으로 환산해낼 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3701/image4.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;시니어는 ‘어떻게’를 풀고, 리드는 ‘왜’를 정의한다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;주니어 시절부터 리드의 시선을 가지는 것의 중요성을 이야기했습니다. 그렇다면 한 가지 의문이 생깁니다. &lt;i&gt;“시니어 개발자와 리드 개발자는 무엇이 다를까요?”&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;흔히들 코딩 실력이 극한에 달하면 리드 개발자가 된다고 생각합니다. 하지만 시니어에서 리드로 넘어가는 과정은 단순한 스킬의 향상보다는 &lt;strong&gt;패러다임의 전환(Paradigm Shift)&lt;/strong&gt;에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이러한 관점은 실제로 실리콘밸리의 빅테크 기업이 정의하는 엔지니어링 레벨(Engineering Level) 가이드에서도 핵심 기준으로 다뤄집니다. 구글이나 메타의 업무 가이드에서는 리드로 성장하기 위해 이전과는 다른 차원의 비즈니스 관점과 주도성을 가질 것을 요구합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그들이 공통적으로 강조하고, 실제 실무에서도 체감할 수 있는 결정적인 차이를 3가지로 요약해 보았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 해결사(Problem Solver) vs 정의자(Problem Definer)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;시니어 개발자의 핵심 역량은 뛰어난 ‘문제 해결 능력’이라고들 합니다. 복잡한 요구사항이 주어졌을 때도 엣지 케이스까지 고려해 버그 없는 좋은 코드를 짜는 거죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 리드 개발자는 JIRA 티켓이 만들어지기 전부터 움직입니다. 단순히 주어진 요청을 처리하는 데 그치지 않고, 데이터와 사용자 피드백을 기반으로 “지금 우리가 정말로 해결해야 할 문제는 무엇인가? 혹시 근본적인 원인은 다른 곳에 있지 않은가?”를 고민해야 합니다. 즉, 리드는 ‘무엇이 문제인지’를 새로 프레이밍(Framing)하는 사람입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3701/image6.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, ChatGPT로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 기술적 해법(How to build) vs 비즈니스 우선순위(What &amp;amp; Why now)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;시니어 개발자는 “이 기능을 어떻게(How) 가장 효율적이고 안정적으로 구현할 수 있을까?”를 고민하며, 팀을 위한 표준 가이드와 문서를 정리합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 리드 개발자는 &lt;strong&gt;“우리는 무엇을(What), 왜 하필 지금(Why now) 만들어야 하는가?”&lt;/strong&gt;를 먼저 묻습니다. 아무리 기술적으로 우아한 아키텍처도 지금 제품의 비즈니스 단계와 맞지 않거나 사용자에게 제공하는 가치가 낮다면 과감하게 “지금 우리 우선순위가 아닙니다”라고 말하며 조직을 설득합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 기술의 언어(옳은 답) vs 비즈니스의 언어(가치와 비용)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;시니어 개발자가 ‘기술적으로 100점에 가까운 정답’을 만들어내는 사람이라면, 리드 개발자는 그 정답을 다른 조직에 ‘설득하고 전달할 수 있는 사람’입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;새로운 기술 스택을 도입하거나 레거시 시스템을 개선해야 할 때, 리드는 단순히 “더 최신 기술이니까요”라고 하지 않습니다. 대신 비용 절감, 장애 리스크 감소, 그리고 비즈니스 가치 창출이라는 &lt;strong&gt;비즈니스의 언어&lt;/strong&gt;로, 타 부서와 경영진에게 선택의 근거를 명확하게 전달합니다.&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;실무자의 정점이자 전략가로 첫 걸음을 내딛은 리드 개발자는 팀의 방향을 결정하는 ‘아키텍트(Architect)’입니다. 코드가 어떻게 동작하는지를 넘어, 우리 팀과 제품이 어디를 향해 나아가고 있는지를 아는 리드 개발자는 조직에서 매우 귀한 인재입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실무에서 증명해야 할 리드의 역할&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;시니어와 리드 개발자의 시야 차이를 보고 나면, 이런 질문이 자연스럽게 떠오를 겁니다. &lt;i&gt;“아직 주니어인 내가, 실무에서 어떻게 리드의 역할을 보여줄 수 있을까?”&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실리콘밸리 빅테크를 비롯한 주요 테크 기업들의 평가 원칙 중 하나는 &lt;strong&gt;“그 다음 레벨로 승진하려면, 이미 그 레벨처럼 일하고 있다는 것을 증명해야 한다(Demonstrate next-level behavior)”&lt;/strong&gt;입니다. 단순히 연차가 쌓였다고 타이틀을 주는 대신, 주니어 시절부터 리드의 역할과 행동 방식을 실무에서 미리 보여주어야 다음 단계로 나아갈 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;‘리드 개발자’처럼 일한다는 것, 그 &lt;strong&gt;핵심은 선제성(Proactivity)과 영향력(Influence)&lt;/strong&gt;으로 요약됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 규칙을 따르는 사람에서 만드는 사람으로&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;주니어 시절에는 보통 팀에 이미 구축된 컨벤션과 아키텍처를 이해하고 따르는 데 집중합니다. 하지만 다음 레벨로 가려면 지금 시스템의 불편함을 당연하게 여기지 않는 태도가 필요합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“우리 팀의 코드 리뷰가 주관적으로 이루어지고 있는데, 이런 체크리스트를 도입해 보면 어떨까요?”라고 제안해 보세요. 또는 반복되는 수동 배포 과정을 스크립트로 자동화하거나, 파편화된 에러 처리 방식을 하나로 정리하는 가이드를 만드는 것도 좋은 방법입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이처럼 &lt;strong&gt;팀의 생산성을 높이고 올바른 방향을 제시하는 규칙(Standard)을 설정&lt;/strong&gt;하는 것이 리드 역할의 출발점입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 코드 작성 전, 기획의 최전선에 서기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;코드를 다 짜고 나서 버그를 고치는 것보다, 기획 단계에서 구조적인 결함을 발견하는 편이 훨씬 저렴합니다. 리드 개발자는 이슈가 터지고서야 이를 수습하는 사람이 아니라, 이슈가 터질 만한 곳을 미리 막는 사람입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;JIRA 티켓의 작업을 수동적으로 기다리지 마세요. 기획 회의나 디자인 리뷰 단계에 적극적으로 참여해야 합니다. “이 기능은 사용자 트래픽이 몰릴 경우 DB에 병목이 생길 수 있으니, 캐싱 전략을 추가하는 것이 안전합니다” 같이 말하는 거죠. 이러한 행동이 바로 선제성(Proactivity)을 발휘하는 방식입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;3. 우리 팀을 넘어 전사적 임팩트 창출하기&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3701/image1.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 지점이 실무형 시니어와 리드 개발자를 가르는 가장 결정적인 차이입니다. 업계에서 리드 엔지니어를 평가할 때 가장 중요하게 보는 기준은 바로 &lt;strong&gt;영향력의 반경(Radius of Impact)&lt;/strong&gt;입니다. 자신의 코드가 팀 내부에만 영향을 미친다면 시니어에 머물겠지만, 전사에 영향을 준다면 리드로 평가받게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;거창할 필요는 없습니다. 내가 해결한 어려운 트러블슈팅 과정을 사내 기술 블로그나 위키에 정리해 보세요. 또는 최근 주목받는 AI 코딩 도구(GitHub Copilot, ChatGPT 등)를 실무에 어떻게 적용해 생산성을 높였는지 베스트 프랙티스로 정리해 공유하는 것도 좋은 방법입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;나의 작은 시도가 다른 팀의 작업 시간을 단축시켰다면, 이미 리드 개발자의 영향력(Influence)을 조직 전반에 행사하고 있는 셈입니다.&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;결국, 직급은 남이 주지만, 역할은 내가 취하는 겁니다. “내가 아직 주니어인데 이런 제안을 해도 될까?”라는 걱정은 내려놓아도 좋습니다. 개발 표준을 제안하고, 기획에 의견을 더하며, 지식을 공유하는 일에는 연차의 제한이 없습니다. 오늘 당장 내가 속한 조직에서 작은 개선 포인트 하나라도 찾아보세요. 이러한 작은 주도성들이 쌓이면서, 자연스럽게 여러분을 다음 레벨로 이끌게 될 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;리드 개발자의 커뮤니케이션, 글쓰기, 그리고 학습법&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;리드 개발자가 갖춰야 할 강력한 무기가 있습니다. 커뮤니케이션, 글쓰기, 그리고 지속적인 학습 역량이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실리콘밸리의 빅테크 기업들도 이 점을 명확히 인식하고 있습니다. 이를테면 구글의 엔지니어링 레벨 시스템을 보면, L5(시니어)까지는 코딩 능력과 시스템 설계 역량이 주요 평가 기준으로 작용합니다. 하지만 L6(스태프) 이상부터는 전혀 다른 기준이 적용됩니다. 실제로 구글에서 Principal Engineer로 일하는 Adam Bender는 이를 다음과 같이 설명합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;L5까지의 성장은 가파르지만 선형적이다. 더 효율적으로, 더 빠르게, 더 많이. 하지만 L6는 사다리 자체가 바뀌는 것에 가깝다. &lt;strong&gt;코드를 작성하는 능력보다 명확한 커뮤니케이션과 전략적 사고 능력이 더 중요&lt;/strong&gt;해진다.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최근 국내 주요 IT 기업들도 이러한 글로벌 기준에 맞춰 엔지니어링 레벨 체계를 재정비하고 있습니다. 그렇게 대부분 시니어 레벨에서는 테크 리드 역할을 기대하는 구조로 점차 전환되고 있죠. 그렇다면 다음 단계의 사다리를 오르기 위해, 우리는 구체적으로 어떤 역량을 길러야 할까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3701/image5.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 커뮤니케이션: 기술적 임팩트를 비즈니스 임팩트로&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;리드 개발자는 PM, 디자이너, 경영진과 소통할 때 개발자만 쓰는 언어에 머무르지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;같은 사실, 다른 파급력:&lt;/strong&gt; “이 API의 레이턴시가 200ms에서 50ms로 줄었습니다”라고 말과 “사용자가 검색 결과를 4배 빠르게 받으며 이탈률이 감소할 것으로 예상됩니다”라는 말은 같은 사실을 설명하고 있습니다. 하지만 이를 듣는 사람에게 전달되는 영향력은 완전히 다릅니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;평가를 가르는 커먼 센스(Common Sense):&lt;/strong&gt; 이러한 말하기 능력은 특히 성과 평가에서 결정적인 차이를 만듭니다. 같은 일을 수행했더라도 “캐싱 레이어를 리팩토링했습니다”라고 쓰는 대신 “캐싱 구조 개선으로 서버 비용을 월 200만 원 절감하고, 응답 속도 개선으로 전환율이 15% 상승했습니다”라고 표현하면 평가가 달라질 수밖에 없습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이는 리드 레벨에서도 동일하게 적용됩니다. 기술적 성과를 비즈니스 언어로 번역해 상위 조직에 전달하는 리드가 있는 팀과 편한 방식 그대로 보고하는 리드가 있는 팀은 받는 평가 자체가 크게 달라집니다. 개발 성과를 몇 MD(Man-Day) 절감했는지, 비용을 얼마나 줄였는지처럼 &lt;strong&gt;누구나 이해할 수 있는 숫자로 설득하는 것&lt;/strong&gt;. 이것이 바로 리드 수준의 커뮤니케이션입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 글쓰기: 구글 독스를 내 IDE로&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;리드 개발자가 되면 코드보다 문서로 더 많은 의사결정에 영향을 미칩니다. Adam Bender는 “구글 독스(Google Docs)가 사실상 내 IDE다.”라고 표현하기까지 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;스케일링의 도구, 글쓰기:&lt;/strong&gt; 전략 문서를 쓰고, 가치 문서를 다루고, 시스템 설계 문서를 작성하며, 다른 사람의 문서를 리뷰하는 일까지, 업무 대부분은 코드가 아니라 글로 이루어집니다. Adam은 글쓰기 역량을 키우는 것이 자신의 영향력(Influence)을 스케일하는 가장 효과적인 방법이었다고 강조합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;회의 열 번보다 강력한 문서:&lt;/strong&gt; RFC(Request for Comments), 기술 제안서, 아키텍처 결정 기록(ADR), 장애 보고서(Post-mortem) 등 대부분 핵심은 글로 쓰입니다. 읽는 사람의 시간을 존중하면서도 핵심을 명확하게 전달하는 글쓰기 능력은 잘 쓴 코드만큼이나 리드 개발자의 핵심 역량입니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 학습 역량: 일상에서 배우는 평생 학습자&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;기술의 변화 속도는 무자비합니다. 그런만큼 리드 개발자는 학습에 높은 우선순위를 두어야 합니다. 다만, 가장 중요한 것은 거창한 계획이 아니라 ‘일관성’입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;업무와 학습의 일체화:&lt;/strong&gt; 그토록 바쁜 일상에서 일관성을 어떻게 유지할까요? 가장 효과적인 방법은 &lt;strong&gt;학습을 업무와 분리하지 않는 것&lt;/strong&gt;입니다. 코드 리뷰를 할 때마다 새로운 패턴을 메모하고, 장애를 대응한 다음에는 근본 원인을 파고들어 시스템의 새로운 영역을 학습해 나가야 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;학습을 습관으로:&lt;/strong&gt; 학습을 주말에 몰아서 수행하는 숙제처럼 두기보다, 매일 숨쉬듯 반복하는 ‘루틴’으로 정착시키는 것도 중요합니다. 꾸준함은 의지보다는 환경에서 만들어집니다. 이렇게 쌓은 지식을 블로그나 오픈소스에 공유하며 나만의 성장 선순환 구조를 갖추는 것이야말로 리드 개발자의 학습 방식입니다.&lt;/li&gt;&lt;/ul&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;이렇게 리드로 도약하기 위해서는 기술 그 이상의 역량이 필요합니다. 전략적인 커뮤니케이션과 논리적인 글쓰기, 그리고 멈추지 않는 학습 습관을 내 것으로 만드세요. 이 무기들을 갈고닦아 &lt;strong&gt;성장의 방향을 조직의 가치와 일치&lt;/strong&gt;시킬 수 있다면, 어느덧 다음 레벨의 사다리 위에 서 있는 자신을 발견할 것입니다. 모두 성장의 사다리를 갈아탈 준비가 되었나요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며: 시간은 시니어를 만들지만, 방향은 리드를 만든다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;주니어라는 타이틀로 리드처럼 행동하다 보면, 문득 &lt;strong&gt;“내가 너무 앞서가는 건 아닐까?”&lt;/strong&gt; 하는 자기 의심(Imposter Syndrome)에 빠질 수도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3701/Gemini_Generated_Image_we6yrtwe6yrtwe6y.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 요즘IT, Gemini로 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;lt;흑백요리사2&amp;gt;에 출연한 손종원 셰프는 “내가 3스타에서 일했다고 해서 그곳이 나를 3스타로 만들어 주는 건 아니다. 나의 스타는 내가 만들어 가야 한다.” 라고 이야기 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;리드 개발자도 마찬가지입니다. 이는 직급의 문제가 아닌 문제를 대하는 태도, 비즈니스를 바라보는 시야, 그리고 일관된 학습 습관에 관한 이야기입니다. 당장의 위치는 주니어 개발자라 하더라도 리드의 렌즈를 끼고 치열하게 고민한 그 여정 자체가 여러분을 뛰어난 개발자로 성장시켜 줄 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;좋은 코드에 집중하는 시니어로 남을 것인지, 아니면 팀과 프로덕트의 방향을 결정하는 리더로 성장할 것인지. 그 갈림길은 10년 뒤 시니어가 되었을 때가 아닌 &lt;strong&gt;주니어인 바로 지금&lt;/strong&gt; 어떤 방향을 선택하느냐에 따라 결정됩니다. 그러니 지금부터 리드처럼 생각하고, 리드처럼 기록하며, 리드처럼 제안해 보세요. 남은 것은 묵묵히 그 길을 걸어가는 것뿐입니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>반복적인 SQL 업무를 자동화하는 AI 에이전트 '곰곰이'</title><link>https://yozm.wishket.com/magazine/detail/3697</link><description>2025년 10월에 태어난 곰곰이는 STAYGE Labs에서 사내 데이터 분석 AI Agent를 담당하며, 데이터를 잘 다룬다는 특징이 있습니다. 짧은 기간이지만, 구성원들이 곰곰이를 통해 데이터 속에 숨어 있는 높은 차원의 정보를 발견하고, 데이터 비전문가임에도 스스로 데이터를 분석할 수 있는 역량을 강화해 가는 모습을 보니 곰곰이를 만든 ‘곰빠’로서 뿌듯한 기분을 느끼고 있는데요. 이번 글에서는 곰곰이는 무엇이고 어떻게 생겼으며, 왜 만들게 되었는지까지 알아보도록 하겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3697</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;2025년 10월에 태어난 곰곰이는 STAYGE Labs에서 &lt;strong&gt;사내 데이터 분석 AI Agent&lt;/strong&gt;를 담당하며, 데이터를 잘 다룬다는 특징이 있습니다. 짧은 기간이지만, 구성원들이 곰곰이를 통해 &lt;strong&gt;데이터 속에 숨어 있는 높은 차원의 정보를 발견&lt;/strong&gt;하고, &lt;strong&gt;데이터 비전문가임에도 스스로 데이터를 분석할 수 있는 역량을 강화&lt;/strong&gt;해 가는 모습을 보니 곰곰이를 만든 ‘곰빠’로서 뿌듯한 기분을 느끼고 있는데요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 곰곰이는 무엇이고 어떻게 생겼으며, 왜 만들게 되었는지까지 알아보도록 하겠습니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;왜 만들었을까?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;제가 STAYGE Labs에 처음 입사했을 때 맡은 프로젝트가 Redash를 사용해 데이터 추출 업무를 자동화하고 BI 대시보드를 구축하는 것이었습니다. BI 도구가 있으니까 데이터 업무에서 자유로울 수 있을 것으로 기대하지만 실상은 그렇지 않습니다. BI 대시보드와 데이터 추출 업무에 사용되는 SQL들은 정적이기 때문에, 새로운 기능이 오픈되어 새로운 데이터가 보고 싶거나, 데이터 추출 업무의 규칙이 바뀌어 살짝 다른 모양의 데이터를 보고 싶다면, &lt;strong&gt;매번 새로운 SQL을 추가하거나 수정해야 하는 불편함&lt;/strong&gt;이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;SQL을 작성하는 것은 쉬운 일이 아닙니다. SQL 작성 시 &lt;strong&gt;데이터 간의 관계를 잘 파악&lt;/strong&gt;하고 있어야 하며, 각 테이블의 특징에 맞게 쿼리 엔진에 부담이 되지 않는 &lt;strong&gt;튜닝 작업&lt;/strong&gt;도 필요합니다. 그리고 가끔씩 사용하는 &lt;strong&gt;고급 SQL은 매번 잊어버려&lt;/strong&gt; 종종 검색을 하곤 합니다. AI가 대세인 지금 시대에 저는 생각했습니다. “귀찮다!”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/1.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;2024년 초부터 2025년에 이르기까지 기업들이 AI Agent를 사용한 자동화 사례를 앞다투어 기술 블로그와 각종 세미나에서 자랑하기 시작했습니다. &lt;a href="https://medium.com/musinsa-tech/langchain-%EA%B8%B0%EB%B0%98-%EC%A7%80%EB%8A%A5%ED%98%95-%EC%9E%90%EB%8F%99%ED%99%94-%EB%8F%84%EC%9E%85%EA%B8%B0-d83cb93291fa"&gt;&lt;u&gt;CS 자동화&lt;/u&gt;&lt;/a&gt;, &lt;a href="https://velog.io/@useradd_temp/%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81-%EC%9D%B4%EC%A0%9C-%EC%95%8C%EB%9E%8C-%EB%BF%90%EB%A7%8C-%EC%95%84%EB%8B%88%EB%9D%BC-%EB%B6%84%EC%84%9D%EB%8F%84-%EC%9E%90%EB%8F%99%ED%99%94-%EB%90%9C"&gt;&lt;u&gt;모니터링 자동화&lt;/u&gt;&lt;/a&gt;, &lt;a href="https://blog.banksalad.com/tech/how-banksalad-testdata/"&gt;&lt;u&gt;테스트 데이터 생성&lt;/u&gt;&lt;/a&gt;, &lt;a href="https://techblog.woowahan.com/18144/"&gt;&lt;u&gt;Text-to-SQL&lt;/u&gt;&lt;/a&gt;, &lt;a href="https://aws.amazon.com/ko/blogs/tech/building-ai-wine-label-image-search-with-bedrock/"&gt;&lt;u&gt;이미지 검색&lt;/u&gt;&lt;/a&gt; 등 정말 다양한 사례가 있었고, 특히 자연어를 통해 SQL을 생성하여 데이터 분석을 자동화하는 ‘Text-to-SQL’ 사례가 유독 많았습니다. 그리고 모든 사례가 &lt;strong&gt;기존에 없던 새로운 가치를 만들고 생산성을 높였다&lt;/strong&gt;는 이야기를 합니다. 저는 여기서 다시 생각했습니다. “왜 나에게는 저런 것이 없지? 부러워!”, “나도 만들어서 동료들에게 억지로라도 맛보게 해야겠다!!”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;무엇을 만들까?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI Agent를 향한 첫걸음으로 데이터 업무와 분석 작업으로부터 나를 해방해 줄 수 있는 사내 데이터 분석 AI Agent부터 시작하기로 했습니다. 우선 사내 데이터 분석 AI Agent를 동료들이 친근하고 쉽게 다가갈 수 있도록, &lt;strong&gt;궁금한 것은 곰곰이 생각하고 답변해준다는 의미인 “곰곰이”&lt;/strong&gt; 라는 이름과 귀여운 캐릭터를 만들어 주었습니다. (이하 사내 데이터 분석 AI Agent는 ‘곰곰이’라고 칭함.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;곰곰이로 달성하고자 하는 것을 네 가지로 정했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;개발자를 대신해서 &lt;strong&gt;데이터를 분석하거나 추출하는 업무를 수행한다.&lt;/strong&gt; 데이터 분석 업무는 복잡하여 자동화하기 어렵지만, LLM이 등장한 현시점에서 단순하고 반복적인 업무를 넘어 복잡하고 반복적인 업무도 엔지니어링을 통해 자동화할 수 있습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;비개발 직무인 각 &lt;strong&gt;도메인의 전문가들이 AI를 통해 데이터의 잠재력을 폭발시킨다.&lt;/strong&gt; 개발자는 SQL을 다룰 수 있을 뿐 기획, 마케팅, 판매와 같은 전문 분야에 대해서는 잘 모릅니다. 소통의 단계를 줄여 도메인 전문가가 직접 데이터를 다루면 데이터 안에서 기존에 없던 새로운 정보를 찾아낼 것입니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;조직의 &lt;strong&gt;데이터 활용 능력을 높여 데이터를 통해 미래를 예측하고 시장의 변화를 빠르게 감지한다.&lt;/strong&gt; 데이터 분석 능력이 높아지면 과거의 데이터를 통해 미래를 예측할 것이고, AI에게 자율성을 부여하여 인간보다 빠르게 이상 탐지를 할 것입니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;하나만 잘하는 싱글 에이전트를 넘어 &lt;strong&gt;많은 분야에 기여할 수 있는 멀티 에이전트로 진화한다.&lt;/strong&gt; 데이터 분석뿐만 아니라 개발, 기획, 운영 분야에 숨어 있는 비효율을 해결할 수 있는 기능을 추가하며 점진적으로 진화할 것입니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/2.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;본격적인 설계와 개발에 앞서 제가 세운 가설에 의문점을 던졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;내가 만든 제품이 고객들에게 정말로 필요한 것일까?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;실제 고객들은 어떤 불편함을 겪고 있지?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;어떤 기능을 먼저 만들어 선보일 것인가?&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;제가 공들여 만든 제품이 실제 고객에게 필요하지 않아 외면받는 것이 싫었고, 제품 개발의 성공 가능성을 높이기 위해 고객인 동료들을 직접 찾아가 인터뷰하기로 했습니다. 인터뷰 대상은 평소 데이터를 자주 보거나 요청하는 분, 그리고 곰곰이의 능력이 필요하거나 잘 활용할 것 같은 분들을 위주로 선정하여 &lt;strong&gt;다양한 직무와 직급의 동료들을 인터뷰&lt;/strong&gt;했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;인터뷰를 통해 기존 시스템에서 동료들이 데이터를 접하는 데 어려워하는 공통적인 다섯 가지 불편함을 찾았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;보이지 않는 데이터&lt;/strong&gt;: 비개발 직군은 우리 데이터가 어디에, 어떻게 존재하는지 알 수 없음.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;기약 없는 대기 시간&lt;/strong&gt;: “데이터 좀 뽑아주세요”라고 요청한 후, 개발자의 일정을 기다려야만 함.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;보고 싶은 것만 못 봄&lt;/strong&gt;: 기존 대시보드는 정해진 틀만 제공하여 새로운 관점의 분석이 불가능함.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;흩어진 정보들&lt;/strong&gt;: BigQuery, Athena, PostgreSQL, 각종 SaaS에 데이터가 파편화되어 통합 확인이 어려움.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;소 잃고 외양간 고치기&lt;/strong&gt;: 이슈(구독 취소 등)를 미리 알지 못해 선제적 대응 타이밍을 놓침.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/3.webp"&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;인터뷰와 도출한 문제를 기반으로 곰곰이에게 필요한 기능과 유저 스토리, MVP 범위를 포함한 1차 기획서를 작성했습니다. 기획서는 긴 개발 과정에서 &lt;strong&gt;다른 길로 빠지지 않을 수 있는 이정표&lt;/strong&gt;가 되어 주며, 아직 &lt;strong&gt;실체가 없는 곰곰이가 무엇인지 동료들에게 이해시키는 효과&lt;/strong&gt;가 있습니다. 또한 곰곰이의 신규 기능을 스프린트 단위로 개발하고 배포하여 사용자의 이용 패턴을 관찰하면, 개발자의 입장이 아닌 사용자의 입장에서 우선순위가 높은 기능이 무엇인지 파악할 수 있어 빠르고 효율적인 개발이 가능합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/4.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;어떻게 사용하나?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI Agent를 많이 경험해 보지 않은 분이 여기까지 아티클을 읽으셨다면, 곰곰이가 도대체 어떻게 생겼는지, 그래서 무엇을 할 수 있는지 감이 잘 잡히지 않을 것입니다. 곰곰이의 사용 방법과 능력 및 사용 범위를 살펴보며 더 자세히 이해해 보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;사용하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;곰곰이의 사용 방법은 매우 간단합니다. &lt;strong&gt;“질문한다 &amp;gt; 기다린다 &amp;gt; 답변받는다.”&lt;/strong&gt; ChatGPT를 사용해 보신 분이라면 익숙할 경험과 유사합니다. ChatGPT가 인터넷 검색을 통해 답변을 생성한다면, 곰곰이는 우리 서비스의 DB 검색을 통해 답변을 생성합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;원하는 데이터와 대상 기간을 자연어로 입력하면, 곰곰이가 분석 과정을 거쳐 원하는 답변을 주는 것을 확인하실 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/5.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;잘 사용하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;다음으로 곰곰이의 데이터 분석 수준은 어느 정도인지 궁금하실 겁니다. 저의 직관이 담긴 의견을 말씀드리자면, 질문하는 사람의 AI 활용 능력에 따라 중급 데이터 분석가 수준까지는 충분한 역량을 보여주는 것 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;인간: “2025년 12월 LiNC 서비스의 재화 판매량과 매출액을 산출하고, 구매자 국적 및 재구매율 등 세부 지표를 통해 종합적인 판매 성과를 정량적으로 분석받고자 함”&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이것은 실제 동료가 원하던 데이터에서 얻고자 한 정보를 각색한 질문입니다. 단순히 기간 내 매출 합계를 구하는 것이 아니라, 구매자 국적 차원에서 재구매율까지 도출하고 종합적인 성과로 정리해야 합니다. 만약 제가 직접 분석했다면 몇 시간은 필요하고, 협업 상황에 따라 며칠이 소요됐을 정도로 까다로운 분석입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;곰곰이: “2025년 12월 총 x원(x건)의 매출을 기록하며 저가형 패키지와 한국 시장이 판매량을 견인했으나, 인당 구매 빈도(충성도)는 해외 사용자가 더 높은 것으로 분석되었습니다.”&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결론적으로 곰곰이는 사용자와 여러 단계의 협업을 거쳐 몇 분 안에 만족스러운 답변을 주었습니다. 곰곰이가 훌륭하게 답변했지만, 질문자의 능력에 따라 답변의 수준이 달라질 수 있습니다. 곰곰이를 더 잘 사용하기 위한 방법은 다음과 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;의도를 알 수 있는 구체적인 질문&lt;/strong&gt;: “매출 알려줘”와 같은 질문으로는 대상 기간과 서비스를 알 수 없습니다. 원하는 분석 결과를 얻기 위해 필수적인 정보를 질문에 담아야 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;단계적인 접근&lt;/strong&gt;: AI에게 너무 큰 단위의 요청을 하면 분석 과정에서 엉뚱한 방향으로 빠질 수 있습니다. [판매량 &amp;gt; 매출 &amp;gt; 국가 비율 &amp;gt; 재구매율 &amp;gt; 종합] 등 질문을 계층화하여 접근하면 성공적인 답변을 받을 확률이 높습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;칭찬&lt;/strong&gt;: 같은 질문인데 귀찮은 협업 과정을 매번 반복할 수는 없겠죠. 곰곰이에게 칭찬을 해준다면, 이를 잘된 분석으로 간주합니다. 그리고 대화 내용을 기반으로 질문과 분석 과정을 정리 및 저장하여 다음 유사 요청에 빠르고 정확하게 답변하게 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/6.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;도구들&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;문맥상 다음에 올 확률이 가장 높은 단어를 생성할 뿐인 거대 언어 모델(LLM)이 탑재된 곰곰이가 질문의 의도를 파악하고, SQL을 작성하며 데이터를 분석할 수 있는 이유는 무엇일까요? 바로 사전에 만들어 둔 도구들(Tools)을 사용하기 때문입니다. 도구에 대한 설명과 사용 방법을 곰곰이에게 학습시키면 사용자의 요청이 들어왔을 때 가장 적절한 답변을 만들기 위해 자율적으로 도구를 선택하고 사용하게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;SQL 실행 도구&lt;/strong&gt;: 데이터베이스에서 정보를 조회하고 분석할 때 사용하며, 토큰 절약을 위해 100줄 이하의 결과만 조회 가능합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;CSV 변환 도구&lt;/strong&gt;: 100줄이 넘는 대용량 데이터 추출이 필요할 때 사용하며, CSV 파일로 변환하여 다운로드할 수 있는 링크를 제공합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;예시 SQL 저장소&lt;/strong&gt;: 질문을 해결하기 위한 SQL 작성 전 정보 수집을 위해 사용하며, 테이블 스키마나 문제를 해결한 예시 SQL을 저장하고 불러올 수 있습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;장기 기억 저장소&lt;/strong&gt;: 질문과 관련된 도메인 지식, 접근 방법, 풀이 과정 등 과거의 기억을 불러와 작업을 예열할 때 사용하며, 대화 맥락에서 필요한 정보를 자율적으로 요약하여 이후 유사한 요청에서 효율적으로 동작합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/7.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;곰곰이에게는 적은 수의 도구가 주어지고 구조도 단순하지만, 매우 높은 가치의 결과를 만들어 냅니다. 곰곰이가 &lt;strong&gt;높은 가치를 창출할 수 있는 비밀은 바로 ‘반복’과 ‘학습’에&lt;/strong&gt; 있습니다. 우선 반복의 원리를 알기 위해서는 ‘ReAct’ 프롬프트를 이해해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;ReAct&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;여기서 ReAct는 프론트엔드에서 유명한 ‘React JS’가 아닙니다. Reasoning(추론)과 Acting(행동)을 결합한 단어로, LLM에게 “생각 — 행동 — 관찰”의 과정을 유도하는 프롬프트 기법입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;ReAct는 다음과 같은 반복적인 흐름으로 작동합니다. 프로그램을 통해 각 과정이 반복될 수 있는 구조를 구축하면, 곰곰이처럼 LLM이 생각과 도구 선택을 반복하며 자율적으로 문제를 해결할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Command (명령):&lt;/strong&gt; 지난주 투표당 투표 횟수에 대해 분석해 줘.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Thought (추론):&lt;/strong&gt; 질문과 유사한 기억이 있는지 저장소를 확인합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Action (행동):&lt;/strong&gt; “투표 및 투표 기록 테이블 검색.”&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Observation (관찰):&lt;/strong&gt; 이전에 동일한 질문을 한 적이 있으며, 진행 중인 투표와 투표 기록을 조인(Join)하는 예시 SQL을 찾았습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Thought (추론):&lt;/strong&gt; 예시 SQL을 기반으로 쿼리를 작성하여 실행 도구를 가동합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Action (행동):&lt;/strong&gt; “SELECT ~~~ ;”&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Observation (관찰):&lt;/strong&gt; 쿼리 결과에서 투표당 투표 횟수 정보를 확인했습니다. 이제 최종 답변을 할 수 있습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;Final Answer (최종 답변):&lt;/strong&gt; 요청 기간 동안 x개의 투표가 진행 중이었고, x건의 투표 기록이 확인되었습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아래는 LLM 애플리케이션 개발을 돕는 LangChain 라이브러리에서 사용하는 프롬프트입니다. 프롬프트가 &lt;strong&gt;생각과 행동을 유도&lt;/strong&gt;하고 있으며, 단 몇 줄의 설정만으로 단순한 AI 모델이 자율적인 AI Agent가 될 수 있다는 것을 보여줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;# 한국어 버전 ReAct 프롬프트

다음 질문에 대해 당신이 할 수 있는 최선의 답변을 해주세요.
당신은 다음 도구들을 사용할 수 있습니다:
{tools}
반드시 다음 형식을 사용해야 합니다:
Question: 당신이 답해야 하는 입력 질문
Thought: 무엇을 해야 할지 항상 먼저 생각해야 합니다.
Action: 수행할 행동, [{tool_names}] 중 하나여야 합니다.
Action Input: 해당 행동에 필요한 입력값
Observation: 행동의 결과물
... (이 Thought/Action/Action Input/Observation 과정은 여러 번 반복될 수 있습니다)
Thought: 이제 최종 정답을 알게 되었습니다.
Final Answer: 원래 입력된 질문에 대한 최종 답변
시작하세요!
Question: {input}
Thought: {agent_scratchpad}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;일반적인 AI Agent들과 곰곰이의 차별점은 바로 ‘장기 기억 저장소’에 있습니다. 이를 우리 인간의 관점으로 이해해 봅시다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;친구가 물어봅니다. “지난 크리스마스에 뭐 했니?” 질문을 들은 저는 약 2초 동안 생각을 합니다. 기억을 불러오는 중인 것이죠. 머릿속에서 ‘크리스마스’와 ‘24년’이라는 키워드와 관련 있는 기억의 파편들이 머리 깊숙한 곳에서부터 떠오릅니다. [트리 만들기, 여자친구와 데이트, 맛있는 스테이크, 추운 날씨에 펑펑 내리는 눈, 흥겨운 캐럴 송] 등… 그리고 기억의 파편들을 조합해서 대답합니다. “작년 크리스마스 때 여자친구랑 맛있는 스테이크 사서 집에서 구워 먹고, 트리 만들기 하면서 놀았던 것 같아!”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/8.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;곰곰이에게도 인간처럼 &lt;strong&gt;기억을 저장하고 과거에 있었던 기억을 불러오는 기능&lt;/strong&gt;이 있습니다. 곰곰이의 장기 기억 저장소로부터 “이번 달 매출이 얼마야?”라는 요청을 받으면, 과거에 저장해 둔 매출 계산식, 데이터 분석 순서, 데이터 집계에 사용한 SQL 등을 청크(Chunk) 단위로 가져올 수 있습니다. 이제 기억의 조각들을 조합하여 보다 정확한 방법과 과정으로 사용자의 요청을 수행할 수 있게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI가 인간의 기억 방식을 흉내 낸다니 정말 신기하지 않나요? 이를 가능하게 해주는 기술적 요소는 행렬 데이터를 저장하고 빠르게 검색할 수 있는 &lt;strong&gt;Vector DB&lt;/strong&gt;, 단어나 문장을 의미가 담긴 행렬로 바꿀 수 있는 &lt;strong&gt;Embedding Model&lt;/strong&gt;, 그리고 두 단어나 문장이 얼마나 의미적으로 비슷한지 계산할 수 있는 &lt;strong&gt;Semantic Search&lt;/strong&gt;에 있습니다. 이것들은 요즘 주목받는 &lt;strong&gt;검색 증강 생성(RAG)&lt;/strong&gt; 을 구성하는 기술들입니다. (해당 기술들에 대해서는 깊게 다루지 않겠습니다.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/9.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;곰곰이는 분석이 잘 이루어진 대화 내용에서 사용자가 알려준 도메인 지식, 데이터 분석 과정, 사용한 SQL 등을 추출하고 정리하여 &lt;strong&gt;장기 기억 저장소에 기록&lt;/strong&gt;합니다. 이후 사용자로부터 유사한 종류의 질문을 받으면, &lt;strong&gt;과거의 기억 정보를 사용하여 더 빠르고 만족스러운 답변&lt;/strong&gt;을 할 수 있게 됩니다. 이는 곰곰이의 &lt;strong&gt;신뢰도를 높여주며 사용자가 곰곰이를 더 자주 사용할 수 있게&lt;/strong&gt; 해줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;시스템 구조&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이제 곰곰이의 내부를 들여다볼 차례입니다. 아래의 시스템 구성도는 곰곰이의 구성 요소와 흐름을 간략하게 표현하고 있습니다. 구성 요소의 성격에 따라 API, Agent, Tool, Data, AI Layer로 구분했으며, 제가 붙여 둔 번호를 순서대로 따라가 봅시다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3697/10.webp"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;1) 사용자의 분석 요청이 Slack UI를 통해 전달되면, API 서버를 거쳐 AWS Lambda 환경에서 LangGraph로 구축된 AI Agent 프로그램이 실행됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;2) ReAct 프롬프트가 입력된 AI Agent는 자율적으로 도구를 선택합니다. 곰곰이는 매 질문마다 첫 번째 단계로 Memory Tool을 호출하여 유사한 기억을 불러옵니다. 이후 Query Tool을 사용하기 전에는 Knowledge Base Tool을 통해 테이블 스키마나 참고용 예시 SQL 정보를 먼저 확인합니다. 또한 사용자의 요청이 있을 경우, 최종 답변 단계에서 CSV Download Tool을 사용해 데이터 파일을 다운로드할 수 있는 링크를 생성합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;3) ReAct AI Agent는 ‘추론 — 행동 — 관찰 — 답변’의 과정을 거치며, 복잡한 문제도 허용된 횟수 내에서 반복하며 자율적으로 해결합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;4) 기존의 데이터 쿼리 도구는 인간의 이해를 돕기 위해 데이터를 한곳에 모으는 DW(Data Warehouse) 방식을 선호했습니다. 하지만 &lt;strong&gt;AI는 조인(JOIN)되지 않은 원천 데이터나 여러 곳에 흩어진 정보라도 인간보다 훨씬 빠르게 인지하고 처리&lt;/strong&gt;할 수 있습니다. 곰곰이는 이러한 특성을 활용해 데이터 적재 상황에 맞춰 GCP BigQuery와 AWS Athena 중 가장 적합한 쿼리 엔진을 유연하게 선택합니다. (물론 정확도를 위해서는 데이터가 한곳에 적재되어 있는 것이 유리합니다.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;5) 곰곰이는 사내 도구의 특성상 주로 업무 시간(월~금, 08시~19시)에 동작하며, 요청이 아주 빈번하게 발생하지는 않습니다. 따라서 Aurora Serverless v2 PostgreSQL의 pg_vector 플러그인을 사용하여 Vector DB 역할을 수행하게 했으며, 사용량이 적을 때는 유휴 상태로 전환되어 비용 효율적으로 운영되도록 설계했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;6) QUERIER_STORE와 LONGTERM_MEMORY 테이블은 둘 다 질문과 가장 유사한 정보를 찾아주는 Vector 테이블입니다. Vector DB의 성능을 최적화하는 방법 중 하나는 적절한 청킹(Chunking) 전략을 선택하는 것입니다. &lt;strong&gt;긴 문장을 20%씩 겹쳐 고정된 청크로 나누어 저장해도 맥락과 의미가 어느 정도 유지&lt;/strong&gt;되는 LONGTERM_MEMORY 테이블과 달리, QUERIER_STORE 테이블은 &lt;strong&gt;청크를 나누면 맥락이 쉽게 무너지는 SQL 정보&lt;/strong&gt;를 담고 있으므로 검색 정확도를 위해 구분하여 저장합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;7) 곰곰이의 핵심 지능인 ReAct 과정을 처리하는 LLM 모델은 &lt;strong&gt;성능과 비용의 균형이 뛰어난 Claude 3.5 Sonnet&lt;/strong&gt;을 사용합니다. Vector DB에서 검색된 결과가 너무 많으면 불필요한 정보로 인해 답변의 질이 떨어지고 비용이 상승할 수 있습니다. 이를 방지하기 위해 &lt;strong&gt;가성비가 좋은 Claude 3 Haiku&lt;/strong&gt; 모델을 앞단에 배치하여, 검색된 정보 중 질문과 무관한 내용을 먼저 걸러내고 핵심만 요약하도록 구성했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;8) 곰곰이가 질문 해결을 위한 충분한 정보를 수집하면, 최종 답변을 생성하여 Slack 채팅을 통해 사용자에게 전달합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이해를 돕기 위해 각색하고 요약한 곰곰이의 프롬프트 내용을 참고해 주세요.&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;# 페르소나
- 이름: 곰곰이
- 소속: STAYGE Labs AI Agent
- 전문: SQL 및 데이터 분석

# 행동 지침 (중요: 무슨 일이 있어도 수행)
- SQL 분석 후 → 사용한 SQL 반드시 첨부 + 짧은 설명
- 모호한 요청 → 도구 사용 전에 추가 정보 요청
- "기억해달라" 요청 → saveLongTermMemory + saveUsedQueryHistory 둘 다 사용
- 일상 질문(점심 메뉴 등)에도 친절히 답변
# 도구 사용 규칙 (공통)
- 실패 시 → 3초 대기 후 최대 3번 재시도
- ⚠️ 10턴 안에 작업 완료 필수
# 도구별 설명
- executeKnowledgeBaseQuery: 벡터 검색으로 테이블 스키마/예시 SQL 조회, Athena 마이그레이션된 테이블은 쿼리 수정 필요
- executeBigQueryQuery: SQL 실행 (LIMIT 100 초과 시 사용자에게 확인)
- executeBigQueryGetLargeResult: jobId → S3 CSV URL
- executeAthenaQuery: Athena SQL (dw_db 기본, GA4는 BigQuery 사용)
- executeAthenaGetLargeResult: queryExecutionId → S3 CSV URL
- saveUsedQueryHistory: 분석 만족 시 SQL을 RAG DB에 저장 (유사 SQL은 1개만)
- saveLongTermMemory: 대화 요약 저장 (SQL 제외, 실수/실패도 저장)
- recallMemory: 과거 대화 검색 (질문당 1회만! 첫 번째 행동으로 사용)&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;도입 후 효과는?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;곰곰이가 도입된 이후 조직에 큰 변화가 생겼습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;개발자보다 데이터를 능숙하게 다루는 AI 비서를 넣게 되었습니다.&lt;/strong&gt; ‘계획 수립 — SQL 작성 및 실행 — 인싸이트 도출’에 이르는 과정을 저보다 빠르게 수행할 뿐만 아니라, 유사 작업의 학습 내용을 응용해 문제를 해결하는 능력까지 갖추었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;이제 동료들은 데이터를 확인하기 위해 더 이상 개발자를 찾지 않습니다.&lt;/strong&gt; 개발자를 거치는 것보다 곰곰이를 활용하는 것이 훨씬 빠르다는 점을 체감했기 때문입니다. 이를 통해 데이터 업무의 흐름은 ‘동료 — 곰곰이 — (문제 발생 시) 개발자 검토’ 방식으로 효율적으로 재편되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;불필요한 소통 비용이 획기적으로 낮아졌습니다.&lt;/strong&gt; “데이터 확인 가능한가요?”, “결과가 이상해요”와 같은 소모적인 질의응답이 사라졌습니다. 곰곰이와 나누는 대화 과정에 이미 사용자의 의도와 맥락이 충분히 녹아들어 있기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;소통의 병목 구간이 사라지자, 동료들은 자신들의 전문적인 도메인 지식을 데이터와 직접 융합하기 시작했습니다.&lt;/strong&gt; 덕분에 기존에는 발견하지 못했던 새로운 정보와 가치 있는 인사이트를 데이터에서 더 쉽게 도출하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;동료들의 데이터 분석 능력 또한 눈에 띄게 향상되었습니다.&lt;/strong&gt; 복잡한 테이블 관계 이해나 SQL 작성이 분석의 허들이었을 뿐, 잘 정리된 데이터를 해석하는 것은 어려운 일이 아니었기 때문입니다. 허들이 ‘자연어’ 수준으로 낮아지자, 동료들은 이제 원하는 정보를 얻기 위해 ‘더 좋은 질문을 던지는 법’을 스스로 익혀가고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;반복적인 데이터 추출 요청에서 벗어나, 그동안 손이 부족해 미뤄두었던 핵심 과업들에 집중하게 되었습니다.&lt;/strong&gt; 전반적인 시스템의 수준을 높이거나 분산된 데이터를 통합하는 등, 생산적인 엔지니어링 업무에 몰입할 수 있는 물리적 시간이 확보되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI 에이전트 분야는 아직 초창기이며, 업계 전체가 정답을 찾아가는 진화의 단계에 있습니다. 다른 기업들의 사례 역시 각양각색이죠. 지금까지 사내 데이터 분석 AI 에이전트 &lt;strong&gt;‘곰곰이’의 탄생 배경과 작동 원리, 그리고 도입 후 조직이 맞이한 혁신적인 변화&lt;/strong&gt;를 살펴보았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;정적인 BI 도구와 반복적인 SQL 요청의 한계를 극복하고, 누구나 자유롭게 데이터에 접근할 수 있는 환경을 만들고자 했던 고민을 담았습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;ReAct 프롬프트 기법과 장기 기억 저장소(Vector DB)를 결합하여, 단순한 챗봇을 넘어 스스로 추론하고 학습하는 ‘지능형 에이전트’로서의 기술적 실체를 구축했습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;데이터 요청의 병목 현상을 해결함으로써 동료들은 스스로 인사이트를 찾는 능동적인 분석가로 성장했고, 개발자는 시스템의 근본적인 수준을 높이는 생산적인 엔지니어링에 집중할 수 있게 되었습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 곰곰이가 만든 이 많은 변화도 조직을 ‘AI 에이전트화’하는 과정의 &lt;strong&gt;첫 단추&lt;/strong&gt;일 뿐입니다. 사용자의 요청이 없어도 곰곰이가 스스로 데이터의 이상 징후를 탐지해 제보하거나, 과거 패턴으로 미래를 예측하는 수준에 도달하는 것이 여전히 남은 목표입니다. AI 에이전트의 본질은 ‘어떤 도구를 손에 쥐여주느냐’에 있습니다. 적절한 도구만 있다면 데이터 비서를 넘어 인사, 마케팅, 개발 등 모든 분야의 조력자로 진화할 수 있기 때문입니다. 곰곰이 역시 멀티 에이전트화를 통해 역량의 한계를 극복하며 더 넓은 영역으로 확장해 나갈 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;물론 해결해야 할 숙제도 있습니다. 현재는 텍스트 위주의 마크다운 형식으로만 답변을 주다 보니 가독성이 떨어지고 시각화 기능이 부족합니다. 이를 위해 슬랙(Slack)이라는 플랫폼을 넘어, 전용 웹 앱을 통해 차트와 대시보드를 풍부하게 제공하는 방향을 고민하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한, 곰곰이가 정적인 대시보드를 완전히 대체할 수는 없습니다. 현재 저희 회사에서 사용 중인 Looker처럼 즉각적인 확인이 필요한 데이터는 여전히 BI 도구가 효율적이기 때문입니다. 두 환경은 상호 보완적인 관계에 가깝습니다. 다만 대시보드를 구성하고 데이터를 연결하는 과정조차 LLM의 코드 작성 능력을 빌려 더 효율적으로 바꿀 수 있지 않을까 생각합니다. 곰곰이가 직접 웹 환경에서 차트와 대시보드를 그려내는 모습을 상상하고 있습니다. 아마도 이런 고민의 결과물들이 ‘곰곰이 아티클 2탄’의 주제가 되지 않을까요?&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&amp;lt;원문&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://monday9pm.com/%EC%9E%AC%EC%A3%BC%EB%8A%94-%EA%B3%B0%EA%B3%B0%EC%9D%B4%EA%B0%80-%EB%84%98%EA%B3%A0-%EB%8F%88%EC%9D%80-%EB%82%B4%EA%B0%80-%EB%B2%88%EB%8B%A4-6c4ff85b4024"&gt;재주는 곰곰이가 넘고 돈은 내가 번다 — 반복적인 SQL 업무를 자동화하는 AI 에이전트&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>AI로 프로젝트 10개 만든 개발자가 서류에서 떨어지는 이유</title><link>https://yozm.wishket.com/magazine/detail/3694</link><description>어느 순간부터 취업을 준비하는 방식이 꽤 달라졌습니다. 예전에는 프로젝트 하나를 완성하는 일조차 쉽지 않았는데, 이제는 AI의 도움으로 훨씬 빠르게 기능을 구현하고 결과물을 만드는 분들이 많아졌기 때문입니다. 실제 개발 포트폴리오를 보다 보면, 짧은 기간 안에 여러 프로젝트를 만들고 배포까지 경험한 사례가 예전보다 확실히 늘었단 것을 느낍니다. 그런데 흥미로운 점은, 그렇게 결과물이 많아졌다고 해서 서류 합격률이 함께 올라가지는 않는다는 사실입니다.</description><guid>https://yozm.wishket.com/magazine/detail/3694</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;어느 순간부터 취업을 준비하는 방식이 꽤 달라졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예전에는 프로젝트 하나를 완성하는 일조차 쉽지 않았는데, 이제는 AI의 도움으로 훨씬 빠르게 기능을 구현하고 결과물을 만드는 분들이 많아졌기 때문입니다. 실제 개발 포트폴리오를 보다 보면 짧은 기간 안에 여러 프로젝트를 만들고 배포까지 경험한 사례가 예전보다 확실히 늘었단 것을 느낍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 흥미로운 점은 그렇게 결과물이 많아졌다고 해서 서류 합격률이 함께 올라가지는 않는다는 사실입니다. 오히려 “이 정도면 충분히 열심히 준비한 것 같은데 왜 계속 떨어질까”라는 고민을 하는 분들도 봤습니다. 저는 그 탈락의 이유가 처음부터 프로젝트 수나 구현량의 문제가 아니었다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 기업은 ‘무엇을 만들었는지’를 넘어, 왜 그 프로젝트를 했고, 어떤 문제를 풀고자 했으며, 그리고 그 과정에서 어떤 판단을 했는지를 더 중요하게 보기 시작했습니다. 오늘은 바로 그 지점, 그러니까 AI 시대의 취업 준비에서 왜 ‘도메인 이해력’이 점점 더 중요해지고 있는지 이야기해보려고 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3694/image1.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;프로젝트는 많아졌는데, 왜 서류 통과는 더 어려워졌을까?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;요즘 취업을 준비하는 분들의 포트폴리오를 보면 정말 열심히 준비한 흔적이 많습니다. 사이드 프로젝트도 하고, 팀 프로젝트도 하며, 배포까지 직접 해보는 등 예전보다 훨씬 다양한 기능을 스스로 구현합니다. AI의 도움으로 개발 속도까지 빨라진데다 결과물 역시 더욱 풍성해졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 이상하게도 서류 합격률이 함께 올라가지는 않는다고들 합니다. 그만큼 다른 지원자들도 일정 수준 이상의 결과물을 만들어낼 수 있기 때문입니다. 다시 말해, 프로젝트를 해봤다는 사실만으로는 예전만큼 차별화되기 어려운 환경이 온 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 기업이 보는 기준도 달라지고 있습니다. 무엇을 만들었는가보다 왜 그걸 만들었는지, 어떤 문제를 보고 시작했는지, 그리고 그 과정에서 어떤 판단을 내렸는지가 더욱 중요해진 거죠. 기업은 멋진 결과물을 보려고 포트폴리오를 읽는 것이 아니라 함께 일할 수 있는 사람인지 판단하려고 검토하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 프로젝트가 많아도 서류에서 힘을 쓰지 못하는 경우가 생깁니다. 무언가를 많이 만든 건 보이는데, 왜 만들었는지가 잘 안 보이기 때문입니다. 기능은 많지만 문제는 흐릿하고, 기술은 다양하지만 판단은 보이지 않는 겁니다. 이제는 프로젝트의 수보다 그 프로젝트를 어떻게 해석하고 설명하느냐에 따라 평가가 갈리는 시대에 더 가까워졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;‘무엇을 만들었나’보다 ‘왜 그렇게 만들었나’를 보는 회사&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;포트폴리오를 만들 때 개발자들은 자연스럽게 “내가 한 일”을 중심으로 정리합니다. 어떤 기능을 구현했고, 어떤 기술을 사용했으며, 배포는 어떻게 했는지를 적습니다. 물론 이 정보들도 중요합니다. 문제는 대부분 포트폴리오가 그 지점에서 멈춘다는 점입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;회사 입장에서 궁금한 건 조금 다릅니다. 무엇을 만들었는지도 보지만, 그보다 더 중요한 것은 왜 그 프로젝트를 진행했는지, 어떤 문제를 해결하려 했는지, 그리고 그 과정에서 어떤 판단을 내렸는지입니다. 사고 과정에 더 큰 관심을 두고 있는 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어 같은 일정 관리 프로젝트를 진행했다고 가정해보겠습니다. 한 지원자는 “캘린더 기능 구현, 알림 기능 구현, 소셜 로그인 구현, Docker 배포”라고 정리합니다. 한 일을 나열한 것이니 틀린 말은 아닙니다. 하지만 이 설명만으로는 이 프로젝트가 어떤 문제를 해결하기 위해 존재하는지 충분히 드러나지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 다른 지원자는 이렇게 설명할 수 있습니다. “기존 일정 관리 앱은 개인 기록 중심이라, 여러 명이 함께 일정을 조율해야 하는 상황에서는 불편하다고 느꼈습니다. 그래서 이 프로젝트에서는 개인 기록보다 일정 조율 경험에 초점을 맞춰 기능 우선순위를 설정했습니다.” 같은 프로젝트라도 전달할 느낌이 완전히 달라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째 설명은 구현 내용이 보이고, 두 번째 설명은 그 구현 뒤에 있는 생각이 보입니다. 회사가 더 높게 평가하는 쪽은 대개 후자입니다. 실무에서는 결국 요구사항을 이해하고, 애매한 상황에서 판단을 내리며, 그 선택의 이유를 설명할 수 있는 사람이 필요하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;좋은 포트폴리오에는 이러한 판단의 흔적이 남습니다. 왜 이 기능을 먼저 만들었는지, 왜 이 기술을 선택했는지, 왜 어떤 요소는 과감히 뺐는지가 보여야 합니다. 이제는 무엇을 만들었는가만큼 어떻게 사고하며 만들었는가가 훨씬 더 중요해졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;‘전문지식’보다 ‘현실감’에 가까운 도메인 이해력&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이처럼 도메인 이해력이 중요하다고 하면 부담부터 느끼는 분이 많을 겁니다. ‘그럼 해당 업계 지식을 엄청 많이 알아야 하나?’라고 생각하기 때문이죠. 하지만 취업 준비 단계에서 필요한 도메인 이해력은 업계 전문가 수준의 지식을 의미하는 게 아닙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;제가 말하는 도메인 이해력은 훨씬 더 현실적인 개념입니다. 내가 만든 서비스가 어떤 문제를 해결하려는지, 사용자는 어디서 불편을 느끼는지, 실제 운영 과정에서는 어떤 변수와 예외가 발생할 수 있는지 고민해본 경험에 가깝습니다. 거창한 전문성이라기보다 ‘현실감’이라고 보는 편이 적절합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이를테면 스터디 모집 서비스를 만든다고 해보겠습니다. 으레 필요한 게시글 CRUD와 댓글 기능을 구현하는 데서 끝날 수도 있습니다. 하지만 조금만 더 현실적으로 접근해보면 다른 질문들이 떠오릅니다. 사람들은 모집글을 꼼꼼히 읽을까? 신청만 하고 잠수 타는 경우는 없을까? 모집자와 지원자가 기대하는 운영 방식이 다를 때는 어떤 문제가 생길까? 같은 질문들입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이러한 질문을 고민해본 사람은 기능을 구현할 때도 우선순위가 달라집니다. 단순히 만들 수 있는 기능이 아니라 실제로 자주 부딪힐 문제를 먼저 다루기 때문입니다. 그리고 바로 그 차이가 포트폴리오를 설명하는 방식에서도 드러납니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;모든 프로젝트를 대단한 서비스로 출시해야 한다는 말은 아닙니다. 다만 가능하다면, 실제 사용자에게 보여주고 반응을 받아본 경험이 꽤 강력한 무기가 됩니다. 머릿속으로 상상한 문제와 현실에서 겪는 문제가 상당히 다르기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;정리하면, 취업 준비에서 말하는 도메인 이해력은 박사 수준의 전문지식을 뜻하지 않습니다. 사용자의 문제를 구체적으로 상상하고 서비스가 현실에서 어떻게 쓰일지 고민해본 흔적에 가깝습니다. 저는 이 정도 현실감만으로도 다른 포트폴리오보다 훨씬 더 세진다고 봅니다. 왜냐하면 대부분이 기술은 설명해도 현실은 설명하지 못하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;기술 설명과 기여도는 중요하지만, 그것만으로는 부족합니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이쯤에서 오해하지 말아야 할 부분이 있습니다. ‘기술 설명’이 필요 없다는 관점입니다. 저는 그렇게 생각하지 않습니다. 사용한 기술 스택, 구현한 기능, 맡았던 역할, 그리고 본인 기여도는 여전히 포트폴리오에 중요합니다. 특히 팀 프로젝트라면 “그래서 본인이 정확히 무엇을 했는지”가 분명하게 드러나야 합니다. 기본 중의 기본입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 많이들 여기서 한 가지를 더 놓칩니다. 문서를 길고 자세하게 만드는 것과 설득력 있게 만드는 것은 전혀 다른 문제라는 점입니다. 저는 이력서와 포트폴리오를 굳이 나눌 필요는 없다고 생각합니다. 오히려 하나의 문서 안에서 핵심이 빠르게 읽히고, 면접관이 자연스럽게 궁금증을 느낄 수 있도록 정리된 쪽이 훨씬 실전에 유리합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;중요한 건 많이 적는 게 아니라 짧게 적더라도 방향이 보여야 한다는 점입니다. 안 좋은 사례, Before는 이런 식입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;Redis 적용&lt;/li&gt;&lt;li style="text-align:justify;"&gt;Docker 배포&lt;/li&gt;&lt;li style="text-align:justify;"&gt;JWT 로그인 구현&lt;/li&gt;&lt;li style="text-align:justify;"&gt;게시글 CRUD 개발&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;물론 틀린 말은 아닙니다. 다만 이 정보만으로는 기술을 사용했다는 사실만 보일 뿐 왜 그렇게 했는지는 잘 드러나지 않습니다. 조금만 바꿔도 이렇게 괜찮은 After를 만들 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;잦은 조회가 발생하는 인기 게시글 응답 속도 개선을 위해 Redis 캐시 적용&lt;/li&gt;&lt;li style="text-align:justify;"&gt;팀원간 개발환경 차이를 줄이고 배포 과정을 단순화하기 위해 Docker 기반 배포 구성&lt;/li&gt;&lt;li style="text-align:justify;"&gt;세션 방식 대신 확장성을 고려해 JWT 기반 로그인 구조 설계&lt;/li&gt;&lt;li style="text-align:justify;"&gt;단순 게시글 등록 기능이 아닌 스터디 모집 흐름에 맞춘 생성/조회/수정 기능 구현&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;길이를 크게 늘리지 않았지만, 느껴지는 인상은 꽤 다릅니다. 기술을 썼다는 사실 그 자체보다 어떤 문제를 보고 선택했는지가 보이기 때문입니다. 바로 이런 식으로 한 줄 안에서도 문제 인식과 판단을 드러낼 수 있어야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 좋은 서류는 모든 걸 다 설명하는 문서가 아닙니다. 핵심만 빠르게 읽히면서도, “이 사람은 왜 이렇게 했을까?”라는 궁금증을 주며, 결국 면접으로 이어지게 만드는 게 필요합니다. 짧게 적는 것과 얕게 적는 것은 다릅니다. 기술 설명과 기여도는 여전히 중요하지만, 이제는 그 안에 문제 맥락과 판단의 흔적까지 함께 담겨야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;‘왜 그렇게 만들었는가’에 더 깊게 답하기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이처럼 AI 덕분에 구현 자체의 진입장벽은 확실히 낮아졌습니다. 예전보다 빠르게 화면을 만들 수 있고, API도 붙일 수 있고, 배포까지 가는 속도도 빨라졌습니다. 이건 분명 좋은 변화입니다. 다만 모두가 더 쉽게 만들 수 있게 됐다는 말은 반대로 단순 구현만으로는 예전만큼 차별화가 어렵다는 뜻이기도 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 더 중요해지는 건 꼬리질문에 답하는 힘입니다. 왜 이 기술을 썼는지, 왜 이 구조를 선택했는지, 왜 이 기능을 먼저 만들었는지, 왜 이 문제를 풀 가치가 있다고 판단했는지까지 설명할 수 있어야 합니다. 결국 경쟁력은 구현한 양보다 판단의 깊이에서 갈리기 시작하니까요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;당연히 여기서 멈추면 또 아쉽겠죠. 그러니 가능하다면 실제 사용자에게 보여주고, 현실의 문제를 해결하려고 해본 경험까지 가는 게 훨씬 강력합니다. 규모가 작아도 괜찮습니다. 직접 배포해보고, 주변 사람이라도 써보게 하고, 예상과 다른 반응을 확인해본 경험은 분명 면접관한테 다른 인상을 줍니다. 머리로 상상한 문제와 현실에서 부딪히는 문제는 다르기 일쑤입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 앞으로의 포트폴리오는 “이만큼 구현했습니다”에서 끝나서는 힘듭니다. “왜 이렇게 만들었고, 실제로 어떤 문제를 확인했고, 그걸 어떻게 바꿨는가”까지 이어져야 힘을 가집니다. 이제는 구현 뒤에 있는 사고와 현실 검증 경험이 더 중요한 시대로 가고 있으니까요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;앞으로 더 희소해질 ‘문제를 정의하고 해결하는 사람’&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;앞으로 개발자의 역량과 경쟁력은 더 선명하게 갈릴 겁니다. 코드를 빠르게 작성하는 사람은 점점 많아질 테고, 구현 자체의 진입장벽도 지금보다 더 낮아질 가능성이 높기 때문입니다. 그럴수록 결국 더 희소해지는 사람은 단순히 잘 만드는 사람이 아니라 무엇을 만들어야 하는지 먼저 정의할 수 있는 사람일 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실무에서는 생각보다 “어떻게 만들지”보다 “무엇을 풀어야 하지”가 더 어려운 경우가 많습니다. 사용자에게 진짜 불편한 지점이 어디인지, 어떤 문제부터 해결해야 효과가 큰지, 기술적으로 가능하다고 해서 다 만들어야 하는 건 아닌지 판단해야 하는 순간이 계속 생기더라고요. 그리고 그 판단은 단순 구현 경험만으로는 와닿지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 다가올 미래에 몸값이 높아질 개발자는 문제를 정의하고, 그 문제를 기술적으로 풀어내고, 필요하다면 비즈니스 관점에서도 설명할 수 있는 사람일 겁니다. 사용자의 불편, 서비스 운영의 현실, 팀의 자원과 우선순위까지 함께 고려할 수 있는 사람이 결국 더 필요해질 테니까요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 회사는 많이 만든 개발자보다 왜 만들어야 하는지 설명해줄 개발자를 더 높게 평가합니다. AI가 발전할수록 이런 차이는 오히려 더 커질지도 모릅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 살아남는 사람은 구현에 머무는 사람이 아니라, 문제를 정의하고 해결하는 사람입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>“오늘 뭐부터 하지?” AI 비서 에이전트 만들어봤습니다</title><link>https://yozm.wishket.com/magazine/detail/3692</link><description>저는 아침에 노트북을 열면 습관처럼 하는 일이 있습니다. GitHub 알림을 확인하고, 슬랙 메시지를 훑고, 여기저기 흩어진 메모를 뒤적이며 "오늘 뭐부터 해야 하지?"를 결정하는 것입니다. 프로젝트가 하나라면 금방 끝나겠지만, 회사 프로젝트와 개인 사업을 합쳐 8개 프로젝트를 동시에 운영하다 보면 이 과정만으로도 30분이 넘게 걸립니다. 정작 중요한 작업을 시작하기도 전에 에너지가 빠지게 되죠. 그래서 AI가 이런 아침 루틴도 대신 해줄 수 있지 않을까? 하는 생각을 하게 됐죠. 그래서 GitHub에 쌓인 이슈와 커밋 기록을 읽고, 내가 정리해 둔 우선순위 파일을 참조해서 매일 아침 슬랙(Slack)으로 "오늘 이것부터 하세요"라고 보고 해주는 비서 에이전트를 만들어 보기로 했습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3692</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;저는 아침에 노트북을 열면 습관처럼 하는 일이 있습니다. GitHub 알림을 확인하고, 슬랙 메시지를 훑고, 여기저기 흩어진 메모를 뒤적이며 "오늘 뭐부터 해야 하지?"를 결정하는 것입니다. 프로젝트가 하나라면 금방 끝나겠지만, 회사 프로젝트와 개인 사업을 합쳐 8개 프로젝트를 동시에 운영하다 보면 이 과정만으로도 30분이 넘게 걸립니다. 정작 중요한 작업을 시작하기도 전에 에너지가 빠지게 되죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 AI가 이런 아침 루틴도 대신 해줄 수 있지 않을까? 하는 생각을 하게 됐죠. 그래서 GitHub에 쌓인 이슈와 커밋 기록을 읽고, 내가 정리해 둔 우선순위 파일을 참조해서 매일 아침 슬랙(Slack)으로 "오늘 이것부터 하세요"라고 보고 해주는 비서 에이전트를 만들어 보기로 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul&gt;&lt;li&gt;GitHub에 Hub Repo를 만들어 모든 프로젝트의 메타데이터와 컨텍스트를 한 곳에 모으고, Python 스크립트와 GitHub Actions로 AI 비서가 매일 아침 슬랙 메세지를 보내주는 시스템을 구축했습니다.&lt;/li&gt;&lt;li&gt;"한 곳에서만 쓰고 여러 곳에서 읽는다"는 컨텍스트 관리 원칙과 AI에게 단순 요약이 아닌 작업의 우선순위 판단까지 하도록 하는 프롬프트 설계를 반영했습니다.&lt;/li&gt;&lt;li&gt;실제로 통합 워크스페이스와 AI 비서를 도입한 뒤 아침 루틴이 "정보 수집과 판단"에서 "확인" 작업으로 바뀌었습니다. 다만, 여전히 우선순위 파일의 수동 업데이트나 AI 브리핑 품질 개선 같은 과제가 남아 있습니다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="margin-left:0px;text-align:justify;"&gt;&lt;strong&gt;통합 워크스페이스 구상&lt;/strong&gt;&lt;/h3&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;여러 프로젝트를 동시에 운영하다 보면, 컨텍스트 스위칭(Context Switching)이 자주 발생합니다. A 프로젝트 버그를 고치다가 B 프로젝트 회의에 참석하고, C 프로젝트 문서를 작성하다가 D 프로젝트 클라이언트 문의를 처리해야 하는 등 계속 머릿속 컨텍스트를 바꾸게 됩니다. 그리고 그 과정에서 각 프로젝트마다 "지금 어떤 상태인지, 다음 작업이 무엇인지"를 파악하는데 너무 많은 에너지를 소모하게 됩니다.&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;또한 프로젝트가 여러 GitHub Repo로 흩어져 있기 때문에 프로젝트 개수가 늘어날수록 아침마다 반복되는 업무 우선순위 판단 루틴도 점점 길어지게 됩니다. 예를 들어, 각 Repo의 이슈와 PR 상태를 확인하고, 어제 어디까지 작업했는지 커밋 로그를 체크하고, 슬랙에서 밤사이 온 메시지를 읽고, 노트 앱에 적어둔 할 일 목록을 다시 확인하는 등의 일이 많아집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/1__%E1%84%8B%E1%85%A5%E1%86%B8%E1%84%86%E1%85%AE_%E1%84%89%E1%85%B5%E1%84%8C%E1%85%A1%E1%86%A8_%E1%84%8C%E1%85%A5%E1%86%AB_%E1%84%8B%E1%85%A1%E1%84%8E%E1%85%B5%E1%86%B7_%E1%84%85%E1%85%AE%E1%84%90%E1%85%B5%E1%86%AB.jpg"&gt;&lt;figcaption&gt;업무 시작 전 아침 루틴 &amp;lt;출처: 작가, Gemini 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이와 같이 프로젝트 상태를 파악하고, 업무 우선순위를 판단하기 위한 정보는 각 프로젝트의 GitHub 이슈, 커밋 로그, 각종 문서 등에 &lt;strong&gt;흩어져&lt;/strong&gt; 있습니다. 이렇게 흩어진 정보들을 찾고 그 과정에서 수많은 컨텍스트 스위칭이 일어나면 업무에 집중하기가 어려워집니다. 그래서 이 문제를 해결하기 위해 GitHub에 별도의 Hub Repo를 두어 모든 프로젝트의 메타데이터와 컨텍스트를 한곳에 모아 관리해 보기로 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;통합 워크스페이스를 위한 Hub Repo 설계&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 구성 원칙&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;통합 워크스페이스를 설계하는 데 있어 제가 정한 핵심 원칙은 &lt;strong&gt;"한 곳에서만 쓰고, 여러 곳에서 읽는다"&lt;/strong&gt;입니다. 즉, AI가 참조할 수 있는 모든 컨텍스트 한 곳에서만 관리하고, 이를 여러 프로젝트에서 활용하는 것입니다. 예를 들어, 개인 프로필, 회사 정보, 사업 전략, 프로젝트 배경, 작업의 우선순위 같은 모든 컨텍스트 정보를 Hub Repo 한 곳에 모아두고, 각 프로젝트 Repo에서 이를 참조하는 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/2__%E1%84%90%E1%85%A9%E1%86%BC%E1%84%92%E1%85%A1%E1%86%B8_%E1%84%8B%E1%85%AF%E1%84%8F%E1%85%B3%E1%84%89%E1%85%B3%E1%84%91%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%89%E1%85%B3_%E1%84%80%E1%85%AE%E1%84%89%E1%85%A5%E1%86%BC_%E1%84%8B%E1%85%AF%E1%86%AB%E1%84%8E%E1%85%B5%E1%86%A8.jpg"&gt;&lt;figcaption&gt;통합 워크스페이스 구성 원칙 &amp;lt;출처: 작가, Gemini 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) Hub Repo 연결 방식 선택&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;저는 Hub Repo를 각 프로젝트 Repo와 어떻게 연결할지 꽤 오랫동안 고민했습니다. 제가 검토했던 선택지는 세 가지였으며, 그 첫 번째는 Git submodules를 이용한 방식이었습니다. &lt;strong&gt;Git submodules&lt;/strong&gt;는 각 프로젝트 Repo를 Hub Repo의 서브모듈로 연결하는 방식인데, 버전 관리가 복잡하고 매번 submodule update를 해야 해서 오히려 관리 부담이 늘어날 가능성이 있었습니다,&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/3__Git_Submodule_%E1%84%8F%E1%85%A5%E1%86%AB%E1%84%89%E1%85%A6%E1%86%B8.png"&gt;&lt;figcaption&gt;Git Submodule 컨셉 &amp;lt;출처: dev-repository.com&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째로 생각했던 것은 &lt;strong&gt;yaml + API&lt;/strong&gt; 방식이었습니다. Hub Repo에 프로젝트 메타데이터를 YAML로 저장하고 API로 접근하는 것이었는데, API 서버를 따로 운영해야 하므로 과하다는 생각이 들었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/4__YAML_%E1%84%8C%E1%85%B5%E1%86%A8%E1%84%8C%E1%85%A5%E1%86%B8_%E1%84%8E%E1%85%A1%E1%86%B7%E1%84%8C%E1%85%A9_%E1%84%86%E1%85%B5%E1%86%BE_GitHub_Actions_%E1%84%92%E1%85%AA%E1%86%AF%E1%84%8B%E1%85%AD%E1%86%BC.jpg"&gt;&lt;figcaption&gt;YAML 직접 참조 + GitHub Actions 활용 &amp;lt;출처: 작가, Gemini 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 최종적으로 선택한 방식은 &lt;strong&gt;yaml + GitHub Actions&lt;/strong&gt;였습니다. 로컬 환경에서는 yaml 파일을 직접 읽도록 하고, AI 비서 에이전트처럼 클라우드 환경에서 Cron 작업이 필요할 때는 GitHub Actions으로 Hub Repo를 checkout하여 yaml 파일을 읽도록 하는 것입니다. 이런 방식으로 구성하면 별도의 API 서버를 구성하거나 복잡한 서브모듈을 적용하지 않더라도 yaml 파일의 프로젝트 메타데이터를 효율적으로 관리할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) Notion MCP를 검토했다가 GitHub으로 돌아온 이유&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;사실 처음에는 노션(Notion)을 컨텍스트 저장소로 고려했었습니다. 그동안 쌓아온 노트와 작업 이력이 노션에 많이 남아 있었기 때문이었는데요. 노션 MCP(Model Context Protocol)를 활용하면 AI가 노션의 데이터베이스를 직접 읽을 수 있으니 기존 자산을 그대로 활용할 수 있겠다고 생각했었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/5__%E1%84%80%E1%85%B3%E1%84%83%E1%85%A9%E1%86%BC%E1%84%8B%E1%85%A1%E1%86%AB_Notion%E1%84%8B%E1%85%A6_%E1%84%80%E1%85%B5%E1%84%85%E1%85%A9%E1%86%A8%E1%84%92%E1%85%A2%E1%84%8B%E1%85%A9%E1%86%AB_%E1%84%82%E1%85%A9%E1%84%90%E1%85%B3_%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5.png"&gt;&lt;figcaption&gt;그동안 Notion에 기록해온 노트 예시 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 실제로 구현을해보니 여러 문제가 있었습니다. 일단 MCP를 통한 노션 접근에는 &lt;strong&gt;토큰 비용&lt;/strong&gt;이 발생하고, 컨텍스트가 노션과 GitHub 두 곳에 흩어지게 되면서 오히려 &lt;strong&gt;관리 부담&lt;/strong&gt;이 늘어날 수 있었습니다. 또한 클로드 코드가 노션에 있는 자료를 참조할 수 있도록 하는 MCP 설정이 생각보다 번거로 웠습니다. 결국 이러한 이유로 노션을 컨텍스트 저장소로 하려던 계획을 철회하고, GitHub에 별도의 Hub Repo를 두어 컨텍스트 관리를 일원화하기로 결정했습니다. 아울러 장기적으로는 노션에 있는 기존 자산 중에 필요한 것만 마크다운으로 변환해서 Hub Repo에 옮기기로 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4) Hub Repo 구조&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Hub Repo의 구조는 root &amp;gt; works &amp;gt; projects 이렇게 &lt;strong&gt;3계층&lt;/strong&gt;으로 설계했습니다. 최상위 폴더(root)에는 모든 업무와 프로젝트에 공유될 수 있는 컨텍스트 정보(개인 프로필, 인생 비전, 우선 순위 등)를 두었습니다. 그리고 각 work에는 업무 단위 맥락을, 각 project에는 개별 프로젝트의 컨텍스트와&amp;nbsp; 메타데이터(project.yaml), 요구사항 문서(PRD.md) 등을 두었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/6__%E1%84%8E%E1%85%AC%E1%84%8C%E1%85%A9%E1%86%BC%E1%84%8C%E1%85%A5%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%AB_Hub_Repo_%E1%84%80%E1%85%AE%E1%84%8C%E1%85%A9.png"&gt;&lt;figcaption&gt;최종적인 Hub Repo 구조 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;만약 새로운 프로젝트가 생기면 해당 업무 그룹 아래에 프로젝트 폴더를 만들고 &lt;strong&gt;project.yaml&lt;/strong&gt;를 추가합니다. project.yaml은 각 프로젝트의 핵심 정보를 담는 간결한 YAML 파일입니다. 여기에는 간단하게 프로젝트의 이름, 설명, 상태, GitHub Repo 주소, 노트 같은 정보를 담았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/7__project_yaml_%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5.png"&gt;&lt;figcaption&gt;project .yaml 예시 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;AI 비서 에이전트 "정대리" 구축&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Hub Repo에 모든 프로젝트 정보를 모아놓고 나니 자연스럽게 다음 작업이 떠올랐습니다. 각 프로젝트의 데이터를 매일 아침 자동으로 읽어서 “오늘 뭐부터 해야 하는지”를 정리해주는 AI 비서 에이전트를 만드는 것이었습니다. 개인적으로 저는 비서 에이전트에 “&lt;strong&gt;정대리”&lt;/strong&gt;라는 이름을 붙여 주었습니다. 이름에 특별한 뜻은 없지만, 에이전트를 의미하는 “대리”를 붙이고 싶었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) AI 비서 에이전트 동작 구조&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;전체 흐름은 다음과 같습니다. 먼저 &lt;strong&gt;GitHub Actions&lt;/strong&gt;로 매일 아침 정해진 시간에 Python 스크립트를 실행합니다. 그러면 스크립트가 먼저 Hub Repo의 각 works 디렉토리에 있는 모든 project.yaml 파일을 읽어 프로젝트 목록과 상태를 파악합니다. 그 다음 각 프로젝트의 &lt;strong&gt;GitHub Repo&lt;/strong&gt;에서 오픈 이슈, PR, 최근 커밋을 조회하고, 우선순위 판단에 대한 정보가 담겨있는 current-priorities.md을 참조한 후 &lt;strong&gt;Claude API&lt;/strong&gt;로 오늘의 브리핑을 생성합니다. 그렇게 완성된 브리핑은 &lt;strong&gt;Slack Webhook&lt;/strong&gt;을 통해 슬랙 메시지로 발송됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/8__AI_%E1%84%87%E1%85%B5%E1%84%89%E1%85%A5_%E1%84%8B%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%8C%E1%85%A5%E1%86%AB%E1%84%90%E1%85%B3_%E1%84%83%E1%85%A9%E1%86%BC%E1%84%8C%E1%85%A1%E1%86%A8_%E1%84%80%E1%85%AE%E1%84%8C%E1%85%A9.jpg"&gt;&lt;figcaption&gt;AI 비서 에이전트 동작 구조 &amp;lt;출처: 작가, Gemini 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Python 스크립트는 클로드 코드를 이용해 작성했습니다. 핵심 로직은 앞서 설명한 것처럼 프로젝트 데이터 수집, GitHub 활동 조회, Claude API로 브리핑 생성, 슬랙 전송으로 나뉩니다. 첫 번째 단계는 &lt;strong&gt;각 프로젝트의 데이터 수집&lt;/strong&gt;으로 다음 코드와 같이 works 디렉토리 아래에 있는 모든 project.yaml 파일을 재귀적으로 찾아 읽습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/9__Python_%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B8%E1%84%90%E1%85%B3_%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5.png"&gt;&lt;figcaption&gt;Python 스크립트 예시 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;GitHub 활동 조회&lt;/strong&gt;입니다. 각 프로젝트의 Repo 필드에 GitHub URL이 있으면, gh CLI를 통해 오픈 이슈, PR, 최근 커밋을 가져옵니다. 여기서 GitHub API 대신 gh CLI를 쓴 이유는 인증 처리가 간편하고, GitHub Actions 환경에서 별도 설치 없이 바로 사용할 수 있기 때문이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) GitHub Actions로 매일 자동 실행하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;저는 매일 아침 &lt;strong&gt;cron 작업&lt;/strong&gt;을 위해 GitHub Actions를 선택했습니다. cron 작업을 실행하는 방법에는 여러가지가 있지만, GitHub Actions는 클라우드에서 실행되기 때문에 로컬보다 안정적이고, 다음과 같은 워크플로 파일로 간단하게 설정할 수 있다는 장점이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/10__GitHub_Actions_%E1%84%8B%E1%85%AF%E1%84%8F%E1%85%B3%E1%84%91%E1%85%B3%E1%86%AF%E1%84%85%E1%85%A9_%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF_%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5.png"&gt;&lt;figcaption&gt;GitHub Actions 워크플로 파일 예시 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 프롬프트 설계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;각각의 프로젝트 데이터를 수집하고, 슬랙으로 메시지를 전송하는 것은 기술적으로 그다지 어렵진 않습니다. 대신 개인적으로 가장 어렵게 느껴졌던 부분은 &lt;strong&gt;AI가 적절한 브리핑을 할 수 있도록&lt;/strong&gt; 프롬프트를 설계하는것이었습니다. 우선 정대리의 브리핑을 위해 필요한 것은 각 작업의 우선순위를 어떻게 판단할 것인가에 대한 것이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/11__%E1%84%87%E1%85%B3%E1%84%85%E1%85%B5%E1%84%91%E1%85%B5%E1%86%BC_%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%86%B7%E1%84%91%E1%85%B3%E1%84%90%E1%85%B3_%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5.png"&gt;&lt;figcaption&gt;브리핑 프롬프트 예시 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;일단 저는 점수를 부여하는 방식으로 프롬프트를 만들었습니다. 예를 들어, &lt;strong&gt;긴급도(35점)&lt;/strong&gt;에는 외부 마감이나 클라이언트 대응처럼 시간에 민감한 요소를 반영하고, &lt;strong&gt;수익 영향도(30점)&lt;/strong&gt;는 그 작업이 회사나 개인 비즈니스 매출에 얼마나 직결되는지를 봅니다. &lt;strong&gt;블로커 해제(20점)&lt;/strong&gt;는 이 작업을 끝내야 다른 프로젝트가 진행될 수 있는지를 판단하며, &lt;strong&gt;에너지 매칭(15점)&lt;/strong&gt;은 아침의 집중력이 높을 때 해야 할 작업과 오후의 낮은 에너지로도 할 수 있는 작업을 구분하는 용도로 활용했습니다. 아울러 프롬프트에 &lt;strong&gt;브리핑 출력 형식&lt;/strong&gt;도 구체적으로 지정했습니다. AI에게 브리핑을 자유롭게 쓰게 하면 매번 형식이 달라져서 빠르게 훑어보기가 어렵기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실제 사용 후기와 개선 아이디어&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 좋았던 점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;정대리를 며칠간 써보며 가장 좋았던 점은 아침 루틴이 &lt;strong&gt;정보 수집과 판단&lt;/strong&gt;에서&lt;strong&gt;확인&lt;/strong&gt;작업으로 바뀌었다는 점이었습니다. 즉, 여러 GitHub Repo나 메모를 체크하며 뭐부터 시작할지 고민하는 시간을 줄일 수 있었습니다. 그래서 요즘에는 정대리 브리핑을 훑고 바로 오전 작업을 시작하고 있습니다. 가끔은 “진짜 이거부터 하는게 맞나?” 하는 경우도 있지만, 직접 뭐부터 할지 정하는 것보다 효율적이었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/12__%E1%84%8C%E1%85%A5%E1%86%BC%E1%84%83%E1%85%A2%E1%84%85%E1%85%B5_%E1%84%87%E1%85%B3%E1%84%85%E1%85%B5%E1%84%91%E1%85%B5%E1%86%BC_%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5.png"&gt;&lt;figcaption&gt;정대리 브리핑 예시 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 &lt;strong&gt;프로젝트 사각지대&lt;/strong&gt;가 줄었습니다. 동시에 여러 프로젝트를 돌리다 보면 며칠째 손 대지 않는 프로젝트가 생기기 마련인데, 정대리 브리핑을 통해 매일 전체 프로젝트 현황을 빠르게 훑고 보충해야할 사안을 떠올릴 수 있었습니다. 아울러 각 프로젝트의 상호 보완과 시너지 전략을 정대리와 토론하고, 앞으로 어떤 방향으로 프로젝트를 진행해할지 전반적인 큰 그림도 그릴 수 있었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 개선 해야할 점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;현재는 정대리가 &lt;strong&gt;GitHub 활동&lt;/strong&gt;(이슈, PR, 커밋 현황 등)을 우선 순위 판단의 핵심 자료로 사용하고 있습니다. 하지만 GitHub 활동만으로는 프로젝트의 진짜 맥락을 파악하기 어렵습니다. 예를 들어, 커밋이 2주간 없는 프로젝트를 정대리는 "정체됨"으로 판단하지만, 실제로는 클라이언트 피드백을 기다리는 중이거나 의도적으로 보류한 것일 수 있습니다. 현재는 project.yaml의 notes 필드에 이런 맥락을 수동으로 기록해서 보완하고 있는데, 이 맥락 정보 자체를 어떻게 자동으로 기록하고 체계화 시킬 수 있을지가 다음 개선 과제입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3692/13__%E1%84%8C%E1%85%A5%E1%86%BC%E1%84%83%E1%85%A2%E1%84%85%E1%85%B5_%E1%84%80%E1%85%A2%E1%84%89%E1%85%A5%E1%86%AB%E1%84%89%E1%85%A1%E1%84%92%E1%85%A1%E1%86%BC.png"&gt;&lt;figcaption&gt;정대리 개선 사항 &amp;lt;출처: 작가, Gemini 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 지금은 각 프로젝트의 GitHub 이슈를 직접 작성하고 있는데, 이 역시 AI 비서를 통해 자동화할 수 있는 영역입니다. 이처럼 AI 에이전트를 일상 업무에 활용하다 보면 자동화할 대상이 계속 눈에 들어오게 되는 것 같습니다. 다만 이러한 작업들은 본 업무를 지원하기 위한 것인 만큼, &lt;strong&gt;오버엔지니어링&lt;/strong&gt;(Overengineering)으로 오히려 개발과 관리 부담이 늘어나지 않도록 &lt;strong&gt;균형&lt;/strong&gt;을 잡는 것이 중요하다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이번에 통합 워크스페이스와 AI 비서 에이전트를 구축해 보면서, 워크플로를 자동화하기 위해서는 &lt;strong&gt;맥락을 어떻게 정리하고 관리하는지&lt;/strong&gt;가 정말 중요하다는 생각이 들었습니다. 지금 정대리에게 제공하는 데이터는 project.yaml의 메타데이터와 GitHub 활동, 그리고 notes 필드에 적어둔 메모 정도입니다. 이 정도만으로도 아침 브리핑은 충분히 쓸모가 있지만, "이 작업이 저 프로젝트와 어떻게 연결되는지", “이 작업을 먼저 했을 때 다른 프로젝트 어떤 영향을 미치는지”처럼 맥락의 깊이가 필요한 판단에서는 여전히 한계가 있습니다. 즉, AI 비서 에이전트의 품질을 결정하는 것은 모델 성능이나 도구가 아니라, 본인의 맥락을 얼마나 잘 구조화해서 전달하는지에 달려있다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 에이전트를 만들고 나서는 나만의 &lt;strong&gt;온톨로지(Ontology) 구축&lt;/strong&gt;이 핵심이라는 생각이 듭니다. 프로젝트 간의 관계, 상태 변화의 이유, 의사 결정의 배경 같은 것들을 기계가 이해할 수 있는 형태로 정의해야 AI 비서를 한 단계 더 성장시킬 수 있습니다. 예를 들어, A 프로젝트 개발이 지연되면 B 일정에 영향을 준다"는 의존 관계나 “이 프로젝트는 클라이언트 피드백 대기 중이라 의도적으로 멈춘 것이다" 같은 맥락을 구조적으로 표현할 수 있다면, 정대리의 브리핑이 단순한 오늘 할 일 정리를 넘어 보다 깊은 수준의 조언까지 가능할 것이라고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개인적으로 AI 에이전트 시대에 요구되는 핵심 역량은 코딩 실력이나 프롬프트 기법이 아니라, 자신의 업무 &lt;strong&gt;맥락을 체계적으로 정의하고 구조화하는 능력&lt;/strong&gt;이라고 생각합니다. 좋은 온톨로지가 설계되면 특정 AI 도구에 종속되지 않으면서도, 동시에 수행하는 프로젝트가 많아져도 에이전트 시스템이 흔들리지 않도록 할 수 있을 것입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>AI 시대 해커톤은 어떻게 변해야 하는가? </title><link>https://yozm.wishket.com/magazine/detail/3691</link><description>구현 속도가 더 이상 차별점이 되지 않는 AI 시대, 해커톤의 본질을 '기술량'이 아닌 '문제 정의와 기획의 밀도'로 재설계한 2026 GDGOC KR 연합 해커톤 'ONE WAVE'의 실험 기록입니다. 18개 대학 160명의 참가자가 '취업난'을 주제로 AI를 활용해 핵심 가치에 집중하고, 배포를 선택제로 두어 기획의 완결성을 높인 과정을 담았습니다. 또한 운영진이 반복 업무를 시스템화하여 현장 대응력을 높인 사례와 대상 수상작 'BARRIER FREE'의 구체적인 페인 포인트 해결 방식 및 데이터 활용 전략을 상세히 공유합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3691</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;참가자&lt;/strong&gt;·&lt;strong&gt;운영자가 함께 변화된&amp;nbsp;&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;2026 GDGOC KR 연합 해커톤 ONE WAVE의 기록&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI로 정보를 찾고, 화면을 만들고, API를 연결하는 일이 눈에 띄게 빨라졌습니다. 이제는 혼자서도 몇 시간 만에 프로토타입을 만들 수 있는 시대입니다. 구현 속도 자체가 더 이상 차별점이 되기 어려워진 지금, 해커톤은 무엇을 증명하는 자리여야 할까요? 단순히 정보를 나누는 행사나 구현량을 겨루는 형식만으로는 해커톤의 의미를 설명하기 어려워지고 있습니다. 어쩌면 해커톤이라는 형식 자체가 사라질 수도 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그럼에도 해커톤이 여전히 필요하다면, 그 이유는 &lt;strong&gt;짧은 시간 안에 문제를 정의하고, 우선순위를 정하고, 가설을 검증 가능한 형태로 만들어보는 밀도 높은 경험&lt;/strong&gt;에 있다고 생각했습니다. 저희는 바로 그 밀도를 지금의 트렌드에 맞게 다시 설계해 보고 싶었습니다. 그래서 2026년 2월, Google for Developers 산하 대학 거점 개발자 커뮤니티 GDG on Campus의 18개 대학이 모여 연합 해커톤 ONE WAVE를 열었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;160명의 참가자, 35개 팀이 무박 2일 동안 하나의 주제를 두고 각자의 방식으로 문제를 정의하고, 서비스를 설계하고, 결과물을 만들어냈습니다. ONE WAVE라는 이름에는 서로 다른 배경의 참가자들이 각자의 물결로 모여 하나의 파도가 된다는 의미를 담았습니다. 단순히 ‘마지막 낭만’으로 소비하고 싶지는 않았습니다. 해커톤을 연 이유가 단순히 "행사를 해보고 싶어서"가 아니었던 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/onewave-poster-igratio.png"&gt;&lt;figcaption&gt;GDGOC ONE WAVE 해커톤 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 해커톤에서 가장 크게 달라진 점은 참가자와 운영진 모두의 역할이 바뀌었다는 것입니다. 참가자에게는 AI를 활용해 구현 시간을 줄이는 대신, 문제 정의와 기획, 차별점과 실현 가능성에 더 많은 시간을 쓰도록 유도했습니다. 배포는 필수가 아니라 선택으로 두었고, 심사 기준도 코드량보다 기획의 밀도에 더 큰 비중을 두었습니다. 운영진 역시 마찬가지였습니다. 참가자 등록과 취소 관리, 팀 매칭 시각화, 심사 배점 자동 취합처럼 반복적으로 발생하는 업무를 AI를 활용해 빠르게 백오피스로 만들어 사용했고, 현장에서 필요한 기능은 즉시 개발해 운영에 반영했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글은 그 실험의 기록입니다. 참가자 측에서 무엇이 달라졌는지, 운영진 측에서 어떻게 일하는 방식을 바꿨는지, 그리고 그 결과 현장에서 실제로 어떤 변화가 만들어졌는지를 중심으로 정리했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;ONE WAVE가 집중했던 부분&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 배포는 ‘선택’으로&amp;nbsp;&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AI 시대의 개발자는 더 이상 단순히 코드를 짜고 배포하는 사람에 머물지 않습니다. 이제는 프로덕트의 가치를 기술로 녹여내는 사람으로 역할이 확장되고 있습니다. 저희는 이번 해커톤이 그 변화를 자연스럽게 체감할 수 있는 자리가 되기를 바랐습니다. 이제 개발자에게 더 중요한 질문은 “얼마나 많이 구현했는가”보다 “무엇을 왜 만들었는가”에 가깝다고 생각했기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 관점을 참가자들이 더 구체적으로 느낄 수 있도록, AI 엔지니어를 연사로 모셔 AI로 개발하는 방법에 대한 특강도 진행했습니다. AI를 단순한 보조 도구가 아니라, 구현 시간을 줄여 더 중요한 판단에 시간을 쓰게 해주는 도구로 받아들이기를 바랐습니다. 그래서 해커톤 전반에서도 계속 “AI를 사용해 빠르게 개발하되, 남는 시간을 기획과 검증에 쓰자”는 방향을 강조했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이런 이유로 이번 해커톤에서는 배포를 ‘필수’가 아니라 ‘선택’으로 두었습니다. 24시간 안에 모든 팀이 배포까지 마쳐야 한다고 강제하면, 적지 않은 팀이 인프라 설정이나 예기치 못한 오류 해결에 많은 시간을 쓰게 됩니다. 저희는 그 시간만큼 문제 정의와 핵심 사용자 흐름, 차별점과 실현 가능성을 더 깊게 다루기를 바랐습니다. 심사 기준 역시 기술의 복잡도나 코드량보다 서비스 자체의 기획, 문제 정의, 실현 가능성에 더 많은 비중을 두었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결과적으로 배포를 선택으로 둔 것이 참가자들의 완주를 막지는 않았습니다. 35개 팀 중 34개 팀이 최종 결과물을 제출해 97%의 완주율을 기록했고, 이 가운데 18개 팀은 배포가 필수가 아니었음에도 자발적으로 서비스 URL까지 배포하며 MVP를 완성했습니다. 배포를 강제하지 않았기에 포기한 것이 아니라, 기획에 충분한 시간을 쓴 뒤 남는 시간으로 배포까지 도달한 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 저희가 참가자들에게 전하고 싶었던 메시지는 분명했습니다. &lt;strong&gt;이제 개발자는 코드를 만들어내는 사람을 넘어, 그 코드가 의미를 갖게 만드는 사람이어야 한다는 점&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 해커톤의 주제: ‘취업난’&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;좋은 서비스는 대개 내가 직접 느끼는 문제에서 출발합니다. 그래서 이번 해커톤의 주제를 정할 때도 참가자들이 가장 보편적으로, 그리고 가장 크게 공감할 수 있는 문제가 무엇일지를 오래 고민했습니다. 그 결과 선정한 주제가 바로 ‘취업난’이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image1.jpg"&gt;&lt;figcaption&gt;GDGOC ONE WAVE 해커톤 OT - 주제 공개 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;대학생에게 취업은 너무 멀지도, 너무 추상적이지도 않은 문제입니다. 이미 현실로 닿아 있고, 주변의 많은 사람이 함께 고민하는 주제이기도 합니다. 실제로 주제가 공개되었을 때 행사장에서는 웃음과 탄식이 동시에 나왔습니다. 모두가 너무 잘 알고 있는 문제였기 때문입니다. 저희는 바로 그 공감대를 출발점으로 삼고 싶었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 큰 주제가 하나로 주어지면 비슷한 아이디어가 반복될 가능성도 큽니다. 이를 막기 위해 ‘검증’, ‘실전’, ‘전략’, ‘멘탈’이라는 네 개의 서브 키워드 중 하나를 선택해 조합하도록 했습니다. 같은 ‘취업난’을 다루더라도 어떤 팀은 정보의 신뢰성과 검증에, 어떤 팀은 실전 준비에, 또 어떤 팀은 전략 설계나 멘탈 관리에 더 집중할 수 있도록 한 것입니다. 이 장치 덕분에 참가자들은 하나의 공통 문제를 두고도 각기 다른 타깃 사용자와 해결 방식을 설계할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 이 장치는 참가자들의 문제 정의를 꽤 선명하게 갈라놓았습니다. 한 팀은 스펙 위주의 서류 전형이 실제 역량을 제대로 보여주지 못한다는 점에 주목해, 이력서를 없애고 실무 과제만으로 평가받는 채용 플랫폼을 제안했습니다. 반면 세 개의 팀은 취업난을 정보나 역량의 문제가 아니라 반복된 탈락 속에서 무너지는 심리의 문제로 해석하고, 짧은 챌린지와 감정 기반 피드백을 제공하는 멘탈 케어 서비스로 풀어냈습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 밖에도 기업 기술 블로그를 바탕으로 실무 시뮬레이션을 만든 팀, 합격자의 준비 과정을 타임라인으로 시각화한 팀 등 접근 방식은 다양했습니다. 결국 같은 '취업난'이라는 주제를 두고도, 어떤 팀은 역량의 검증을, 어떤 팀은 심리적 회복을, 또 어떤 팀은 실전 체감이나 전략 설계를 핵심 문제로 삼은 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/%E1%84%8C%E1%85%A6%E1%84%86%E1%85%A9%E1%86%A8_%E1%84%8B%E1%85%A5%E1%86%B9%E1%84%82%E1%85%B3%E1%86%AB_%E1%84%91%E1%85%B3%E1%84%85%E1%85%A6%E1%84%8C%E1%85%A6%E1%86%AB%E1%84%90%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%89%E1%85%A7%E1%86%AB.jpg"&gt;&lt;figcaption&gt;GDGOC ONE WAVE 해커톤 참가 팀 기획 물 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 또 다른 한팀은 기업마다 다른 실무 환경과 의사결정 문화를 미리 체감하지 못하는 점을 문제로 보고, 기업 기술 블로그를 바탕으로 실제 상황을 롤플레잉하는 시뮬레이션 서비스를 기획했습니다. 결과론적인 합격 스펙보다 합격자가 어떤 순서로 무엇을 해왔는지가 더 중요하다고 판단해, 준비 과정을 타임라인 형태의 전략 로드맵으로 시각화한 두 팀도 있었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또 세 개의 팀은 취업난을 단지 정보나 역량의 문제가 아니라 반복된 탈락 속에서 무너지는 심리의 문제로 해석하고, 짧은 챌린지와 감정 기반 피드백을 제공하는 멘탈 케어 서비스로 풀어냈습니다. 결국 같은 ‘취업난’이라는 주제를 두고도, 어떤 팀은 역량의 검증을, 어떤 팀은 실전의 체감을, 어떤 팀은 준비 전략을, 또 어떤 팀은 심리적 회복을 핵심 문제로 삼았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 미리 ‘기획’을 공개하다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;요즘은 좋은 서비스가 나오면 AI를 활용해 하루 만에 유사한 서비스가 만들어지는 시대입니다. 이런 환경에서는 아이디어를 끝까지 숨기는 것만으로 차별점을 만들기 어렵습니다. 오히려 중요한 것은 같은 문제를 보더라도 어떤 관점으로 정의하고, 어떤 근거와 논리로 풀어내는가에 있다고 생각했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 저희는 각 팀이 행사 첫날 저녁, 기획을 마무리하고 본격적인 개발에 착수하기 직전에 기획 내용을 공유하도록 했습니다. 아이디어가 아직 흐릿한 단계에서는 서로의 방향을 비교하기 어렵고, 반대로 개발이 너무 진행된 뒤에는 중복을 인지하더라도 기획을 수정하기 쉽지 않기 때문입니다. 다시 말해, 서비스의 뼈대는 세워졌지만 아직 방향 전환의 여지가 충분히 남아 있는 시점을 의도적으로 기획 교류 시간으로 잡았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 기획 교류 시간에 등록된 35개 팀의 아이디어를 살펴보면, AI를 활용해 취업 문제를 해결하겠다는 큰 방향은 비슷했지만 세부 주제는 생각보다 많이 겹쳤습니다. 면접 연습 및 피드백이 4팀, 취업 멘탈 케어가 4팀, 취업 로드맵 생성 및 매칭이 4팀, 적합성 검증 및 기업 매칭이 4팀이었고, 이력서·자기소개서 첨삭 및 생성도 3팀에 달했습니다. 마지막 발표 전까지 서로의 기획을 보지 못했다면, 적지 않은 팀이 발표장에서야 “우리와 비슷한 주제가 이렇게 많았구나”를 확인했을 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 구조가 실제로 의미 있었던 이유는, 참가자들이 단순히 기능을 더 붙이는 대신 문제를 다시 정의하게 만들었기 때문입니다. 대표적인 사례가 Team 36이었습니다. 이 팀은 초기에는 깃 로그 분석, 모션 인식 등 여러 기술 요소를 포함한 비교적 넓은 취업 지원 서비스를 구상했습니다. 하지만 기획 교류를 통해 범용 면접 앱이나 자기소개서 관련 서비스가 이미 여러 팀에서 나오고 있다는 점을 확인한 뒤, 방향을 과감하게 좁혔습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image6.jpg"&gt;&lt;figcaption&gt;ONE WAVE 해커톤 밤샘 개발 현장 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI가 자기소개서를 대신 써주거나 면접 답변을 만들어주는 쪽이 아니라, 지원자가 자기 경험을 스스로 복기하고 구조화하도록 돕는 ‘커리어 리플렉션’에 집중한 것입니다. 최종 결과물에서는 모션 인식 같은 부가 기능을 덜어내고, 경험 정리와 질문 유도에 초점을 맞춘 서비스로 정체성을 선명하게 만들었습니다. 같은 취업 준비라는 주제를 다루더라도, 어디를 문제의 핵심으로 보느냐에 따라 완전히 다른 서비스가 될 수 있다는 점을 보여준 사례였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기획 교류 이후 가장 인상적이었던 점은 ‘기능의 추가’보다 오히려 ‘&lt;strong&gt;기능의 삭제&lt;/strong&gt;’가 더 자주 일어났다는 사실입니다. 초기 기획안과 최종 결과물을 비교해 보면, 많은 팀이 이것저것 다 넣으려는 방향에서 벗어나 한 줄로 설명 가능한 핵심 가치에 집중했습니다. 저희는 이 과정을 통해, AI 시대의 해커톤에서는 구현 자체보다도 누구의 어떤 문제를, 왜 이 방식으로 해결하는가를 더 밀도 있게 설명하는 기획이 차별점이 된다는 사실을 다시 확인했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4. 운영진 또한 AI로 일한다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AI 시대의 해커톤을 이야기하면서 참가자만 바뀌어서는 충분하지 않습니다. 운영 방식 역시 함께 달라져야 합니다. 해커톤 현장에는 생각보다 많은 반복 업무가 있습니다. 참가자 등록과 취소 상태 관리, 운영진 및 참가자 권한 부여, 팀 매칭 현황 시각화, 참가자 연락, 팀별 현황 조사, 심사 배점 입력과 결과 취합처럼 하나하나 보면 단순하지만 실제로는 많은 시간을 잡아먹는 일들입니다. 이런 업무가 수작업에 의존할수록 운영진은 작은 변경에도 여러 문서를 오가며 확인해야 하고, 현장 대응 속도도 자연스럽게 느려질 수밖에 없습니다. 그래서 저희는 반복적이고 비효율적인 운영 업무를 가능한 한 시스템 안으로 끌어들였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;대표적인 사례는 심사 결과 자동 산정 대시보드였습니다. 심사위원이 시스템에서 바로 점수를 입력하면 예선·본선 점수와 가중치가 즉시 반영되고, 동점 여부까지 포함한 최종 순위가 자동으로 계산되도록 구성했습니다. 운영진이 별도의 시트에서 점수를 다시 모으고 계산식을 확인하던 과정을 줄이면서, 시상 직전의 취합 부담도 크게 낮출 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image9.png"&gt;&lt;figcaption&gt;심사 현황 관리 시스템 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image10.png"&gt;&lt;figcaption&gt;심사 현황 관리 시스템 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;참가자 상태 관리 역시 자동화했습니다. 해커톤 운영에서는 참여 취소, 팀 변경, 명단 수정처럼 참가자 상태가 바뀌는 일이 생각보다 자주 생깁니다. 문제는 이런 변경이 오프라인 명단 수정에서 끝나지 않는다는 점입니다. 참가자들이 모여 있는 디스코드에서도 해당 인원의 접근 권한을 조정하고, 필요한 경우 닉네임 표시까지 함께 바꿔야 했기 때문입니다. 이를 수작업으로 처리하면 운영진이 디스코드 관리자 화면에서 한 명씩 사용자를 찾아 역할을 수정해야 해 시간이 많이 들고, 변경 사항이 누락될 가능성도 있었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 저희는 백오피스에서 상태가 변경된 참가자들을 선택하면 디스코드 권한과 닉네임이 자동으로 함께 반영되도록 만들었습니다. 덕분에 오프라인에서 변경된 내용이 온라인 운영 공간에도 바로 동기화됐고, 운영진은 반복적인 권한 관리보다 참가자 경험과 현장 흐름을 살피는 일에 더 집중할 수 있었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image3.png"&gt;&lt;figcaption&gt;참가자 관리 시스템 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image2.png"&gt;&lt;figcaption&gt;참가자 관리 시스템 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 현장에서는 계획한 기능만으로는 부족한 순간이 자주 생깁니다. 이번 해커톤에서는 그런 순간마다 필요한 기능을 즉시 만들어 실제 운영에 반영할 수 있었습니다. 행사 도중 구글 로그인 오류가 발생했을 때는 팀별 임시 비밀번호 로그인 기능을 곧바로 추가해 제출 병목을 해소하기도 했습니다. 저희에게 AI는 단순히 일을 빨리 하는 도구가 아니라, 운영 과정에서 드러나는 병목을 현장에서 바로 시스템으로 바꾸는 도구였습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 지점에서 운영진의 역할도 조금 달라졌다고 느꼈습니다. 예전처럼 많은 일을 손으로 빠르게 처리하는 사람이 되는 것보다, 반복 업무를 시스템화하고 현장의 흐름이 끊기지 않도록 구조를 설계하는 사람이 되는 것이 더 중요해졌기 때문입니다. ONE WAVE는 참가자들이 AI를 활용해 개발 방식의 변화를 경험한 자리였을 뿐 아니라, 운영진 역시 AI를 활용해 일하는 방식 자체를 바꿔본 자리이기도 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;대상 수상작 소개&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;기획 교류 시간에 팀별 아이디어를 등록하면 관리자였던 저 역시 내용을 함께 확인할 수 있었는데요. 그중에서 주제를 처음 봤을 때 “이 팀은 참신하다”는 인상을 준 팀이 있었습니다. 바로 8팀이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image4.jpg"&gt;&lt;figcaption&gt;8팀 발표 모습 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;8팀은 장애인 구직자와 기업을 연결하고, 채용 정보의 디지털 접근성을 개선하는 매칭 플랫폼 ‘BARRIER FREE’를 제안했습니다. 이들이 높은 평가를 받은 이유는 ‘취업난’이라는 큰 주제 속에서 타깃 사용자가 명확했고, 그들이 겪는 현실적인 장벽을 구체적인 데이터와 UX로 풀어냈기 때문입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;8팀이 제안한 서비스의 핵심 플로우는 이렇습니다. 시각장애인 구직자가 앱에 접속하면 화면을 읽기 힘든 점을 고려해 클라우드 기반 텍스트 음성화(TTS) 기능으로 사운드 안내를 제공합니다. 구직자가 안내에 따라 10~60초간 자신의 경력을 음성으로 녹음하면, 음성 텍스트화(STT) 기술과 OpenAI를 활용해 말하는 것만으로 이력서가 자동 생성됩니다. 기존 채용 플랫폼이 장애 정도를 단순히 ‘심하다/심하지 않다’로 뭉뚱그려 정보만 제공했던 것과 달리, 실제 사용자가 정보를 입력하고 탐색하는 과정 자체의 '디지털 접근성' 장벽을 허문 것입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image5.png"&gt;&lt;figcaption&gt;8팀 발표 슬라이드 - 핵심 기능 &amp;lt;출처: GDGOC ONE WAVE, 8팀(남경인, 강지윤, 안성현, 조정현)&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한, 이들은 문제 해결의 근거로 구체적이고 수치화된 데이터를 활용했습니다. 구직자의 직무 역량을 판단하기 위해 수작업, 근력, 시력 등 6개의 신체 역량을 4단계로 세분화하여 수치화했습니다. 이 데이터와 공공데이터포털의 정보를 결합하여, 신체 환경 적합도뿐만 아니라 고용 안정성과 급여 매력도 등을 100점 만점의 매칭 점수로 환산해 추천해 주는 전략적인 검색 엔진을 구축했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;심사위원분들의 평가 역시 비슷한 방향에 모였습니다. 발표가 깔끔하고 전달력이 좋았으며, 문제를 잘 정의한 뒤 그에 맞는 해결책을 제시하는 흐름이 좋았다는 평가가 있었습니다. 참신한 아이디어로 틈새시장을 날카롭게 공략했다는 의견도 있었고, 다수의 사람이 공감할 수 있는 약자와 소수자의 문제를 해결하려 했다는 점을 강점으로 보신 분들도 계셨습니다. 활용하는 데이터와 API가 비교적 구체적이었고, 시장을 설정하는 앞단의 논리 구조 역시 잘 짜여 있었다는 평가도 이어졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저 역시 이 팀이 높은 평가를 받은 이유가 분명하다고 느꼈습니다. 먼저 서비스의 타깃이 입체적이었습니다. 장애인 구직자뿐만 아니라, 장애인을 고용하지 않을 경우 1인당 200만 원의 고용부담금을 내야 하는 기업의 HR 담당자까지 핵심 타깃으로 삼아 맞춤형 대시보드를 기획했습니다. 또 문제 해결에 사용할 데이터와 근거가 비교적 구체적이었으며, 그 사용자를 위한 UX 흐름도 자연스럽게 설계되어 있었습니다. 결국 이 수상작은 이번 해커톤이 무엇을 더 중요하게 보았는지를 잘 보여주는 사례였습니다. 코드의 양보다 누구를 위해, 어떤 문제를, 어떤 근거와 흐름으로 풀어냈는가가 더 중요하다는 점 말입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;ONEWAVE Team 인터뷰&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;ONE WAVE는 11월 초부터 약 두 달간, 전국 18개 챕터에서 모인 운영진이 8개 파트(Sales, DevRel, HR, Infra, Marketing, Branding, Finance, Operation)로 나뉘어 준비했습니다. 이 글에서 계속 이야기한 것처럼, 이번 해커톤은 참가자뿐 아니라 운영진의 일하는 방식도 함께 바뀌는 실험이었습니다. 그 변화를 가장 직접적으로 체감한 세 파트를 소개합니다. 백오피스를 직접 설계한 총괄, 체크인 시스템을 자체 개발한 Infra, 평가 환경의 설계를 바꾼 Sales의 이야기입니다. 이어서 나머지 파트의 운영진이 각자의 자리에서 어떤 역할을 맡았는지도 함께 전합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/%E1%84%8B%E1%85%AE%E1%86%AB%E1%84%8B%E1%85%A7%E1%86%BC%E1%84%8C%E1%85%B5%E1%86%AB_%E1%84%83%E1%85%A1%E1%86%AB%E1%84%8E%E1%85%A6%E1%84%89%E1%85%A1%E1%84%8C%E1%85%B5%E1%86%AB.jpg"&gt;&lt;figcaption&gt;GDGoC ONE WAVE 해커톤 운영진 단체사진 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;총괄: 강남대학교 정은혁&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;안녕하세요! 이번 ONE WAVE 해커톤에서 총괄을 맡은 정은혁입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 행사를 준비하며 가장 중요하게 생각한 방향은 ‘지속 가능한 모두를 위한 해커톤’을 만드는 것이었습니다. 참가자뿐 아니라 운영진 역시 운영 경험을 통해 배우고 성장하는 또 다른 참여자라고 생각했기 때문에, 팀 구성과 협업 방식, 문서화, 태스크 관리까지 최대한 체계적으로 설계해 더 건강한 운영 환경을 만들고자 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 과정에서 가장 크게 고민한 것은 어디까지 직접 개입하고 어디까지 믿고 맡길지에 대한 균형이었습니다.이를 고민하는 과정에서 특히 총괄이 세부 실행까지 모두 붙잡기보다 초기에 방향과 기준을 명확히 잡고 필요한 순간에만 조율하는 방식이 더 중요하다는 점을 많이 배웠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 참가자 관리와 심사 운영 과정에서 반복적으로 발생하는 불편을 줄이기 위해 백오피스를 직접 개발해 적용했는데, 이런 자동화가 큰 규모의 행사 운영을 훨씬 안정적으로 만든다는 것도 확인할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 해커톤을 통해 잘 설계된 구조와 좋은 팀워크가 있다면, 연합 해커톤도 충분히 즐겁고 지속 가능하게 운영할 수 있다는 확신을 얻었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Infra: 성공회대학교 윤준석&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;안녕하세요, GDGOC 성공회대학교 오거나이저 윤준석입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 ONE WAVE 해커톤에서는 Infra 팀을 맡아 해커톤이 원활하게 진행될 수 있도록 전반적인 인프라를 담당했습니다. Infra 팀이라는 이름은 단순한 기술 지원을 넘어 온라인과 오프라인을 아우르는 해커톤 운영 환경 전체를 책임지겠다는 의미를 담고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;먼저 준비 단계에서는 운영진들의 빠른 의사결정과 업무 연속성을 위해 노션 회의록을 관리하고, 부서장 중심의 디스코드 커뮤니케이션 구조를 구축해 부서 간 소통이 원활하도록 지원했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여러 학교의 운영진이 함께 준비하는 행사였기에 이러한 협업 환경을 정리하는 것이 중요한 일 중 하나였다고 생각합니다. 현장에서는 “성공적인 마무리를 위한 인프라 지원”에 초점을 두었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;참가자들의 원활한 입장을 위해 체크인 시스템을 직접 개발해 키오스크 형태로 운영했고, 이를 통해 행사장 입장시 발생할 수 있는 병목과 대기 시간을 크게 줄일 수 있었습니다. 또한 메인 홀 행사 중 상단 TV가 출력되지 않는 예상치 못한 상황이 있었지만, 만일을 대비해 챙겨간 HDMI 분배기를 활용해 빠르게 문제를 해결할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아울러 호실 방송 시스템을 구축해 공지 전달을 지원하고, 참가자들이 개발에 몰입할 수 있도록 참여형 음악 플레이리스트를 제공했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Infra 팀은 무대 위가 아니라 무대 뒤에서 행사가 자연스럽게 흘러가도록 기반을 만드는 팀이라고 생각합니다. 이번 ONE WAVE 해커톤을 통해 보이지 않는 곳에서 행사를 완성도 있게 만들어 주는 지속적인 인프라 지원의 중요성을 다시 한번 느낄 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Sales: 서울과학기술대학교 염정우&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;안녕하세요, GDGOC 서울과학기술대학교 오거나이저 염정우입니다. 이번 ONE WAVE 해커톤에서 영업팀장을 맡아 심사위원 및 멘토 섭외, 후원사 컨택을 담당했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;섭외 과정에서 제가 가장 깊이 고민한 부분은 'AI 시대 해커톤의 새로운 평가 기준'이었습니다. AI 도구의 발전으로 기술 구현의 장벽이 크게 낮아진 지금, 해커톤의 핵심은 단순한 기술력 평가를 넘어섰다고 생각합니다. 이제는 프로덕트가 어떤 문제를 어떻게 해결하는지, 그 기획과 비즈니스 역량을 평가하는 것이 훨씬 중요해진 시대입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;참가자들의 치열한 결과물이 제대로 인정받을 수 있도록, 이번 행사에서는 Tech와 Biz 전문가를 고루 모셔 심사위원단의 밸런스를 맞추는 데 가장 큰 공을 들였습니다. 다각도의 날카로운 피드백을 통해 1박 2일의 시간이 참가자들에게 단순한 대회를 넘어 '확실한 성장의 시간'이 되도록 경험의 밀도를 높이고 싶었습니다. 이러한 목표에 공감하고 한마음으로 움직여준 운영진분들 덕분에 참가자들의 기획과 기술을 입체적으로 평가할 수 있는 최적의 심사 환경을 만들 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 해커톤은 '어떤 시각으로 프로덕트를 바라보고 평가할 것인가'에 대한 해답을 찾아가는 과정이었습니다. 운영진으로서 평가 환경을 설계하며, 기술의 완성도만큼이나 비즈니스적 가치 창출이 중요하다는 점을 다시금 깨달을 수 있었던 값진 경험이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 외에도 ONE WAVE는 다양한 파트의 운영진이 함께 만들었습니다. 브랜딩을 맡은 계원예술대학교 노권후는 도쿄 여행 중 출력물 발주 위기를 원격으로 해결하며 현장 몰입을 설계했고, DevRel의 대진대학교 이우민은 본선 심사가 길어진 40분을 전날 못 쓴 콘텐츠로 즉석 커버했습니다. 마케팅의 삼육대학교 김성윤은 서로 다른 배경의 참가자들을 하나의 메시지로 모객하는 역할을, 회계의 전남대학교 황재현은 변동하는 예산을 실시간으로 반영해 안정적인 집행을 이끌었습니다. HR의 중앙대학교 최민준은 약 200명의 사전 설문 데이터를 AI 기반 매칭 프로세스로 분석해 35개 팀의 직군 밸런스를 맞추는 팀 빌딩을 이끌었고, A현장운영의 가천대학교 장영하는 멘토가 직접 팀을 찾아가는 동선을 설계해 참가자의 멘토링 접근성을 높였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3691/image7.jpg"&gt;&lt;figcaption&gt;GDGoC ONE WAVE 해커톤 단체사진 &amp;lt;출처: GDGOC ONE WAVE&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이번 해커톤에서 확인한 것은 세 가지입니다. 첫째, 배포를 필수에서 선택으로 바꾸자 참가자들은 실제로 기획에 더 많은 시간을 썼고, 심사 상위 팀일수록 문제 정의의 밀도가 높았습니다. 둘째, 기획 교류를 프로세스 안에 넣자 비슷한 주제의 중복이 초기에 걸러졌고, 팀들은 기능을 더 붙이는 대신 차별점을 다듬는 쪽으로 움직였습니다. 셋째, 운영진이 반복 업무를 AI로 시스템화하자 현장 대응에 쓸 수 있는 시간이 늘어났고, 예상하지 못한 필요에도 즉시 대응할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 이 세 가지 변화가 실제로 작동하고 있다는 걸 가장 분명하게 보여준 건 현장의 분위기였습니다. 체력이 바닥난 새벽에도 팀들이 붙들고 있었던 건 코드의 양이 아니라 "우리의 로직이 진짜 이 문제를 풀 수 있는가"라는 본질적인 질문이었습니다. 단순히 해커톤을 후원하는 차원을 넘어, 이 실험의 방향성에 공감해 함께해 준 파트너들의 존재도 큰 힘이 되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;동시에 다음에 바꿔야 할 것도 보였습니다. 기획 교류의 효과를 더 정밀하게 측정할 장치가 필요했고, 운영 백오피스도 사전에 더 체계적으로 설계했다면 현장에서 즉석으로 만드는 부담을 줄일 수 있었을 것입니다. 참가자에게 "기획이 중요하다"고 말하면서도, 그 기획의 질을 끌어올려 줄 수 있는 멘토링 구조는 아직 충분하지 않았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;해커톤을 준비하는 분들이 이 글에서 한 가지라도 가져갈 수 있다면, 이것을 말씀드리고 싶습니다. AI가 구현의 장벽을 낮추는 만큼, 해커톤의 무게중심은 자연스럽게 "무엇을 왜 만드는가"로 옮겨갑니다. 그리고 그 변화는 참가자에게만 해당하는 이야기가 아닙니다. 참가자가 기획에 집중하길 바란다면, 운영진도 반복 업무에 묶여 있는 방식에서 먼저 벗어나야 합니다. ONE WAVE는 그 실험의 첫 번째 기록이었고, 다음에는 더 나은 버전을 만들 수 있다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;글:&lt;/strong&gt;&lt;span style="color:rgb(49,49,49);"&gt;GDGoC 정은혁&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#757575;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>자바스크립트 AbortController로 비동기 작업 취소하기</title><link>https://yozm.wishket.com/magazine/detail/3686</link><description>우리가 검색창에 글자를 입력할 때마다 서버에 요청을 보내는 자동완성 기능을 떠올려봅시다. 사용자가 “자바스크립트”를 검색하려고 “자”, “자바”, “자바스”를 빠르게 입력하면, 이전에 보낸 요청들은 더 이상 필요 없어집니다. 이처럼 비동기 작업을 시작한 뒤 중간에 취소해야 하는 상황은 실무에서 꽤 자주 발생하는데요, 자바스크립트에서는 AbortController를 통해 이런 비동기 작업을 깔끔하게 취소할 수 있습니다. 이번 글에서는 AbortController의 기본 구조부터 실무에서 활용하는 패턴까지 함께 살펴보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3686</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;우리가 검색창에 글자를 입력할 때마다 서버에 요청을 보내는 자동완성 기능을 떠올려봅시다. 사용자가 “자바스크립트”를 검색하려고 “자”, “자바”, “자바스”를 빠르게 입력하면, 이전에 보낸 요청들은 더 이상 필요 없어집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3686/%EA%B7%B8%EB%A6%BC1.avif" alt="비동기작업"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href="https://smart-interface-design-patterns.com/articles/autocomplete-ux"&gt;smart-interface-design-patterns.com&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이처럼 비동기 작업을 시작한 뒤 중간에 취소해야 하는 상황은 실무에서 꽤 자주 발생하는데요, 자바스크립트에서는 AbortController를 통해 이런 비동기 작업을 깔끔하게 취소할 수 있습니다. 이번 글에서는 AbortController의 기본 구조부터 실무에서 활용하는 패턴까지 함께 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul&gt;&lt;li&gt;AbortController를 통해 비동기 작업을 시작한 뒤 중간에 취소해야 하는 상황을 깔끔하게 처리할 수 있습니다.&lt;/li&gt;&lt;li&gt;controller.abort()를 호출하면 signal의 aborted 속성이 true로 바뀌면서 연결된 비동기 작업이 중단됩니다.&lt;/li&gt;&lt;li&gt;fetch 요청 취소, 이벤트 리스너 관리, 여러 비동기 작업을 한 번에 취소하는 패턴까지 활용할 수 있습니다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;AbortController의 기본 구조&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AbortController를 사용하려면 먼저 두 가지 개념을 알아야 합니다. 바로 AbortController 자체와, 여기서 파생되는 AbortSignal입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3686/%EA%B7%B8%EB%A6%BC2.webp" alt="AbortController"&gt;&lt;figcaption&gt;&amp;lt;출처: https://reliasoftware.com/blog/axios-in-react-js&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) AbortController와 AbortSignal&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AbortController를 생성하면, signal이라는 속성을 통해 AbortSignal 객체가 함께 노출됩니다. AbortController가 취소 명령을 내리는 쪽이라면, AbortSignal은 그 취소 신호를 전달받는 쪽입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;비유하자면, AbortController는 리모컨이고, AbortSignal은 TV에 달린 수신기라고 생각할 수 있습니다. 리모컨의 버튼을 누르면 수신기가 신호를 받아서 TV가 꺼지는 것처럼, controller.abort()를 호출하면 signal이 신호를 받아서 연결된 작업이 취소됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const controller = new AbortController();
const signal = controller.signal;
console.log(signal.aborted); // false

controller.abort(); // 취소 명령 전달
console.log(signal.aborted); // true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;AbortController()로 컨트롤러를 생성하면, 자동으로 signal 속성에 AbortSignal 객체가 만들어집니다. 이 상태에서 abort()를 호출하면 signal의 aborted 속성이 true로 바뀌면서, 이 signal을 전달받은 비동기 작업이 중단됩니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) abort 이벤트 감지하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;그렇다면 취소 시점에 맞춰 정리 작업을 해야 할 때는 어떻게 할까요? signal의 abort 이벤트를 활용하면 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const controller = new AbortController();
const signal = controller.signal;

signal.addEventListener("abort", () =&amp;gt; {
  console.log("작업이 취소되었습니다");
  console.log("취소 사유:", signal.reason);
});

controller.abort("사용자가 페이지를 떠남");
// "작업이 취소되었습니다"
// "취소 사유: 사용자가 페이지를 떠남"&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;abort() 메서드에 인자를 전달하면 signal.reason으로 취소 사유를 확인할 수 있습니다. 참고로 reason에는 문자열뿐만 아니라 어떤 값이든 넣을 수 있어서, 에러 객체나 코드 값을 전달하는 식으로 활용할 수도 있습니다. reason을 생략하면 기본적으로 “AbortError” DOMException이 들어갑니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;fetch 요청 취소하기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AbortController의 기본 구조를 알았으니, 이제 실제로 가장 많이 쓰이는 fetch 요청 취소에 적용해 보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 기본적인 fetch 취소&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AbortController가 가장 많이 쓰이는 곳은 fetch 요청입니다. fetch의 두 번째 인자에 signal을 전달하면, 해당 요청을 원하는 시점에 취소할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const controller = new AbortController();

fetch("https://api.example.com/users", {
  signal: controller.signal, // signal 연결
})
  .then((res) =&amp;gt; res.json())
  .then((data) =&amp;gt; console.log(data))
  .catch((err) =&amp;gt; {
    if (err.name === "AbortError") {
      console.log("요청이 취소되었습니다");
    } else {
      console.error("요청 실패:", err);
    }
  });

// 필요한 시점에 취소
controller.abort();&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;abort()가 호출되면 fetch는 AbortError라는 특별한 에러를 발생시킵니다. catch 블록에서 err.name을 확인하면 사용자가 의도적으로 취소한 것인지, 네트워크 오류인지 구분할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 실무에서 자동완성처럼 연속으로 요청을 보내는 경우, 단순히 이전 요청을 abort하는 것만으로는 부족할 수 있습니다. 네트워크 환경이나 캐시 상태에 따라 늦게 도착한 이전 응답이 최신 결과를 덮어쓰는 경우가 생기기도 하는데요, 이런 상황을 방지하려면 abort와 함께 마지막 요청만 반영하는 로직을 같이 사용하는 편이 안전합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;let currentController = null;

async function search(query) {
  // 이전 요청이 있으면 취소
  if (currentController) currentController.abort();
  currentController = new AbortController();

  try {
    const res = await fetch(`/api/search?q=${query}`, {
      signal: currentController.signal,
    });
    const data = await res.json();
    renderResults(data); // 마지막 요청 결과만 반영
  } catch (err) {
    if (err.name !== "AbortError") {
      console.error("검색 실패:", err);
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 하면 이전 요청을 가능한 빨리 취소할 수 있습니다. 위 코드에서 매번 new AbortController()로 새 컨트롤러를 만드는 이유는, 한 번 abort된 signal은 재사용할 수 없기 때문입니다. 이미 abort된 signal을 다시 fetch에 넘기면 요청이 즉시 reject되므로, 매 요청마다 새로운 AbortController를 생성해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 abort는 fetch 요청 자체를 중단시킬 뿐, UI 반영 로직까지 자동으로 막아주는 것은 아닙니다. 실무에서는 이미 처리 단계에 들어간 이전 응답이 뒤늦게 화면을 덮어쓰는 경우까지 방지하기 위해, abort와 함께 요청 ID를 비교하는 방식으로 마지막 요청만 반영하도록 만드는 것이 더 안전합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 타임아웃 설정하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;서버 응답이 너무 오래 걸릴 때 자동으로 요청을 취소하고 싶다면, AbortSignal.timeout()을 활용할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;// 5초 안에 응답이 없으면 자동 취소
fetch("https://api.example.com/data", {
  signal: AbortSignal.timeout(5000),
})
  .then((res) =&amp;gt; res.json())
  .then((data) =&amp;gt; console.log(data))
  .catch((err) =&amp;gt; {
    if (err.name === "TimeoutError") {
      console.log("요청 시간이 초과되었습니다");
    }
  });&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AbortSignal.timeout(5000)은 5초 후에 자동으로 취소 신호를 보내는 signal을 생성합니다. 기존에는 setTimeout과 abort()를 조합해야 했지만, 이 정적 메서드를 사용하면 한 줄로 간결하게 타임아웃을 설정할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;스펙상 timeout으로 인한 취소는 TimeoutError로 구분할 수 있게 되어 있지만, fetch에서 최종적으로 어떤 에러 이름이 보이는지 런타임에 따라 차이가 있을 수 있습니다. 그래서 에러를 더 정확히 구분하고 싶다면 err.name과 함께 signal.reason까지 같이 확인하는 편이 안전합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;다양한 활용법&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AbortController는 fetch 외에도 다양한 Web API에서 활용할 수 있습니다. 이벤트 리스너 관리부터 여러 비동기 작업을 한꺼번에 제어하는 패턴까지 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) addEventListener에서의 활용&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AbortController는 fetch뿐만 아니라 이벤트 리스너 관리에도 활용할 수 있습니다. addEventListener의 세 번째 인자에 signal을 전달하면, abort() 호출 시 이벤트 리스너가 자동으로 해제됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const controller = new AbortController();

document.addEventListener(
  "click",
  () =&amp;gt; {
    console.log("클릭!");
  },
  { signal: controller.signal } // signal 전달
);

// 이벤트 리스너 자동 해제
controller.abort();&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기존에는 removeEventListener로 직접 이벤트를 해제해야 했고, 이때 동일한 함수 참조를 유지해야 하는 번거로움이 있었습니다. signal을 활용하면 이런 불편함 없이 깔끔하게 이벤트를 정리할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 하나의 controller로 여러 이벤트 리스너를 한 번에 해제할 수도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const controller = new AbortController();
const { signal } = controller;

window.addEventListener("resize", handleResize, { signal });
window.addEventListener("scroll", handleScroll, { signal });
document.addEventListener("keydown", handleKeydown, { signal });

// 세 개의 이벤트 리스너를 한 번에 해제
controller.abort();&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;컴포넌트 언마운트나 페이지 전환 시점에 controller 하나만 abort하면 관련된 리스너를 한꺼번에 정리할 수 있어, 이벤트 해제 누락으로 인한 리소스 낭비를 줄이는 데 유리합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 여러 비동기 작업 한 번에 취소하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;같은 원리로, 하나의 signal을 여러 fetch 요청에 전달하면 한 번의 abort()로 모든 요청을 동시에 취소할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3686/%EA%B7%B8%EB%A6%BC3.gif"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href="https://www.c-sharpcorner.com/article/easy-way-to-handle-cancellation-of-api-requests-in-react-with-abortsignal-types/"&gt;www.c-sharpcorner.com&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const controller = new AbortController();
const { signal } = controller;

// 여러 요청에 같은 signal 전달
const userReq = fetch("/api/user", { signal });
const postReq = fetch("/api/posts", { signal });
const commentReq = fetch("/api/comments", { signal });

// 페이지 이동 시 모든 요청을 한 번에 취소
controller.abort();&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 여러 개의 취소 조건을 하나로 합쳐야 할 때는 AbortSignal.any()를 활용할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const userController = new AbortController();
const timeoutSignal = AbortSignal.timeout(5000);

// 사용자가 취소하거나, 5초가 지나면 취소
const signal = AbortSignal.any([
  userController.signal,
  timeoutSignal,
]);

fetch("/api/data", { signal })
  .then((res) =&amp;gt; res.json())
  .then((data) =&amp;gt; console.log(data))
  .catch((err) =&amp;gt; console.log("취소됨:", err.message));&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AbortSignal.any()는 전달받은 signal 중 하나라도 abort되면 취소 신호를 보내며, 이때 가장 먼저 abort된 signal의 reason이 최종 reason으로 전달됩니다. 위 코드에서는 “사용자가 직접 취소”하거나 “5초 타임아웃”이 발생하면 요청이 취소됩니다. 다만, AbortSignal.any()는 비교적 최신 API라 일부 구형 환경에서는 호환성 확인이 필요할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 AbortController의 기본 구조부터 fetch 취소, 이벤트 리스너 관리, 그리고 여러 작업을 한 번에 취소하는 패턴까지 살펴봤습니다.비동기 작업에서 “시작”하는 방법은 많이 다루지만, “취소”하는 방법은 상대적으로 덜 주목받는 경우가 많습니다. 하지만 불필요한 요청을 제때 취소하지 않으면 메모리 누수나 예상치 못한 상태 업데이트로 이어질 수 있기 때문에, 비동기 작업의 취소는 시작만큼이나 중요한 부분입니다. AbortController의 사용법이 그리 어렵지 않은 만큼, 다음 프로젝트에서 한번 적용해 보시면 좋겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>개발자, 이직이 완벽한 도피처가 될 수 있을까요?</title><link>https://yozm.wishket.com/magazine/detail/3683</link><description>여러분은 혹시 늦은 밤, 불 꺼진 방 안에서 모니터만 멍하니 바라보며 "나, 이대로 계속 개발을 해도 괜찮은 걸까?"라는 서늘한 불안감을 느껴본 적이 있으신가요? 아마 매일 똑같이 반복되는 업무에 지쳐서, 혹은 시간이 지나도 더 이상 실력이 발전하지 않는다는 생각에 이직 채용 사이트를 습관적으로 들여다보고 계실지도 모르겠습니다. 사실 저 또한 그런 시절이 있었습니다. 특히 일본에서의 첫 전직은 단순히 제 명함의 로고를 바꾸거나 출근하는 지하철 노선을 바꾸는 가벼운 일이 결코 아니었죠. 오늘은 일본에서 첫 전직을 결심하고 실행에 옮기며 부딪혔던 차가운 현실, 그리고 그 과정에서 철저하게 제 부족함을 돌아봤던 이야기를 나누어 보려고 합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3683</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;일본에서의 첫 이직: 개발자로서의 고뇌&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여러분은 혹시 늦은 밤, 불 꺼진 방 안에서 모니터만 멍하니 바라보며 "나, 이대로 계속 개발을 해도 괜찮은 걸까?"라는 서늘한 불안감을 느껴본 적이 있으신가요? 아마 매일 똑같이 반복되는 업무에 지쳐서, 혹은 시간이 지나도 더 이상 실력이 발전하지 않는다는 생각에 이직 채용 사이트를 습관적으로 들여다보고 계실지도 모르겠습니다. 사실 저 또한 그런 시절이 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;타국에서 커리어를 쌓아간다는 것은 생각보다 훨씬 외롭고 막막한 순간들의 연속이었습니다. 특히 일본에서의 첫 전직(轉職, 직업이나 직무를 바꾸어 옮김)은 단순히 제 명함의 로고를 바꾸거나 출근하는 지하철 노선을 바꾸는 가벼운 일이 결코 아니었습니다. 당장 제 체류 자격을 증명하고 삶을 지탱해 주는 비자 문제가 걸려 있었고, 한 치 앞을 알 수 없는 복잡한 연봉 체계를 새롭게 계산해야 하는 치열한 생존의 문제였죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;무엇보다 일본 IT 특유의 파견 및 도급 중심 구조 속에서, 제가 개발자로서 올바른 방향으로 성장하고 있는지 스스로에게 냉정하게 물어야만 하는 고통스러운 과정이기도 했습니다. 처음 전직을 결심했던 순간만 해도, 제가 겪는 모든 성장의 정체와 불만족은 '내가 속한 환경' 탓이라고 굳게 믿었습니다. "회사가 나를 제대로 가르쳐 주지 않아서", "할당받은 프로젝트의 퀄리티가 너무 낮아서"라고 탓하곤 했죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 본격적으로 이력서를 쓰고 면접의 문을 두드리며 뼈저리게 깨닫게 된 사실이 하나 있습니다. 그 견고한 산업의 구조보다도 먼저 부족했던 건, 바로 준비되지 않은 저 자신이었다는 사실을요. 오늘은 일본에서 첫 전직을 결심하고 실행에 옮기며 부딪혔던 차가운 현실, 그리고 그 과정에서 철저하게 제 부족함을 돌아봤던 이야기를 여러분과 허심탄회하게 나누어 보려고 합니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;성장의 시계가 멈추다: 전직을 고민하게 된 진짜 이유&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3683/image4.png"&gt;&lt;figcaption&gt;반복 업무, 1인 개발, 성장 정체의 악순환 &amp;lt;출처: 작가&amp;gt;&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;혼자라는 자유로움 뒤에 숨겨진 성장의 한계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;제가 이전 회사에서 주로 담당했던 업무는 고객의 요구에 따라, 시스템을 만들어 납품하는 이른바 수탁 개발 형태였습니다. 다양한 산업군의 기능을 접해볼 수 있을 거라는 초기의 기대와는 달리, 현실은 늘 빠듯한 예산 속에서 쫓기듯 진행되는 소규모 프로젝트의 연속이었는데요. 회사의 이익 구조상 남는 것이 적다 보니 자연스럽게 저희의 급여도 제자리걸음을 면치 못하는 악순환이 계속되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;게다가 규모가 작다 보니 개발의 기획 단계부터 납품까지 온전히 저 혼자 감당해야 하는 1인 개발 형태가 매우 잦았습니다. 물론 1인 개발을 통해 처음부터 끝까지 혼자 고민해 보며, IT 기술의 전반적인 파이프라인(Pipeline)을 넓고 유연하게 접할 수 있었다는 점은 큰 장점이었습니다. 하지만 체계적인 코드 리뷰(Code Review)나 뛰어난 시니어 개발자의 멘토링을 기대하는 것은 사치에 불과했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;당장 눈앞에 떨어진 버그를 고치고 납품 기한을 맞추는 데 급급하다 보니 설계의 본질에 대해 깊이 고민할 여유가 없었습니다. 막히는 에러가 발생해도 물어볼 곳 하나 없이 속 시원히 해결되지 않아, 퇴근 후에도 어김없이 집에서 노트북을 열고 끙끙 앓아야 했던 날들이 무수히 많았습니다. 이러한 환경에서 과연 5년 뒤, 10년 뒤의 제가 어떤 모습일지 상상하니 눈앞이 캄캄해졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;개발자 타이틀을 잃을지도 모른다는 깊은 위기감&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이러한 불만족이 쌓여가던 중, 저를 본격적인 전직 시장으로 강력하게 내몬 결정적인 위기가 찾아왔습니다. 다니던 회사가 다른 기업과 합병을 겪게 되면서 심각한 영업 부진에 빠진 것이었는데요. 합병 이후 영업이 급격히 위축되면서, 동료 개발자들은 하나둘 회사를 떠나기 시작했습니다. 결국 남은 건 저 혼자였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개발할 프로젝트도 사라진 상황에서, 매출이라도 만들어야 했던 회사는 저를 IT 시스템 운영팀으로 보낼 수밖에 없었습니다. 그렇게 5개월이라는 결코 짧지 않은 시간 동안, 본연의 코딩 업무가 아닌 무미건조한 운영 업무만을 전담하게 되었습니다. 운영팀에서의 하루하루는 제게 커다란 절망감을 안겨주었습니다. 당장 이곳에서 아무리 훌륭하게 성과를 낸다고 한들, 개발자로서 급여가 더 오를 희망은 보이지 않았기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;무엇보다 하루가 다르게 새로운 기술이 쏟아져 나오는 이 업계에서, 소중한 제 커리어에 회복하기 힘든 공백이 생길 것이라는 걱정이 매일 밤 저를 짓눌렀습니다. 더 늦기 전에 멈춰버린 성장의 톱니바퀴를 다시 굴려야 한다는 확신이 들었습니다. 그것이 제가 서둘러 정든 곳을 떠날 채비를 하게 만든 가장 절박한 이유였습니다. 결코 여유롭고 안정적인 상황에서 준비한 이직이 아니었기에 제 마음은 더욱 초조할 수밖에 없었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;피부로 느낀 일본 IT의 맨얼굴: 구조적 현실과 마주하다&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3683/image3.png"&gt;&lt;figcaption&gt;일본 IT 산업의 다단계 하청 구조 &amp;lt;출처: 작가&amp;gt;&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 style="text-align:justify;"&gt;&amp;nbsp;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;견고하게 자리 잡은 의존적 생태계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;일본에서 개발자로 첫발을 내딛고 살아가다 보면, 피할 수 없이 마주치게 되는 단어가 있습니다. 바로 SES(System Engineering Service)라는 파견 위주의 기술 인력 제공 형태입니다. 한국의 시스템 통합(SI) 업무 환경과 비슷한 맥락이지만, 현장에 상주하는 방식과 다단계의 계약 구조에서 뚜렷한 차이를 보입니다. 실제로 수많은 일본의 IT 기업들이 자체적인 서비스를 기획하고 구축하는 사내 개발을 하기보다는, 이 SES나 수탁 개발 구조에 절대적으로 의존하고 있는 것이 엄연한 생태계의 현실입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;자체 플랫폼이나 서비스를 가진 사내 개발 환경에서는 하나의 프로덕트에 대해 깊이 있게 고민하고, 대규모 트래픽(Traffic)에 대비해 코드를 리팩터링(Refactoring)하며 성장해 나가는 경험을 차곡차곡 쌓을 수 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면, 수탁 개발이나 많은 외국인 개발자들이 흔히 겪는 SES 환경에서는 어떨까요? 짧으면 몇 개월, 길어도 1년 남짓한 프로젝트가 끝나면 또다시 새로운 환경의 전혀 다른 시스템 코드를 뜯어봐야 합니다. 잦은 환경 변화 속에서 자신만의 기술적인 철학과 깊이를 뾰족하게 가다듬는 것은 정말이지 쉽지 않은 일이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;언어 장벽과 홀로서기라는 미션&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;게다가 외국인 개발자에게 이러한 폐쇄적인 구조 속에서의 생존과 전직은 결코 가벼운 마음으로 던질 수 있는 출사표가 아니었습니다. 제가 처음 다녔던 회사는 다행스럽게도 한국인 동료들이 꽤 포진해 있어 심리적인 안정감이 매우 높은 편이었습니다. 기술적인 소통의 어려움이나 미묘한 문화적 차이를 선배들이 훌륭하게 메워주고 배려해 주었죠. 하지만 제가 진정한 성장을 위해 온전히 홀로 일본의 IT 생태계 속으로 뛰어들어 '완전한 일본계 회사'로 발걸음을 옮기려다 보니 상황의 온도는 180도 달라졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;철저히 내국인 일본 개발자들과 똑같은 기준의 잣대 위에서 평가받아야 했기 때문입니다. 회의의 논리 전개 방식, 까다로운 내부 문서 작성 프로세스 등 모든 것이 생경했습니다. 따뜻한 온실 속에서만 자라다가, 처음으로 매서운 야생 한가운데 내던져진 기분이랄까요? 단순히 코드를 잘 짜는 것을 넘어, 일본어라는 언어의 장벽을 뚫고 내 실력을 증명해야 하는 이중고를 겪어야 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;보이지 않는 모래주머니: 비자와 급여 체계의 공포&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3683/image6.png"&gt;&lt;figcaption&gt;한국 여권과 급여 봉투 사이의 불안한 균형 &amp;lt;출처: 작가&amp;gt;&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 style="text-align:justify;"&gt;&amp;nbsp;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;카운트다운이 시작되는 비자 문제&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;외국인으로서 타국에서 다른 직장을 알아볼 때 가장 먼저 우리의 숨통을 조여 오는 부분은 무엇보다도 '비자'라는 무거운 이름표입니다. 현지인들에게 전직은 그저 연금 수첩을 갱신하고 보험증을 새로 발급받는 약간의 수고로움일지 모릅니다. 하지만 우리는 상황이 완전히 다릅니다. 이직하려는 새 회사의 직무가 현재 소지한 취업 비자의 명목과 조금의 오차 없이 맞닿아 있는지 확인해야 하며, 퇴사 후 14일 이내에 출입국재류관리청에 의무적으로 소속 기관 변경 신고를 해야만 하죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;만약 다음 행선지를 정하지 못한 채 무직으로 3개월이 넘어가 버린다면, 비자 갱신이 거절될 수도 있다는 보이지 않는 시한폭탄을 가슴에 안고 살아가야 합니다. 더 나은 내일을 위해 내린 결단이었음에도 불구하고, '공백기'라는 시간적 압박은 엄청난 족쇄이자 공포로 다가왔습니다. 당장 생활비도 문제지만, 일본이라는 나라에서 쫓겨날지도 모른다는 근원적인 불안감이 전직 활동 내내 저를 괴롭혔습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;연봉의 허수와 무퇴직금의 설움&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;급격히 달라지는 급여 구조의 맹점 또한 간과할 수 없는 심리적 짐이었습니다. 일본 회사들의 경우 기본 연봉을 단순히 12개월로 균일하게 나누어 지급하는 곳도 있지만, 상여금(Bonus)이 전체 실수령액에서 차지하는 비중이 비정상적으로 큰 구조가 빈번하게 존재합니다. 이 말은 곧, 이직 후 입사 첫해에는 자격 요건 미달로 이 상여금을 온전히 수령하지 못하는 경우가 허다하다는 뜻입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 연봉 조건을 높여 이직했음에도 첫해에는 오히려 손에 쥐는 돈이 줄어드는 아찔한 기현상을 마주할 수도 있는 것이죠. 여기에 더해 한국인들에게는 너무나 당연하게 여겨지는 '퇴직금' 제도가 아예 존재하지 않는 일본 기업들이 부지기수입니다. 제가 몸담았던 첫 회사 역시 단 1엔의 퇴직금조차 위로금으로 나오지 않는 곳이었죠. 이직 사이에 잠깐의 빈 타이밍이 발생한다면, 매달 숨만 쉬어도 나가는 살인적인 월세와 각종 세금을 오로지 예금 잔고로 버텨내야 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;알량한 자만심의 붕괴: 나를 무너뜨린 처절한 실패기&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3683/image5.png"&gt;&lt;figcaption&gt;면접장에서 말이 나오지 않는 순간 &amp;lt;출처: 작가&amp;gt;&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;과거의 애매한 스펙이 발목을 잡다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;솔직히 고백하자면, 처음 이력서 작성을 시작할 때까지만 해도 제 마음 한구석에는 은근한 자신감이 깔려 있었습니다. 나름 4년제 대학교에서 컴퓨터공학과를 전공했고, OCJP나 정보처리기사, SQLD 같은 자격증도 몇 개 따 두었으니까요. 대단한 것은 아니었지만, 적어도 서류에서 빈칸을 채울 정도는 된다고 생각했습니다. 실무 경험도 나쁘지 않다고 자부했죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;한국에서 꽤 비중 있는 SI 프로젝트와 대용량 빅데이터(Big Data) 처리, 전산실 실무까지 경험해 보았습니다. 일본으로 건너와서도 지난 3년 이상 묵묵히 버텨내며, 고객의 가혹한 수정 요청을 이겨내고 성공적으로 납품을 마친 소프트웨어 제품까지 포트폴리오(Portfolio)에 올릴 수 있었습니다. 제가 봐도 꽤 그럴듯한 이력서였습니다. 당연히 어디든 저를 원할 거라고 맹신하며 여러 회사에 과감하게 입사 지원서를 던졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;소통의 단절, 그리고 드러난 진짜 민낯&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;서류는 생각보다 쉽게 통과되었습니다. 하지만 실전의 공기는 제 예상과 너무나도 달랐습니다. 가장 뼈아팠고 치명적이었던 패인은 바로 언어, 즉 '일본어 구사력'이었습니다. 한국인 동료들의 친절한 통역 뒤에 숨어서 일하던 시절에는 미처 깨닫지 못했던 제 일본어의 얕은 밑천이 적나라하게 드러난 것이죠. 기술 면접 과정이나 왜 우리 회사여야만 하는지 꼬리를 무는 질문 앞에서 제 입은 무겁게 얼어붙고 말았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그뿐만 아니라 제 과거의 멋진 경험을 상대방의 관점에서, 매력적인 '이익'으로 포장해 내는 요령도 전무했습니다. "이것도 써봤고, 저것도 다뤄봤다"라는 식의 백화점식 나열형 대답은 면접관들의 흥미를 끌어내지 못했습니다. 기업이 진정으로 필요로 하는 핵심 역량이 무엇인지 꿰뚫어 보지 못한 채, 막연히 "열심히 하겠습니다" 식의 겉도는 파편만 나열했습니다. 철저한 자기 객관화 없이 과거의 타이틀에만 기대었던 안일함이 불러온 쓰라린 실패였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실패 속에 피어난 자각: 진짜 부족했던 세 가지&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3683/image1.png"&gt;&lt;figcaption&gt;세 조각으로 갈라진 거울 속 나의 부족함 &amp;lt;출처: 작가&amp;gt;&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;얕은 기술력과 앵무새 같은 비즈니스 언어&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;수없는 불합격의 고배를 마시던 중, 정말 운 좋게도 제 가능성을 믿어준 지금의 회사를 만났습니다. 하지만 최종 합격 메일을 받은 그 밤, 제 마음속에 일렁이는 감정은 환희보다는 부끄러운 자기반성이었습니다. 제가 마주했던 결핍 중 첫 번째는 참담할 정도로 얕은 '기술의 깊이'였습니다. 외부 코드를 가져다 쓰는 임기응변은 능숙했을지 모르나, 정작 컴퓨터 공학의 본질적 코어 원리에 대해 집요하게 파고들어 본 경험이 부족했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 처참했던 '비즈니스 일본어'의 부재였습니다. 코드야말로 만국 공통어라고 자위하며 살았지만, 결국 그 코드를 팀원들과 함께 어떤 가치를 위해 짤 것인지 설득하는 과정은 인간의 언어로 이루어집니다. 상대방의 의도를 곡해 없이 파악하고 나의 논리를 부드럽고 묵직하게 설득해 낼 수 있는 수준의 경어와 뉘앙스 최적화가 안 된다면, 누군가가 시키는 잡무만 받아내는 부속품으로 전락할 수밖에 없음을 아프게 실감했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;모든 걸 밖에서 찾으려 했던 내면의 나태함&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;마지막으로 저를 가장 부끄럽게 만든 것은 모든 문제의 화살을 외부로 돌리기 바빴던 **'수동적인 태도'**였습니다. 멘토가 없었다면 외부 커뮤니티를 직접 찾아가 기꺼이 제 코드를 까발리며 리뷰를 간청했어야만 했습니다. 회사의 성장이 멈추는 것 같아 억울했다면, 주말을 반납해서라도 오픈 소스(Open Source)를 뜯어보며 스스로 생존의 길을 모색했어야 옳았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러나 저는 그 귀중한 시간 동안 가혹한 현실을 불평하고 회사의 보수적인 시스템만 원망하며 한탄하는 구경꾼에 머물렀습니다. 스스로 배의 조타수를 쥐고 거친 파도 속으로 뛰어들 생각은 조금도 하지 못한 채, 언제나 잔잔한 우물 안에서 구조선만 기다리던 불쌍한 개구리였던 셈입니다. 이러한 자각은 저에게 큰 충격을 주었고, 비로소 제가 앞으로 가야 할 길이 보이기 시작했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;환경을 원망하기 전, 내 안의 거울을 먼저 닦아볼까요?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;참으로 다사다난했던 저의 첫 번째 전직 생활은 단순히 일하는 회사의 간판을 갈아 끼우는 과정이 아니었습니다. 제 자신을 냉혹한 시장의 저울대 위에 던져 넣음으로써, 그동안 외면하고 싶었던 실력의 비루한 민낯과 마주하는 시간이었습니다. 그리고 현재의 진짜 제 수준을 가감 없이 직시하고 바닥부터 인정하게 만들어 준 세상에서 가장 아프고도 찬란한 성장의 터닝 포인트였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여러분, 전직은 결코 지금 마주한 일상의 어려움에서 도망치기 위해 선택하는 달콤한 도피처가 되어서는 안 됩니다. 내가 향하고자 하는 뚜렷한 목표 깃발을 꽂고 정면 돌파하기 위한 철저하고 주도적인 '나침반'이 되어야만 하죠. 도전과 좌절이 공존하는 일본이라는 시장에서 우리는 어떻게 생존해야 할까요? 대체 불가능한 개발자로 뿌리내리기 위해서는 비즈니스 언어의 칼날, 시장을 꿰뚫는 통찰력, 그리고 기술적 소양이 완벽하게 맞물려 돌아가야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지금 당장 이직 버튼을 눌러야 할지 고민하고 계신 여러분께 조심스럽게 여쭤보고 싶습니다. 지금 여러분이 떠나고 싶은 그곳은 숨 막히는 현실을 피해 도망갈 '안락한 퇴로'인가요? 아니면 나의 역량을 가슴 벅차게 증명해 낼 치열한 '새로운 전쟁터'인가요? 이력서를 쓰기 전에 부디 며칠 만이라도 시간을 내어 자신이 다져온 기술의 뿌리와 태도의 궤적을 서늘하게 되짚어보시기를 권해드립니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;가장 초라한 내 부족함을 인정하는 그 아픈 순간이 역설적이게도 앞으로 맞이할 수많은 면접관들 앞에서 여러분을 가슴 활짝 펴고 도약하게 만들어 줄 강력한 무기가 될 것입니다. 오늘 비록 에러를 다 잡지 못해 속상했더라도, 묵묵히 전진하는 여러분의 눈부신 내일을 저 역시 뜨겁게 응원하겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>소프트웨어의 유튜브 모멘트: 이제 누구나 제품을 만든다</title><link>https://yozm.wishket.com/magazine/detail/3681</link><description>"개발자가 없어서 못 하고 있어요." 아이디어가 반짝이지만 개발자가 없어서 시작도 못 한 이야기를 한 번쯤 들어봤거나, 직접 해봤을 말입니다. 그런데 2025년을 기점으로 이 말은 변명이 되어가고 있습니다. 그런데 2025년을 기점으로 이 말은 변명이 되어가고 있습니다. a16z의 파트너 Anish Acharya는 지난 1월 이렇게 말했습니다. "소프트웨어의 유튜브 모멘트가 지금 일어나고 있다. 소프트웨어에도 같은 일이 벌어지고 있습니다. Cursor, Claude Code, Replit, Wabi 같은 AI 코딩 도구들이 그 장벽을 허물고 있기 때문입니다.</description><guid>https://yozm.wishket.com/magazine/detail/3681</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;"개발자가 없어서 못 하고 있어요."&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아이디어가 반짝이지만 개발자가 없어서 시작도 못 한 이야기를 한 번쯤 들어봤거나, 직접 해봤을 말입니다. 아이디어는 있는데 개발 리소스가 없고, 외주를 맡기자니 비용이 너무 비싸고, 그렇다고 개발자를 뽑자니 초기 팀에 그런 여유가 없는 상황 말이죠. PM이나 기획자들이 수도 없이 부딪혀온 벽일 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 2025년을 기점으로 이 말은 변명이 되어가고 있습니다. a16z의 파트너 &lt;a href="https://www.a16z.news/p/softwares-youtube-moment-is-happening"&gt;Anish Acharya&lt;/a&gt;는 지난 1월 이렇게 말했습니다. "소프트웨어의 유튜브 모멘트가 지금 일어나고 있다. "YouTube가 2005년에 나왔을 때, 영상은 방송국과 전문 PD의 영역이었습니다. 장비, 편집, 배급 전부 진입 장벽이었죠. 그게 스마트폰 카메라 하나로 무너졌습니다. 지금은 유튜버가 지상파보다 영향력이 큰 게 당연한 세상이고요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3681/8ad2567a-2994-423e-ab16-d2efd42a3ef3_1196x544.webp"&gt;&lt;figcaption&gt;"이제 만들 때입니다. 이제 누구나 만들 수 있습니다." &amp;lt;출처: &lt;a href="https://www.a16z.news/p/softwares-youtube-moment-is-happening"&gt;a16z.news&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;소프트웨어에도 같은 일이 벌어지고 있습니다. Cursor, Claude Code, Replit, Wabi 같은 AI 코딩 도구들이 그 장벽을 허물고 있기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;YouTube가 영상 창작의 문턱을 낮췄듯, AI 코딩 도구는 소프트웨어 제작의 문턱을 낮추고 있다. 이제 개발자가 없어도 서비스를 만들 수 있는 시대가 열리고 있다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;기획자, PM, 창업자에게 이 변화는 단순한 도구 변화가 아니다. 아이디어 검증 속도가 달라지고, 경쟁 구도가 바뀌고, 누가 시장에 진입할 수 있는지가 달라지는 비즈니스 지형의 변화다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;이 기회를 잡으려면 '어떻게 만들지'보다 '무엇을 만들지'를 판단하는 능력이 훨씬 더 중요해진다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;유튜브가 이미 보여준 것&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3681/2.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 픽사베이&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Acharya는 영상 창작의 역사를 세 단계로 나눕니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 &lt;strong&gt;“Hollywood” 시대&lt;/strong&gt;입니다. 영화 한 편을 만들려면 수백만 달러의 제작비와 전문 스튜디오가 필요했습니다. 창작은 소수의 전문가 집단 손에 있었죠.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;“인디 감독” 시대&lt;/strong&gt;입니다. 1990년대 쿠엔틴 타란티노, 폴 토마스 앤더슨 같은 감독들이 저예산으로 영화를 만들기 시작했습니다. 장벽이 낮아졌지만, 여전히 전문성과 비용이 필요했습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;세 번째가 &lt;strong&gt;“YouTube” 시대&lt;/strong&gt;입니다. 스마트폰 하나면 누구나 촬영하고, 편집하고, 전 세계에 배포할 수 있게 됐습니다. Mr. Beast는 방송국 없이도 수억 명의 구독자를 가진 크리에이터가 됐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;소프트웨어도 정확히 같은 경로를 걷고 있습니다. 할리우드 시대에는 소프트웨어 하나 만들려면 대기업이거나 수억 원을 쏟아야 했습니다. 인디 시대에 Y Combinator 같은 스타트업 액셀러레이터(초기 스타트업에 투자와 멘토링을 해주는 프로그램)가 생기면서 Airbnb, Coinbase 같은 아웃사이더들이 끼어들기 시작했고요. &lt;strong&gt;지금은 AI 코딩 도구가 유튜브 역할&lt;/strong&gt;을 하고 있습니다. 코딩을 모르는 사람도 제품을 만들 수 있는 시대가 된 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;a16z가 소개한 사례들을 보면 과장이 아니라는 걸 알 수 있습니다. 누군가는 MRI 이미지를 시각화하는 대시보드를 직접 만들었는데, 의료 전문가들 반응이 "원래 상용 소프트웨어가 필요한 작업"이었다고 합니다. 라이브 방송하면서 실시간으로 앱을 짜는 사람도 있고, CLI 하나로 광고 캠페인 전체를 뚝딱 만들어내는 사람도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;몇 년 전만 해도 개발팀 없이는 꿈도 못 꿨을 일들입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실제로 일어나고 있는 일들&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;실제로 비개발자가 앱을 만들 수 있느냐고요? 제 지인은 개발자가 아닙니다. 그런데 최근 Cursor와를 이용해서 간단한 데이터 분석 대시보드를 만들었습니다. 특정 키워드가 포함된 기사들을 모아서 날짜별 트렌드를 시각화하는 도구였는데, 예전 같았으면 개발자 친구한테 부탁하거나 몇백만 원짜리 외주를 줬어야 할 작업이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;걸린 시간은 반나절이었습니다. 물론 한계는 있습니다. 복잡한 로직이나 고도화된 기능은 여전히 개발자 손이 필요합니다. 하지만 아이디어를 검증하는 수준의 프로토타입이라면, 이제 개발 전공이 필수가 아닙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Replit의 CEO Amjad Masad는 "앞으로 10억 명이 소프트웨어를 만들 것"이라고 했습니다. 과장 같죠. 그런데 YouTube가 처음 나왔을 때 "수억 명이 영상 크리에이터가 된다"는 말도 똑같이 허풍처럼 들렸습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;한국에서도 조짐이 보입니다. 국내 스타트업에서는 PM이 직접 프로토타입을 만들어 사용자 인터뷰를 돌리거나, 마케터가 데이터 분석 도구를 직접 만드는 사례가 늘고 있습니다. 개발자를 기다릴 필요 없이, 아이디어가 떠오른 그날 바로 테스트해 볼 수 있게 된 거죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;서비스를 만드는 사람들에게 생긴 실질적인 변화&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3681/3.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 픽사베이&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 변화가 기획자, PM, 창업자에게 구체적으로 뭘 의미할까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;첫째, 아이디어 검증 주기의 변화&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;기존 개발 사이클을 떠올려보세요. 아이디어 → 기획 → 개발 의뢰 → 개발 완료 → 테스트 → 수정 요청 → 재개발까지, 짧으면 몇 주, 길면 몇 달. 그 사이에 시장이 바뀌기도 합니다. 막상 만들어놓고 보니, 사용자가 원하는 게 전혀 다른 거였다는 걸 뒤늦게 알게 되기도 했죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제는 아이디어가 생기면 그날 바로 클릭 가능한 프로토타입을 만들 수 있습니다. 사용자한테 보여주고, 피드백 받고, 다음 날 고치면 됩니다. "최소한의 제품을 빠르게 만들고 사용자 반응을 보면서 방향을 잡자"는 린 스타트업 방법론, 그동안 이상에 가까웠던 "빠른 실험과 검증"이 이제야 현실이 된 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;둘째, 사라진 프로토타이핑 비용&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;예전에는 기능 하나 검증하려 해도 개발팀에 의뢰를 넣어야 했습니다. 개발팀 시간은 한정돼 있으니, "아직 검증 안 됐으니 보류"로 묻히는 아이디어가 수두룩했죠. 이제 프로토타입 만드는 비용이 거의 0입니다. 그만큼 더 많은 아이디어를 실험해 볼 수 있고, 많이 실험할수록 좋은 서비스가 나올 확률도 올라갑니다. 성공 방정식 자체가 달라진 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;셋째, 개발자와의 협업 방식이 바뀐다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;기획하는 사람과 개발하는 사람 사이에는 늘 번역의 문제가 있었습니다. 한쪽은 사용자 경험을 이야기하고, 한쪽은 기술적 제약을 이야기하고. 같은 서비스를 만들면서 서로 다른 언어로 대화하는 느낌이었죠. AI 코딩 도구가 이 간극을 줄여줄 수 있습니다. 기획자가 직접 프로토타입을 만들어서 "이런 느낌인데, 여기서 기술적으로 뭐가 어려워?"라고 물어볼 수 있게 되니까요. 말로 설명하던 걸 직접 보여주면서 대화하는 거라, 협업의 질이 확 달라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;비즈니스 관점에서 보면 어떨까요?&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;기회: 새로운 시장이 열린다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Acharya 말대로, 소프트웨어에 관심도 없던 사람들이 직접 만들기 시작했습니다. 교사가 자기 수업에 딱 맞는 학습 도구를 만들고, 의사가 자기 진료 방식에 맞는 기록 시스템을 만들고, 요리사가 레시피 관리 앱을 만듭니다. 개발자들이 "이런 게 왜 필요해?"라고 넘겼던 문제들을 이제 비개발자들이 직접 코딩를 하기 시작한 것이죠. 여기서 기존에 없던 서비스들이 나올 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;기회: 소프트웨어는 콘텐츠와 다르다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Acharya는 이렇게 말합니다. 콘텐츠는 올리는 순간부터 가치가 떨어집니다. 조회수 찍고 내려가죠. 반면 소프트웨어는 사용자가 쌓일수록 가치가 올라갑니다. 한번 잘 만들어놓으면 사용자가 늘고, 데이터가 쌓이고, 서비스가 좋아지는 선순환이 생깁니다. 개발 비용이 거의 0이 된 지금, 이 복리 효과를 누릴 수 있는 사람이 훨씬 많아진 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;위협: 나만 쉬운 게 아니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;기회가 있으면 위협도 있습니다. 나만 쉽게 만들 수 있는 게 아니라, 경쟁자도 쉽게 만들 수 있습니다. 내 제품과 비슷한 걸 누군가가 하루 만에 만들어서 무료로 뿌릴 수도 있는 거죠. 덕분에 비슷한 형식의 스마트폰 게임이 수백 개가 출시되고 있는 것처럼 말이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;a16z 글의 댓글에는 더 날카로운 지적도 있었습니다. "이런 작은 도구들은 결국 Claude나 ChatGPT 같은 대형 모델이 기능을 흡수해버리면 살아남기 어렵다. 도구를 만들게 해준 플랫폼이 곧 경쟁자가 되는 셈이다." 그러니까 이제는 "만들 수 있다"는 것만으로는 부족합니다. 누구를 위해, 어떤 문제를 풀고 있는지가 진짜 경쟁력이 되는 시대입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;위협: '만들 수 있다'와 '잘 만들었다'의 차이&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;YouTube가 나온 후 수억 개의 영상이 올라왔지만, 그중에서 실제로 사람들에게 가치를 주는 콘텐츠는 소수였습니다. 소프트웨어도 마찬가지일 겁니다. 누구나 만들 수 있게 되면, 오히려 "잘 만든 것"의 기준이 높아집니다. 사용자 경험, 제품 감각, 문제에 대한 깊은 이해 등 이런 것들이 더 중요해집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;지금부터 준비해야 할 것은?&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3681/4.png"&gt;&lt;figcaption&gt;&amp;lt;출처: Claude Code, 터미널 화면 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그렇다면 이 변화 앞에서 우리는 뭘 해야 할까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;첫째, AI 코딩 도구를 직접 써보세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이론으로 이해하는 것과 직접 써보는 것은 완전히 다릅니다. Cursor, Claude, v0(Vercel의 UI 생성 도구), Replit 중 하나를 골라서 본인이 평소에 "있으면 좋겠다"고 생각했던 간단한 도구를 직접 만들어보세요. 처음에는 느리고 답답하겠지만, 이 경험 자체가 엄청난 인사이트를 줍니다. 어디까지 가능한지, 어디서 막히는지, 어떤 도구가 어떤 작업에 맞는지가 보이기 시작합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;못 만든다고 생각했던 것들이 가능하다는 걸 느끼는 순간, 아이디어를 보는 눈이 달라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;둘째, 빠른 검증을 팀의 문화로 만드세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AI 코딩 도구가 주는 가장 큰 선물은 속도입니다. 그런데 도구만 빨라져서는 소용이 없습니다. 팀이 그 속도에 맞춰 움직여야 합니다. 완벽한 기획서를 기다리는 대신, 대충이라도 만들어서 사용자한테 보여주고 반응을 보는 거죠. 회의실에서 "이거 될까요?" 논쟁하는 시간에 그냥 뚝딱 만들어서 돌려보는 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;셋째, '무엇을 만들 것인가'에 고민해 보세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;아이러니하게도, 만드는 게 쉬워질수록 "뭘 만들지"가 더 중요해집니다. 누구나 만들 수 있으니까, 잘 만드는 건 더 이상 차별점이 아닙니다. 진짜 경쟁력은 풀어야 할 문제를 찾아내는 눈입니다. 사용자가 뭘 불편해하는지, 시장에 어떤 빈틈이 있는지, 이 문제가 정말 돈을 내고 해결할 만한 건지. 이건 아무리 AI가 좋아져도 대신 못 해주는 영역입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;유튜브도 마찬가지였습니다. 카메라를 잘 다루는 사람이 성공한 게 아니라, "이런 영상이 뜨겠지?"라고, 먼저 생각한 사람이 성공했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;넷째, AI 도구를 팀 전체가 쓸 수 있게 환경을 만드세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;개발팀만 AI를 쓸 이유가 없습니다. PM, 디자이너, 마케터 모두 각자 맡은 영역에서 AI 도구를 쓸 수 있어야 합니다. 간단한 가이드라인을 만들어두고, 누가 어떻게 쓰고 있는지 공유하는 자리를 만들어보세요. 한 팀원이 AI로 분석 시간을 반으로 줄였다면, 그걸 혼자 알고 있을 이유가 없습니다. 이런 변화를 개인이 아닌 팀이 함께 움직여야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;변명이 사라진 시대의 ‘진짜 경쟁력’&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;소프트웨어의 유튜브 모멘트가 왔다는 말은, 단순히 "이제 코딩 안 해도 된다"는 뜻이 아닙니다. 더 많은 사람들이 더 빠르게 더 많은 것을 만들 수 있게 됐다는 뜻이고, 그 말은 경쟁의 기준선 자체가 올라간다는 의미입니다. 유튜브가 서비스를 시작했을 때, 결국 살아남은 건 "누구나 만들 수 있으니 끝났다"고 겁먹은 사람이 아니라, 자기만의 관점과 이야기를 가진 사람이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;서비스를 만드는 사람들도 마찬가지입니다. "개발자가 없어서 못 만든다"는 말이 더 이상 안 통하는 시대에, 진짜 경쟁력은 뭘 만들지 아는 것, 누구를 위해 만드는지 아는 것, 그리고 빠르게 실험하고 배우는 것입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;도구의 문턱은 낮아졌습니다. 이제 남은 건 아이디어와 실행, 그리고 그걸 해볼 용기뿐입니다.&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;&amp;lt;참고&amp;gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;[a16z] &lt;a href="https://www.a16z.news/p/softwares-youtube-moment-is-happening"&gt;&lt;u&gt;Software's YouTube moment is happening now&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;[inference] &lt;a href="https://inferencebysequoia.substack.com/p/replit-ceo-amjad-masad-on-1-billion-173"&gt;&lt;u&gt;Replit CEO Amjad Masad on 1 Billion Developers: A Better End State than AGI&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>누구도 알려주지 않는 AWS 보안의 첫 번째 원칙</title><link>https://yozm.wishket.com/magazine/detail/3679</link><description>흠뻑 젖은 채로 리조트 방 앞에 서서야 깨달았습니다. “아, 방에서 키 안 가지고 나왔다….” 호텔이나 리조트에 놀러 다니다 보면 쉽게 이런 상황을 마주하기도 합니다. 만약 잃어버린 것이 호텔 키가 아니라 개인이나 회사의 클라우드 인프라 열쇠였다면 어떨까요? 누군가 내 클라우드 계정에 접근해 고객들의 개인정보를 탈취하고, 심지어 서비스까지 중단시킬 수도 있습니다. 위시켓 클라우드팀에서 업무상 수많은 AWS 계정을 관리하는 제게, 이러한 사건은 남의 이야기가 아닙니다. 그런 경험을 바탕으로 클라우드 보안에서 가장 흔하면서도 가장 위험한 실수 하나에 관해 설명해 보려고 합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3679</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;&lt;i&gt;이 글은 위시켓과 함께 요즘IT 브랜디드 콘텐츠로 제작했습니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;흠뻑 젖은 채로 리조트 방 앞에 서서야 깨달았습니다. “아, 방에서 키 안 가지고 나왔다….” 수영장에 다녀오며 카드키를 방에서 안 가지고 나왔던 겁니다. 결국 수영복 차림으로 떨며, 멀리 떨어진 프론트 데스크까지 걸어가서 새 키를 받으러 갔습니다. 지난 겨울 휴가 때 제 이야기입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;호텔이나 리조트에 놀러 다니다 보면 쉽게 이런 상황을 마주하기도 합니다. 평소 결제와 신분증 확인을 모두 휴대폰으로 해결하다 보니, 지갑 없이 폰 하나로 다니는 데 익숙하기 때문입니다. 호텔 카드키를 따로 챙기는 일은 꽤 번거롭게 느껴졌고, 때로는 방에 두고 나오거나 심지어 밖에서 잃어버리고 오는 일도 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;밖에서 놀다가 호텔 키를 잃어버리면 어떻게 될까요? 카드키를 받을 때는 호텔 측에서 작은 종이 케이스에 방 번호를 적어 주기도 하는데요, 이 경우 누구나 제 호텔 방에 들어올 수 있게 됩니다. 만약 그 열쇠를 잃어버린 사실조차 모른 채 방을 방치해 둔다면 어떨까요? 방에 있던 짐은 그대로 도난당하고, 파손된 가구나 전자제품에 대해 호텔 측에 변상해야 할 수도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image8.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 만약 잃어버린 것이 호텔 키가 아니라 개인이나 회사의 클라우드 인프라 열쇠였다면 어떨까요? 마찬가지로 누군가 내 클라우드 계정에 접근해 고객들의 개인정보를 탈취하고, 심지어 서비스까지 중단시킬 수도 있습니다. 실제로 &lt;a href="https://www.theregister.com/2014/06/18/code_spaces_destroyed/"&gt;&lt;u&gt;2014년&lt;/u&gt;&lt;/a&gt;, 한 기업은 클라우드 열쇠를 탈취당해 모든 데이터와 백업이 삭제되었고, 회사는 영구 폐업했다고 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;위시켓 클라우드팀에서 업무상 수많은 AWS 계정을 관리하는 제게, 이러한 사건은 남의 이야기가 아닙니다. 그런 경험을 바탕으로 클라우드 보안에서 가장 흔하면서도 가장 위험한 실수 하나에 관해 설명해 보려고 합니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;클라우드의 두 가지 자격 증명&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;요즘 메리어트나 IHG 같은 호텔 체인에서는 모바일 키를 지원합니다. 이런 모바일 키가 있었다면 카드키를 두고 나와도 당황하는 일은 없었을 것입니다. 또, 카드키를 잃어버리더라도 제 얼굴 인증 없이는 모바일 키를 사용할 수 없을 겁니다. &lt;span style="color:#757575;"&gt;(실제로 메리어트 본보이 앱은 모바일 카드키 사용 시 페이스 아이디를 요구합니다.)&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;클라우드에서도 이처럼 전통적인 키와 모바일 키처럼 두 가지 인증 방식이 존재합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;첫 번째 증명: 카드 키 방식&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;우리는 호텔에 도착하면 보통 프론트 데스크에서 카드키를 받습니다. 서울의 호텔, 도쿄의 호텔, 뉴욕의 호텔 모두 호텔마다 프론트에서 각각 다른 카드키를 받아야 합니다. 만약 잃어버린다면 어떨까요? 누군가 주워 제 방에 들어갈 수도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AWS의 인증 열쇠를 잃어버리면, 호텔 열쇠와는 비교할 수 없을 만큼 심각한 문제가 발생할 수 있습니다. 특히, 호텔의 카드키는 최소한 체크아웃 날짜가 지나면 만료됩니다. &lt;span style="color:#757575;"&gt;(그래서 일부 호텔에서는 카드키를 기념으로 가져가게 해주기도 합니다.)&lt;/span&gt; 반면 AWS의 장기 자격 증명인 IAM 접근 키는 마치 쇠로 된 열쇠와 같습니다. 누군가 직접 문에 달린 자물쇠를 바꾸지 않는 한 꾸준히 작동합니다. 게다가 쇠 열쇠보다 복제하기도 쉽습니다. 두 줄의 문자열을 복사해 붙여넣기만 하면 되기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;두 번째 증명: 모바일 키 방식&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;반면 모바일 키는 조금 다릅니다. 예를 들어 메리어트 호텔의 모바일 키는 본사에서 중앙 관리됩니다. 하나의 메리어트 계정만 있으면 호텔 지점과 관계없이 어디서든 체크인하고 모바일 키로 객실 문을 열 수 있도록요. 심지어 동시에 예약한 호텔이 두 곳이라면, 하나의 휴대폰으로 두 객실을 모두 열 수도 있습니다. 또, 제 휴대폰이기 때문에 얼굴과 같은 생체 정보 없이는 사용할 수 없습니다. 여기에 체크아웃 이후에는 별도의 관리가 필요하지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AWS에서도 마찬가지입니다. 저는 하루에도 여러 번 AWS 계정을 오가며 작업하는데, 로그인할 때마다 각 계정의 아이디와 비밀번호를 모두 알아야 한다면 매우 번거로운 일이 될 것입니다. 그래서 모바일 키 방식을 적극 사용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;장기 기억 증명 vs. 단기 자격 증명&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AWS에서는 이 두 가지를 다음과 같이 구분합니다. 카드키, 마치 호텔의 쇠 열쇠 같은 방식은 &lt;strong&gt;장기 자격 증명&lt;/strong&gt;&lt;span style="color:#757575;"&gt;(long-term credential)&lt;/span&gt;이라고 부릅니다. 반면 모바일 키와 같은 방식은 &lt;strong&gt;단기 자격 증명&lt;/strong&gt;&lt;span style="color:#757575;"&gt;(short-term credential)&lt;/span&gt;이라고 합니다. 한 번 만들어지면 열쇠구멍이 바뀌지 않는 한 쓸 수 있는 쇠 열쇠와 달리, 모바일 키는 사용할 때마다 제 생체 인증이 필요하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;장기 자격 증명의 대표적인 예는 AWS IAM&lt;span style="color:#757575;"&gt;(Identity and Access Management)&lt;/span&gt;의 &lt;strong&gt;접근 키&lt;/strong&gt;&lt;span style="color:#757575;"&gt;(Access Key)&lt;/span&gt;입니다. 이 접근 키는 두 줄의 문자열로 이루어져 있습니다. 한 번 생성되면 그 자체로는 만료되지 않는 특징도 가집니다. 또한 문자열 형태이기 때문에 누구에게나 복사해 전달할 수 있습니다. 카카오톡으로 주고받거나, 코드에 들어간 채 클라우드나 깃허브와 같은 원격 저장소에 업로드될 수도 있습니다. 이처럼 발급된 키를 삭제하려면 해당 계정에서 직접 삭제해야 합니다. 호텔마다 프론트 데스크에서 카드키를 따로 발급하듯, 각 AWS 계정에서 개별적으로 생성하고 관리합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 단기 자격 증명은 &lt;strong&gt;IAM 자격 증명 센터&lt;/strong&gt;&lt;span style="color:#757575;"&gt;(IAM Identity Center)&lt;/span&gt;&lt;strong&gt;를 통해 발급&lt;/strong&gt;됩니다. 호텔 체인 본사가 앱을 통해 키를 관리하듯, AWS 조직&lt;span style="color:#757575;"&gt;(AWS Organization, 여러 계정을 하나로 묶어 관리하는 단위)&lt;/span&gt;의 관리 계정에서 중앙으로 관리됩니다. 하나의 사용자로 여러 AWS 계정에 접근할 수 있다는 점도 특징입니다. 로그인할 때는 다단계 인증&lt;span style="color:#757575;"&gt;(Multi-Factor Authentication, MFA)&lt;/span&gt;을 거쳐야 하며, 인증이 완료되면 임시 토큰이 발급됩니다. 이 토큰은 사전에 설정된 일정 시간이 지나면 만료되고, 로그인할 때마다 새로 발급됩니다. 만료 이후에는 별도로 신경 쓸 필요가 없습니다. 알아서 사라지니까요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image2.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude로 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image1.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;AWS 접근 키를 잃어버리면, 어떤 사고가 날까요?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AWS 접근 키를 잃어버리면 어떻게 될까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 열쇠에는 만료일이 없고, 복제도 매우 쉽습니다. 사실 키 값이 그리 길지도 않아 마음만 먹으면 외울 수도 있는 수준입니다. 누가 복사했는지, 복사본이 몇 개나 존재하는지도 알 수 없습니다. 누군가 자물쇠를 바꾸기 전까지 그 열쇠의 복사본을 가진 누구든 언제든 문을 열 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;키 유출이 악용으로 이어진 시간&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이에 대한 &lt;a href="https://www.comparitech.com/blog/information-security/github-honeypot/"&gt;&lt;u&gt;실험&lt;/u&gt;&lt;/a&gt;이 있습니다. 보안 연구팀 Comparitech는 AWS 자격 증명을 공개 깃허브 리포지토리에 일부러 올려두었습니다. 결과는 충격적이었습니다. 첫 번째 악용이 1분 이내에 발생했습니다. 1분입니다. 음료수 한 모금 마시기도 전에, 누군가 그 열쇠로 문을 열고 들어온 셈입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이건 우연이 아닙니다. 팔로알토 네트워크의 Unit 42 팀이 추적한 &lt;a href="https://unit42.paloaltonetworks.com/malicious-operations-of-exposed-iam-keys-cryptojacking/"&gt;&lt;u&gt;EleKtra-Leak 캠페인&lt;/u&gt;&lt;/a&gt;에 따르면, 공격자들은 깃허브에 노출된 AWS 자격 증명을 자동으로 스캔하고 있었습니다. 키가 노출되면 평균 5분 이내에 악용이 시작됐고, 탈취한 키로 수백 대의 EC2 인스턴스를 생성해 암호화폐를 채굴했습니다. 이 캠페인은 2020년부터 최소 3년간 지속되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;우버 역시 비슷한 &lt;a href="https://www.breaches.cloud/incidents/uber/"&gt;&lt;u&gt;사례&lt;/u&gt;&lt;/a&gt;를 겪었습니다. 2013년에 생성된 다음, 한 번도 교체되지 않은 접근 키가 깃허브 리포지토리에서 발견됐고, 곧바로 5,700만 건의 고객 데이터가 유출되었습니다. 이어 1억 4,800만 달러의 벌금이 부과되었고, 보안 책임자(CISO)는 형사 유죄 판결을 받았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;키 유출을 알아챌 때까지 걸리는 시간&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;그렇다면 규모는 어느 정도일까요? &lt;a href="https://www.gitguardian.com/state-of-secrets-sprawl-report-2025"&gt;&lt;u&gt;깃가디언&lt;/u&gt;&lt;/a&gt;의 2025년 보고서에 따르면, 2024년 한 해 동안 공개 깃허브에서 유출된 암호 키는 2,380만 개에 달합니다. 이는 전년 대비 25% 증가한 수치입니다. 더 무서운 점은, &lt;strong&gt;2022년에 유출된 키의 70%가 2025년에도 여전히 유효하다는 사실&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image4.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude로 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러니까 이들은 열쇠가 탈취되었는데도 자물쇠를 바꾸지 않은 것입니다. 무려 3년 동안이나요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;왜 바꾸지 않았을까요? 정확히는, 바꾸지 못했을 겁니다. 유출 사실을 몰라 바꾸지 않았을 수도 있고, 혹은 그 과정에서 기존에 정상적으로 작동하던 서비스에 영향을 줄까 걱정했을 수도 있습니다. 호텔에 비유하면, 객실 문고리를 전부 교체하는 바람에 기존 열쇠를 가진 직원들이 객실 청소를 못하게 되는 상황과 비슷합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그렇다면 모바일 키, 즉 단기 자격 증명이 유출된다면 어떨까요? 애초에 임시 토큰은 복사나 공유를 전제로 만들어진 값이 아닙니다. 또한 다단계 인증을 거쳐 발급되기 때문에 이를 굳이 복사해 전달할 상황 자체가 많지 않습니다. 즉, 유출 경로 자체가 상대적으로 적습니다. 설령 유출되더라도 이 키는 수 시간 내에 자동으로 만료됩니다. 체크아웃 이후의 키카드처럼, 만료된 토큰은 의미 없는 문자열에 불과합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;그래도 감시 카메라(CloudTrail)가 있지 않나요?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;호텔에 CCTV가 있듯, AWS에는 클라우드트레일&lt;span style="color:#757575;"&gt;(CloudTrail)&lt;/span&gt;이라는 서비스가 있습니다. 누가 언제 어떤 작업을 했는지, 모든 API 호출을 기록하는 서비스입니다. 장기 자격 증명이든 단기 자격 증명이든, 예외 없이 모두 기록됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image5_BD9XkHd.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;문제는 기록이 남는 것과 범인을 특정하는 것은 별개의 문제라는 점입니다. 모바일 키 방식, 즉 IAM 자격 증명 센터를 통한 접근은 기록이 비교적 명확합니다. “김승빈이 오후 2시 13분에 서울 호텔 503호에 들어갔다”처럼, 사용자 누구가 무슨 계정에서 어떤 작업을 했는지 신원을 특정할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:50%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image7.png"&gt;&lt;figcaption&gt;실제 위시켓에서 활용중인 추척 봇 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 접근 키를 사용하면 기록에는 키 ID만 남습니다. 해당 키를 원래 주인이 사용한 것인지, 복사본을 가진 누군가가 사용한 것인지 구분할 수 없다는 뜻입니다. CCTV에 정문으로 자연스럽게 들어오는 사람이 찍혔지만, 그 사람이 실제 투숙객인지 열쇠를 주운 사람인지 알 수 없는 상황과 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;즉, 감시 카메라가 존재하더라도 범인이 정당한 열쇠를 들고 정문으로 들어온다면 이를 의심하기는 어렵습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;게다가 클라우드트레일에는 또 하나의 치명적인 한계가 있습니다. 기본 설정에서는 녹화 기록이 90일만 보관되며, 기간이 지나면 로그는 자동으로 삭제된다는 겁니다. 더 오래 보관하려면 별도의 저장소를 직접 설정해야 합니다. 클라우드트레일의 존재 자체를 모르는 경우도 적지 않고, 알고 있더라도 사건이 발생한 이후에야 CCTV를 돌려보듯 로그를 확인하는 경우가 비일비재합니다. 심지어 필요한 로그를 제대로 찾지 못하는 상황도 흔하죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;따라서 실시간으로 이상 징후를 탐지하는 체계가 무엇보다 중요합니다. AWS에는 이러한 감지기 역할을 하는 다양한 서비스가 있기 때문에, 상황에 맞게 활용하면 보다 선제적으로 계정을 보호할 수 있습니다. &lt;span style="color:#757575;"&gt;(더 자세한 내용은, 글이 호응을 얻는다면 후속 편에서 준비해 보겠습니다.)&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image3.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude로 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마스터 키인 루트 사용자(Root User) 관리하기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;지금까지 이야기한 접근 키는 호텔 객실 하나를 열어주는 열쇠에 비유할 수 있습니다. 그런데 이 호텔에는 &lt;strong&gt;마스터 키&lt;/strong&gt;가 존재한다면 어떨까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AWS 계정에는 루트 계정 사용자(Root Account User)라는 특별한 사용자가 있습니다. 계정을 처음 생성할 때 만들어지는 이 사용자는 해당 계정 내 모든 리소스에 접근할 수 있습니다. 서버를 생성하거나 삭제하는 것은 물론이고, 다른 IAM 사용자를 만들고 권한을 변경하거나, 심지어 계정 자체를 폐쇄하는 것까지 합니다. 호텔 체인 전체를 열 수 있는 마스터 키와 같은 존재입니다. 어떤 객실이든, 어떤 금고든 열 수 있는 열쇠입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;일반 사용자&lt;span style="color:#757575;"&gt;(IAM User)&lt;/span&gt;의 권한을 아무리 잘 설정해두더라도, 루트 계정 사용자가 탈취되면 모든 보안은 무력화됩니다. 공격자가 이 마스터 키를 손에 넣는 순간, 다른 열쇠로는 대응할 방법이 사실상 사라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Root User의 두 가지 자격 증명&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이 루트 계정 사용자 역시 IAM 사용자와 마찬가지로 두 가지 자격 증명을 가집니다. 하나는 이메일 주소와 비밀번호로, AWS 콘솔(웹사이트)에 로그인할 때 사용합니다. 다른 하나는 접근 키로, 앞서 설명한 것과 동일한 두 줄의 문자열입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AWS 공식 문서는 이 두 가지 모두에 대해 강하게 &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/root-user-best-practices.html"&gt;&lt;u&gt;경고&lt;/u&gt;&lt;/a&gt;합니다. 콘솔 로그인에 대해서는 “루트 계정 사용자가 필요한 작업이 아니면 사용하지 마세요”라고 안내하며, 접근 키에 대해서는 아예 “생성하지 마세요”라고 명시합니다. 그러나 아이러니하게도 접근 키를 생성하는 버튼은 콘솔에 버젓이 존재합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;부주의하게 만약 이 마스터 키를 유출했다면 어떻게 될까요? 글의 서두에서 잠깐 언급했던 코드 스페이스 사건이 바로 그 사례입니다. 2014년, 공격자는 루트 계정을 얻어 코드 스페이스의 AWS 콘솔 접근 권한을 탈취했습니다. 회사가 대응을 시도하자 공격자는 서버와 저장소, 백업 등 복구 가능한 모든 리소스를 삭제해버렸습니다. 결국 코드 스페이스는 영구적으로 폐업했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;모바일 키로 바꿔라&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;지금까지의 이야기를 정리하면 이렇습니다. 쇠 열쇠(IAM 접근 키)는 만료되지 않고, 복제가 쉽고, 누가 사용하는지 구별하기 어렵습니다. 한 번 유출되면 회수도 거의 불가능합니다. 여기에 마스터 키(루트 계정 사용자)까지 유출된다면, 사실상 대응 자체가 불가능해집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;물론 열쇠를 잃어버려 나오는 이 머리 아픈 상황에 대한 해법은 이미 정해져 있습니다. 모바일 키로 바꾸는 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;AWS도 권장하는 해법&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;IAM 자격 증명 센터는 AWS가 제공하는 모바일 키 시스템입니다. 이 시스템은 AWS 조직 관리 계정에서 모든 멤버 계정의 사용자와 권한을 통합 관리합니다. 로그인할 때마다 MFA를 거쳐야 하고, 인증이 완료되면 임시 토큰이 발급됩니다. 이 토큰은 일정 시간이 지나면 자동으로 만료됩니다. 또, 그렇기에 누가 어떤 계정에서 어떤 작업을 했는지 기록도 명확하게 남습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/image6.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 이 개념은 새로 등장한 규정은 아닙니다. AWS는 2017년 AWS SSO라는 이름으로 이 서비스를 처음 출시했고, 2022년 IAM 자격 증명 센터로 이름을 변경하며 공식 권장 방식으로 자리 잡았습니다. 이어 2025년에는 공식 블로그에서 “&lt;a href="https://aws.amazon.com/blogs/security/beyond-iam-access-keys-modern-authentication-approaches-for-aws/"&gt;&lt;u&gt;장기 IAM 접근 키를 넘어서라&lt;/u&gt;&lt;/a&gt;”는 제목의 글까지 발행했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그럼에도 불구하고 많은 개발자가 여러 이유로 IAM 사용자와 접근 키를 씁니다. 아주 큰 글씨로 경고가 적힌 공식 문서를 충분히 읽지 못했을 수도 있고, 코딩 에이전트가 생성한 설정을 의심없이 신뢰했을 수도 있습니다. 또는 문제를 알면서도 관성적으로 기존 방식을 고수했을 지도 모릅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서일까요? 접근 키를 코드에 포함한 채 깃허브에 올렸다는 이야기를 개발자라면 한 번쯤은 들어봤을 겁니다. 그렇게 여전히 2024년 한 해에만 2,380만 개의 암호 키가 유출되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;보안 시스템을 직접 구축하기 어렵다면?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;문제는 현실은 녹록지 않다는 겁니다. AWS 조직을 구성하고, IAM 자격 증명 센터를 설정하며, 사용자와 권한을 관리하고, 클라우드트레일 로그를 별도 저장소에 백업하는 일까지, 이 모든 과정을 직접 수행하려면 AWS 보안에 대한 전문 지식이 필요합니다. “개발자라면 이런 것쯤은 다 알지 않을까?”라고 생각할 수도 있습니다. 하지만 병원에서 수술을 받을 때도 외과 의사와 마취과 의사가 각자의 역할을 맡듯, DevSecOps나 클라우드 전문가 없이 이를 구축하는 일은 쉽지 않습니다. 중요한 보안 관련 일을 AI 모두에게 맡기는 것도 찝찝하고요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 직접 개발을 하지 않고 외주 개발사에 맡기는 경우도 마찬가지입니다. 개발 과정에서 외주 개발사가 접근 키를 실수로라도 유출하지 않았다고 확신할 수 있을까요? 임시 자격 증명 운용이 번거롭다는 이유로, 두 줄짜리 문자열을 복사해 여러 곳에서 사용하고 있을 가능성도 있습니다. 또한 AWS에 대한 기초 지식이 부족하다면, 외주 개발이 끝난 다음 불필요한 사용자나 접근 키가 모두 정리되었는지 확인하기도 어렵습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 그래서 저는 위시켓에서 이런 일을 대신합니다. &lt;a href="https://www.wishket.com/vault/"&gt;&lt;u&gt;안심 호스팅 서비스&lt;/u&gt;&lt;/a&gt;라는 것을 운영하며 AWS 계정 생성부터 IAM 자격 증명 센터 사용자 생성, 권한 관리를 고객을 대신해 설정하고 운영합니다. 불필요한 리전에서의 서버 생성을 차단하고, 클라우드트레일 로그를 삭제하는 행위도 막습니다. 또한 보안에 취약한 IAM 사용자나 접근 키 생성 자체를 원천적으로 제한합니다. 정책은 누구든 예외 없이 적용됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3679/wishket_vault.png"&gt;&lt;figcaption&gt;위시켓 안심 호스팅 서비스 &amp;lt;출처: 위시켓&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;물론 서비스 홍보도 홍보지만, 저희한테 맡기지 않더라도 모바일 키로의 전환은 꼭 검토했으면 합니다. 위시켓 클라우드팀에서 근무하다 보니, 탈취된 자격 증명으로 뭄바이나 스톡홀름과 같은 예상치 못한 리전에 서버가 만들어지고, 암호화폐 채굴에 악용되는 사례를 직접 목격한 적도 있습니다. 보안 규칙을 매일 고민하고 다루는 입장에서 가장 쉬운 일을 두고 큰 피해를 입는 고객사를 보며, 그 지식을 전하고 싶었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 다시 한 번 강조하려고 합니다. 애초에 열쇠를 만들지 않는다면 잃어버릴 열쇠도 존재하지 않습니다. AWS 스스로가 말하듯 쇠 열쇠를 내려놓고, 모바일 키로 바꿔야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기회가 된다면, IAM 자격 증명 센터의 기술적인 부분을 더 깊이 다뤄볼 예정입니다. 실제로 모바일 키를 어떻게 설정하고, 어떤 구조로 동작할지, 그 내부 구조를 열어보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>하네스 경쟁의 시작, 왜 opencode와 OMO일까?</title><link>https://yozm.wishket.com/magazine/detail/3676</link><description>LLM의 스케일링 법칙(Scaling Laws)은 이제 한계라는 의견이 많습니다. 더욱이 SLM을 특정 작업에 맞춰 최적화하고, 고품질 데이터로 재학습시키며, 나아가 MoE 구조로도 활용합니다. 특히 신규 LLM 모델은 실제로 “체감할 수 있는 차이”에 있어서, “구체적으로, 그리고 정량적으로 우리의 작업이 얼마나 나아졌는가”를 설명하기가 매우 어려워졌습니다. 모델 경쟁이 끝난 것은 아닙니다. 하지만 차별화의 중심축은 이미 윗단 레이어로 올라가고 있습니다. 특히 코딩, 리서치, 마이그레이션, 대규모 리팩토링처럼 길고 복잡한 작업에서는 “한 번 잘 답하는가”보다 “끝까지 안정적으로 완주하는가”가 훨씬 중요합니다. 그리고 그 완주 능력을 만들어내는 것이 바로 에이전트 하네스(Agent Harness)입니다.</description><guid>https://yozm.wishket.com/magazine/detail/3676</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;모델 경쟁이 끝나고, ‘하네스 경쟁’의 시작?!&lt;/strong&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;LLM을 평가하는 기준은 빠르게 바뀌고 있습니다. 이제는 “모델이 얼마나 똑똑한가”만으로 체감 품질을 설명하기 어렵습니다. 실제 현업에서의 생산성은 긴 작업을 얼마나 안정적으로 이어갈 수 있는지, 그리고 도구·컨텍스트·검증 루프를 얼마나 잘 운영하는지에 따라 갈립니다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;LLM의 스케일링 법칙(Scaling Laws)은 이제 한계라는 의견이 많습니다. (&lt;a href="https://velog.io/@qlgks1/LLM-Intro-to-Large-Language-Models#8-%EC%84%B1%EB%8A%A5%EC%9D%84-%EB%86%92%EC%9D%B4%EB%8A%94-%EC%97%B4%EC%87%A0-%EC%8A%A4%EC%BC%80%EC%9D%BC%EB%A7%81-%EB%B2%95%EC%B9%99scaling-laws"&gt;참조 링크&lt;/a&gt;) 더욱이 SLM을 특정 작업에 맞춰 최적화하고, 고품질 데이터로 재학습시키며, 나아가 MoE 구조로도 활용합니다. 특히 신규 LLM 모델은 실제로 “체감할 수 있는 차이”에 있어서, &lt;i&gt;“구체적으로, 그리고 정량적으로 우리의 작업이 얼마나 나아졌는가”&lt;/i&gt;를 설명하기가 매우 어려워졌습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;모델 경쟁이 끝난 것은 아닙니다. 하지만 차별화의 중심축은 이미 윗단 레이어로 올라가고 있습니다. 특히 코딩, 리서치, 마이그레이션, 대규모 리팩토링처럼 길고 복잡한 작업에서는 “한번 잘 답하는가”보다 “끝까지 안정적으로 완주하는가”가 훨씬 중요합니다. 그리고 그 완주 능력을 만들어내는 것이 바로 &lt;strong&gt;에이전트 하네스(Agent Harness)&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/2.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, AI 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;하네스란?&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;에이전트 하네스는 AI 모델을 감싸고, 장기적이거나 복잡한 작업을 안정적으로 수행하도록 관리하는 운영 인프라에 가깝습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;모델이 문장을 생성하는 엔진이라면, 하네스는 그 엔진 위에 올라가는 차량의 프레임, 조향 장치, 브레이크, 계기판처럼 사람의 승인 지점, 파일 시스템 접근 제어, 도구 호출 순서, 하위 에이전트 협업, 프롬프트 프리셋, 실패 복구까지 묶어 실제로 “작동하는 시스템”으로 만드는 레이어(layer)입니다. (참조: &lt;a href="https://aakashgupta.medium.com/2025-was-agents-2026-is-agent-harnesses-heres-why-that-changes-everything-073e9877655e"&gt;2025 Was Agents. 2026 Is Agent Harnesses. Here’s Why That Changes Everything.&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;‘Opencode’란?&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 정의 및 배경&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;OpenCode는 스스로를 &lt;i&gt;&lt;strong&gt;오픈소스 AI 코딩 에이전트로&lt;/strong&gt;&lt;/i&gt; 소개하며, 터미널 기반 인터페이스, 데스크톱 앱, IDE 확장 형태로 사용할 수 있습니다. LSP 지원, 멀티 세션, 세션 공유 링크, 다양한 모델 프로바이더 연결을 핵심 특성으로 내세웁니다. 즉 OpenCode는 단순한 “채팅형 코딩 도구”라기보다, 에이전트를 실행하는 런타임에 더 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;LSP 기반 코드 이해(심볼/정의/진단 등)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;멀티 세션(작업별 세션 관리)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;플러그인 지원(동작 확장)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;결과 공유(링크 공유) 및 팀 사용 시나리오&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;즉, OpenCode 자체가 이미 &lt;i&gt;&lt;strong&gt;“에이전트 실행기 + 도구 런타임 + 세션 관리자”&lt;/strong&gt;&lt;/i&gt; 성격을 갖고 있고, 그 위에 플러그인을 얹어 하네스 역량을 키우는 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 작동 원리&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;아주 기본적인 개념은 "다양한 LLM 들을 하나의 tool에서 모아서 사용"이라는 점에서 크게 다르지 않습니다. 세션 단위로 작업 컨텍스트를 유지하며, 사용자는 TUI에서 입력/전환/실행을 수행합니다. &lt;i&gt;&lt;strong&gt;(실행 시 TUI와 HTTP 서버가 함께 뜨는 client/server architecture)&lt;/strong&gt;&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/3.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최근에는 &lt;code&gt;mode&lt;/code&gt; 보다 &lt;code&gt;agent&lt;/code&gt; 구성이 중심이지만, 사용 경험상 여전히 많은 분들이 &lt;code&gt;Build&lt;/code&gt; 와 &lt;code&gt;Plan&lt;/code&gt; 을 “모드”처럼 이해하고 있습니다. (물론 저도요.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;내장 &lt;strong&gt;primary agent&lt;/strong&gt;는 &lt;code&gt;Build&lt;/code&gt; 와 &lt;code&gt;Plan&lt;/code&gt; 이고, &lt;strong&gt;subagent&lt;/strong&gt;로는 &lt;code&gt;General&lt;/code&gt; 과 &lt;code&gt;Explore&lt;/code&gt; 가 제공됩니다. (근데 다들 각자 플러그인을 많이 사용하다 보니 순정을 보기 힘들어진 기분)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;Build&lt;/code&gt; 는 일반 개발 작업용으로 모든 도구 접근이 열려 있고, 실제 편집, 패치, 명령 실행, 검증에 적합합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;Plan&lt;/code&gt; 은 파일 수정과 bash 실행을 제한하거나 승인 기반으로 다뤄 분석과 설계 중심으로 쓰이도록 설계되어 있고, 분석, 설계, 변경안 검토, 위험 식별에 적합합니다. (기본적으로 파일 수정과 bash 실행이&lt;code&gt;ask&lt;/code&gt; 로 제한됨)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;General&lt;/code&gt; 은 범용적이게 사용하고,&lt;code&gt;Explore&lt;/code&gt; 는 읽기 &amp;amp; 탐색 중심!&lt;/li&gt;&lt;li style="text-align:justify;"&gt;또 내부적으로는 &lt;code&gt;compaction&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;summary&lt;/code&gt; 같은 숨겨진 시스템 에이전트가 자동 실행된다고 합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 이런 접근은 이제 아주 일반화가 된 것 같습니다. 저 역시 바이브 코딩과 LLM에 대한 대규모 서베이, Augmented Coding 글과 같이 "plan"의 중요성을 매우 체감하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;사실 권한 제어와 LSP control이 핵심&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;권한 제어와 도구들의 디테일&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;권한은 &lt;code&gt;allow&lt;/code&gt;, &lt;code&gt;ask&lt;/code&gt;, &lt;code&gt;deny&lt;/code&gt;로 제어되고&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;read&lt;/code&gt;, &lt;code&gt;edit&lt;/code&gt;, &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;task&lt;/code&gt;, &lt;code&gt;lsp&lt;/code&gt;, &lt;code&gt;webfetch&lt;/code&gt;, &lt;code&gt;websearch&lt;/code&gt;, &lt;code&gt;codesearch&lt;/code&gt; 같은 항목별로 통제한다고 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;glob&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt; 는 내부적으로 &lt;code&gt;ripgrep&lt;/code&gt; 을 사용하며, &lt;code&gt;.gitignore&lt;/code&gt; 를 따른다고 하며 (디테일), 사실 LLM 기반으로 마치 Re-ACT agent, tool calling 처럼, 도구 호출 중심 실행 프레임워크로 만들어졌다고 보는 게 맞습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;LSP(Language Server Protocol)&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;LLM이 코드베이스와 상호작용 할 때 진단 정보(diagnostics)를 활용합니다. 또한 여러 언어에 대해 내장/자동 설치 LSP를 제공한다고 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;그래서 OpenCode는 단순히 파일 내용을 긁어서 모델에 던지는 수준이 아니라, 정적 분석 계층의 피드백까지 모델 루프 안으로 넣는 구조입니다. (그래서 토큰이 녹아내릴 수 있죠.)&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/4.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, AI 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 플러그인 시스템: 하네스가 붙는 자리&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;플러그인은 JavaScript/TypeScript "모듈 형태로 훅"을 내보내며, 로컬 플러그인 디렉터리 또는 &lt;code&gt;npm&lt;/code&gt; 패키지 방식으로 로드할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ol&gt;&lt;li style="text-align:justify;"&gt;로컬 파일: 프로젝트/전역 플러그인 디렉터리에 JS/TS 배치&lt;/li&gt;&lt;li style="text-align:justify;"&gt;npm 패키지: opencode.json의 plugin 배열에 패키지명을 등록&lt;/li&gt;&lt;/ol&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;npm 플러그인은 시작 시 Bun으로 자동 설치되며, 캐시는 &lt;code&gt;~/.cache/opencode/node_modules/&lt;/code&gt; 에 default로 저장됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;로드 순서는 &lt;strong&gt;[전역 config → 프로젝트 config → 전역 dir → 프로젝트 dir]&lt;/strong&gt; 입니다. 에이전트 하네스 쪽은 보통 설정 충돌, 훅 순서, 컨텍스트 주입 순서 때문에 디버깅이 어려운데, OpenCode는 적어도 플러그인이 어디서, 어떤 순서로 붙는지를 문서화해 둔 편입니다. 그래서 플러그인 생태계가 잘 만들어질 수 있었던 것 같습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4) 설치 &amp;amp; 세팅&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;다만 작성일 기준이라, &lt;a href="https://opencode.ai/ko"&gt;공식 홈페이지&lt;/a&gt;를 한 번 참고하시는 게 좋습니다. 최근에는 데스크톱 앱이 나온 것 같은데요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;code&gt;curl -fsSL https://opencode.ai/install | bash&lt;/code&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;역시 인기 있는 tool은 설치와 세팅이 아주 간단합니다. 설치 후 &lt;code&gt;opencode&lt;/code&gt; 로 실행이 끝입니다. 이후 &lt;code&gt;/connect&lt;/code&gt; 커맨드 활용해서 "프로바이더 (상용 LLM 포함 외부 LLM auth 세팅)" 세팅까지 이어가면 바로 사용 가능합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/5.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/6.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;‘OMO: Oh-my-opencode’란?&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 정의 및 배경&lt;/strong&gt;&lt;/h4&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;Oh My OpenCode는 공식 사이트에서 스스로를 &lt;strong&gt;“OpenCode 위에 올라가는 specialized orchestration layer”&lt;/strong&gt;라고 설명합니다. OMO는 OpenCode를 대체하는 별도 제품이 아니라, OpenCode 위에 에이전트, 훅, MCP, LSP, 설정값을 묶어 더 강한 운영 구조를 제공하는 플러그인입니다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그냥 “코드를 잘 써주는 도구”가 아니라,&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;복잡한 빌드 파이프라인 이해&lt;/li&gt;&lt;li style="text-align:justify;"&gt;다수 에이전트 병렬 실행&lt;/li&gt;&lt;li style="text-align:justify;"&gt;컨텍스트 관리&lt;/li&gt;&lt;li style="text-align:justify;"&gt;작업 지속성&lt;/li&gt;&lt;li style="text-align:justify;"&gt;세션 복구&lt;/li&gt;&lt;li style="text-align:justify;"&gt;문서 검색과 코드 탐색 자동화&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;를 기반으로 "잘 굴러가게 만드는 하네스" 를 지향합니다. "AI 팀"에 비유하며, 다수의 전문 에이전트(역할 분업), 스킬(워크플로 템플릿), 커맨드(/refactor 등), 훅(키워드 감지/복구/알림/컨텍스트 주입)을 묶어서 제공한다고 설명합니다. (&lt;a href="https://github.com/code-yeongyu/oh-my-opencode"&gt;플러그인 공식 깃헙 레포&lt;/a&gt;, &lt;a href="https://news.hada.io/topic?id=24978"&gt;관련 긱뉴스&lt;/a&gt;, &lt;a href="https://youtu.be/o-rE93-nLpY?si=y4calJcK_Bf4vcq7"&gt;제작자 유튜브 인터뷰(팟캐스트)&lt;/a&gt;)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image"&gt;&lt;img src="https://velog.velcdn.com/images/qlgks1/post/488c8818-b759-4b1d-99bc-72a857984e63/image.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, AI 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 style="text-align:justify;"&gt;&amp;nbsp;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) Oh-My-OpenCode의 “각 모드”는 무엇이며, 언제 쓰는가?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;OMO는 기본적으로 &lt;code&gt;Planner-Sisyphus&lt;/code&gt;, &lt;code&gt;Librarian&lt;/code&gt;, &lt;code&gt;Explore&lt;/code&gt;, &lt;code&gt;Oracle&lt;/code&gt; 같은 전문 에이전트를 제공합니다. &lt;code&gt;Sisyphus&lt;/code&gt;를 기본 오케스트레이터로 설명하고, &lt;code&gt;Prometheus&lt;/code&gt;, &lt;code&gt;Metis&lt;/code&gt; 같은 계획 보조 에이전트, 그리고 &lt;code&gt;frontend-ui-ux-engineer&lt;/code&gt;, &lt;code&gt;document-writer&lt;/code&gt;, &lt;code&gt;multimodal-looker&lt;/code&gt; 같은 역할 특화 에이전트가 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;다수 에이전트를 “AI 팀”으로 제공&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li style="text-align:justify;"&gt;Sisyphus: 기본 오케스트레이터(계획·위임·실행)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;Prometheus / Metis / Momus: 계획 수립·사전 점검·계획 리뷰&lt;/li&gt;&lt;li style="text-align:justify;"&gt;Oracle / Librarian / Explore: 설계·문서/OSS 리서치·코드베이스 탐색(쓰기 제한)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;document-writer: README, API 문서, 가이드 작성&lt;/li&gt;&lt;li style="text-align:justify;"&gt;multimodal-looker: PDF/이미지/다이어그램 분석&lt;/li&gt;&lt;/ol&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;code&gt;@&lt;/code&gt; 를 통해서 에이전트를 타겟할 수 도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/8.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) ultrawork, search, analyze는?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이게 지금의 OMO를 만들어준, 하이라이팅될 수 있던 feature들이 아닐까 싶습니다. OMO는 "키워드 기반 감지"로 하네스가 작동이 됩니다. &lt;code&gt;ultrawork&lt;/code&gt; 또는 &lt;code&gt;ulw&lt;/code&gt; 는 최대 성능 모드, &lt;code&gt;search&lt;/code&gt; 또는 &lt;code&gt;find&lt;/code&gt; 는 병렬 탐색 모드, &lt;code&gt;analyze&lt;/code&gt; 또는 &lt;code&gt;investigate&lt;/code&gt;는 심층 분석 모드로 안내됩니다. 또 &lt;code&gt;think deeply&lt;/code&gt;, &lt;code&gt;ultrathink&lt;/code&gt; 같은 표현은 &lt;code&gt;think mode&lt;/code&gt; 훅이 감지해 추론 설정을 조정한다고 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사용자가 “이번 작업의 성격”만 잘 말해도 하네스가 행동 방식을 바꿔주기 때문입니다. 즉, 프롬프트가 단순 지시문이 아니라, 오케스트레이션 정책을 바꾸는 신호가 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;ultrawork/ulw = 최대 성능 모드&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;ultrawork, 줄여서 ulw는 OMO README에서 사실상 “마법의 단어”처럼 소개됩니다. 공식 README 표현을 정리하면, 병렬 에이전트 실행, 백그라운드 작업, 적극적 탐색, 완료까지 밀어붙이는 성격을 가진 최대 성능 모드입니다. 대규모 리팩토링, 복잡한 마이그레이션, 여러 파일과 여러 축의 검증이 동시에 필요한 작업에 잘 맞습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;작업 범위가 크고(리팩토링/마이그레이션/대규모 기능 추가)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;실패 비용이 높고(프로덕션/핵심 모듈)&lt;/li&gt;&lt;li style="text-align:justify;"&gt;여러 축(리서치·코드·테스트·문서)을 병렬로 돌려야 할 때&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기본 오케스트레이터가 작업을 분해하고, 전문 에이전트를 공격적으로 병렬 실행하는 성격으로 설계돼 있다고 설명합니다. 즉 자체적으로 "각 업무 전문가에게 일을 할당하고, 평가하고, 리팩토링하고 등이 모두 묶여있습니다. (다음 섹션에서 저는 어떻게 ulw를 사용하는지 정리해 뒀습니다.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;search/find = 병렬 탐색 모드&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;이 모드는 빠른 코드베이스 탐색이 핵심입니다. OpenCode의 내장 &lt;code&gt;Explore&lt;/code&gt; 가 원래 읽기 전용 탐색 성격을 갖고 있는데, OMO는 이런 탐색 성격을 더 공격적으로 활용합니다. 레거시 프로젝트 진입점 찾기, 설정 파일 찾기, 실제 호출 경로 파악, 특정 동작이 어디서 시작되는지 확인할 때 특히 유용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;레거시 프로젝트 온보딩&lt;/li&gt;&lt;li style="text-align:justify;"&gt;특정 동작의 진짜 진입점/호출 경로를 찾아야 할 때&lt;/li&gt;&lt;li style="text-align:justify;"&gt;설정 파일/핵심 클래스/핫스팟 파일을 빠르게 식별해야 할 때&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;analyze/investigate = 심층 분석 모드&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;이 모드는 구현보다 해석과 판단에 가깝습니다. 장애 원인 분석, 설계 리뷰, 트레이드오프 비교, “왜 이런 구조가 되었는가”를 증거 기반으로 정리할 때 잘 맞습니다. 공식 사이트의 &lt;code&gt;Oracle&lt;/code&gt; 소개와 README 설명을 합치면, 코드 설명과 문제 진단, 아키텍처 판단을 보조하는 방향으로 이해할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;장애 재현이 어렵거나, 원인이 여러 후보로 갈릴 때&lt;/li&gt;&lt;li style="text-align:justify;"&gt;설계 결정을 내려야 하는데 트레이드오프가 복잡할 때&lt;/li&gt;&lt;li style="text-align:justify;"&gt;“왜 이 로직이 이렇게 됐는지”를 증거 기반으로 정리해야 할 때&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;문서는 oracle을 “아키텍처 결정/코드 리뷰/디버깅(읽기 전용)” 상담역으로 설명합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;think mode&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;Think mode는 구현 이전 사고 비용을 늘리는 장치입니다. “바로 고치지 말고 먼저 깊게 생각해라”라는 의도를 하네스 차원에서 반영합니다. 문제 정의가 불분명하거나, 정책과 SDK 제한을 함께 검토해야 하거나, 근거를 모아 판단해야 할 때 특히 유효합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;구현 이전에 문제 정의/요구사항 정리/리스크 식별이 필요할 때&lt;/li&gt;&lt;li style="text-align:justify;"&gt;장단점/대안 비교가 본질일 때&lt;/li&gt;&lt;li style="text-align:justify;"&gt;문서·정책·SDK 제한 때문에 “확실한 판단”이 필요한데 근거를 모아야 할 때&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;think-mode 훅이 관련 키워드를 감지해 모델 설정(extended thinking 등)을 조정한다고 명시합니다. (사견으로는 생각 자체에 회귀할 때가 있어서 적절한 결론에 대한 신호 체계를 만드는 게 좋습니다.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4) 설치 &amp;amp; 세팅&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;물론 &lt;code&gt;OpenCode&lt;/code&gt; 설치가 무조건 선행되어야 합니다. 하지만, 역시 간단합니다. (&lt;code&gt;bun&lt;/code&gt; 런타임이 필요합니다.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;code&gt;bunx oh-my-opencode install&lt;/code&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러면 세팅 가이드가 자동으로 안내해 줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/9.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실제 사용 예시 살펴보기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;일단 하나의 예시를 보면,&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/10.png"&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/11.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/gif1.gif"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;OMO의 &lt;code&gt;ulw&lt;/code&gt; 는 진짜 한 줄만 줘도 진정한 의미의 바이브 코딩을 합니다. "딸깍"이 가능하죠. 근데 제가 여전히 구시대적인 사람인지 몰라도 저는 이게 너무 와닿지 않습니다. 통제 가능성과 일관성, 규칙이 저에게는 너무 중요하기 때문이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 일단 플젝 세팅부터 제대로&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;1. 무엇을 만들어야 하는지 결정된다면&lt;/strong&gt;&lt;code&gt;&lt;strong&gt;stack&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;부터 정합니다.&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;이땐 리서치와 대화형 LLM만 사용합니다. 사실 통제 가능성이 중요하기에 제가 익히 잘 아는 stack에서 잘 벗어나지 않습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;대부분 ts, react + nextjs, nestjs, python, django + drf or ninja ... 가끔 rust 섞음&lt;/li&gt;&lt;li style="text-align:justify;"&gt;아직까진 모노레포를 선호하지는 않습니다. 최근에 모노레포로 한 번 했다가 AI markdown 세팅이나 AI rule 세팅이 더 복잡해져서 바로 버렸습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;code&gt;&lt;strong&gt;AGENTS.md&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;(CLAUDE.md 등 포함) 부터 출발합니다.&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;요즘은 &lt;code&gt;/init&lt;/code&gt;으로 직접 이 마크다운을 만드는 경우가 많지만, 저는 여전히, &lt;a href="https://velog.io/@qlgks1/Kent-Beck-Augmented-Coding"&gt;Augmented Coding&lt;/a&gt;에서 차용한 TDD와 Tidy code를 아주 적극적으로 사용합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;그래서 &lt;code&gt;AGENTS.md&lt;/code&gt; 에는 "논리적인 방법론" 들을 정리합니다. 기본적인 역할, TDD, Tidy First, Quality 등에 대해서요.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;디렉토리나 스택, 언어 등을 언급하지 않고, 대신 "SYSTEM_DESIGN.md 꼭 참조해라!"라는 인디케이터만 넣습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;3.&lt;/strong&gt;&lt;code&gt;&lt;strong&gt;SYSTEM_DESIGN.md&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;를 만듭니다.&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;일례로 아래와 같습니다. 제가 &lt;code&gt;python&lt;/code&gt;으로 작업할 땐 꼭 아래 시스템 디자인으로 출발합니다. 포인트는 &lt;code&gt;&lt;strong&gt;Do not over-apply design patterns&lt;/strong&gt;&lt;/code&gt;입니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;# SYSTEM_DESIGN

This document defines the core system design rules for this project.

---

## 1. Python Version &amp;amp; Typing

- We use **Python 3.13 or higher**.
- Do **not** use the `typing` module for type hints.
- Always use **built-in types** for annotations (e.g., `int`, `str`, `list`, `dict`, etc.).

---

## 2. Code Style

- Follow the **Google Python Style Guide**:
  - &amp;lt;https://google.github.io/styleguide/pyguide.html&amp;gt;
- Follow **PEP 8** (Python’s official style guide):
  - &amp;lt;https://peps.python.org/pep-0008/&amp;gt;

If there is any conflict between local conventions and these guides, prefer clarity and consistency within this project.

---

## 3. Object-Oriented Design

We favor **object-oriented programming (OOP)** and its core principles:

- **Encapsulation** – Group related data and behavior inside classes and hide internal details.
- **Abstraction** – Expose clear interfaces and hide unnecessary implementation details.
- **Inheritance** – Reuse behavior via well-designed base classes and subclasses when appropriate.
- **Polymorphism** – Design interfaces so that different implementations can be used interchangeably.

OOP should improve readability and maintainability, not add unnecessary complexity.

---

## 4. Architectural Pattern

- We **aim for a layered architecture pattern** (e.g., presentation, application/service, domain, infrastructure).
- Each layer should have a clear responsibility and minimal knowledge of other layers.

At the same time:

- Do **not** over-apply design patterns or split the codebase into too many tiny files.
- Avoid “architecture for architecture’s sake.”
- Aim for:
  - **Reasonable maintainability**
  - **Reasonable separation of concerns**
  - **Always pragmatic, balanced design**

In short, we prefer a **practical, moderately layered architecture** that is easy to understand, extend, and maintain, rather than a theoretically "perfect" but over-engineered structure.&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;이 파일에서 저는 "물리적인 방법론" 과 실제 구현 방향에 대해 정확하고 구체적으로 정리합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;특히 python 은 "빠르게, 저렴하게" 라는 측면에서 바이브코딩과 아주 맞닿아 있지만, 언어 특성때문에 볼륨이 조금만 커져도 무너져 내리더라구요. 1부터 10개 작업하면, 2번과 9번의 코드 스타일이 완전하게 달라지는 이슈도 빈번했구요.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;그래서 type 을 꽤나 엄격하게 다루는데, &lt;code&gt;mypy&lt;/code&gt; 보다는 &lt;code&gt;pyright&lt;/code&gt; 가 좀 더 유연한 측면에서 맞는 것 같네요.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;4.&lt;/strong&gt;&lt;code&gt;&lt;strong&gt;pre-commit&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;,&lt;/strong&gt;&lt;code&gt;&lt;strong&gt;ruff(eslint &amp;amp; prettier)&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;,&lt;/strong&gt;&lt;code&gt;&lt;strong&gt;test(pytest, jest)&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;세팅을 바로 합니다.&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;저는 &lt;code&gt;uv + ruff&lt;/code&gt; 으로 아래 기본 세팅은 하고 갑니다. 스크롤이 너무 길어져서 뺄까 했는데, 혹시나 다른 분들을 위해 설정값을 공유합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;(아래 pre-commit)&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;ci:
  autoupdate_schedule: monthly

default_language_version:
  python: python3.13

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-yaml
      - id: check-toml
      - id: check-added-large-files
      - id: check-merge-conflict
      - id: end-of-file-fixer
      - id: trailing-whitespace

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.15.0
    hooks:
      - id: ruff
        args: [--fix, --exit-non-zero-on-fix]
      - id: ruff-format

  - repo: https://github.com/astral-sh/uv-pre-commit
    rev: 0.10.2
    hooks:
      - id: uv-export
        args:
          - --frozen
          - --no-dev
          - --no-hashes
          - --output-file=requirements.txt
          - --quiet&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;(아래 toml에서 기본 설정들)&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;# ================================================================
# Ruff (Linter &amp;amp; Formatter) Settings
# ================================================================
[tool.ruff]
# 수정에서 제외할 파일 및 디렉토리 목록
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".hg",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "venv",
    "*/migrations/*.py",
]
# 한 줄의 최대 글자 수
line-length = 100

# --- Linter (코드 분석기) 설정 ---
[tool.ruff.lint]
# 활성화할 규칙 선택:
# E, W: pycodestyle (에러, 경고)
# F: Pyflakes (논리적 오류)
# I: isort (import 정렬)
select = ["E", "F", "W", "I"]
ignore = []

# 모든 수정 가능한 규칙을 자동으로 고치도록 설정
fixable = ["ALL"]
unfixable = []

# --- Formatter (코드 포맷터) 설정 ---
[tool.ruff.format]
# Black과 유사한 포맷팅 스타일을 따릅니다.
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

# --- 플러그인별 상세 설정 ---
[tool.ruff.lint.isort]
# 프로젝트에서 사용하는 서드파티 라이브러리 목록
# known-third-party = ["django", "graphene_django"]

# --- 파일/디렉토리별 규칙 무시 설정 ---
[tool.ruff.lint.per-file-ignores]
# settings 파일: 와일드카드 import 허용
# "config/settings/*" = ["F403", "F405"]

# __init__.py 파일: 하위 모듈 노출을 위한 미사용/와일드카드 import 허용
"**/__init__.py" = ["F401", "F403"]

# 테스트 파일: 가독성을 위해 긴 줄 허용
"**/test_*.py" = ["E501"]&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;js&amp;amp;ts 파일도 붙여 넣을까 했는데 진짜 너무 과하게 길어질 것 같아서 생략합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;맥락은 같습니다. 어차피 AI 또는 next(or nest)를 쓰든 프로젝트 init 하면 린터와 포매터 세팅은 따라 나옵니다. 이걸 입맛에 맞는 커스텀 템플릿으로 바꾸는 정도입니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;그리고 ts 경우 type을 얼마나 strict하게 할지, 미리 세팅해 두면 큰 도움이 되죠.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;5. github action CI부터 역시 바로 세팅합니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;내용이 너무 길어서 건너뛰고, 일부분만 사진으로 대체할게요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/12.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 &lt;code&gt;github cli&lt;/code&gt;인 &lt;code&gt;gh&lt;/code&gt;를 기가 막히게 잘 쓰더라고요. 그래서 더욱이 CI부터 세팅하려고 합니다. 위는 python, uv 기반 CI 파이프라인이고, 처음부터 멀티 버전 (매트릭스) 대상으로 하지는 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 그리고 작업 시작, plan.md부터!&lt;/strong&gt;&lt;/h4&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/13.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저는 무조건 &lt;code&gt;plan.md&lt;/code&gt; 부터 작성합니다. 이게 &lt;code&gt;AGENTS.md&lt;/code&gt;에서 명시한 것들과 일맥상통하기도 하고, 통제 가능성이 여전히 중요하기도 하고요. &lt;strong&gt;그리고 여전히 저는 무조건 테스트 코드부터 작성합니다.&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/14.png"&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/29.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이를 병목으로 보는 시선도 많아졌더라고요. 되돌아보면 과거에 비해 plan을 좀 더 넓은 범위로 작성하게 됐습니다. 예전에는 딱 한 작업, 한 commit 단위를 대상으로 plan을 작성했었습니다. (예를 들어, A라는 API만 바꾸고 싶다든지요.) 지금은 범위가 조금 더 큽니다. “알림 관련 기능을 만들 건데 이러이러해. 이러이러한 것을 위한 ORM 모델부터 핵심 API만 만들자” 이런 느낌에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;더욱이 plan.md는 이제 하나의 “체크포인트”이기도 합니다. 그래서 저는 plans 디렉터리에 따로 모아둡니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:60%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/30.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;근데 opencode &amp;amp; omo를 쓰시면 &lt;code&gt;.sisyphus&lt;/code&gt; 경로에 자동으로 저장되긴 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:60%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/31.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h4 style="text-align:justify;"&gt;&amp;nbsp;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;plan.md 를 작성했으면 이제 이를 기반으로 작업을 합니다. opencode + omo에서는 원래 &lt;code&gt;/start-work&lt;/code&gt;라는 사전 명령어를 사용해서 시작합니다. 그러면 &lt;code&gt;.sisyphus&lt;/code&gt; 경로에 자동 저장된 plan 찾아서 바로 작업을 이어가고, agent에게 일을 할당해 주기 시작합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/17.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;제가 쓰는 &lt;code&gt;AGENTS.md&lt;/code&gt; 에 따르면 &lt;code&gt;go&lt;/code&gt;라는 시그널만 주는데, 이는 좀 때에 따라 다르게 하긴 합니다. &lt;code&gt;ulw&lt;/code&gt; 가 필요하다 싶으면 Sisyphus를 사용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/18.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/19.gif"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여러 에이전트에게 자동으로 작업이 분할·위임되고, 병렬로 처리되는 것을 확인할 수 있습니다. 특히 좋은 점은 opencode가 “에이전트의 실행 상태”를 개괄적으로 모니터링하는 GUI(TUI)를 제공하는데, 이 부분은 다른 네이티브 CLI(claude, codex 등)보다 낫다는 점입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;plan 규모가 좀 있다면 무조건 검토를 시킵니다.&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;plan.md 기반으로 모든 사항이 적용되었는지 A to Z를 검토해야 해.
아래 사항에 따라 검토하되, 체크 박스도 모두 제대로 처리해.

1. AGENTS.md 와 SYSTEM_DESIGN.md를 1순위로 따르고 있는지 체크.
2. 변경에 따른 하위호환성과 영향 범위를 절대 잊지 말고 더블 체크.
3. 관련된 테스트 코드 역시 업데이트 되어야 해.
4. 관련된 테스트가 과하거나, 중복되거나, 이미 자명한데 쓸데없는 테스트를 하거나 하지 않는지 체크
5. 2025년, 2026년 외부 공식 자료와 외부 best example을 참고해서 개선해줘. 최대한 비판적으로 수용하고 지금 코드를 업데이트 해야 해.

이를 위해 다양한 모델과 서브에이전트를 적극적으로 활용해.&lt;/code&gt;&lt;/pre&gt;&lt;h3 style="text-align:justify;"&gt;&amp;nbsp;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 다음 턴부터는 상황에 따라&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;저는 Plan 을 한 번 하면 검토를 하고, 검토 output이 최종이라고 생각하며 자체 H-I-L(human in the loop), E2E를 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;그 과정에서 리팩토링 &amp;amp; 세부 피쳐를 작업할 땐 바로 플랜을 짜지 않고, 이때부턴 기본적인 AI md(AGENTS.md 등)만 활용하고, &lt;strong&gt;skill 을 적극적으로 사용&lt;/strong&gt;합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/20.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지금은 거의 세 가지 중 하나를 쓰게 되더라고요. 특히 가장 많이 쓰는 건 &lt;code&gt;ui-ux-pro-max&lt;/code&gt;입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/21.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이런 식으로 &lt;code&gt;skill&lt;/code&gt;과 하네스를 섞어서 쓰기도 합니다. 이땐 작업 범위가 좁을수록 아웃풋이 좋았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4) 절대 AGENTS.md, SYSTEM_DESIGN.md 등을 그대로 두지 않습니다.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;진행할 록 layer는 많아지고 무조건 프로젝트는 복잡성이 올라갑니다. 그래서 무조건 이 AI를 위한 마크다운을 초기설정 그대로 두지 않습니다. &lt;strong&gt;무조건 프로젝트 현 상태에 따라 맞춰 업데이트를 합니다.&lt;/strong&gt; 일례로, 동시성에 대한 경고, web이 아닌 OS 응용 프로그램, GUI를 위한 룰, 또는 FE 작업할 땐 &lt;code&gt;DESIGN_SYSTEM.md&lt;/code&gt;도 만드는데, 이 디자인 룰 역시도요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;최대한 영어로, 최대한 핵심만 짧고 요약해서&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;AI를 위한 마크다운은 무조건 토큰에 영향을 주고, 이는 비용과 퍼포먼스에 영향을 줄 수밖에 없습니다. 그래서 저는 무조건 영어로, 최대한 짧고 굵게 작성하려고 합니다. 특히 &lt;code&gt;AGENTS.md&lt;/code&gt; 와 같이 기본적으로 에이전트가 물고가는 마크다운 파일은 더욱더요!&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;5) 한 세션이 너무 길어진다면?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;멀티 에이전트는 보통 아래 흐름입니다. (실제로 위에서 사용한 흐름이 모두 아래와 같죠.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;Research Agent
   ↓
Planner Agent
   ↓
Implementation Agent
   ↓
Reviewer Agent
   ↓
Documentation Agent&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/22.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;한 세션에서 너무 볼륨 큰 작업을 하거나, 계속 한 세션에서 작업을 길게 이어간다면, 초기 지시 사항을 잊을 수도 있습니다. 대표적으로 아래와 같은 허들 이슈가 있죠.&lt;/p&gt;&lt;ol&gt;&lt;li style="text-align:justify;"&gt;긴 세션에서 컨텍스트가 사라짐&lt;/li&gt;&lt;li style="text-align:justify;"&gt;다른 에이전트가 작업을 이어받을 때 맥락 손실&lt;/li&gt;&lt;li style="text-align:justify;"&gt;작업 상태 / 결정 / 다음 단계가 사라짐&lt;/li&gt;&lt;/ol&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그럴 때마다 &lt;code&gt;ctrl + c&lt;/code&gt;로 취소하거나 &lt;code&gt;/new&lt;/code&gt;로 바로 새로운 세션을 시작할 필요가 없습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/23.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;code&gt;&lt;strong&gt;/handoff&lt;/strong&gt;&lt;/code&gt;를 쓰면 됩니다. &lt;code&gt;/handoff&lt;/code&gt;는 현재 에이전트나 세션의 작업 상태(context)를 다른 에이전트 또는 다음 단계의 작업으로 넘기는 작업 전달 메커니즘입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/24.png"&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/25.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;자동으로 위 프롬프트가 세팅되고, 바로 그 다음 사진과 같이 핵심 작업이 자동으로 요약이 됩니다. (현재 작업 목표, 지금까지의 결정, 구현된 내용, 남은 작업, 다음 담당자)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/26.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그냥 심플하게 새로운 세션으로 가서 해당 내용을 그대로 복사해서 사용하면 끝이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;정리하며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;정리해 보면, opencode + OMO 세팅에서는 결국 아래 몇 가지 흐름으로만 쓰게 되는 것 같습니다. 프로젝트 세팅부터 AI용 마크다운까지 포함해, 전반적으로 제대로 갖춰두는 방식으로요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;불확실한 요구사항/큰 작업&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;Prometheus (Plan Builder)&lt;/code&gt;로 plan&lt;/li&gt;&lt;li style="text-align:justify;"&gt;때에 따라 &lt;code&gt;Atlas (Plan Executor)&lt;/code&gt; 또는 &lt;code&gt;Sisyphus(Ultraworker)&lt;/code&gt;를 통해 &lt;code&gt;ulw&lt;/code&gt;를 붙여 병렬 실행을 유도(하네스 최대 가동).&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;레거시 코드 파악이 먼저인 작업&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;프롬프트에 &lt;code&gt;find&lt;/code&gt; 또는 &lt;code&gt;search&lt;/code&gt;를 포함해 탐색 모드로 시작&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;@explore&lt;/code&gt;에게 “진입점/핵심 모듈/핫스팟 파일”을 먼저 뽑게 하고(쓰기 제한이 있어 안전), 이후 Build로.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;디버깅/근본 원인 분석&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;프롬프트에 &lt;code&gt;investigate&lt;/code&gt;를 넣어 분석 모드로 전환&lt;/li&gt;&lt;li style="text-align:justify;"&gt;설계/논리 검토는 &lt;code&gt;@oracle&lt;/code&gt;을 “읽기 전용”으로 붙여 객관화&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;볼륨이 크지는 않지만 특정 부분(또는 역할)만 업그레이드할 경우&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;스킬과 하네스 섞어서 사용&lt;/li&gt;&lt;li style="text-align:justify;"&gt;적극적으로 외부 공식 자료와 외부 best example을 search하게 유도&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 3번, 4번은 오픈소스 코드나 이미 볼륨이 커진 프로젝트에서 특정 부분에만 집중할 때 꽤 유용했습니다. 요즘처럼 AI 관련 스택의 생명주기가 반년도 안 되는 시대에는, 이런 접근이나 방법도 언젠가 레거시처럼 여겨질지 모르겠습니다.&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&amp;nbsp;&lt;/h4&gt;&lt;h4 style="text-align:justify;"&gt;p.s.&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;가끔 자기 전, 외출 전에 랄프(Ralph Loop)를 가동하긴 합니다. 그런데 개인적으로는 랄프보다는 ulw를 프롬프트로 자동회귀하게 세팅하는 쪽이 체감 성능이 더 좋더라고요. plan을 가득 만들어두고 한 호흡으로 진행하라는, 즉 무조건 끝날 때까지 진행하라는 프롬프트와 함께 ulw를 돌리면 토큰을 다 쓸 때까지 돌아가는 마법을 보실 수도 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;code&gt;opencode stats&lt;/code&gt;를 한 번 입력해 보세요! - &lt;a href="https://opencode.ai/docs/cli/"&gt;https://opencode.ai/docs/cli/&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/27.png"&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3676/28.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저는 &lt;code&gt;Cache Read&lt;/code&gt; 에 24억 7,120만 토큰 정도를 사용했네요! 캐시라서 정말 다행입니다. 약 30일간 총 27억 토큰 정도 사용했습니다. &lt;span style="color:#999999;"&gt;(그 이상의 기간은 비밀입니다. 저도 알고 싶지 않았습니다.)&lt;/span&gt;&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;&amp;lt;출처&amp;gt;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://aakashgupta.medium.com/2025-was-agents-2026-is-agent-harnesses-heres-why-that-changes-everything-073e9877655e"&gt;2025 Was Agents. 2026 Is Agent Harnesses. Here’s Why That Changes Everything.&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://opencode.ai/"&gt;오픈코드 공식 홈페이지&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://github.com/code-yeongyu/oh-my-opencode"&gt;OMO 플러그인 공식 깃헙 레포&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://news.hada.io/topic?id=24978"&gt;OMO 관련 긱뉴스&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://youtu.be/o-rE93-nLpY?si=y4calJcK_Bf4vcq7"&gt;OMO 제작자 유튜브 인터뷰(팟캐스트)&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://velog.io/@qlgks1/Kent-Beck-Augmented-Coding"&gt;Augmented Coding&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/detail/3590/"&gt;요즘IT, 한 달 만에 20만 다운로드, 전 세계 홀린 한국 개발자&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;lt;원문&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://velog.io/@qlgks1/opencode-oh-my-opencode-harness"&gt;LLM - 모델 경쟁이 끝나고, “하네스 경쟁”의 시작?!, opencode 와 oh-my-opencode&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>코드는 줄고 판단은 남았다: AI 시대 개발자의 일일일</title><link>https://yozm.wishket.com/magazine/detail/3673</link><description>“딸깍” 코드가 생성된다. 테스트 코드도 함께 따라온다. 레거시 분석은 몇 분이면 끝난다. POC는 하루 만에 마무리되고, 위키 문서까지 자동으로 정리된다. 요즘 개발자들 사이에서 종종 듣는 말이다. IDE보다 채팅창을 더 오래 바라보는 날이 늘어나고, 최근에는 채팅창을 넘어 클로드 코드 같은 도구를 사용하며 터미널만 바라보는 시간이 많아졌다. 우리는 점점 코드를 덜 쓰는 방향으로 가고 있다. 시니어 개발자가 될수록 설계와 문서화 같은 더 높은 레벨의 일을 해야 한다는 이야기는 오래전부터 있었다. 그래서 40년 차 미국 빅테크 프린시펄 엔지니어부터 쿠팡, 네이버 개발자에게 같은 질문을 던져보았다. “AI를 어떻게 받아들이고 있으며, 실제 업무에서는 어떻게 활용하고 있나요?”</description><guid>https://yozm.wishket.com/magazine/detail/3673</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;AI 에이전트 시대의 개발자는 어떤 모습이어야 할까?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;40년 차 미국 빅테크 개발자부터, 쿠팡·네이버 개발자 인터뷰&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“딸깍” 코드가 생성된다. 테스트 코드도 함께 따라온다. 레거시 분석은 몇 분이면 끝난다. POC는 하루 만에 마무리되고, 위키 문서까지 자동으로 정리된다. 요즘 개발자들 사이에서 종종 듣는 말이다. IDE보다 채팅창을 더 오래 바라보는 날이 늘어나고, 최근에는 채팅창을 넘어 클로드 코드 같은 도구를 사용하며 터미널만 바라보는 시간이 많아졌다. 우리는 점점 코드를 덜 쓰는 방향으로 가고 있다. 시니어 개발자가 될수록 설계와 문서화 같은 더 높은 레벨의 일을 해야 한다는 이야기는 오래전부터 있었다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 이렇게 빠르게 “코드를 덜 쓰는 개발자의 삶”이 올 줄은 예상하지 못했다. 그래서 문득 이런 질문이 들었다. 이게 맞는 방향일까?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;주니어는 앞으로 어떻게 성장해야 할까?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;리드 엔지니어의 역할은 사라지는 걸까?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;우리는 지금 무엇을 공부해야 할까?&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 40년 차 미국 빅테크 프린시펄 엔지니어부터 쿠팡, 네이버 개발자에게 같은 질문을 던져보았다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“AI를 어떻게 받아들이고 있으며, 실제 업무에서는 어떻게 활용하고 있나요?”&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;“우리는 AI와 페어 프로그래밍을 하고 있다”&lt;/strong&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;첫 번째 인터뷰: 40년 차 미국 빅테크 개발자&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그는 세미나에서 만난 40년 차 개발자였다. 아마존을 포함한 여러 빅테크에서 시스템을 설계했고, 현재도 미국 빅테크에서 프린시펄 엔지니어로 일하고 있다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 요새 AI가 핫한데, 어떻게 느끼시나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;내가 개발을 시작한 80년대에도 AI는 핫한 토픽이었어. Smalltalk 머신도 있었지. 다만 그때는 연산 능력과 데이터가 부족했을 뿐이야. 페어 프로그래밍(Pair Programming)에 대해 잘 알지? 내가 이렇게 연차가 쌓이고 나와 함께 페어 프로그래밍을 하겠다고 찾아오는 사람은 없는데, 지금은 AI와 페어 프로그래밍을 하는 것 같아. 다만 이제는 상대가 사람이 아니라 모델일 뿐이지.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그에게 AI는 처음 보는 토픽이 아니었다. 하지만 예전과 달리, 지금은 이론과 실험을 넘어 실용적인 도구로 실제 업무에 적극 활용된다는 점이 다르다고 했다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI는 정말 페어 프로그래머처럼 동작한다.&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;코드를 제안한다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;리팩토링을 제안한다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;테스트를 작성한다&lt;/li&gt;&lt;li style="text-align:justify;"&gt;구조를 정리해준다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;문서를 만든다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 그는 중요한 차이를 강조했다. “&lt;strong&gt;AI는 비판하지 않아&lt;/strong&gt;. AI와 대화해 보면 알겠지만, 아직까지는 내가 질문한 의도대로 답변하는 경향이 있지. 그리고 이것이 사람과의 대화에서 가장 큰 차이점이라고 생각해.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사람과 페어 프로그래밍을 하면 의견에 대한 반박이 오가고, 논리와 근거에 따라 때로는 내 의견이 받아들여지기도 하고, 상대방의 의견이 받아들여지기도 한다. 그리고 그 과정을 거쳐 코드가 완성된다. 나의 경우에도 페어 프로그래밍을 하다가 코드 컨벤션 문제로 크게 충돌했던 경험이 있었는데, 결국 그 사람과 팀이 달라지고 나서야 해결됐다. 지금 생각해 보면 아주 중요한 일은 아니었는데 말이다. 이렇듯 사람과의 페어 프로그래밍은 때로 강한 논쟁을 수반한다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 이와 달리 AI는 사람이 반박하면 대부분 수용적인 입장으로 바뀌고, 이를 최대한 답변에 녹여내려 한다. 최근에는 이런 점 때문에 코드 리뷰 에이전트에 ‘무조건 반대하는 입장에서 코드를 리뷰’하는 역할을 부여하기도 한다는 글이 종종 보인다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 우린 어떤 것을 준비해야할까요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;다들 느끼겠지만, AI의 결과의 퀄리티는 질문과 설계의 퀄리티에 달려있어. 그리고 이 말은 내가 개발을 시작했던 40년 전에도 똑같이 들었던 이야기야. 물론 AI의 결과가 아닌 사람의 결과라는 차이점이 있지만 말이지. &amp;nbsp;따라서 내가 어떤 문제를 풀고자 하는지를 정확히 아는지 중요해, 이전에 주니어 레벨은 주어진 것만 완벽히 그리고 빠른 시간내에 구현하는 것이 최고였지. 그런데 이제는 AI가 더 빠르고 더 완벽해, 물론 질문이 완벽하다는 전제가 필요하지만. 아무튼 이젠 질문하는 법을 배워야해 다른 것은 그 다음에 챙겨도 돼.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;생각해 보면 이런 류의 작업은 전통적으로 주니어를 넘어 시니어의 일이었다. 어떤 문제인지 정의하고, 어떤 방법으로 해결할지를 설계하고, 또 일을 분배하는 작업을 말한다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;이 문제의 이해관계자는 누구인가?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;언제까지 이 문제를 해결해야 하는가?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;어떤 제약 사항이 있는가?&lt;/li&gt;&lt;li style="text-align:justify;"&gt;성공적인 문제 해결의 기준과 측정 방법은 무엇인가?&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그는 또 하나의 우려를 덧붙였다. “나는 주니어가 &lt;strong&gt;초기에 겪어야 할 고통이 없다는 게 두렵다고 봐&lt;/strong&gt;.그러니 그 경험을 준비하라고 말해주고 싶지.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;버그를 추적하며 스택을 따라 내려가는 경험, 잘못된 설계로 장애를 내보고 복구하는 경험, 이런 감각은 자동으로 생기지 않는다고 그는 말했다. 그리고 이런 경험을 바탕으로 시스템을 설계하면서, 시스템의 가용성, 회복성 등 여러 가지를 고려하는 능력이 자연스럽게 길러진다고 덧붙였다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“그렇다고 AI를 쓰지 말라는게 아니야&lt;strong&gt;. AI와 함께 버그를 추적하며 설계&lt;/strong&gt;를 해보면 돼.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 최근 업무에서 AI를 활용한 경험에 대해 알려주세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;크게 두 가지가 있어. 원래 나는 간단한 사이트를 만들 시간이 없어. 그래서 대부분 주니어 개발자에게 위임하곤 했지. 그런데 이번에는 AI와 함께 주말 동안 만들어봤어. 피그마 디자인과 함께 말이지. 그다음으로는 특정 DB 버그의 stack trace 전문을 읽게 했더니, 한 번에 오류를 찾아냈어. 그 방법론과 접근법은 내가 생각한 것과 매우 유사했고, 결과도 내가 예상했던 이슈와 정확히 일치했지.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그가 사용했던 방법은 우리가 사용하던 것과 크게 다르지 않았다. 다만 이전에는 시간이 없어 하지 못했던 일, 그리고 본인이 생각했던 검증을 누구보다 빠르게 실행해 주는 도구로 AI를 활용하고 있었다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 덧붙여 말했다. “AI는 도구야. 장인은 도구를 탓하지 않는다던데, 실력도 좋은데 도구까지 좋으면 &lt;strong&gt;더 빨리, 더 멀리 갈 수 있지 않겠나?&lt;/strong&gt;”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 말을 듣고, AI에 매몰되지 말자고 스스로 다짐했던 생각이 다시 떠올랐다. 40년 차인 그에게 AI는 본인의 일을 빼앗는 경쟁자가 아니라, 만능 도구에 불과했다는 점이 아이러니하게 느껴졌다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;스킬을 만드는 스킬을 만들어요&lt;/strong&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;두 번째 인터뷰: 쿠팡 9년 차 프론트엔드 개발자&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여러 스타트업을 거쳐 쿠팡에 들어간 9년 차 개발자인 그는 개발을 시작할 때부터 프론트엔드만 집요하게 파고들었다. 그런 그를 이전 회사 동료로서 인터뷰해 보았다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 요새 AI가 핫한데, 어떻게 느끼시나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;핫하기도 하고, 회사에서도 AI를 업무에 많이 녹이려고 노력하고 있어요. 그리고 매니저와 1대1 미팅을 할 때도 요새 AI를 업무에 어떻게 사용하고 있느냐는 질문을 꼭 받아요. 제가 여기 들어온 지 이제 반년인데, 입사할 때부터 계속 같은 질문을 하시더라고요. 재작년까지만 해도 AI는 딱 제 연차에 엄청난 기회를 준다고 했어요. 절대적인 코딩 시간이 부족한 시니어 개발자에게 주니어 개발자를 여럿 붙여준다는 의미였지요. 그런데 지금 생각하면 아니에요. 모든 개발자에게 엄청난 기회를 주고 있다고 느껴요. 물론 AI가 여기서 더 발전하면, 그때는 어떻게 될지 모르겠네요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;쿠팡에서는 대부분의 팀이 AI 도구를 활용하고 있다고 한다. 그리고 전사적으로 할당된 AI 툴을 선점하기 위해 오픈런이 가끔씩 벌어지기도 한다고 한다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“agent.md 문서를 계속 업데이트해요. AI가 일관된 방향으로 작업하도록 규칙을 정리하고, 또 계속 추가하죠. 그리고 AI가 리뷰를 해주는데, 코멘트나 컨벤션에 어긋나는 부분이 있으면 바로 규칙에 반영해요. 제가 작성하는 PR 중 10%는 오로지 AI를 위한 수정 사항이에요.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러면서 간단한 예시를 몇 개 말해줬다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“테스트 코드는 XXXX 이런 식으로 작성해야 해요. jest 규칙에 언급되어 있죠. 하지만 AI가 그것을 누락했으니 규칙을 추가해야 하죠. CSS의 design token은 YYYY에 있는 파일에서 가져다 써야 해요. 그런데 기존 코드베이스에서는 이게 섞여 있어서 잘못된 방식으로 읽어오고 있으니, 여기도 규칙을 추가해야 해요.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;옆에서 보는 그의 모습은 마치 AI에게 코드 리뷰를 하고 있는 듯했다. 그리고 그는 이렇게 말했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“실은 지금 말했던 예시들은 제가 초반에 입사하고 나서 받았던 코드 리뷰 내용이에요. 처음에는 하나의 PR에 대충 30개의 리뷰가 달렸었어요. 그중에는 간단하지만 반복되는 리뷰들도 있었죠. 그래서 중간에는 자체적으로 ‘pr-check’라는 스킬을 만들어, 코드 리뷰에서 반복적으로 나오는 코멘트를 먼저 수정하는 과정을 거쳤었죠. 그리고 최근에는 AI 리뷰가 자동으로 도입되면서, 이런 스킬들을 바탕으로 agent rule을 만들어 계속 추가하고 있네요.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 최근 업무에서 AI를 활용한 경험에 대해 알려주세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;쿠팡은 아니고, 이전 회사에서 CMS(Content Management System)를 자체적으로 구현해야 했어요. 콘텐츠가 정적인 텍스트로만 이뤄지면 참 좋겠지만, 실제로는 다양한 미디어 파일과 인터랙션을 포함한 데모형 콘텐츠가 많았죠. 그래서 ‘puck editor’라는 오픈소스를 가져와 구현했어요. 이 라이브러리는 제가 사전에 구현해 둔 컴포넌트를 바탕으로, 사용자가 drag &amp;amp; drop으로 컴포넌트를 가져와 콘텐츠를 수정할 수 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3673/image2.png"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href=" https://demo.puckeditor.com/edit"&gt;공식 홈페이지&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 저는 여기에서 사용되는 컴포넌트들을 AI를 이용해 대부분 만들었어요. 예전 같으면 해당 컴포넌트를 만드는 데 컴포넌트 하나당 며칠씩은 걸렸을 거예요. 그런데 AI를 이용해 회사에서 쓰는 디자인 시스템을 바탕으로 puck editor에 필요한 컴포넌트로 포팅하는 작업을 전체 3일 만에 끝냈어요. 기본적인 레이아웃용 컴포넌트와 데모용 컴포넌트까지 포함하면 대략 30개 정도를 지원했던 것 같은데, 이전에는 상상도 못 할 속도예요. 그리고 저는 이 시스템을 만들어보면서 &lt;strong&gt;AI가 수평 확장에 정말 강력하다&lt;/strong&gt;는 걸 깨달았어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;같은 구조를 여러 곳에 적용해야 할 때, AI는 압도적으로 빠르다. 그러면서 그는 말을 덧붙였다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“그렇다면 개발자가 할 일은 수평 확장이 가능하도록, 수직 확장의 토대를 마련하는 것이죠.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI는 지시된 방향 안에서 훌륭하다. 하지만 방향을 설정하고, 수직 확장이 가능하도록 토대를 만드는 일은 여전히 인간, 곧 개발자의 몫이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 요새 어떤 것을 공부하고 계시나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;방금 말한 것처럼, 수직 확장을 위해 조금 더 깊은 내용을 공부하고 있어요. 최근에 읽은 책으로는 &amp;lt;멀티패러다임 프로그래밍(유인동 저)&amp;gt;을 포함해, 테스트 코드를 위한 책들을 중점적으로 보고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3673/image1.png"&gt;&lt;figcaption&gt;인터뷰이가 공유해 준 책 구매 이력 &amp;lt;출처: 작가&amp;gt;&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;요새 AI가 테스트 코드를 잘 만들어주잖아요. 그런데 그게 테스트 개수만 늘리는 건지, 테스트 커버리지만 채우는 건지 제가 잘 모르겠더라고요. 그래서 이번 기회에 테스트 코드에 대해 깊이 있게 학습해보려고, 우선 5권을 구매해서 보고 있어요. 지금은 4권째 읽고 있습니다. 여기에서 읽은 지식과 학습한 내용을 바탕으로, 테스트 코드를 위한 agent.md 파일을 작성하는 것을 목표로 삼고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;현재 제가 주로 일하는 서비스는 AI가 본격적으로 도입되면서 테스트 코드가 3배가량 증가했어요. 제 목표는 이것들을 더 이상 늘리지 않고, 유의미한 개수로 유지하는 거예요. 테스트가 많아질수록 CI/CD 시간이 오래 걸리고, 불필요한 테스트는 오히려 리팩토링 프로세스에도 좋지 않은 영향을 주니까요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 왜 이렇게 테스트 코드에 진심이세요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;요즘 일부에서는 ‘코드를 안 보고 배포한다’는 말도 나오는데, 저는 AI를 신뢰하는 것과 판단을 위임하는 것은 다르다고 생각해요. 만약 제가 혼자 일하고 모든 책임도 혼자 진다면, 코드를 안 보고 배포할 수도 있겠죠. 하지만 실제 제품은 혼자 힘으로 동작하지 않아요. 따라서 안 보고 배포한다는 말은, 나는 책임질 수 없으니 너희가 책임지라는 의미처럼 들려요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그렇지만 또 AI가 생성하는 코드를 안 쓸 수는 없죠. 저는 AI가 생성한 코드의 책임을 테스트 코드에서 찾아보고 있어요. 요새는 ‘&lt;strong&gt;테스트를 통과하면 제대로 된 기능이다&lt;/strong&gt;’라는 말도 유행하고 있어요. 이게 맞는 명제인지는 모르겠지만, 현실적인 타협안이라고 생각하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;9년 차 개발자는 책임을 질 수 있는 수준으로 AI를 활용하고 있었고, 그 책임을 위해 여러 가지 자신만의 규칙과 환경을 만들어가며 깊이 공부하고 있었다. 그렇다면 규칙은 어떻게 세우고 있는지 물어봤다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“요새 많이 하는 것 중 하나는 ‘이때까지 대화 중에 스킬이나 룰로 만들 수 있는 것이 있으면 만들어줘’라는 명령어예요. 그리고 이를 바탕으로, 위에서 말한 스킬을 만드는 스킬(/create-skills)을 커스텀해서 만들고 있어요.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;스킬을 만들기 위한 스킬이라니, 처음 재귀 함수를 봤을 때처럼 오묘하고 신기했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;나는 직접 코드를 안 쓴 지 두 달째다&lt;/strong&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;세 번째 인터뷰: 네이버 12년 차 백엔드 개발자&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그는 프론트엔드로 시작해 백엔드를 거쳐, 현재는 풀스택으로 일하고 있다. 그리고 이제 막 매니저 역할을 시작한 초보 매니저이기도 하다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 요새 AI가 핫한데, 어떻게 느끼시나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;갑자기 생각난 건데, 올해(인터뷰 날짜 기준 3월 초)에는 IDE를 안 켜본 것 같아요. 갑자기 소름이 끼치네요. AI가 핫한 만큼 저도, 그리고 조직도 AI에 발 빠르게 적응하려고 준비하고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;IDE를 안 켠다고 해서 개발을 안 하고 있는 것은 아닙니다. 오히려 PR 양은 이전보다 더 늘어났어요. 저는 주로 클로드 코드를 사용하고 있는데요. 문서와 지라 티켓에 상세하게 작성된 PRD(Product Requirements Document, 제품 요구사항 정의서의 약자로 서비스나 기능의 목표, 타깃 고객, 핵심 기능, 성공 지표 등을 명확히 정의해 개발팀, 디자인팀 등 이해관계자와 공유하는 문서)를 클로드 코드가 알아서 가져와 백엔드 코드를 작성해줘요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;물론 제가 하는 일이 단순히 API를 만드는 것뿐만 아니라 다양하게 있지만, 그래도 그중에서 가장 많은 시간을 잡아먹는 것은 단연 API를 만드는 부분이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그는 최근 IDE를 사용하는 시간이 눈에 띄게 줄었다고 말했다. 그렇다면 개발 시간은 과연 줄어들었을까?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“단순히 AI가 있어서 개발 시간이 10분의 1로 줄었나? 생산성이 10배, 100배가 되었나? 이런 느낌은 아니네요. 제가 하는 업무가 단순히 코딩이 전부가 아니고, 또 AI가 이렇게 발전하기 전에도 코딩 그 자체가 시간을 가장 많이 잡아먹는 일은 아니었거든요. 요즘도 그렇고 이전에도 코딩보다는 컨텍스트를 정리하고 문서화하는 시간이 더 길어요. 여러 가지 문서를 읽고 R&amp;amp;R(Role &amp;amp; Responsibilities의 약자로, 조직이나 프로젝트 내에서 각 구성원이 맡은 ‘역할과 책임’을 의미)를 정리하는 일이죠. 대신 한 가지 고무적인 점은, 제가 하는 컨텍스트 정리와 문서화 작업이 실제로 개발 속도를 끌어올린다는 점입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;제가 이 작업을 하는 이유는 개발자들(프론트엔드, 백엔드)에게 스펙을 정의하고 전달하기 위해서였어요. 때로는 기획자의 역할도 해야 하니, 이런 부분을 구체화하고 통일한 문서를 바탕으로 기능을 만들기 위해 시간을 들여 정성껏 작성하고 공유하는 것이었죠. 물론 이 작업이 개발자들의 일을 줄여주기도 합니다. 제대로 된 문서는 잘못된 개발 방향을 초반부터 걷어내고, 불필요한 의사소통 비용을 줄여주니까요. 하지만 이게 직접적으로 코딩 그 자체의 속도에 영향을 주지는 않았어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 AI가 본격적으로 업무 프로세스에 녹아들면서 달라졌어요. 제가 만든 문서는 AI가 일을 한 번에, 그리고 제대로 하게 만드는 잘 정리된 Plan 문서로 동작합니다. 실제로 저는 업무를 정리하면서 해야 할 To-do list를 만드는데, 이것조차 AI를 잘 동작하게 하는 하나의 방법론으로 작동합니다.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 최근 업무에서 AI를 활용한 경험에 대해 알려주세요.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;아마 많은 분들이 직접적인 개발 과정에서 AI를 활용한 경험을 말씀하실 텐데요. 저는 오히려 비개발적인 부분에서 AI를 활용하는 일이 생산성을 더 높여준다고 생각합니다. 예를 들어, 매니저인 저에게 지라 티켓이나 일정을 관리하는 일은 항상 어렵고 큰일이지만, 사실 하기 싫은 일이기도 하죠. 왜냐하면 그 많은 지라 티켓을 일일이 확인하면서 기능 개발이 어디까지 왔는지, 또 일정은 잘 진행되고 있는지 체크하는 건 너무 번거로운 일이기 때문이에요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지라 대시보드나 여러 기능도 있지만, 많은 개발자분들이 경험적으로 느끼시겠지만 생각보다 지라 티켓이나 일정 관리를 꼼꼼히 하지 않아요. 주로 개발을 시작할 때 한 번, 그리고 개발이 전부 마무리돼 ‘완료’ 처리할 때 한 번, 이렇게 두 번 정도만 상태를 변경합니다. 이게 개발자 입장에서는 꽤 번거로운 일이거든요. 그래서 저는 이 프로세스의 상당 부분을 클로드 코드를 이용해 자동화하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;클로드 코드를 연결해 지라 티켓을 가져온 뒤, 어떤 작업을 시작할 거라고 하면 클로드 코드가 다음 작업을 진행해줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;지라 티켓 status 변경&lt;/li&gt;&lt;li style="text-align:justify;"&gt;지라 티켓 번호를 포함한 브랜치 설정&lt;/li&gt;&lt;li style="text-align:justify;"&gt;해당 브랜치를 기반으로 GitHub draft 작성&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 되니 ‘지라 대시보드와 GitHub pull request에서 누가 어떤 작업을 진행 중이구나’를 한눈에 볼 수 있더라고요. 그리고 하루에 한 번씩 일정 관리 크론잡도 돌고 있는데요. 지라 티켓과 GitHub 정보, 그리고 일정 정보를 바탕으로 일이 어느 정도 진행되고 있는지 알려주는 스크립트입니다. 저는 이것을 통해 매니저 역할을 해 나가고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러면서 그는 클로드 코드에서 해당 화면을 보여주었다. 그의 클로드 코드는 터미널 기반이지만, 한껏 커스텀되어 필자가 보기에도 깔끔한 하나의 매니저 도구처럼 보였다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“그리고 하나의 작업이 더 있어요. 제가 오늘 하루 동안 작업한 내용을 바탕으로 성과 관리 문서를 생성합니다. 그리고 주간, 월간, 분기 단위로 제 성과 관리를 해가고 있어요. 아직 이 자동화를 시작한 지 반년이 안 돼서 연간 단위는 없지만, 지금 추세라면 연간 성과 관리도 잘할 수 있을 것이라 생각합니다.”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그가 자동화에 푹 빠져 클로드 코드에 대해 설명하던 그 순간은, IDE를 몇 달 동안 켜지 않았음에도 가장 개발자답게 보이는 순간이었다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;&amp;nbsp;Q. 요새 어떤 것을 공부하고 계시나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;“제가 학부생 때는 동기들끼리 마우스 없이 코딩하는 날 같은 것도 만들어서 했었어요. 그때는 vim으로 빠르게 코딩하는 게, 뭔가 동기들 사이에서 실력의 척도였어요. 초등학교 때 타자 수가 빠르면 컴퓨터를 잘하는 사람 취급받는 것처럼요. 생각해 보니 그때도 속도가 전부였네요. 아무튼 그때 저는 코딩을 잘하기 위해 도구 사용법을 따로 시간을 들여 공부했어요. 그리고 AI도 마찬가지라고 생각해요. 시간을 들여 익혀야 해요. 우리가 vim 수련을 한 것처럼요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;요새는 또 &lt;strong&gt;하네스 엔지니어링&lt;/strong&gt;(인공지능 모델, 특히 LLM(거대 언어 모델)을 감싸서 그 능력을 실전에 안전하게 활용할 수 있도록 통제하고, 도구와 연결해 실제 행동을 수행하게 하는 외부 소프트웨어 프레임워크 또는 구조)이나 &lt;strong&gt;AI 오케스트레이션&lt;/strong&gt;(거대 언어 모델(LLM), 이미지 모델, 데이터베이스 등 서로 다른 AI와 시스템을 하나의 워크플로 안에서 지휘자처럼 통합·관리해, 단일 모델로 해결하기 어려운 복잡한 문제를 풀고 효율을 높이는 기술) 같은 것들을 어떻게 활용할 수 있을지 고민해보고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 이런 것들은 때로 너무 빨리 변해서, 제가 공부하기도 전에 새로운 방법론과 패러다임의 변화가 일어나기도 합니다. 그래서 불안하기도 하죠. 그래도 어쩌겠습니까? 다들 AI라는 비행기를 타고 날아가고 있는데, 저만 뛰어갈 수는 없잖아요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;신이 나서 클로드 코드를 만지고 있는 그의 모습에서, 어쩌면 AI라는 비행기의 속도보다 하늘을 난다는 그 기술 자체에 매료된 한 사람을 본 것 같았다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;세 명의 개발자와의 인터뷰를 마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;세 사람의 이야기를 듣고 나니 한 가지는 분명했다. AI가 등장했다고 해서 개발이라는 일이 완전히 다른 일이 된 것은 아니라는 점이다. 다만 우리가 시간을 쓰는 방식이 조금 바뀌고 있을 뿐이다. 코드를 직접 작성하는 시간은 줄어들고, 문제를 정리하고 맥락을 설명하고 방향을 잡는 시간은 늘어나고 있다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;40년 차 엔지니어는 좋은 결과는 &lt;strong&gt;여전히 좋은 질문에서 시작한다&lt;/strong&gt;고 말했다. 쿠팡 개발자는 &lt;strong&gt;AI가 잘 일하도록 규칙을 계속 추가&lt;/strong&gt;하고 있었고, 네이버 개발자는 &lt;strong&gt;문서와 맥락을 정리하는 일이 개발 속도를 높인다&lt;/strong&gt;고 했다. 세 사람의 이야기를 듣다 보니 결국 같은 결론으로 이어졌다. AI는 일을 더 빠르게 만들어주는 도구지만, 무엇을 만들지 결정하고 책임지는 일은 여전히 사람의 몫이라는 것이다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 요즘의 개발자는 코드를 얼마나 많이 쓰느냐보다 어떤 문제를 풀려고 하는지, 어떤 맥락에서 이 일을 하는지, AI에게 무엇을 맡기고 무엇은 직접 판단할지를 조금 더 깊이 고민하게 되는 것 같다. 아직 정답은 없다. 지금은 모두가 조금씩 자기 방식으로 실험해보고 있는 시기인 듯하다. 그래서 인터뷰를 마치고 나서 남은 질문은 이것 하나였다. “나는 오늘 AI에게 무엇을 시켰는가”가 아니라, “나는 오늘 어떤 문제를 풀려고 했는가?”라는 것. 여러분은 어떻게 생각하시나요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>cURL은 왜 버그 바운티를 끝냈을까?</title><link>https://yozm.wishket.com/magazine/detail/3668</link><description>버그 바운티는 오픈소스 생태계에서 “가장 설명하기 쉬운 약속” 중 하나입니다. 취약점을 찾으면 보상한다는 약속은, 전 세계의 기여자들이 같은 코드베이스를 바라보게 만들고 “더 많은 눈이 모이면 더 안전해진다”는 집단 방어의 기대와 맞물립니다. 그래서 cURL처럼 의존성이 크고 사용자 기반이 넓은 프로젝트일수록 버그 바운티는 지속 가능성을 뒷받침하는 ‘기본 장치’처럼 보이곤 합니다. 그런데 2026년 1월, cURL은 그 정답지 같은 선택을 접었습니다. “버그 바운티를 끝낸다”는 공지만으로도 충격인데, 공지에 담긴 문장들은 더 노골적이었습니다. AI 슬롭이 늘었고, 그 결과 유지보수자의 부담이 감당하기 어려운 수준이 됐다고 말합니다. 심지어 AI 슬롭 제보자에 대한 강경한 대응 방침까지 공식 글에 적었습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3668</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;AI 슬롭이 만든 ‘검토 예산’ 붕괴&lt;/strong&gt;&lt;/h4&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;버그 바운티*는 오픈소스 생태계에서 “가장 설명하기 쉬운 약속” 중 하나입니다. 취약점을 찾으면 보상한다는 약속은, 전 세계의 기여자들이 같은 코드베이스를 바라보게 만들고 “더 많은 눈이 모이면 더 안전해진다”는 집단 방어의 기대와 맞물립니다. 그래서 cURL*처럼 의존성이 크고 사용자 기반이 넓은 프로젝트일수록 버그 바운티는 지속 가능성을 뒷받침하는 ‘기본 장치’처럼 보이곤 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;*버그 바운티: 화이트햇 해커가 기업·기관의 서비스 및 제품에서 보안 취약점을 발견해 제보하면 포상금을 지급하는 제도&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;*cURL(Client URL): HTTP, HTTPS, FTP 등 다양한 프로토콜을 사용하여 서버와 데이터를 주고받는 명령줄 도구 및 라이브러리&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3668/section_0.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href="https://arstechnica.com/security/2026/01/overrun-with-ai-slop-curl-scraps-bug-bounties-to-ensure-intact-mental-health/"&gt;&lt;u&gt;Overrun with AI slop, cURL scraps bug bounties to ensure “intact mental health”&lt;/u&gt;&lt;/a&gt;, arstechnica&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 2026년 1월, cURL은 그 정답지 같은 선택을 접었습니다. “버그 바운티를 끝낸다”는 공지만으로도 충격인데, 공지에 담긴 문장들은 더 노골적이었습니다. AI 슬롭*이 늘었고, 그 결과 유지보수자의 부담이 감당하기 어려운 수준이 됐다고 말합니다. 심지어 AI 슬롭 제보자에 대한 강경한 대응 방침까지 공식 글에 적었습니다. 보안 사건 하나를 처리하는 공지라기보다, 운영 체계가 한계에 닿았다는 경고에 가깝습니다. (이 글에서 말하는 AI 슬롭은 문장과 형식은 그럴듯하지만, 재현과 증거가 빈약해 검증이 불가능한 생성형 보고서를 뜻합니다.)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;*AI 슬롭(AI Slop): 생성형 인공지능 기술을 사용하여 양산되는 글과 그림 등 저품질 컨텐츠를 경멸적인 용도로 사용되는 단어&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI는 이 현상을 더 빨리 드러내는 촉매가 됐습니다. 작성이 쉬워질수록 제출물은 늘어나지만, 검토에 필요한 정보가 자동으로 채워지지는 않습니다. 재현이 없고, 영향 범위가 없고, 테스트가 없고, 실패 시 대응이 없으면 그 빈칸을 누군가는 메워야 합니다. 보통 그 역할은 오픈소스를 운영하는 이들에게 돌아옵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 글에서는 이와 관련해 세 가지를 정리해 봤습니다.&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;첫째, AI 슬롭이 늘어날수록 오픈소스 운영의 병목이 코드 품질이 아니라 ‘검토 예산’과 ‘승인 책임’에서 먼저 터지는 이유를 구조로 설명합니다.&lt;/li&gt;&lt;li&gt;둘째, cURL의 버그 바운티 종료를 출발점으로 삼아, 텍스트 양식이 잘 채워져도 검증 가능한 증거가 없으면 검토가 질의응답으로 무너지고 결국 채널과 정책이 재설계되는 과정을 설명합니다.&lt;/li&gt;&lt;li&gt;셋째, 금지나 비난이 아니라 문턱을 세우는 방식으로, 평판과 재현 가능한 증거를 기준으로 검토가 시작되게 만들고 이를 운영 규칙과 자동화로 고정하는 방법을 제안합니다. 마지막으로 기여자가 ‘설명’이 아니라 ‘증거’를 제출해 승인 책임의 불확실성을 줄이는 행동 원칙까지 정리합니다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;1. 버그 바운티가 망가지는 방식: ‘찾는 비용’은 내려가고 ‘검증 비용’은 남는다&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;제출은 쉬워지고, 검증은 그대로입니다. 이 비대칭이 검토 예산을 잠식합니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;버그 바운티의 전제는 단순합니다. “제보를 늘려 취약점을 빨리 발견한다.” 제보자에게 보상을 약속해 더 많은 제보가 들어오도록 만들고, 그 결과 프로젝트의 보안 수준을 끌어올립니다. 오픈소스 생태계에서 이 구조는 실제로 강력하게 작동해 왔습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 운영 관점에서 버그 바운티에는 함정이 하나 있습니다. 제보를 제출하는 비용은 쉽게 내려갈 수 있는데, 제보를 검증해 결론을 내리는 비용은 잘 내려가지 않습니다. 검증은 사람의 시간을 요구하고, 재현과 확인이 끝나야만 결론이 납니다. 즉, 제보 한 건이 검토 대기열에 들어오는 순간부터 비용은 제출자가 아니라 유지보수자의 검토 예산에서 빠져나갑니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최근 몇 년 사이 이 비대칭은 더 커졌습니다. 제보를 만드는 문서 작성 비용이 내려갔고, 그럴듯한 문장과 구조를 갖춘 보고서를 빠르게 만드는 방법도 쉬워졌습니다. 여기서 AI는 원인이 아니라 촉매로 작동합니다. “제보가 그럴듯해 보이게 만드는 비용”을 낮추기 때문입니다. 제목과 표현은 점점 긴박해지는데, 정작 재현과 증거는 비어 있는 제보가 늘어납니다. 그러면 유지보수자는 같은 일을 반복하게 됩니다. 읽고, 확인하고, 반박하고, 다시 읽고, 또 확인합니다. 결론이 나지 않는 제보가 쌓이면, 그 자체로 검토 예산을 갉아먹는 채널이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3668/section_1.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 이미지 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;cURL 공지가 말하는 전환점이 바로 여기입니다. 제보가 늘어서 힘든 것이 아니라, “검토로 결론을 낼 수 없는 제보”가 늘어서 운영이 흔들렸다는 겁니다. 이 상태가 되면 질문은 “제보를 더 받는 방법”이 아니라 “검토를 어떤 조건에서 시작할 것인가”로 바뀝니다. 그리고 다음 선택지는 대체로 둘 중 하나입니다. 채널을 줄이거나, 문턱을 세우거나. cURL은 버그 바운티를 종료하며 채널을 줄이는 결정을 먼저 꺼냈고, 그 판단의 근거를 ‘검토 예산’과 ‘유지보수자의 부담’으로 정리했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;보상, 채널, 문턱을 다시 잡다. cURL이 택한 운영적 해법&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;cURL의 결정이 흥미로운 이유는 “AI를 금지하자” 같은 선언으로 끝내지 않았기 때문입니다. 메시지는 오히려 운영적입니다. “더 이상 검토 예산을 이 채널에 소비할 수 없으니, 제보가 들어오는 방식 자체를 바꾼다”는 방향입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;cURL이 선택한 변화는 크게 세 가지입니다.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;첫째, 금전적 보상을 중단했습니다. 심각도와 상관없이 보상 자체를 제공하지 않겠다고 했습니다.&lt;/li&gt;&lt;li&gt;둘째, 제보 채널에서 해커원(HackerOne)을 제거하고, 깃허브(GitHub)의 비공개 취약점 제보 기능(Private vulnerability reporting)으로 안내했습니다.&lt;/li&gt;&lt;li&gt;셋째, AI 슬롭을 제출하는 계정은 즉시 차단하고 공개적으로 지적하겠다는 방침을 명시했습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다니엘 스텐버그는 해커원 버그 바운티로 제출된 보안 취약점 제보 중, AI 슬롭으로 의심되는 사례를 별도 목록(&lt;a href="https://gist.github.com/bagder/07f7581f6e3d78ef37dfbfc81fd1d1cd"&gt;&lt;u&gt;AI slop security reports submitted to curl&lt;/u&gt;&lt;/a&gt;)으로 공개해 두었습니다. 목록은 실제 제보 링크로 구성돼 있고, “AI 슬롭 제보자는 즉시 차단한다”는 현재 정책도 같은 문서에 함께 적혀 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 변화의 의미는 간단합니다. 그럴듯해 보이지만 검증이 어려운 제보가 몰려드는 상황을 줄이고, “검증 가능한 증거”가 포함된 제보가 들어오도록 문턱과 흐름을 다시 설계한 것입니다. 인력을 늘리기 어렵고 승인 책임은 사라지지 않는다면, ‘사람이 더 열심히’가 아니라 ‘사람이 판단해야 하는 순간을 줄이는 설계’를 선택할 수밖에 없습니다. 버그 바운티를 끝낸 건 “제보가 싫어서”가 아니라 “검토 가능한 제보만 남도록 운영을 재정렬하기 위해서”입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;2. 저품질 기여는 왜 병목이 될까: 정보가 없으면 기여가 ‘질의응답’으로 바뀐다&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;저품질 기여의 공통점은 잘못된 코드가 아니라 ‘정보의 공백’입니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;저품질 기여를 ‘코드가 나쁘다’로만 보면 핵심을 놓칩니다. 검토 예산을 갉아먹는 이유는 코드의 품질이 아니라, 제출물이 ‘검토를 시작할 만큼의 정보’를 담고 있지 않기 때문입니다. 저품질 기여의 핵심은 코드 품질이 아니라 정보의 공백입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 공백은 대체로 비슷한 모습으로 나타납니다. 재현 절차가 없고, 기대 결과와 실제 결과가 없고, 영향 범위가 비어 있고, 테스트가 없고, 실패 시 대응(롤백 계획, 모니터링 포인트)이 없습니다. 이런 상태의 제출물은 변경 제안이 아니라 “이 상황을 대신 파악해 달라”는 요청에 가깝습니다. 그리고 그 요청을 처리하는 비용은 제출자가 아니라 검토자, 더 정확히는 승인 책임자에게 전가됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3668/section_2.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 이미지 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, 이슈가 “안 됩니다”로 시작하면 검토자는 질문부터 꺼내야 합니다. 어떤 버전에서 발생하는지, 어떤 환경에서 실행했는지, 어떤 시나리오로 재현되는지. 답을 받으면 다시 재현하고, 재현이 안 되면 다시 질문합니다. 정보가 비어 있을수록 이 왕복은 길어지고, 그 순간부터 기여는 질의응답으로 바뀝니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 오해가 자주 생깁니다. 기여자는 “내가 시간을 들여 만들었는데 왜 이렇게 까다롭게 굴지?”라고 느낍니다. 반대로 유지보수자는 “이건 제출물이 아니라 빈칸이다”라고 판단합니다. 이 간극은 태도의 문제가 아니라 운영 비용의 문제입니다. 정보가 비어 있으면 누군가는 그 빈칸을 메워야 하고, 그 비용과 책임은 결국 승인 책임자에게 모입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;질의응답의 끝은 ‘승인 책임’입니다. 질문이 쌓일수록 검토는 느려지는 게 아니라 무거워집니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;정보 공백이 병목이 되는 이유는 단순히 “시간이 오래 걸려서”가 아닙니다. 공백이 클수록 승인 책임이 더 무거워지기 때문입니다. 재현과 검증에 필요한 정보가 없으면 검토자는 “아마 이럴 것이다”로 넘어갈 수 없습니다. 승인 이후 문제가 터졌을 때 책임은 그대로 돌아오기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 제출물의 정보가 빈 상태일수록 검토자는 가정 대신 확인을 택하게 되고, 재현 환경을 만들고 검증 절차를 설계하는 데 더 많은 시간을 써야 합니다. 특히 제보가 보안, 데이터 손상, 서비스 중단처럼 되돌리기 어려운 리스크를 암시할수록, 검토자는 더 보수적으로 움직일 수밖에 없습니다. 결과적으로 정보가 비어 있는 제출물일수록 검토 예산이 더 빨리 소진됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 과정이 반복되면 검토 대기열은 길어지고, 응답은 늦어지고, 커뮤니케이션 비용은 늘어납니다. 그 다음부터 오픈소스 프로젝트가 선택할 수 있는 대응은 사실상 제한됩니다. 인력을 쉽게 늘릴 수 없고, 승인 책임도 사라지지 않기 때문입니다. 그래서 프로젝트는 접수 채널을 줄이거나, 기여 문턱을 높이거나, 우선순위를 규칙으로 고정하는 방식으로 움직입니다. 어떤 선택이든 공통점은 하나입니다. 사람의 판단이 필요한 순간을 줄여 승인 책임을 감당 가능한 범위로 되돌리는 방향으로 수습합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결론은 단순합니다. 저품질 기여는 불쾌함의 문제가 아니라 운영의 문제입니다. 기여자가 “코드만 제출”하면, 승인자는 “정보를 채우는 업무”를 떠안게 됩니다. 그래서 해법은 도덕이나 태도가 아니라 설계입니다. 검토가 시작되는 최소 조건을 명확히 명시해야 하고, 그 조건을 양식과 규칙으로 고정해야 합니다. 그래야 기여는 질의응답이 아니라 검토 가능한 제출물로 들어옵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;3. 기여는 권리가 아니라 합의다: ‘증거’로 검토를 시작하는 문턱&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;양식은 기본값이 되었지만, AI 슬롭은 ‘채운 양식’으로 들어옵니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;앞 문단에서 정리한 결론은 분명합니다. 정보가 비어 있으면 기여는 질의응답으로 바뀌고, 그 비용과 책임은 승인 책임자에게 붙습니다. 그래서 많은 오픈소스 프로젝트는 이미 버그 리포트 양식, 이슈 양식, 변경 제안 양식처럼 “필수 입력 칸”을 갖춘 채로 운영합니다. 빈칸 제출을 줄이고, 같은 질문을 반복하지 않기 위한 최소한의 안전장치입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;문제는 AI 슬롭이 이 안전장치를 너무 쉽게 통과한다는 점입니다. 양식의 칸은 모두 채워져 있고, 문장도 그럴듯합니다. 그런데 검토자가 결론을 내리기 위해 필요한 핵심, 즉 재현 가능한 증거와 검증 가능한 근거는 비어 있는 경우가 많습니다. 이 순간부터 검토 예산이 소진됩니다. 빈칸이라면 “정보 보완 요청”으로 빠르게 분기할 수 있지만, 그럴듯한 서술은 사람을 붙잡아두고 “혹시 사실일지도 모른다”는 가능성 위에서 시간을 태우게 만들기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;cURL 사례가 정확히 이 함정에 걸렸습니다. 2025년에 들어서며 실제 취약점으로 확인되는 비율이 이전의 15%대에서 5% 아래로 떨어졌고, 슬롭 제보를 반박하는 데 드는 시간과 정신적 비용이 운영을 흔들었다고 공개적으로 적었습니다. 또한 해커원의 평판 시스템과 프로그램 설정만으로는 “모래가 기계로 들어오는 것”을 막기에 충분하지 않았다고 정리합니다. 양식이 존재한다는 사실만으로 검증 부담이 자동으로 줄어들지는 않는다는 뜻입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 여기서 방향이 갈립니다. 양식을 더 촘촘히 만들어 문장을 더 많이 쓰게 하는 쪽이 아니라, 검토를 시작하는 문턱을 “작성 가능한 텍스트”가 아니라 “조작하기 어려운 증거” 쪽으로 옮겨야 합니다. 그리고 그 문턱은 기여자와 유지보수자 사이의 합의로 고정돼야 합니다. 그래야 기여가 다시 질의응답이 아니라, 검토와 판단의 흐름으로 돌아옵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;평판과 재현물로 문턱을 세우면, 검토 예산이 ‘판단’에 쓰이기 시작합니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;양식은 누구나 채울 수 있습니다. AI는 더 쉽게 채웁니다. 그래서 문턱은 두 갈래로 세워야 합니다. 누가 제보하느냐를 걸러내는 평판 문턱, 무엇을 제보하느냐를 검증하는 재현물 문턱입니다. 둘 다 목적은 같습니다. 사람이 시간을 쓰기 전에, 검토가 시작될 조건을 먼저 만족시키게 만드는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3668/section_3.png"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href="https://nodejs.org/en/blog/announcements/hackerone-signal-requirement"&gt;&lt;u&gt;New HackerOne Signal Requirement for Vulnerability Reports&lt;/u&gt;&lt;/a&gt;, node.js&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫째, &lt;strong&gt;제출자 평판 문턱&lt;/strong&gt;입니다. Node.js는 해커원 제보에 신호 점수(Signal) 1.0 이상을 요구하는 정책으로 방향을 틀었습니다. 배경 설명이 구체적입니다. 보안 팀이 저품질 제보 증가를 겪어 왔고, 특히 12월 15일부터 1월 15일 사이에 30건이 넘는 제보가 들어오면서 분류와 검증이 실제 보안 업무 시간을 잠식했다고 명시합니다. 그래서 최소한의 평판을 요구해 “유효한 제보를 꾸준히 해온 제출자”를 우선 통과시키고, 문턱 아래의 제출자는 다른 방식으로 보안 팀과 접촉하도록 안내합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 정책은 ‘제보를 닫는 결정’이라기보다 ‘검토가 시작되는 경로를 재설계한 결정’에 가깝습니다. Node.js는 2026년 2월 19일 업데이트에서 신호 점수가 없는 신규 연구자는 해커원을 통해 더 이상 제보를 제출할 수 없다고 분명히 못 박았습니다. 대신 신규 제보자는 보안 릴리스 담당자에게 슬랙으로 먼저 연락하라고 안내합니다. 운영적으로 보면, 검토 예산이 가장 비싼 경로로 새 제보가 쏟아지는 상황을 막고, 추가 확인이 필요한 제보는 다른 통로에서 먼저 정리되도록 흐름을 바꾼 것입니다. 검토 예산이 제한돼 있을 때는 “누가 어떤 통로로 들어오느냐” 자체가 곧 문턱이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;둘째, &lt;strong&gt;재현 가능한 증거 문턱&lt;/strong&gt;입니다. AI 슬롭을 가장 확실하게 줄이는 방식은 “설명”이 아니라 “재현물”이 제출물의 중심이 되게 만드는 것입니다. 사람들이 일상적으로 쓰는 대형 오픈소스일수록 텍스트 양식보다 “재현 링크”를 문턱으로 세우는 쪽에 더 가깝게 움직입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, 리액트 네이티브(React Native)는 제보 양식에서 “재현물 링크”를 의무 항목으로 두고, 재현물이 없으면 이슈가 닫힐 수 있다고 명시합니다. 여기서 중요한 점은 “재현 절차를 글로 적어 달라”가 아니라 “재현이 가능한 형태의 결과물로 보여 달라”는 요구입니다. 글을 잘 쓰는 능력과 상관없이, 실제로 실행 가능한 재현물이 있어야만 검토가 시작됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;정리하면, “정보 공백”을 메우는 수준을 넘어 이제는 “텍스트 공백을 텍스트로 채우는 방식” 자체가 한계에 닿았습니다. AI 슬롭 시대의 합의는 더 선명해져야 합니다. 제출물은 ‘증거’를 포함해야 하고, 유지보수자는 그 증거가 들어왔을 때만 검토 예산을 판단에 씁니다. 그리고 이제 남은 과제는, 이 문턱을 개인의 판단이 아니라 운영 규칙과 자동화로 고정해 일관되게 작동시키는 일입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;4. 금지 대신 문턱을 세운다: 품질 문턱으로 검토 예산을 지키는 방법&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;오픈소스가 아니어도, 품질 문턱은 이렇게 세웁니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;검토 예산과 승인 책임이 존재하는 곳이라면 오픈소스가 아니어도 같은 원리가 작동합니다. 제보나 요청, 변경 제안이 늘어나는 속도에 비해 사람의 판단 시간은 자동으로 늘지 않습니다. 그래서 “좋은 의도”에 기대기보다, 검토가 시작되는 조건을 운영 규칙으로 고정해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;핵심은 네 가지입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;첫째, &lt;strong&gt;검토를 시작할 수 있는 상태를 먼저 정의&lt;/strong&gt;해야 합니다. 재현 가능성, 검증 가능성, 영향 범위, 실패 시 대응처럼 승인 책임을 무겁게 만드는 빈칸이 무엇인지부터 합의해야 합니다. 이 정의가 없으면 검토는 매번 사람의 감각과 컨디션에 기대게 되고, 같은 유형의 왕복이 반복됩니다.&lt;/li&gt;&lt;li&gt;둘째, 그 &lt;strong&gt;기준을 “권고”가 아니라 “문턱”으로 만들어야&lt;/strong&gt; 합니다. 필수 정보가 없으면 검토를 시작하지 않고 보완 요청 상태로 분기하고, 일정 기간 응답이 없으면 정리되는 흐름을 규칙으로 고정해야 합니다. 문턱은 누군가를 혼내기 위한 장치가 아니라, 검토가 질의응답으로 무너지는 것을 막는 운영 장치입니다.&lt;/li&gt;&lt;li&gt;셋째, &lt;strong&gt;사람이 보기 전에 기계가 먼저 확인할 수 있는 증거를 앞단에 붙여야&lt;/strong&gt; 합니다. 기본 테스트나 자동 검증 절차가 통과하지 않으면 사람의 검토 시간을 쓰지 않는 원칙을 세우면, 검토 예산은 설명을 읽는 데가 아니라 판단과 결론을 내리는 데 쓰이기 시작합니다. 이 한 줄 원칙이 “사람이 판단해야 하는 순간”을 눈에 띄게 줄입니다.&lt;/li&gt;&lt;li&gt;넷째, &lt;strong&gt;우선순위를 규칙으로 공개&lt;/strong&gt;해야 합니다. 경고와 긴박한 표현이 아니라, 재현물과 근거, 영향 범위가 우선순위를 결정하도록 설계해야 승인 책임이 통제됩니다. 무엇이 먼저 처리되고 무엇이 뒤로 밀리는지가 규칙으로 설명되면, 커뮤니케이션 비용도 함께 내려갑니다.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;정리하면 품질 문턱은 “거절을 늘리는 장치”가 아니라 “검토가 시작되는 버튼을 명확히 하는 장치”입니다. 이 버튼이 없으면 친절함은 오래가지 못하고, 결국 채널 축소나 범위 축소로 이어집니다. 문턱을 먼저 세우는 편이, 닫지 않고 유지하는 쪽에 더 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;오픈소스에 기여하고자 한다면, 이렇게 행동하셔야 합니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;오픈소스 생태계에 기여하려는 기여자라면, “무엇을 제출할지” 이전에 “&lt;strong&gt;어떤 책임을 질지&lt;/strong&gt;”부터 분명해져야 합니다. 오픈소스는 누군가의 시간과 승인 책임 위에 돌아가는 운영체제입니다. 그래서 기여는 권리가 아니라 의무를 동반한 합의입니다. 내가 던진 한 줄이 검토 대기열을 늘리고, 승인자의 불확실성을 키우고, 결국 채널 축소나 운영 범위 축소로 이어질 수도 있다는 사실을 감안해야 합니다. 기여는 ‘선한 마음’이 아니라, 생태계의 검토 예산을 아끼는 방식으로 증명됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 관점에서 가장 위험한 기여는 ‘내가 무엇을 바꾸는지’와 ‘그 변화가 어디까지 영향을 주는지’를 충분히 이해하지 못한 상태에서 제출되는 기여입니다. 동기는 다양할 수 있습니다. 실제로 쓰다가 불편해서일 수도 있고, 학습이나 경험을 위해서일 수도 있고, 이력서 한 줄을 남기기 위한 시도일 수도 있습니다. 문제는 동기가 아니라 준비 수준입니다. 맥락을 깊게 파지 않은 채 그럴듯한 설명과 코드를 얹어 제출하면, 겉으로는 생산적으로 보이지만 실제로는 운영 비용을 소비시킵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 AI가 이 위험을 더 키웁니다. 그럴듯한 글과 코드가 빠르게 만들어지면서 “검토 가능한 상태”로 보이게 만들기 쉬워졌기 때문입니다. 하지만 재현과 검증이 없으면, 유지보수자는 그 순간부터 제출자가 생략한 사실 확인과 영향 분석을 대신 떠안게 됩니다. 결국 남는 것은 오픈소스의 개선이 아니라 늘어난 질의응답과 더 보수적으로 변한 승인 기준입니다. 이런 기여는 커뮤니티를 돕는 제안이라기보다, 커뮤니티의 시간을 소비하는 요청에 더 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 기여는 “증거”에서 시작해야 합니다. 문장으로 설득하려 하지 말고, 내가 겪은 문제 혹은 불편함을 재현 가능한 형태로 고정해야 합니다. 최소 재현이 가능하도록 조건을 좁히고, 가능하면 실행 가능한 재현물 링크나 시나리오를 남겨야 합니다. “어떻게 하면 같은 문제가 다시 일어나는지”가 포함되지 않으면, 검토는 개선이 아니라 조사로 바뀝니다. 그리고 이 조사의 비용은 결국 승인 책임자에게 붙습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다음은 검증입니다. 단순히 “개선했습니다”가 아니라 문제 혹은 불편함을 “어떻게 확인했는지”가 제출물 안에 있어야 합니다. 테스트가 왜 실패했고 어떻게 통과하게 됐는지, 테스트로 구현하기 힘들다면 어떤 시나리오로 발생을 했는지, 결과가 무엇인지가 포함돼야 검토가 판단으로 진행됩니다. 마지막으로 영향 범위를 좁혀 주셔야 합니다. 어디까지 영향을 주는지, 호환성 변화가 있는지, 문제가 생기면 어떻게 되돌릴 수 있는지까지 적히면 승인 책임이 가벼워지고 검토는 빨라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3668/section_4.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 이미지 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;무엇보다 중요한 태도는 “&lt;strong&gt;사용자 관점의 깊이&lt;/strong&gt;”입니다. 오픈소스에 진심으로 기여한다는 것은, 내가 실제로 쓰는 사용자로서 문제를 끝까지 파고들고 재현과 검증으로 사실을 고정한 뒤, 유지보수자가 결론을 낼 수 있는 형태로 제출물을 완성하는 일입니다. 여기서 핵심은 “열심히 썼다”가 아니라 “승인 책임을 가볍게 만들었다”입니다. 재현이 되고, 검증이 되고, 영향 범위가 좁혀져 있으면 검토는 빠르게 판단으로 진행됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;생태계를 바로 잡는 기여는 시간을 요구합니다. 그 시간을 누가 먼저 쓰느냐가 운영 비용을 결정합니다. 내가 쓰지 않으면 유지보수자가 씁니다. 내가 증거를 만들지 않으면 승인 책임자가 사실을 확인합니다. 그래서 기여는 결국 “내 시간을 먼저 쓰겠다는 선택”입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결론적으로, &lt;strong&gt;좋은 기여는 원인이 분명하고 불확실성을 줄인 제출물&lt;/strong&gt;입니다. 오픈소스를 아끼는 기여자는 더 많은 제안을 올리는 사람이 아니라, 한 번의 제출로 더 적은 질문이 오가게 만드는 사람입니다. 이런 합의를 지키는 기여가 늘어날수록, 오픈소스 생태계는 채널을 닫는 쪽이 아니라 더 오래 열어둘 수 있는 쪽으로, 더 건강하고 지속 가능한 방향으로 나아갈 수 있을 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>개발자의 일상, 글감으로 바꾸는 ‘글감봇’을 만들다</title><link>https://yozm.wishket.com/magazine/detail/3663</link><description>글을 쓸 때 가장 어려운 부분은 무엇일까? 나에게는 글감을 정하는 일이다. 원고를 한 달에 한 번 쓰는데, 3주가 넘도록 고민한 적도 있다. 글감은 내가 평소 관심을 갖는 주제들 중에서 고른다. 보통 제일 먼저 최근 작업했던 코드 리포지토리와 북마크해 두었던 웹페이지들을 열어보면서 글감 후보를 리스트업한다. 사이드 프로젝트를 많이 하는 시기에는 외부에 공개할 만한 코드가 많지만, 회사 업무가 바쁜 시기에는 대부분의 코드가 회사 코드라 한 번 더 생각해야 한다. 그런데 내가 하는 대부분의 일은 컴퓨터로 이루어지고, 매일 같은 툴을 반복적으로 사용한다. 그렇다면 자동화할 수 있는 부분이 있지 않을까 하는 생각이 문득 들었다. 그래서 나는 글감 찾는 일을 한 번 AI에게 맡겨보기로 했다.</description><guid>https://yozm.wishket.com/magazine/detail/3663</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;글감 정하기가 제일 어렵다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;글을 쓸 때 가장 어려운 부분은 무엇일까? 나에게는 글감을 정하는 일이다. 원고를 한 달에 한 번 쓰는데, 3주가 넘도록 고민한 적도 있다. 글감은 내가 평소 관심을 갖는 주제들 중에서 고른다. 보통 제일 먼저 최근 작업했던 코드 리포지토리와 북마크해 두었던 웹페이지들을 열어보면서 글감 후보를 리스트업한다. 사이드 프로젝트를 많이 하는 시기에는 외부에 공개할 만한 코드가 많지만, 회사 업무가 바쁜 시기에는 대부분의 코드가 회사 코드라 한 번 더 생각해야 한다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아무리 흥미로운 소재도 필터링을 거치는 과정에서 재미 요소가 많이 휘발되기 때문에, 대체로 최종 글감 후보에서 탈락시키게 된다. 그리고 너무 어려운 소재나 식상한 소재도 제외해야 한다. 이렇듯 다양한 기준으로 후보를 좁혀 나가다 보면 정말 오랜 시간이 걸린다. 결국, 글쓰기를 시작하기도 전에 지치고 만다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;생각해 보면, 글감을 정하는 일은 일종의 메타인지 작업이다. "최근에 내가 뭘 했지?", "뭐에 관심이 있었지?", "그중에 다른 사람에게도 의미 있는 이야기는 뭐지?"를 찾는 일이다. 그런데 내가 하는 대부분의 일은 컴퓨터로 이루어지고, 매일 같은 툴을 반복적으로 사용한다. 그렇다면 자동화할 수 있는 부분이 있지 않을까 하는 생각이 문득 들었다. 그래서 나는 글감 찾는 일을 한 번 AI에게 맡겨보기로 했다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;글감봇 개발 과정 A to Z&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;내가 자동화를 원하는 기능은 다음과 같았다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;최근에 내가 작업한 내용들을 조회&lt;/li&gt;&lt;li&gt;작업내용을 AI 모델에 인풋으로 넣으면, 이를 기반으로 글감을 추천&lt;/li&gt;&lt;li&gt;결과물은 이메일로 전송&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 이걸 위한 코드를 짜야 하는데, 그것조차도 AI에게 시키고 싶었다. 코딩에 특화된 AI 에이전트로는 대표적으로 클로드 코드와 코덱스가 있다. 코딩 에이전트의 특징은 터미널에서 실행된다는 것이다. 만약 내가 ChatGPT에게 코드를 작성해 달라고 하면, 응답으로 코드를 받고 그것을 복사해서 사용해야 한다. 이건 두 가지 측면에서 불편한데, 하나는 일일이 손으로 복사해 붙여 넣기를 해야 한다는 점이고, 또 하나는 그 코드가 아무런 맥락 없이 짜인 코드라는 점이다. 하지만 터미널에서 실행하는 코딩 에이전트는 알아서 주변 파일들로부터 맥락을 학습해 파일을 생성하고 코드를 작성해 준다. 나는 클로드 코드를 선택했다. 2026년 2월 기준, &lt;a href="https://www.swebench.com/"&gt;&lt;u&gt;AI 모델 벤치마크&lt;/u&gt;&lt;/a&gt; 1위는 Claude의 Opus 모델이며, GPT의 모델들은 상대적으로 낮은 순위를 기록하고 있다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;클로드 코드 같은 터미널 기반 에이전트를 사용하면 로컬 파일 시스템에 자유롭게 접근시킬 수 있다. 로컬에 있는 Chrome 북마크 파일을 파싱하고, VS Code 캐시를 읽는 등의 작업도 매우 쉽게 시킬 수 있다. 초반에는 어떤 작업물들을 조회하게 해야 할지 확신이 없어서 완벽한 프롬프트를 기반으로 시작하지는 못했다. ‘글감봇을 만들고 싶어’로 시작해서 클로드와 대화를 통해 프로젝트를 발전시켜 나갔다. 기본 기능을 완성하기까지는 약 2시간이 소요되었고, 지난 일주일간 지속적으로 개선하는 중이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/email.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 데이터 수집&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;글감봇의 핵심 아이디어는 단순하다. 평소에 내가 글감을 찾을 때 훑어보는 데이터 소스를 그대로 AI에게 넘겨주는 것이다. 나는 보통 글감을 정할 때 최근에 작업한 코드, 노션에 기록한 내용, 크롬에 북마크해 둔 페이지들을 참고한다. Claude Code에게 "나의 일상에서 사용하는 도구 중 글감 소스로 활용할 수 있는 것"을 물었더니, 다음 7가지를 제안해 주었다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Notion:&lt;/strong&gt; 메모와 기록. 평소에 떠오르는 생각을 적어두는 곳이다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;브라우저 북마크:&lt;/strong&gt; 최근 관심 분야를 가장 잘 보여준다. 어떤 기술을 검색하고 저장했는지가 고스란히 남아 있다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Claude 대화 기록:&lt;/strong&gt; AI와 함께 작업한 내용. 어떤 문제를 풀었는지, 어떤 삽질을 했는지가 대화 형태로 기록되어 있다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;VS Code / Cursor 에디터 캐시:&lt;/strong&gt; 최근에 어떤 프로젝트를 열었는지 알 수 있다. 에디터가 캐시해 둔 최근 파일 목록을 읽는다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;GitHub 활동:&lt;/strong&gt; 커밋, PR, 이슈. 실제로 코드를 쓴 기록이다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Apple Calendar:&lt;/strong&gt; 일정에서 스터디, 기술 미팅 같은 이벤트를 가져온다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;RSS 피드:&lt;/strong&gt; 구독 중인 블로그의 최신 글. 업계 트렌드를 반영한다.&lt;/li&gt;&lt;/ol&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;흥미로운 점은 이 목록 중 대부분이 내 아이디어가 아니라, Claude Code가 제안해준 것이라는 점이다. 나는 처음에 Notion과 GitHub 정도만 생각하고 있었는데, "에디터가 캐시해 둔 최근 파일 목록도 읽을 수 있다"는 것은 미처 떠올리지 못했다. 그래서 클로드에게 이 제안을 받았을 때 무척 솔깃했다. 실제로 이 데이터는 "요즘 어떤 프로젝트에 시간을 쓰고 있는지"를 가장 정직하게 보여준다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최종적으로는 브라우저 북마크와 VSCode 에디터 캐시를 소스에서 제외했다. VSCode 에디터 캐시는 특정 컴퓨터의 로컬 디렉터리에 저장되기 때문에, 원격 저장소인 GitHub에서 GitHub Actions를 실행할 때 직접 접근할 수 없다. 또한 코드는 어차피 GitHub에 Push되므로, 저장소에 있는 코드로 충분히 대체할 수 있다고 판단했다. 브라우저 북마크는 실질적인 활용도가 낮아 제외했다. 평소에도 북마크는 단순 참고용으로만 사용했으며, 직접적인 작업 소재로 활용하는 경우는 거의 없었기 때문이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;각 소스에서 데이터를 가져오는 수집기 코드도 모두 Claude Code가 작성해 주었다. 나의 역할은 클로드가 접근 권한이 없어 문제를 겪지 않도록, 필요한 토큰들을 환경 변수에 등록해 주는 일이었다. 데이터들의 중요도는 처음에는 동등했으나, 나중에는 가중치를 추가했다. 가령 내가 직접 적어 둔 기록은 높게, 외부에서 읽은 글은 낮게 반영된다. 이 가중치 덕분에 추천되는 글감이 "내가 진짜 경험한 이야기" 위주로 나오게 되었다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;7가지 소스에서 수집한 데이터를 하나의 프롬프트로 묶어 Claude API에 전달한다. 이때 Claude에게 "개발자 출신의 편집자 겸 글쓰기 코치" 역할을 부여한다. 나는 단순히 소재만 원한 것이 아니라, 글의 주제와 방향성까지 제안받고 싶었다. 그래서 각 글감에 대해 추천 이유, 예상 독자, 개요, 참고 키워드를 함께 생성하도록 했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/diagram.png"&gt;&lt;figcaption&gt;&amp;lt;출처: Claude Code 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 글감 추천&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;결과물들은 대부분 괜찮았다. 사실 이번 글감봇도 글감봇에게 추천받은 주제다. 꽤 만족스러웠고, 실제로 추천받은 개요를 많이 참고했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/result_good.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런가 하면 할루시네이션이 포함된 결과물도 있었다. 클로드는 ‘한 일’과 ‘할 일’을 구분하지 못한다. 그래서 내가 할 일로 적어 둔 일정을 이미 완수한 일로 생각한다. 하지만 이는 실제로 진행한 적이 없는 일이므로, 클로드는 그 과정을 상상력으로 채우는 모양이다. 이건 아직도 고민하고 있는 부분이다. 아래 예시는 순전히 클로드가 상상해 낸 것이고, 내 캘린더에는 ‘Write Promotion 권한 회수 요청하기’라는 할 일이 적혀 있었을 뿐이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/result_bad.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 성능 튜닝&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;처음에는 이메일로 도착한 글감 메일을 보고, 불을 처음 발견한 원시인처럼 기뻐했으나 몇 번 더 테스트해 보는 과정에서 개선할 부분이 눈에 보였다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;첫째, 뻔한 주제만 나왔다&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;초반에는 RSS 피드 최신 글에 과도하게 영향을 받아, "2026년 AI 트렌드 정리" 같은 누구나 쓸 수 있고 나와 큰 관련이 없는 글감이 상위에 추천됐다. 이를 해결하기 위해 데이터 소스별 가중치 시스템을 도입했다. 내가 직접 작성한 Notion 메모에 2.0, Claude 대화와 GitHub에 1.5, 외부 RSS에 0.5를 부여했다. 결과는 즉시 달라졌다. 글감봇 개발기를 비롯한 프로젝트 관련 내용들이 상위로 올라왔다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/weight.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;둘째, 같은 글감이 반복 추천되었다&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;물론 테스트 중에는 짧은 간격으로 결과물을 생성하니 당연한 결과였다. 하지만 한 프로젝트를 긴 기간 동안 붙잡고 있는 경우도 많기 때문에, 글감의 중복 추천은 분명 생각해 볼 만한 문제였다. 이 문제를 고민하면서 글감 추천 주기에 대해서도 함께 고민했다. 회사에 입사하고 바빠지면서 이메일이나 메시지를 읽는 일이 번거롭게 느껴져, 구독했던 뉴스레터들도 하나씩 정리해 나가던 차였다. 마찬가지로 글감봇이 매일같이 이메일을 보낸다면 소음처럼 느껴지고 금방 질릴 것 같았다. 그래서 주기를 일주일로 정했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;topic_history.json에 과거 12주간 추천 이력을 저장하고, 프롬프트에 "이미 추천한 주제는 피해줘"라는 조건을 추가했다. 그러자 글감봇은 우회 전략을 선택한 것인지, 같은 기술이라도 다른 각도로 추천해주었다. 예를 들어 한 번은 “NullReferenceException 디버깅 과정”이라고 추천해주고, 그다음번에는 “.NET 개발자가 알아야 할 Exception Settings”라고 추천해주는 식이었다. 다양한 관점으로 추천해 주는 건 괜찮은 것 같아서 수긍하기로 했다. 또한 현재는 topic_history.json으로 관리하고 있지만, 양이 많아지면 Notion 테이블을 DB로 활용하는 것도 고민 중이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;셋째, 모델에 따라 품질 차이가 컸다&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;모델별 성능을 비교하고 싶어서 같은 데이터를 넣고, Claude의 Sonnet과 Opus로 A/B 테스트를 돌려봤다. 소재 선정 자체는 비슷했다. 차이는 개요에서 갈렸다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/result_sonnet.png"&gt;&lt;figcaption&gt;Sonnet이 추천한 글감 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/result_opus.png"&gt;&lt;figcaption&gt;Opus가 추천한 글감 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Sonnet은 사실을 평면적으로 서술하는 반면, Opus는 좀 더 입체적이고 통합적으로 사고하는 것으로 보였다. 비용은 약 5배 정도 차이가 나지만, 그래도 추천받은 글감을 가지고 이야기를 만들어 내야 하는 입장에서는 상황을 판단하고, 해석까지 제시해 주는 Opus가 낫다고 판단해 Opus를 선택했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4) 배포와 운영&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;글감봇은 GitHub Actions로 매주 금요일 오후 5시(KST)에 자동 실행된다. 결과는 HTML 이메일로 포맷팅되어 Gmail로 발송된다. 금요일 퇴근 무렵에 이메일을 열면, 주말에 살펴볼 글감 10개가 개요와 함께 정리되어 있다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;GitHub Actions를 선택한 이유는 배포를 따로 관리하지 않아도 되고, GitHub 레포지토리에 올라간 코드만으로 바로 실행할 수 있으며, 스케줄링 기반으로 동작하기 때문이다. 글감봇은 주 1회만 실행되면 충분하고, 한 번 실행하는 데 약 5분이면 끝난다. 이런 작업을 위해 상시 서버를 운영하는 것은 과하다고 판단했다. 또한 GitHub Actions는 퍼블릭 레포지토리에서는 무료로 사용할 수 있고, 프라이빗 레포지토리에서도 월 2,000분의 무료 실행 시간이 제공된다. 글감봇의 실행 주기와 소요 시간을 고려하면 비용 부담도 거의 없다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;배포 과정에서 한 가지 까다로웠던 부분이 있다. 바로 로컬 디렉터리 경로에 존재하는 에디터 캐시, 북마크, 클로드 히스토리를 다루는 부분이었다. 이 중 에디터 캐시는 GitHub로 대체할 수 있다고 판단해 제외했고, 브라우저 북마크는 평소에도 참고만 하는 정도라 과감히 제외했다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Claude 대화 기록은 로컬의 ~/.claude/ 디렉터리에만 존재하는데, GitHub Actions에서 이 데이터를 사용하려면 어딘가에 올려 둬야 했다. GitHub Secrets에 넣기에는 48KB 용량 제한에 걸렸고, 결국 Private Gist를 경유하는 방식으로 해결했다. Claude와 대화를 종료할 때 SessionEnd hook을 통해 그날의 대화 내역이 Gist에 업로드되고, GitHub Actions가 실행될 때 Gist에서 다운로드하는 흐름이다. 30일 이상 된 Gist는 삭제하도록 했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;5) 프라이버시와 보안&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;7개의 데이터 소스에는 Notion 메모, 캘린더 일정, AI 대화 기록, 에디터 캐시처럼 민감할 수 있는 정보가 포함된다. 따라서 보안은 처음부터 고려해야 할 요소였다. 모든 API 키와 시크릿은 .env 파일에만 저장하고, .gitignore에 .env를 등록해 저장소에 커밋되지 않도록 했다. GitHub Actions에서는 Repository Secrets를 통해 런타임에만 환경 변수를 주입하는 방식으로 관리한다. 코드에는 어떤 비밀 값도 하드코딩하지 않는다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;6) 비용 관리&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Claude API 비용을 살펴보면, Opus 모델 기준 회당 약 $0.6, 월 4회 실행 시 약 $2.5이다. 처음에 사용한 Sonnet 모델은 회당 $0.11로 저렴했지만, 앞서 말한 품질 차이 때문에 Opus로 전환했다. 커피 한 잔 값으로 한 달간 글감 40개의 브리프를 받는 셈이니, 글쓰기에 투자하는 비용으로는 꽤 합리적이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/cost_graph.jpeg"&gt;&lt;figcaption&gt;&amp;lt;출처: Cluade Code 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;클로드에게 전달하는 프롬프트에서는 한 번에 10개의 주제를 생성하도록 설정했다. 그런데 특정 주제에서 출력 토큰이 과도하게 사용되면 전체 10개가 완성되기 전에 응답이 잘리는 문제가 발생했다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이를 해결하기 위해 주제 하나당 max_output_tokens를 800으로 제한했다. 덕분에 예산을 통제하면서도 안정적으로 10개의 결과를 받을 수 있게 되었다. 또한 매 실행 시 토큰 사용량과 비용을 기록하도록 해서 지속적으로 모니터링하고 있다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3663/cost_table.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;글감봇을 2주간 사용해 보니 효과는 숫자로 나타났다. 글감 선정에 최소 반나절에서 몇 주가 소요되곤 했는데, 이제 이메일을 훑는 5분으로 줄었다. 아직 첫 번째 원고이긴 하지만, 추천받은 글감이 실제 원고로 연결되는 경험도 했다. 그리고 채택하지 않은 다른 글감들도 "아, 이런 관점도 있구나" 하는 자극을 주기 때문에 나름의 가치가 있다고 느낀다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;글감봇의 가장 큰 장점은 "나만 쓸 수 있는 글"을 추천해준다는 점이다. 내 GitHub 커밋, 내 Notion 메모, 내 Claude 대화에서 뽑아낸 주제이기 때문에 다른 누구도 같은 글감을 받을 수 없다. 개발 블로그의 차별화는 결국 자신만의 경험에서 나온다고 생각하는데, 글감봇이 그 경험을 알아서 발굴해 주는 셈이다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 글감봇을 만들면서 한 가지 깨달은 것이 있다. AI를 가장 잘 활용하는 방법은 "대단한 것을 시키는 것"이 아니라, "귀찮지만 반복적인 나의 작업을 대신 시키는 것"이었다. 글감 선정은 창의적인 작업이라고 생각했지만, 알고 보니 데이터 수집과 패턴 매칭에 가까웠다. 그 사실을 알게 된 것만으로도 이 프로젝트는 가치가 있었고, 최고의 글감은 거창한 데서 오는 것이 아니라, 이미 내 일상 속에 있었다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>소프트웨어 기획 전용 AI 개발기</title><link>https://yozm.wishket.com/magazine/detail/3661</link><description>안녕하세요, 팀 매니패스트입니다. 요즈음 저희 프로덕트인 매니패스트의 정식 출시 축하와 더불어, "왜 그런 소프트웨어 기획 전용 AI를 만들게 됐냐"는 질문을 자주 받습니다. 보통은 기술적인 답을 기대하시는데, 솔직히 말씀드리자면 저희의 출발점은 기술이 아니라 반복된 좌절이었습니다. 아이디어는 있는데 구조화된 기획서가 없고, 구조화된 기획서가 없으니 커뮤니케이션이 깨지고, 커뮤니케이션이 깨지니 결과물이 산으로 갑니다. 그때 저희가 품은 질문이 하나 있습니다. "이렇게 치명적이고 반복적인 문제를, 왜 아무도 도구로 풀지 않았을까?" 오늘은 저희가 이 질문에서 시작해, 소프트웨어 기획 전용 AI를 직접 만들기까지의 과정을 이야기해 보려 합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3661</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;&lt;strong&gt;이 글은 ‘리오랩(매니패스트)’이 제작하고, 요즘IT가 기업 제휴 콘텐츠로 소개합니다.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;1. 디자인 에이전시를 운영하며 느낀 ‘기획 병목’ 문제&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;안녕하세요, 팀 &lt;a href="https://yozm.wishket.com/magazine/product-valley/products/manyfast/"&gt;매니패스트&lt;/a&gt;입니다. 요즈음 저희 프로덕트인 매니패스트의 정식 출시 축하와 더불어, "왜 그런 소프트웨어 기획 전용 AI를 만들게 됐냐"는 질문을 자주 받습니다. 보통은 기술적인 답을 기대하시는데, 솔직히 말씀드리자면 저희의 출발점은 기술이 아니라 반복된 좌절이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저희 팀의 전신은 UXUI 전문 디자인 에이전시입니다. 스타트업 MVP부터 대기업 사내벤처까지, 4년간 350건이 넘는 프로젝트를 수행하면서 소프트웨어가 태어나고 성장하는 과정의 거의 모든 장면을 옆에서 지켜봐 왔습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저희가 주로 만났던 고객은 초기 스타트업이나 사내벤처처럼 규모가 작고 속도가 빠른 조직들이었습니다. 이런 조직들에게 기획은 대체로 후순위였습니다. 예산은 한정되어 있고, 사용할 수 있는 시간도 적습니다. 그러다 보니 "일단 만들어보고 시장 반응을 보자"는 판단이 먼저 앞섰기 때문입니다. 기획에 시간과 비용을 따로 쓰는 곳은 드물었고, 자연스럽게 UXUI 전문 디자인 에이전시인 저희의 역할도 좁아졌습니다. 고객이 이미 정해온 방향 위에서 화면을 설계하고, 개발 전달용 산출물을 만들어내는 것. 그게 저희의 사실상 업무 범위의 전부였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 기획을 간과한 채 시작된 프로젝트는 어김없이 흔들렸습니다. 중간에 방향이 바뀌거나, 일정이 끝없이 늘어나거나, 결국 누구도 책임지지 못한 채 조용히 소멸하거나. 좋은 결과를 낸 프로젝트도 물론 많았습니다. 하지만 실패한 것들을 나란히 놓고 보면, 놀라울 정도로 같은 패턴이 반복되고 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기획이 제대로 안 되어 있었습니다. 정확히 말하면 구조화가 부족했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아이디어는 있는데 구조화된 기획서가 없고, 구조화된 기획서가 없으니 커뮤니케이션이 깨지고, 커뮤니케이션이 깨지니 결과물이 산으로 갑니다. 방향이 잡히지 않은 개발은 아무리 빠르게 실행해도 실패에 가까워질 뿐이었습니다. 그리고 이 문제는 특정 고객사만의 문제가 아니었습니다. 규모와 산업을 가리지 않고, 거의 모든 프로젝트에서 반복되는 구조적인 문제였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그때 저희가 품은 질문이 하나 있습니다. "이렇게 치명적이고 반복적인 문제를, 왜 아무도 도구로 풀지 않았을까?"&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;오늘은 저희가 이 질문에서 시작해, 소프트웨어 기획 전용 AI를 직접 만들기까지의 과정을 이야기해 보려 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image3.png" alt="리오랩 시절 수행한 누적 프로젝트 수 및 LG전자, 교보, LS산전 등 다양한 고객사들"&gt;&lt;figcaption&gt;리오랩 시절 수행한 누적 프로젝트 수 및 다양한 고객사들&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;2. 범용 LLM을 통한 기획은 충분하지 않다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;문제를 인식한 다음, 저희가 가장 먼저 한 일은 당연히 이미 존재하는 도구로 문제를 해결하려고 시도해 보는 것이었습니다. ChatGPT와 Claude는 이미 충분히 강력한 도구였고, "이걸로 기획까지 커버할 수 있지 않을까?"라는 기대는 저희만의 것이 아니었을 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 범용 LLM에 기획을 맡겨보면, 처음에는 꽤 감탄하게 됩니다. "부동산 중개인을 위한 SNS 서비스를 기획해줘"라고 입력하면, 그럴듯한 기능 목록이 쏟아져 나옵니다. 회원가입, 매물 등록, 피드, 메시지, 알림 얼핏 보면 완성된 기획서처럼 보이기도 합니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 실무에서 이걸 그대로 쓸 수 있느냐고 물으면, 대답은 "아니요"입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;문제는 기획 사이의 정합성이었습니다. 기획이라는 작업의 본질은 단순히 기능을 나열하는 것이 아니라, 기능과 기능 사이의 관계를 정의하고, 그 관계가 모순 없이 작동하는지를 검증하는 일입니다. 회원가입 로직이 바뀌면 권한 체계가 달라지고, 권한 체계가 달라지면 피드에 보이는 콘텐츠의 범위도 바뀝니다. 기획에서의 하나의 변경은 연쇄적으로 다른 항목에 영향을 미칩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;범용 LLM은 이 연쇄 관계를 유지하지 못합니다. 대화가 길어지면 앞에서 정의한 내용을 잊어버리고, 기능 A에서 설정한 조건과 기능 B에서 설정한 조건이 서로 충돌하는 경우가 빈번하게 발생했습니다. 프롬프트를 아무리 정교하게 작성해도, 결국 사람이 전체 맥락을 머릿속에 들고 다니면서 일일이 검증해야 했습니다. AI를 쓰는 건데, 결국 사람의 부담이 줄지 않는 구조였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또 하나의 근본적인 한계가 있었습니다. 바로 출력 형태의 문제입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;소프트웨어 기획에는 텍스트만으로 표현할 수 없는 영역이 분명히 존재합니다. 정보구조도(IA), 플로우차트, 와이어프레임 이런 시각화된 산출물이 있어야, 개발자와 디자이너가 같은 그림을 보고 일할 수 있습니다. AI는 마크다운과 JSON 같은 텍스트 기반의 언어로 세상을 이해하지만, 최종 의사결정권자인 사람은 도표와 흐름도, 화면으로 시각화된 요소들로 판단하고 결정을 내립니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;범용 LLM은 텍스트를 생성하는 데에는 탁월하지만, 이 텍스트를 구조화된 시각 산출물로 전환하는 것은 태생적으로 어렵습니다. 결국 AI가 뱉어낸 텍스트를 사람이 다시 Excel에 옮기고, Figma에서 흐름도를 그리고, PPT로 정리하는 과정이 반복됩니다. 도구를 줄이려고 AI를 도입했는데, 오히려 한 단계가 더 추가되는 셈이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저희는 이 경험을 통해 확신하게 되었습니다. 프롬프트 엔지니어링만으로는 기획의 문제를 풀 수 없다는 것. 기획이라는 업무의 구조 자체를 이해하고, 그 구조에 맞게 설계된 전용 시스템이 필요하다는 것이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image7.png" alt="범용 LLM으로 기획을 시도한 결과물과 실무 기획서를 비교하는 그림. “AI를 도입해도, 텍스트를 다시 정리하는 수고는 계속되었습니다”라는 텍스트."&gt;&lt;figcaption&gt;범용 LLM으로 기획을 시도한 결과물 (ChatGPT 출력 예시 vs 실무 기획서 비교)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;3. 개발 여정에서 부딪힌 다양한 문제들&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;프로덕트를 설계하는 것과 실제로 만드는 것은 완전히 다른 일이었습니다. 저희는 무엇이 사람들이 겪고 있는 문제인지 안다고 생각했고, 어떤 프로덕트를 만들면 그 문제를 해결해줄 수 있는지도 안다고 생각했습니다. 그러나 머릿속에서는 완벽했던 그림이, 현실의 기술과 사용자 앞에서 무너지는 순간을 저희는 여러 번 경험했습니다. 그중 두 가지 이야기를 솔직하게 나눠보려 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 와이어프레임은 종착점이었지, 출발점이 아니었습니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;개발 초기, 저희가 가장 확신을 가지고 탑재한 기능은 와이어프레임 자동 생성이었습니다. 유저 리서치에서도, 내부 논의에서도 니즈가 가장 높았던 기능이었습니다. 기획 데이터를 입력하면, 화면 구성이 바로 시각화되는 것. 저희도 이것이 매니패스트가 도달해야 할 종착점이라고 생각했고, 지금도 그 생각은 변하지 않았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;문제는 그 종착점을 준비되지 않은 상태에서 먼저 꺼내 들었다는 데 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 기능을 출시하고 나니, 현실은 냉혹했습니다. 와이어프레임 렌더링에 시간이 너무 오래 걸렸고, 나오는 결과물도 불완전했습니다. 기획자가 빠르게 구조를 잡고 반복 수정해야 하는 흐름에서 이 지연과 불완전함은 단순한 불편이 아니었습니다. 유저 이탈율이 눈에 띄게 올라가기 시작했습니다. 가장 기대를 걸었던 기능이 오히려 프로덕트의 신뢰를 깎아 먹고 있었습니다. 결국 저희는 이 기능을 롤백하는 결정을 내려야 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 단순히 "속도가 느려서 뺐다"로 끝난 경험이 아니었습니다. 이 과정에서 두 가지 중요한 깨달음을 얻었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 핵심 기술을 오롯이 외부 AI에 의존하는 구조로는 안 된다는 것이었습니다. 범용 모델의 출력을 그대로 가져다 쓰는 방식으로는, 기획이라는 도메인이 요구하는 정밀도와 속도를 동시에 만족시킬 수 없었습니다. 이 경험이 자체적인 파인튜닝과 독자 기술 개발에 본격적으로 투자하게 된 계기가 되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 더 본질적인 인사이트였습니다. 와이어프레임이 원하는 형태로 출력되려면, 그 이전 단계의 기획 맥락이 충분히 채워져 있어야 한다는 것입니다. 요구사항이 정의되고, 기능이 구조화되고, 플로우차트가 잡혀 있을 때 그제서야 와이어프레임은 적은 공수로도 의도한 형태에 가까운 결과를 낼 수 있습니다. 맥락 없이 화면부터 그리려 했던 것이 문제의 근원이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 저희는 방향을 틀었습니다. 와이어프레임이라는 종착점을 향해 곧장 달려가는 대신, 플로우차트부터 차근차근 편집하고 구현할 수 있도록 기획의 미싱 링크를 하나씩 채워나가는 과정을 시작했습니다. 돌아가는 길처럼 보였지만, 결과적으로 이 결정이 프로덕트의 뼈대를 훨씬 단단하게 만들어주었다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) AI에게 기획을 통째로 맡겨서는 안 됩니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;두 번째 시행착오는 저희 프로덕트의 본질에 대한 질문으로 이어진 경험이었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개발 중간 단계에서, 새로 추가할 기능의 방향을 정해야 하는 시점이 있었습니다. 저희는 일종의 실험을 해봤습니다. AI에게 처음부터 끝까지 기능을 추천받고, 그 추천을 100% 반영한 기획안을 작성해서 샘플 개발까지 진행한 것입니다. 결과물은 논리적으로 빈틈이 없었습니다. 구현 조건도 깔끔하게 정리되어 있었고, 누가 봐도 고개를 끄덕일 만한 명세서였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 이상하게도, 그 기획안대로 만들어질 프로덕트에서는 아무런 매력이 느껴지지 않았습니다. 아니, 그 기획안으로 프로덕트 만들면 100% 망할 것 같았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI가 추천하는 기능은 데이터의 평균치에 수렴합니다. 보편적인 대중이 거부감을 느끼지 않을, 실패 확률이 낮은 방향으로 정리됩니다. 하지만 프로덕트의 성공은 그 보편성을 뚫고 나오는 날카로운 개성에서 시작됩니다. 특정 타깃의 고통을 집요하게 파고드는, 논리만으로는 설명되지 않는 집착. AI의 논리만 따라가면 프로덕트는 매끈해질 수도 있지만, 프로덕트의 야성과 매력은 사라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 경험 이후 저희는 확신하게 되었습니다. AI 기획 도구의 본질은 "AI가 기획을 대신 해주는 것"이 아니라는 것을.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI가 방대한 데이터를 빠르게 구조화해 완성도 높은 초안을 만들어줄 수는 있습니다. 하지만 "왜 이 기능이어야 하는가", "무엇을 포기할 것인가"라는 판단은 결국 사람의 몫입니다. 그래서 저희는 AI와 사람 사이에 충분한 질의응답 과정이 들어가야 한다고 생각합니다. AI가 초안을 제시하고, 사람이 질문하고, AI가 대안을 내놓고, 사람이 최종 결정을 내리는 이 반복적인 대화의 과정 속에서만 인간다운 의사결정이 가능해집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI는 도구로 쓰되, 의사결정의 핸들은 사람이 쥐고 있어야 합니다. 저희 프로덕트는 그 핸들을 사람의 손에 돌려주기 위해 존재합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image4.png" alt="매니패스트 AI 챗봇에서 질의응답을 주고받으며 기획을 다듬는 과정을 보여주는 그림. AI가 기획서에서 유저의 결정이 필요한 부분(범위, 정책 등)을 유저에게 묻는다."&gt;&lt;/figure&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image6.png" alt="매니패스트 AI 챗봇에서 질의응답을 주고받으며 기획을 다듬는 과정을 보여주는 그림. AI가 기획서에서 유저의 결정이 필요한 부분(범위, 정책 등)을 유저에게 묻는다."&gt;&lt;figcaption&gt;매니패스트 AI 챗봇에서 질의응답을 주고받으며 기획을 다듬는 과정&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;4. 그래서 저희는 기획 전용 AI를 이렇게 만들었습니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;그래서 저희는 이렇게 만들었습니다. 현재 저희가 가지고 있는 저희 프로덕트의 가장 큰 그림은, "기획 전용 AI가 갖춰야 할 세 가지 축"이입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 &lt;strong&gt;AI 챗봇&lt;/strong&gt;입니다. 자연어로 아이디어를 입력하면, AI가 그것을 기획의 언어로 번역해주는 역할입니다. 여기까지는 범용 LLM과 비슷해 보일 수 있습니다. 하지만 결정적인 차이가 있습니다. 매니패스트의 AI는 단순히 텍스트를 생성하는 것이 아니라, 구조화된 기획 데이터 안에서 동작합니다. 요구사항을 정의하면 그것이 기능 명세로 연결되고, 기능 명세는 플로우차트로 이어집니다. 하나의 맥락이 끊기지 않고 전체 기획 체계 안에서 유지되는 것, 이것이 범용 LLM과의 근본적인 차이입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;시각화 에디터&lt;/strong&gt;입니다. 앞서 말씀드렸듯이, 기획에는 텍스트만으로 표현할 수 없는 영역이 있습니다. 기획의 구조와 흐름을 직관적으로 표현하는 것. 플로우차트, 와이어프레임 같은 시각 산출물이 기획자와 개발자, 디자이너가 같은 그림을 보고 일할 수 있게 만드는 핵심입니다. 매니패스트는 AI가 생성한 기획 데이터를 별도의 도구 없이 솔루션 내부에서 바로 시각화할 수 있도록 설계했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;세 번째는 &lt;strong&gt;문서화 에디터&lt;/strong&gt;입니다. 기획의 최종 산출물은 결국 문서입니다. 기능명세서, 요구사항 정의서, 개발 명세서까지 실무에서 요구되는 문서의 형태는 다양하고, 그 포맷도 조직마다 다릅니다. 매니패스트는 내부 기획 데이터를 엑셀, 마크다운, 이미지 등 원하는 형식으로 원클릭 내보내기할 수 있도록 만들었습니다. 기획 데이터를 구조화하고, 편집하고, 내보내는 전 과정이 하나의 솔루션 안에서 완결되는 것. 이것이 저희가 "올인원 기획 에디터"라고 부르는 이유입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image5.png" alt="AI 챗봇 + 시각화 에디터 + 문서화 에디터가 합쳐진 특징을 알 수 있도록 매니패스트의 한 화면을 보여주는 그림"&gt;&lt;figcaption&gt;AI 챗봇 + 시각화 에디터 + 문서화 에디터가 합쳐진 매니패스트&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 세 가지 축을 관통하는 설계 원칙이 하나 있습니다. 바로 AI가 이해하는 텍스트 구조와 인간이 이해하는 시각 구조 사이의 간극을 메우는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI는 텍스트 기반의 구조화된 데이터로 세상을 이해합니다. 반면 사람은 도표와 흐름도, 화면으로 판단하고 의사결정을 내립니다. 매니패스트는 이 간극 위에 서 있는 도구입니다. AI가 생성한 구조화 데이터를 인간이 직관적으로 이해할 수 있는 형태로 실시간 변환하고, 인간이 수정한 내용을 다시 AI가 이해할 수 있는 구조로 반영하는 양방향 흐름. 이것이 저희 프로덕트의 핵심 아키텍처입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image8.png" alt="매니패스트에서 작성한 기획서를 AI 코딩툴도 이해할 수 있음을 표현하는 그림."&gt;&lt;figcaption&gt;인간과 AI가 함께 이해할 수 있는 기획 방식&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 한 가지 더. 저희는 매니패스트를 닫힌 도구로 만들 생각이 없었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저희는 MCP(Model Context Protocol) 기반 설계는, 매니패스트에서 구조화된 기획 데이터를 외부 AI 도구들에게 직접 전달할 수 있게 해줍니다. 매니패스트에서 기획을 구조화하고, 그 데이터가 Figma AI 같은 디자인 도구로, 다시 Cursor 같은 개발 도구로 이어지는 흐름. 저희는 이것을 "바이브 플래닝 → 바이브 디자인 → 바이브 코딩"으로 연결되는 파이프라인이라고 부르고 있습니다. 기획이 더 이상 문서 작성에서 끝나는 것이 아니라, 소프트웨어 개발 전체의 시작점이자 연결 고리가 되는 것. 그것이 저희가 그리는 그림입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image2.png" alt="Manyfast에서 Figma AI, Claude Code로 연동되는 MCP 연동 시나리오가 표현된 그림."&gt;&lt;figcaption&gt;매니패스트가 생각하는 MCP 연동 시나리오 — 바이브 플래닝 → 바이브 디자인 → 바이브 코딩&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;5. 기획 편집기에서 시작해, 소프트웨어 개발의 새로운 표준으로&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;솔직하게 말씀드리면, 매니패스트는 아직 완성된 프로덕트가 아닙니다. 저희가 그리는 그림의 첫 번째 칸을 겨우 채운 단계에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지금의 매니패스트는 기획 업무의 효율화를 위한 시각화 편집기입니다. 아이디어를 입력하면 기획 데이터가 구조화되고, 그것을 편집하고, 산출물로 내보내는 과정을 하나의 솔루션 안에서 완결짓는 것. 작년 11월 소프트런칭 이후 4,000명이 넘는 글로벌 유저가 사용해주셨고, 14,000건 이상의 기획 문서가 생성되었습니다. 2회 이상 재방문하는 유저 비율이 70%라는 수치는, 이 문제가 저희만의 문제가 아니었다는 것을 확인시켜 주었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 저희의 시선은 이미 다음 단계를 향하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다음 단계는 AI 에이전트의 고도화입니다. 자연어 입력 기반으로 기획 전주기를 수행하는 멀티모달 생성 엔진을 만들고 있습니다. 기획서를 자동으로 검토하고, 프로덕트의 사용성을 시뮬레이션하는 기능까지 내다보고 있습니다. 그리고 그 다음에는 MCP와 API, 플러그인을 통해 다양한 도구와 환경을 유연하게 연결하는 마켓플레이스를 구축하려 합니다. 최종적으로는 팀과 조직의 기획 중심 협업을 돕는 워크스페이스, 그리고 기획부터 배포·운영까지 IT 프로젝트 전 과정을 아우르는 통합 운영체제를 지향하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;거창하게 들릴 수 있다는 것을 압니다. 하지만 저희가 이 로드맵을 확신하는 이유는 단순합니다. 4년간 350개의 프로젝트를 수행하면서 반복적으로 목격한 문제, AI 시대에 더 심화되고 있는 기획의 병목, 그리고 베타 기간 동안 다수의 유저들이 보내준 생생한 피드백들, 이 모든 것이 같은 방향을 가리키고 있기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기획의 실패를 줄일 때, 프로젝트의 성공 확률은 높아집니다. 그리고 그 시작은 거창한 혁신이 아니라, 기획자의 빈 화면 앞에서 첫 구조를 함께 잡아주는 일에서 출발한다고 저희는 믿고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저희는 아직 그 표준을 만들어 가는 길 위에 있습니다. 완성되었다고 말씀드리기엔 이릅니다. 다만, 이 문제를 오래 곱씹어 온 팀이 현장의 목소리를 들으며 한 발씩 나아가고 있다는 것, 그리고 그 과정 자체를 이렇게 나눌 수 있다는 것이 저희에게는 의미 있는 일입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글이 비슷한 고민을 안고 계신 분들께 작은 참고가 되었으면 합니다. 긴 글 읽어주셔서 감사합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3661/image1.png" alt="에디터에서 시작하여 AI-Agent, 기획 Marketplace, SW 개발 Workspace, Meta-OS로 나아가는 매니패스트의 로드맵"&gt;&lt;figcaption&gt;매니패스트의 프로덕트 로드맵&lt;/figcaption&gt;&lt;/figure&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;&amp;lt;참고&amp;gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="http://manyfast.io/blog"&gt;&lt;u&gt;manyfast.io/blog&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>클로드 코드로 ‘해외 송금 비교 서비스’ 만들어봤습니다</title><link>https://yozm.wishket.com/magazine/detail/3660</link><description>불과 1년도 안 돼서 바이브 코딩(Vibe Coding)이라는 용어가 대세가 되었습니다. 미국의 개발 현장에서도 이러다 일자리가 없어지는 것 아닌지 걱정하는 사람이 많아졌고, 그 와중에 발 빠르게 AI 기술을 익혀 개발자에서 프로덕트 메이커로 커리어를 전환하고 있는 사람도 있습니다. 저 역시 이대로 있으면 안 되겠다는 생각에 클로드 코드(Claude Code)로 회사 업무뿐만 아니라 다양한 사이드 프로젝트를 진행하면서 아이디어를 테스트해 보고 있습니다. 이번 글에서는 제가 클로드 코드로 실제 서비스를 만들어 출시하기까지의 과정, 그리고 개인적으로 느낀 바이브 코딩의 실제 효용과 한계를 공유해 보고자 합니다.</description><guid>https://yozm.wishket.com/magazine/detail/3660</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;해외 송금 비교 서비스 제작기 (feat. 클로드 코드)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;불과 1년도 안 돼서 바이브 코딩(Vibe Coding)이라는 용어가 대세가 되었습니다. 미국의 개발 현장에서도 이러다 일자리가 없어지는 것 아닌지 걱정하는 사람이 많아졌고, 그 와중에 발 빠르게 AI 기술을 익혀 개발자에서 프로덕트 메이커로 커리어를 전환하고 있는 사람도 있습니다. 저 역시 이대로 있으면 안 되겠다는 생각에 클로드 코드(Claude Code)로 회사 업무뿐만 아니라 다양한 사이드 프로젝트를 진행하면서 아이디어를 테스트해 보고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그중 하나가 바로 최근에 배포해서 운영을 시작한 ‘&lt;a href="http://sendfeecompare.com"&gt;&lt;u&gt;센드피컴페어&lt;/u&gt;&lt;/a&gt;’라는 &lt;strong&gt;해외 송금 비교 서비스&lt;/strong&gt;입니다. 이번 글에서는 제가 클로드 코드로 실제 서비스를 만들어 출시하기까지의 과정, 그리고 개인적으로 느낀 바이브 코딩의 실제 효용과 한계를 공유해 보고자 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/1__%ED%95%B4%EC%99%B8_%EC%86%A1%EA%B8%88_%EB%B9%84%EA%B5%90_%EC%84%9C%EB%B9%84%EC%8A%A4.png"&gt;&lt;figcaption&gt;해외 송금 비교 서비스 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;클로드 코드로 실제 서비스를 만들어 출시하기까지의 과정과 개인적으로 느낀 바이브 코딩의 실제 효용과 한계를 공유합니다.&lt;/li&gt;&lt;li&gt;12개 이상의 업체 스크래퍼, 17개 이상의 서비스 모듈, 6개의 자동화 워크플로우를 1인으로 몇&amp;nbsp; 주만에 구현할 수 있었던 것은 AI 코딩 도구의 도움 없이는 불가능했을 것입니다.&lt;/li&gt;&lt;li&gt;AI가 코드를 대신 작성해 주는 만큼, 개발자의 역할은 코드를 작성하는 사람에서 프로덕트를 설계하고 판단하는 사람으로 변해야 합니다.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;프로젝트의 시작&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이번 프로젝트의 아이디어는 &lt;strong&gt;개인적인 불편함&lt;/strong&gt;에서 시작되었습니다. 저는 미국에 거주하면서 한국에 있는 가족에게 송금할 일이 자주 있었습니다. 부모님께 생활비를 보내거나, 한국에 남아 있는 금융 계좌를 관리하거나, 경조사를 챙겨야 하는 경우가 대표적인데요. 문제는 은행이나 송금 업체마다 적용 환율이 다르고, 수수료 구조가 제각각이라는 점이었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/2__%EC%A7%81%EC%A0%91_%EC%A0%95%EB%A6%AC%ED%96%88%EB%8D%98_%EA%B5%AC%EA%B8%80_%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C%EC%8B%9C%ED%8A%B8.png"&gt;&lt;figcaption&gt;직접 정리했던 구글 스프레드시트 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;송금액이 큰 경우에는 어떤 은행, 어떤 업체를 쓰는지에 따라 실제로 한국에 송금되는 돈의 차이가 꽤 컸습니다. 그래서 이전에는 어디가 가장 유리한지 따져보기 위해 각 업체의 웹사이트를 열어 금액을 입력하고, 구글 스프레드시트로 비교했습니다. 그런데 그 과정이 매번 번거로웠죠. 그래서 이걸 &lt;strong&gt;자동화할 수 있지 않을까&lt;/strong&gt; 하는 생각에 이번 프로젝트를 시작하게 되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;기술 스택과 바이브 코딩 환경 세팅&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 기술 스택 구성&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;개인적으로 사이드 프로젝트에서 가장 중요하게 생각하는 요소는 &lt;strong&gt;출시까지의 속도&lt;/strong&gt;와 &lt;strong&gt;운영 비용의 최소화&lt;/strong&gt;입니다. 아무리 좋은 아이디어라도 만드는 데 너무 오래 걸리면 동력을 잃기 쉽고, 수익이 불확실한 상황에서 높은 운영 비용은 프로젝트를 지속 가능하지 않게 하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/3__%EA%B8%B0%EC%88%A0_%EC%8A%A4%ED%83%9D_%EB%B0%8F_%EB%8F%84%EA%B5%AC.png"&gt;&lt;figcaption&gt;기술 스택 및 도구 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 프레임워크로는 프론트엔드와 백엔드를 하나의 프로젝트에서 관리할 수 있고, 검색 엔진 최적화(SEO)에 유리한 서버 사이드 렌더링(SSR)을 지원하며, &lt;strong&gt;버셀(Vercel)&lt;/strong&gt;을 통해 무료로 배포할 수 있는 &lt;strong&gt;넥스트(Next.js)&lt;/strong&gt;를 선택했습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/4__Vercel_%ED%99%94%EB%A9%B4.png"&gt;&lt;figcaption&gt;Vercel 화면 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;데이터베이스와 사용자 인증은 슈퍼베이스(Supabase)로 해결했는데, 무료 티어만으로도 PostgreSQL 데이터베이스, 사용자 인증, 실시간 구독 기능을 모두 사용할 수 있어 별도의 서버 비용이 들지 않았습니다. 사실 요즘에는 더 좋은 대안들이 나오고 있지만, 버셀(Next.js) + 수파베이스(PostgreSQL) 조합은 이미 많은 Saas 개발에 사용되었기에, 대부분의 경우 무난한 선택이라고 판단했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/5__Supabase_%ED%99%94%EB%A9%B4.png"&gt;&lt;figcaption&gt;Supabase 화면 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아울러 매시간 각 업체의 환율과 수수료 데이터를 자동으로 수집하기 위해 &lt;strong&gt;깃허브 액션(GitHub Actions)&lt;/strong&gt;을 사용했습니다. 이를 통해 정기적인 스크래핑을 추가 비용 없이 운영할 수 있었죠. 결과적으로 현재 운영 비용은 도메인 구입 비용을 제외하면 사실상 0원에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/6__GitHub_Actions_%ED%99%94%EB%A9%B4.png"&gt;&lt;figcaption&gt;GitHub Actions 화면 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 프로젝트에서 주로 사용한 AI 코딩 도구는 &lt;strong&gt;클로드 코드&lt;/strong&gt;였습니다. 참고로, 클로드 코드는 엔트로픽(Anthropic)에서 만든 터미널 기반의 AI 코딩 도구입니다. 개인적으로 생각하는 클로드 코드의 장점은 프로젝트의 컨텍스트(Context)를 깊이 이해한 상태에서 전반적인 프로젝트 구조와 기존 코드 패턴에 맞는 코드를 작성해 준다는 점입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/7__VS_Code%EC%99%80_%ED%81%B4%EB%A1%9C%EB%93%9C_%EC%BD%94%EB%93%9C.png"&gt;&lt;figcaption&gt;VS Code와 클로드 코드 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저는클로드 코드 맥스(Max)를 구독해서 사용 중이며, 비주얼 스튜디오 코드(VS Code)와 워프(Warp) 터미널을 이용해, 2~3개의 에이전트(agent)를 병렬로 이용했습니다. 프로젝트 중간에는 클로드 코드가 계속 일하도록 하는 &lt;strong&gt;랄프 루프&lt;/strong&gt;(Ralph Loop)를 쓰기도 했습니다. 하지만 프로젝트가 제가 생각했던 것과 다른 구조로 만들어지는 것을 보고 더 이상 사용하지 않았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;핵심 기능 구현 과정&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) PRD 작성과 UI 설계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;프로젝트 초기 &lt;strong&gt;PRD&lt;/strong&gt;(Product Requirements Document, 제품 요구사항 문서)를 설계할 때는 클로드 코드와 제미나이(Gemini)를 함께 사용하여, 교차 검증하는 방식을 취했습니다. 한쪽에서 작성한 PRD를 다른 쪽에서 리뷰하고, 빠진 요구사항이나 논리적 허점을 잡아내는 방식이었는데요. 초기 PRD 작성 시 전반적인 프로젝트 아키텍처와 각 Phase 별 플래닝도 동시에 문서화했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/8__%ED%95%B4%EC%99%B8_%EC%86%A1%EA%B8%88_%EB%B9%84%EA%B5%90_%EC%84%9C%EB%B9%84%EC%8A%A4_PRD.png"&gt;&lt;figcaption&gt;해외 송금 비교 서비스 PRD &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;UI 디자인은 &lt;strong&gt;피그마(Figma)&lt;/strong&gt;를 활용하여, 전체적인 레이아웃과 컴포넌트(Component) 구조를 잡은 후, 클로드 코드를 통해 실제 코드로 구현하는 방식으로 진행했습니다. 이처럼 클로드 코드를 중심으로 제미나이와 피그마를 보조적으로 활용하는 것이 이번 프로젝트에서 수행한 바이브 코딩 환경이었습니다. 다만, 최근에는 피그마 외에도 UI 디자인에 활용할 수 있는 좋은 툴들이 많아, 다음 프로젝트에는 다른 방식의 UI 디자인을 테스트해 보려고 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 송금 업체 데이터 수집 프로세스 구현&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;현재 미국 한국 간 송금을 지원하는 은행과 업체는 수없이 많습니다. 그중에서 우선 한인들이 가장 많이 사용하는 와이즈(Wise), 와이어바알리(WireBarley), 레밋리(Remitly) 같은 핀테크 업체와 뱅크오브아메리카(Bank of America) 같은 시중 은행 등 &lt;strong&gt;12개 이상의 업체&lt;/strong&gt; 데이터를 자동으로 수집하는 프로세스를 만들었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/9__%EB%8B%A4%EC%96%91%ED%95%9C_%EC%86%A1%EA%B8%88_%EC%84%9C%EB%B9%84%EC%8A%A4.png"&gt;&lt;figcaption&gt;다양한 송금 서비스 &amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;데이터 수집을 위해 기본적으로 &lt;strong&gt;퍼피티어(Puppeteer)&lt;/strong&gt;로 브라우저를 띄워 실제 사용자처럼 금액을 입력하고 수취 예상액을 확인하며, 정적 페이지인 경우에는 &lt;strong&gt;치리오(Cheerio)&lt;/strong&gt;로 데이터를 파싱하도록 했습니다. 수집된 데이터는 DB에 저장되며, 기준 환율(Mid-market Rate)과의 차이도 함께 기록하여 각 업체가 얼마나 환율 마진을 가져가는지까지 파악하도록 했습니다. 그리고 이러한 프로세스를 구현하기 위해 클로드 코드를 통해 각 업체별로 스크립트를 생성했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) AI 분석 기능 구현&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;데이터 비교를 넘어, 사용자에게 실질적인 판단 근거를 제공하기 위해 AI 분석 기능도 추가했습니다. 이를 위해 오픈AI API를 활용하여 두 가지 기능을 만들었습니다. 하나는 AI가 &lt;strong&gt;비교 결과 설명&lt;/strong&gt;해 주는 것으로 "왜 이 업체가 이 금액 구간에서 유리한지"를 환율 마진, 수수료 구조, 현재 프로모션 등을 종합하여 자연어로 설명해 주는 기능입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/10__AI_%EB%B6%84%EC%84%9D_%EA%B8%B0%EB%8A%A5.png"&gt;&lt;figcaption&gt;AI 분석 기능 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;송금 타이밍 분석&lt;/strong&gt;으로 최근의 환율 추이를 분석하여, 지금 돈을 보내는 것이 유리한지, 조금 기다리는 것이 나은지에 대한 의견을 제공하는 기능입니다. 다만, 이런 AI 기능을 도입하면서 &lt;strong&gt;비용 대비 효용&lt;/strong&gt;이라는 현실적 고민도 생겼습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/11__%EC%86%A1%EA%B8%88_%ED%83%80%EC%9D%B4%EB%B0%8D_%EB%B6%84%EC%84%9D_%EA%B8%B0%EB%8A%A5.png"&gt;&lt;figcaption&gt;송금 타이밍 분석 기능 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;비록 GPT-4o-mini라는 비교적 저렴한 모델을 선택했지만, API 호출 건수가 늘어나면 비용이 무시할 수 없는 수준이 되기도 합니다. 특히 무료 사용자에게까지 AI 분석을 무제한 제공하면, 수익 없이 비용만 증가하는 구조가 됩니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;따라서 AI 분석을 회원 가입이 필요한 프리미엄 기능으로 분류했고, 이는 기술적 판단이 아니라 일종의 &lt;strong&gt;비즈니스 측면의 결정&lt;/strong&gt;이었습니다. 아울러 지속적인 수익 창출을 위한 다양한 CTA(Call to Action) 요소도 배치했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/12__%EB%8B%A4%EC%96%91%ED%95%9C_CTA_%EC%9A%94%EC%86%8C_%EB%B0%B0%EC%B9%98.png"&gt;&lt;figcaption&gt;다양한 CTA 요소 배치 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;바이브 코딩의 실제 효용과 한계&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) AI가 잘 도와준 부분&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;바이브 코딩이 특히 빛을 발한 영역은 &lt;strong&gt;UI 컴포넌트 개발&lt;/strong&gt;과 &lt;strong&gt;비즈니스 로직 생성&lt;/strong&gt;, 그리고 &lt;strong&gt;빠른 프로토타이핑&lt;/strong&gt;이었습니다. 예를 들어, 클로드 코드에 "송금 업체 비교 결과를 카드 형태로 보여주는 컴포넌트를 만들어줘. 실수령액이 높은 순서대로 정렬하고, 각 카드에는 업체 로고, 환율, 수수료, 실수령액을 표시해줘"와 같이 요청하면, 테일윈드 CSS가 적용된 깔끔한 컴포넌트가 바로 생성되었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;비록 미세 조정은 필요했지만, 직접 코드를 작성하는 것과는 비교도 되지 않는 속도였습니다. 또한 "이런 레이아웃으로 비교 화면을 만들어보자"라는 생각을 단 몇 분 안에 실제 동작하는 UI로 만들 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/13__%EB%B0%94%EC%9D%B4%EB%B8%8C_%EC%BD%94%EB%94%A9_%ED%99%9C%EC%9A%A9.png"&gt;&lt;figcaption&gt;바이브 코딩 활용 &amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 프로젝트에는 비교 계산, 환율 관리, 스크래핑, AI 분석, 게시판, 이메일 발송, 구독 관리 등 총 &lt;strong&gt;17개의 서비스 모듈&lt;/strong&gt;이 있었는데, 각 모듈의 기본 구조 위에 AI가 빠르게 비즈니스 로직을 채워 넣는 방식으로 작업을 진행했습니다. 아울러 12개 이상의 업체 데이터를 다루다 보면 데이터 파싱(Parsing), 포맷 변환, API 응답 처리 등에서 유사한 패턴의 코드가 반복되는데, 클로드 코드에 이런 패턴을 스킬(skill)과 문서로 제공하여 보다 효율적으로 일관된 코드를 만들 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 바이브 코딩의 한계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;반면, 아직은 모든 개발을 AI에게 전적으로 맡기기 어려운 부분도 분명히 있었습니다. 특히 어느 정도 바이브 코딩으로 프로젝트를 진행하다 보면, &lt;strong&gt;무지성으로 Yes를 클릭&lt;/strong&gt;하는 시점이 오게 되는데, 이때가 가장 위험한 단계였습니다. 프로젝트 구조와 패턴의 일관성이 무너지기 시작하고, 이미 만들어진 기능과 유사한 중복 코드가 발생했습니다. 결국 기존 기능이나 UI에 버그가 생기기 시작하고, 이를 디버깅하는 시간도 점차 늘어나게 되었습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/14__%EB%B0%94%EC%9D%B4%EB%B8%8C_%EC%BD%94%EB%94%A9%EC%9D%98_%ED%95%9C%EA%B3%84.png"&gt;&lt;figcaption&gt;바이브 코딩의 한계 &amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;데이터 아키텍처&lt;/strong&gt; 설계도 마찬가지입니다. 12개 이상 업체의 서로 다른 수수료 구조(정액제, 정률제, 환율 내재형 등)를 어떻게 정규화하여 하나의 비교 테이블로 만들 것인가, 스크래핑 데이터의 이력은 어떻게 관리하고 최신 데이터는 어떤 기준으로 갱신할 것인가와 같은 문제에는 어느 정도 데이터베이스와 관련된 지식이 필요했습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, AI에게 단순히 "송금 수수료 비교 시스템을 설계해줘"라고 요청하면 일반적인 구조를 제안해 주지만, 실제 업체들의 특수한 수수료 구조까지 반영한 DB 설계는 개발자의 판단이 필요했습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;서비스 운영 비용&lt;/strong&gt;과 관련된 현실적 제약에 대한 판단도 마찬가지입니다. 업체 정보를 실시간으로 스크래핑하는 것은 기술적으로 가능하지만 현실적으로 비용 이슈가 있으며, 유지보수가 어렵다는 판단을 내려야 했습니다. 그래서 송금 금액 구간을 나누고, 실시간이 아닌 정기 스크래핑으로 타협하는 결정을 내렸습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개인적으로 이와 같은 판단은 시스템 운영 경험에서 나오는 것이라고 생각합니다. AI는 대부분 "이상적인" 솔루션을 제시하는 경향이 있어, 이런 트레이드오프(Trade-off) 결정까지 기대하기는 어려웠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/15__%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98_%ED%8C%90%EB%8B%A8.png"&gt;&lt;figcaption&gt;개발자의 판단 &amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;정리하자면, 아직까지 바이브 코딩은 &lt;strong&gt;0에서 1을 만드는 도구&lt;/strong&gt;가 아니라&lt;strong&gt;1을 10으로 만드는 가속기&lt;/strong&gt;에 가까운 것 같습니다. 간단한 랜딩 페이지나 프로토타입 수준이라면 코딩 경험 없이도 만들 수 있지만, 실제 사용자에게 서비스하는 수준의 프로덕트를 만들려면 AI가 프로젝트 구조를 일관성 있게 가져갈 수 있도록 가이드라인(CLAUDE.md 및 프로젝트 문서 구조 설계 등)을 마련하고, 시스템 운영에 필요한 판단을 내릴 수 있어야 합니다. 아울러 기본적인 &lt;strong&gt;보안 지식&lt;/strong&gt;과 AI가 생성한 &lt;strong&gt;코드를 이해할 수 있는 수준&lt;/strong&gt;의 능력은 여전히 필요하다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;사용자 반응과 향후 개선 계획&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 커뮤니티 공유 후 피드백&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;저는 이번에 개발한 서비스를 마일모아라는 미국 한인 커뮤니티에 &lt;a href="https://www.milemoa.com/bbs/board/12093281"&gt;&lt;u&gt;제작기&lt;/u&gt;&lt;/a&gt;를 공유했습니다. 해당 글은 &lt;strong&gt;6,000회 이상의 조회수&lt;/strong&gt;를 기록하며 실제 해외 송금 사용자들의 구체적인 피드백을 받을 수 있었습니다. “다른 송금 업체도 더 추가해 달라", "업체별 사용 후기를 공유할 수 있으면 좋겠다" 등의 개선 요청이 있었고, 이를 반영하여 2차 업데이트를 진행했습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/16__%EC%A0%9C%EC%9E%91%EA%B8%B0%EC%97%90_%EB%8C%80%ED%95%9C_%EC%BB%A4%EB%AE%A4%EB%8B%88%ED%8B%B0_%EB%8C%93%EA%B8%80.png"&gt;&lt;figcaption&gt;제작기에 대한 커뮤니티 댓글 &amp;lt;출처: 마일모아, 작가 캡처&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 업데이트에서는 송금과 관련된 정보와송금 업체의사용 후기를 공유할 수 있는&lt;strong&gt;게시판 기능&lt;/strong&gt;을 추가하고, 사용자가 원하는 환율 조건을 설정해 두면 조건이 충족될 때 자동으로 알림을 보내는 &lt;strong&gt;로그인 기반 환율 알림 기능&lt;/strong&gt;도 도입했습니다. 이를 통해 사용자의 지속적인 참여를 이끌고자 했죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/17__%EC%9D%B4%EB%A9%94%EC%9D%BC_%ED%99%98%EC%9C%A8_%EC%95%8C%EB%A6%BC_%EA%B8%B0%EB%8A%A5.png"&gt;&lt;figcaption&gt;이메일 환율 알림 기능 &amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 향후 개선 계획&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;프로젝트를 배포한 후 궁극적으로 구현하고자 하는 것이 무엇인지에 대한 고민도 하게 되었습니다. 최종적으로 사용자가 자신의 조건과 선호 기간만 설정해 두면, AI가 환율 흐름과 수수료 구조를 지속적으로 관찰하다가, 가장 유리한 시점에 가장 적절한 송금 서비스를 선택해 &lt;strong&gt;자동으로 송금까지 처리하는 서비스&lt;/strong&gt;를 만들어 보고 싶다는 생각이 들었고요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3660/18__%EC%84%9C%EB%B9%84%EC%8A%A4%EC%9D%98_%EC%B5%9C%EC%A2%85_%EB%AA%A9%ED%91%9C.png"&gt;&lt;figcaption&gt;서비스의 최종 목표 &amp;lt;출처: 작가, Gemini로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아울러 계속해서 발전하는 바이브 코딩 개발 방식도 다음 업데이트에 적용해 보고자 합니다. 특히 여러 AI 에이전트(Agent)에게 각각 다른 역할(코드 작성, 코드 리뷰, 테스트 생성 등)을 맡기고, 이를 조율하는 &lt;strong&gt;오케스트레이션&lt;/strong&gt;(Orchestration)과 다양한 &lt;strong&gt;멀티 에이전트 워크플로&lt;/strong&gt;(Multi-Agent Workflow)를 실험하고, 이러한 경험도 정리하여 공유해볼까 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이상 클로드 코드를 활용한 바이브 코딩으로 &lt;a href="https://sendfeecompare.com"&gt;&lt;u&gt;해외 송금 비교 서비스&lt;/u&gt;&lt;/a&gt;를 기획부터 출시까지 한 경험을 정리해 보았습니다. 이번 프로젝트에서 제가 경험한 바이브 코딩은 &lt;strong&gt;개발자의 생산성&lt;/strong&gt;을 급격히 높여 주었습니다. 12개 이상의 업체 스크래퍼, 17개 이상의 서비스 모듈, 6개의 자동화 워크플로우를 혼자 몇 주 만에 구현할 수 있었던 건 AI 코딩 도구의 도움 없이는 불가능했을 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만, 서비스를 온전히 출시하기 위해서는 기획, UI/UX, 마케팅, 보안, 운영 등에 대한 노하우가 필요하다는 점도 분명했습니다. AI가 코드를 대신 작성해 주는 만큼, 개발자의 역할은 코드를 작성하는 사람에서 &lt;strong&gt;프로덕트를 설계하고 판단하는 사람&lt;/strong&gt;으로 변해야 한다고 생각했죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI 시대에 개발자가 사이드 프로젝트를 통해, 아이디어를 실현하는 것이 그 어느 때보다 쉬워진 것이 사실입니다. 따라서 &lt;strong&gt;이런 서비스가 있으면 좋겠다는 아이디어&lt;/strong&gt;를 가지고 있는 개발자라면, 바이브 코딩을 활용하여 직접 만들어 보는 것을 추천합니다. 불편함을 해결하는 작은 서비스 하나가 많은 사람에게 도움이 될 수 있을 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>자바스크립트 Proxy와 Reflect, 객체를 다루는 새로운 방법</title><link>https://yozm.wishket.com/magazine/detail/3659</link><description>자바스크립트에서 객체를 다루다 보면, 프로퍼티에 접근하거나 값을 변경할 때 “자동으로 추가 동작을 실행”하고 싶은 순간이 있습니다. 예를 들어, 객체의 값이 바뀔 때마다 로그를 남기거나, 유효하지 않은 값이 들어오면 막아버리거나, 값이 바뀌면 화면을 자동으로 갱신하고 싶은 경우가 대표적이죠. 이전 글에서 살펴본 내부 메서드는 자바스크립트 엔진이 내부적으로 사용하는 동작이라, 개발자가 직접 가로채거나 변경할 수 없었는데요. Proxy를 사용하면 바로 이 내부 동작을 가로채서 원하는 로직을 끼워 넣을 수 있고, Reflect는 그 과정에서 원래의 기본 동작을 안전하게 수행할 수 있도록 도와줍니다. 이번 글에서는 Proxy와 Reflect가 무엇인지, 그리고 실무에서는 어떻게 활용되는지까지 함께 살펴보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3659</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;자바스크립트에서 객체를 다루다 보면, 프로퍼티에 접근하거나 값을 변경할 때 “자동으로 추가 동작을 실행”하고 싶은 순간이 있습니다. 예를 들어, 객체의 값이 바뀔 때마다 로그를 남기거나, 유효하지 않은 값이 들어오면 막아버리거나, 값이 바뀌면 화면을 자동으로 갱신하고 싶은 경우가 대표적이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/detail/3597/"&gt;&lt;u&gt;이전 글&lt;/u&gt;&lt;/a&gt;에서 살펴본 내부 메서드는 자바스크립트 엔진이 내부적으로 사용하는 동작이라, 개발자가 직접 가로채거나 변경할 수 없었는데요. Proxy를 사용하면 바로 이 내부 동작을 가로채서 원하는 로직을 끼워 넣을 수 있고, Reflect는 그 과정에서 원래의 기본 동작을 안전하게 수행할 수 있도록 도와줍니다. 이번 글에서는 Proxy와 Reflect가 무엇인지, 그리고 실무에서는 어떻게 활용되는지까지 함께 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;미리 요점만 콕 집어보면?&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Proxy는 객체의 기본 동작을 가로채서 커스텀 로직을 추가할 수 있는 도구이고, Reflect는 원래 동작을 안전하게 수행하도록 돕는 짝꿍입니다.&lt;/li&gt;&lt;li&gt;get 트랩과 set 트랩을 통해 프로퍼티 읽기와 쓰기를 가로채 유효성 검사나 반환 값 제어가 가능하며, 트랩은 내부 메서드와 상당 부분 1:1로 대응하도록 설계되어 있습니다.&lt;/li&gt;&lt;li&gt;트랩 안에서 Reflect를 통해 원래 동작을 위임하는 것이 가장 안전하고 권장되는 패턴이며, 성능 오버헤드와 일부 내장 객체와의 호환성 문제에 주의해야 합니다.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Proxy란?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Proxy는 영어로 “대리인”이라는 뜻을 가지고 있는데요, 자바스크립트에서의 Proxy도 비슷합니다. 어떤 객체에 대한 작업을 직접 처리하는 대신, 중간에 대리인을 두고 그 대리인이 작업을 가로채서 추가적인 동작을 수행할 수 있게 해주는 객체입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3659/%EA%B7%B8%EB%A6%BC1__1_.png" alt="Proxy 동작 원리"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Claude로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) Proxy의 기본 문법&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Proxy를 이해하려면 세 가지 핵심 용어를 알아야 합니다. target은 Proxy가 감는 원본 객체, handler는 가로채는 동작을 정의하는 객체, 그리고 trap은 handler 안에 정의하는 메서드로, 말 그대로 특정 동작을 가로채는 “함정”입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const user = {
  name: "홍길동",
  age: 27,
};

const handler = {
  // 여기에 트랩(Trap)을 정의합니다
};

const proxy = new Proxy(user, handler);&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;handler에 아무런 트랩도 정의하지 않으면, Proxy는 원본 객체에 대한 동작을 그대로 통과시킵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) 간단한 Proxy 예제&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;아래 코드는 get 트랩을 사용해서, 프로퍼티를 읽을 때마다 로그를 남기는 예제입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const user = {
  name: "홍길동",
  age: 27,
};

const handler = {
  get(target, prop) {
    console.log(`${prop} 프로퍼티에 접근했습니다.`);
    return target[prop];
  },
};

const proxy = new Proxy(user, handler);

console.log(proxy.name);
// "name 프로퍼티에 접근했습니다."
// "홍길동"&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;get 트랩의 첫 번째 매개변수 target은 원본 객체, 두 번째 prop은 접근하려는 프로퍼티의 이름입니다. 이렇게 Proxy를 사용하면, 객체 접근 자체를 가로채서 원하는 로직을 추가할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;주요 트랩(Trap) 살펴보기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Proxy에서 사용할 수 있는 트랩은 get 외에도 다양합니다. 프로퍼티를 읽을 때, 쓸 때, 삭제할 때 등 객체에 대한 거의 모든 동작을 가로챌 수 있는데요, 실무에서 자주 사용되는 트랩들을 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) get 트랩: 프로퍼티 읽기 가로채기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;get 트랩은 객체의 프로퍼티를 읽는 동작을 가로채는 트랩입니다. 앞서 간단한 로그 예제를 살펴보았는데요, get 트랩의 핵심은 프로퍼티를 읽을 때 원래 값을 그대로 반환하는 것이 아니라, 개발자가 원하는 방식으로 반환 값을 가공하거나 제어할 수 있다는 점입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, 존재하지 않는 프로퍼티에 접근했을 때 undefined 대신 의미 있는 메시지를 반환하도록 만들어 볼 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const user = {
  name: "홍길동",
  age: 27,
};

const handler = {
  get(target, prop) {
    if (prop in target) {
      return target[prop];
    }
    return `"${prop}" 프로퍼티는 존재하지 않습니다.`;
  },
};

const proxy = new Proxy(user, handler);

console.log(proxy.name);    // "홍길동"
console.log(proxy.address); // "address" 프로퍼티는 존재하지 않습니다.&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;일반 객체였다면 proxy.address는 undefined를 반환했을 텐데요, get 트랩 덕분에 프로퍼티 읽기 동작 자체를 가로채서, 원하는 방식으로 결과를 바꿀 수 있게 된 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) set 트랩: 프로퍼티 쓰기 가로채기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;set 트랩은 객체의 프로퍼티에 값을 할당하는 동작을 가로채는 트랩입니다. get 트랩이 읽기를 가로챘다면, set 트랩은 쓰기를 가로채는 것이죠. 값이 저장되기 전에 원하는 로직을 먼저 실행할 수 있기 때문에, 대표적으로 유효성 검사에 활용됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const user = {
  name: "홍길동",
  age: 27,
};

const handler = {
  set(target, prop, value) {
    if (prop === "age" &amp;amp;&amp;amp; (typeof value !== "number" || value &amp;lt; 0)) {
      throw new Error("나이는 0 이상의 숫자여야 합니다.");
    }
    target[prop] = value;
    return true;
  },
};

const proxy = new Proxy(user, handler);

proxy.age = 30;  // 정상 동작
proxy.age = -5;  // Error: 나이는 0 이상의 숫자여야 합니다.&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;set 트랩은 target, prop, value 세 가지 매개변수를 받으며, 반드시 true 또는 false를 반환해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3) 트랩과 내부 메서드의 대응 관계&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;앞서 내부 슬롯과 내부 메서드를 다룰 때, 자바스크립트 엔진이 객체를 처리하기 위해 호출하는 내부 메서드들을 살펴보았는데요, 사실 Proxy의 트랩은 프로퍼티 접근/할당/삭제처럼 객체의 기본 동작을 수행하는 내부 메서드와 상당 부분 1:1로 대응하도록 설계되어 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3659/%EA%B7%B8%EB%A6%BC2__1_.png" alt="트랩과 내부 메서드"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, GPT로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;즉, Proxy는 자바스크립트 엔진이 내부적으로 수행하는 동작을 개발자가 가로챌 수 있도록 열어주는 공식적인 방법이라고 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Reflect란?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;트랩 안에서 “원래 동작을 그대로 수행”해야 하는 경우가 자주 있는데요, 이때 사용하는 것이 바로 Reflect입니다. Reflect는 자바스크립트의 내장 객체로, 객체에 대한 기본 동작을 메서드 형태로 제공합니다. 메서드 이름은 Proxy의 트랩 이름과 정확히 동일합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3659/%EA%B7%B8%EB%A6%BC3.png" alt="target vs Reflect 차이점"&gt;&lt;figcaption&gt;&amp;lt;출처 : 작가, Claude로 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) Reflect가 필요한 이유&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;“트랩 안에서 target[prop]처럼 직접 접근하면 되지 않나?”라고 생각할 수 있는데요, 간단한 경우에는 문제가 없지만, 상속 관계에서 문제가 발생합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const parent = {
  _name: "부모",
  get name() {
    return this._name;
  },
};

const handler = {
  get(target, prop, receiver) {
    return target[prop]; // Reflect를 사용하지 않음
  },
};

const proxy = new Proxy(parent, handler);
const child = Object.create(proxy);
child._name = "자식";

console.log(child.name); // "부모" (기대값: "자식")&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;target[prop]을 사용하면 getter 안의 this가 parent를 가리키게 되어, child._name이 아닌 parent._name이 반환됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) Reflect로 해결하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Reflect.get()의 세 번째 인자 receiver는 getter 안에서 this로 사용될 객체를 지정합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;const handler = {
  get(target, prop, receiver) {
    return Reflect.get(target, prop, receiver);
  },
};

const proxy = new Proxy(parent, handler);
const child = Object.create(proxy);
child._name = "자식";

console.log(child.name); // "자식" (정상 동작)&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이처럼 트랩 안에서 원하는 로직을 수행한 후, Reflect를 통해 원래 동작을 위임하는 것이 가장 안전하고 권장되는 패턴입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;실무에서 Proxy는 어떻게 활용될까?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Proxy는 단순히 개념적인 도구가 아니라, 실제 프론트엔드 프레임워크에서도 핵심적으로 사용되고 있습니다. 대표적인 활용 사례를 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1) 데이터 변경 감지와 반응형 시스템&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;가장 대표적인 활용 사례가 바로 반응형 시스템입니다. Vue 3의 reactive()는 내부적으로 Proxy를 기반으로 구현되어 있는데요. 원리를 간단하게 살펴보면, set 트랩에서 값 변경을 감지하고 화면 갱신 로직을 실행하는 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-javascript"&gt;function reactive(target) {
  return new Proxy(target, {
    set(target, prop, value, receiver) {
      const result = Reflect.set(target, prop, value, receiver);
      console.log(`${prop} 값이 변경되었습니다. 화면을 갱신합니다.`);
      return result;
    },
  });
}

const state = reactive({ count: 0 });
state.count = 1;
// "count 값이 변경되었습니다. 화면을 갱신합니다."&lt;/code&gt;&lt;/pre&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Vue 3가 이전 버전에서도 사용하던 Object.defineProperty() 대신 Proxy를 선택한 이유도, Proxy가 객체에 대한 대부분의 기본 동작을 가로챌 수 있어 더 유연하고 강력하기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2) Proxy 사용 시 주의할 점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Proxy는 강력한 도구이지만, 몇 가지 주의할 점이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;첫째, 성능 오버헤드입니다. 트랩이 호출될 때마다 추가 함수 실행이 발생하므로, 대량의 데이터를 반복 처리하는 코드에서는 신중하게 사용해야 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;둘째, 일부 내장 객체와의 호환성 문제입니다. Map, Set, Date처럼 내부 슬롯에 의존하는 객체는 Proxy로 감싸면 정상 작동하지 않을 수 있으므로, 별도의 처리가 필요합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;지금까지 자바스크립트의 Proxy와 Reflect에 대해 살펴보았습니다. Proxy는 객체의 기본 동작을 가로채서 커스텀 로직을 추가할 수 있는 도구이고, Reflect는 그 과정에서 원래 동작을 안전하게 수행하도록 돕는 짝꿍입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 Proxy의 트랩은 자바스크립트 엔진의 내부 메서드와 상당 부분 1:1로 대응되기 때문에, 이전에 살펴본 내부 슬롯과 내부 메서드의 개념을 함께 이해하고 있다면 훨씬 깊이 있게 활용할 수 있습니다. Proxy는 이미 우리가 사용하는 프레임워크 곳곳에서 활용되고 있는데요, 이번 글을 통해 Proxy와 Reflect의 기본 원리를 이해했다면, 다음에는 직접 활용해 보시길 바랍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>채용 공고에서 말하는 ‘주도적인 사람’은 누굴까?</title><link>https://yozm.wishket.com/magazine/detail/3656</link><description>“주도적으로 문제를 해결하는 분” 채용 공고에서 정말 흔하게 마주치는 문구입니다. 하지만 이 단어를 보는 이들의 마음은 그리 편치 않습니다. 여기서 말하는 주도성이, 회사가 시키지 않아도 알아서 야근하고 남의 일까지 떠맡는 ‘가성비 좋은 일꾼’을 찾는 표현처럼 들리기 때문이죠. 하지만 우리가 느끼는 이 피로감은 단어 자체의 잘못이 아닙니다. 주도성은 회사가 원하는 인재상이 되기 위해서가 아니라, “이 회사에서는 더 이상 성장할 수 없을 것 같다”는 매너리즘에서 나를 구하고 나의 시장 가치를 스스로 증명하기 위해 필요한 능력입니다. 지금부터 주도성이 무엇인지, 그리고 어떻게 주도적인 사람이 될 수 있을지를 알아보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3656</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;“주도적으로 문제를 해결하는 분”&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;채용 공고에서 정말 흔하게 마주치는 문구입니다. 하지만 이 단어를 보는 이들의 마음은 그리 편치 않습니다. 여기서 말하는 주도성이, 회사가 시키지 않아도 알아서 야근하고 남의 일까지 떠맡는 ‘가성비 좋은 일꾼’을 찾는 표현처럼 들리기 때문이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 우리가 느끼는 이 피로감은 단어 자체의 잘못이 아닙니다. &lt;span style="background-color:transparent;"&gt;주도성을 단순히 개인의 성격 문제로 치부하는 오해, 나아가 이 주도성이 회사와 나에게 어떤 의미인지 제대로 알지 못해 생기는 오해&lt;/span&gt;, 이 두 가지 ‘해석의 오류’가 그 원인입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3656/image1.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 진정한 의미의 주도성은 회사를 위한 무조건적인 희생이 아닙니다. 자기 전문성을 지키기 위한 전략이며, 협업에서 발생하는 불필요한 비용과 불확실성을 줄여 나가는 실력에 가깝습니다. “저는 시키는 대로 다 했는데요?”라는 말이, 그리고 그런 태도가 조직의 속도를 늦추고 나의 가치를 갉아먹고 있다면 더욱 주도성에 대해 완전히 다시 정의해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그렇게 이 글에서는 우리가 흔히 오해하는 주도성을 제대로 이해해 보고, 왜 주도적인 태도가 결국 ‘진짜 실력’으로 치환되는지 다음의 세 가지 관점에서 깊이 있게 다뤄보려 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;첫째, 태도의 차이가 만드는 결과:&lt;/strong&gt; “안 돼요”와 “이렇게 하면 돼요”라는 한마디가 프로젝트의 성패와 동료의 신뢰를 어떻게 가르는지 5가지 구체적인 사례로 살펴봅니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;둘째, 태도가 실력이 되는 메커니즘:&lt;/strong&gt; 주도적인 태도가 어떻게 기술 부채를 관리하고, 동료들에게 ‘예측 가능한 확신’을 주는 전문성으로 이어지는지 분석합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;셋째, 주도성과 조직의 상관관계:&lt;/strong&gt; 개인의 주도성이 꽃피기 위해 필요한 환경은 무엇이며, 질문의 비용이 낮아질 때 조직이 어떻게 스스로 움직이게 되는지 이야기합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 주도성은 회사가 원하는 인재상이 되기 위해서가 아니라, &lt;strong&gt;“이 회사에서는 더 이상 성장할 수 없을 것 같다”&lt;/strong&gt;는 매너리즘에서 나를 구하고 나의 시장 가치를 스스로 증명하기 위해 필요한 능력입니다. 지금부터 주도성이 무엇인지, 그리고 어떻게 주도적인 사람이 될 수 있을지를 알아보겠습니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;태도의 차이가 만드는 신뢰&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;우리는 늘 수많은 선택을 해야 합니다. 새로운 기능을 추가하자는 기획자의 요청, 갑작스러운 버그 수정 지시, 혹은 기존 시스템의 구조를 바꿔야 하는 기술적 결정에 따라서죠. 이때 우리가 내뱉는 말 한마디는 단순 의사소통을 넘어 내가 이 일을 어떻게 바라보는지 보여줍니다. 그렇기에 동료가 나를 신뢰할 수 있을지 가늠하는 지표가 되기도 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 말들이 주도적인 태도와 수동적인 태도에 따라 어떻게 달라지는지, 5가지 예시 상황으로 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3656/image3.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 안 돼요 vs. 이렇게 하면요?&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;수동적:&lt;/strong&gt; 그 기능은 지금 구조상 &lt;strong&gt;안 돼요.&lt;/strong&gt; 서버 부하가 너무 커서요.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;주도적:&lt;/strong&gt; 현재 구조로는 서버 부하가 우려되네요. 하지만 데이터 노출 범위를 제한하거나, 캐시를 활용하는&lt;strong&gt;조건이라면 가능할 것 같습니다.&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;방어적인 태도는 늘 안 되는 이유를 찾기 바쁩니다. 기술적 제약을 자신을 보호하는 논리로 쓰기 때문이죠. 반면 주도적인 사람은 제약이 있음을 인정하면서도, 그 안에서 &lt;strong&gt;실행 가능한 옵션&lt;/strong&gt;을 먼저 제시합니다. 동료에게 거절이 아닌 ‘대안’을 건네는 것, 바로 이 지점이 협업의 속도를 결정합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만, 오해는 말아야 합니다. 주도성이 모든 요청에 무조건적인 Yes를 외치는 희생을 의미하는 것은 아니라는 점입니다. 주도성은 오히려 프로젝트의 본질을 해치는 불필요한 요청을 논리적으로 거절하고, 진짜 해결해야 할 핵심 문제에 에너지를 집중하는 전략적 선택에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 다 했습니다 vs. 이게 최선일까요?&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;수동적:&lt;/strong&gt; 요청하신 기획대로 구현 &lt;strong&gt;다 했습니다.&lt;/strong&gt; 확인해 보세요.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;주도적:&lt;/strong&gt; 요청하신 기능을 구현하다 보니, 이 버튼을 누를 때 실제 사용자 흐름이 끊기더라고요. &lt;strong&gt;이게 최선일까요?&lt;/strong&gt; 로딩 애니메이션을 추가하는 게 나을 것 같아 함께 수정해 봤습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;수동적인 이들에게 완료의 기준은 전달받은 기획이나 티켓의 종료입니다. 하지만 주도적인 이들에게 완료의 기준은 문제의 원인 파악과 해결입니다. 단순히 코드를 짜는 행위를 넘어, 이 결과물이 사용자에게 어떤 경험을 줄지 고민하는 것이죠. 이러한 고민이 결국 제품의 퀄리티를 한 단계 끌어올리는 원동력이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 원래 이랬는데요? vs. 지금도 정말 유효할까요?&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;수동적:&lt;/strong&gt; 이 코드 &lt;strong&gt;원래 이랬는데요?&lt;/strong&gt; 전임자가 짜놓은 거라 건드리면 위험합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;주도적:&lt;/strong&gt; 로직이 복잡하긴 하지만, &lt;strong&gt;지금의 트래픽 규모에서도 정말 유효할까요?&lt;/strong&gt; 리팩토링 계획을 세워 조금씩 개선해 보겠습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;익숙함은 편안하지만 동시에 위험합니다. 수동적인 사람은 변화로 인해 발생할 문제와 그에 따른 책임을 두려워합니다. 반면 주도적인 사람은 현재의 맥락에서 과거의 유산을 끊임없이 재평가합니다. 그리고 시스템이 점점 낡아가는 상황을 방지하려고 스스로 일을 자처합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;4. 제 일 아닌데요? vs. 같이 논의해 보겠습니다&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;수동적:&lt;/strong&gt; 그건 인프라 업무잖아요, &lt;strong&gt;제 일 아닌데요?&lt;/strong&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;주도적:&lt;/strong&gt; 이 이슈가 그대로면 결국 사용자에게 영향이 가지 않나요? 일단 제가 한번 확인해 보고, 담당자에게 로그 데이터 공유해서 &lt;strong&gt;같이 논의해 보겠습니다.&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;R&amp;amp;R은 책임의 범위를 정하기 위한 도구이지, 협력을 거부하기 위한 장치가 아닙니다. 주도적인 사람은 이슈의 주인이 누구인지보다 문제 해결이 더 중요하다는 사실을 알고 있습니다. 그래서 기꺼이 경계를 넘나들며 조직 곳곳에 흩어진 정보를 연결합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;5. 굳이 해야 해요? vs. 검증하고 결정하죠&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;수동적:&lt;/strong&gt; 에이, 이거 예전에도 해봤는데 안 됐어요. &lt;strong&gt;굳이 해야 해요?&lt;/strong&gt;&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;주도적:&lt;/strong&gt;과거에 실패한 이력이 있네요. 그때 실패 요인이 지금도 유효한지, &lt;strong&gt;핵심 가설만 작게 검증(PoC)해보고 결정&lt;/strong&gt;할까요?&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;부정적인 태도는 아무것도 하지 않는 방향으로 갑니다. 가장 쉽고 비용이 적게 드는 선택이죠. 하지만 주도적인 사람은 과거의 실패에 머물지 않습니다. 대신 &lt;strong&gt;지금, 여기서, 어떻게&lt;/strong&gt; 검증할지, 그 방법을 제안합니다. 이들에게 실패는 좌절의 이유가 아니라 다음 실험을 더 정교하게 다듬을 데이터일 뿐입니다.&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;그렇다면, 이러한 차이는 어디에서 비롯될까요? 단순히 착해서 혹은 열정이 넘쳐서 생기는 것일까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;아닙니다. 이는 바로 자신의 일을 대하는 &lt;strong&gt;오너십(Ownership)의 차이&lt;/strong&gt;에서 시작됩니다. 한편 이런 태도의 차이는 실제 개인의 실력과 어떤 상관관계를 가지는 지도 궁금해집니다. 태도가 어떻게 기술적 실력으로 이어지는지, 그리고 왜 주도적인 사람이 결국 ‘진짜 전문가’가 될 수밖에 없는지 함께 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;태도와 실력은 어떤 관계일까?&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;흔히들 엔지니어의 실력을 알고리즘 해결 능력이나 기술 스택의 숙련도로 생각합니다. 하지만 시니어 레벨로 올라갈수록 실력이란 &lt;strong&gt;복잡성을 관리하고 지속 가능한 가치를 만드는 능력&lt;/strong&gt;으로 확장됩니다. 바로 이 지점에서 주도적인 태도가 압도적인 기술의 격차를 만들어 냅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3656/image2.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini 생성&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 기술 부채를 만드는 나쁜 태도&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;개발 현장에서 말하는 기술 부채(Technical Debt)는 단순히 나쁜 코드를 의미하지 않습니다. 이는 &lt;strong&gt;현재의 편의를 위해 미래의 유지보수 비용을 미리 끌어다 쓰는 행위&lt;/strong&gt;에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;수동적인 개발자는 명시되지 않은 예외 상황을 종종 무시합니다. “로그 처리가 빠졌지만, 기획에 없었으니까” 혹은 “테스트 코드를 작성하기엔 일정이 너무 타이트하니까”라고 말하면서 말이죠. 이러한 선택은 당장의 배포 속도를 높여 주지만, 머지않은 미래에 누군가가 더 많은 시간을 들여 디버깅해야 하는 부채로 돌아옵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 주도적인 개발자는 기술 부채를 더 전략적으로 다룹니다. 당장 구현이 급하더라도 “이 부분은 나중에 확장할 때 병목이 될 것 같다”며 의견을 먼저 제시합니다. 혹은 최소한의 인터페이스라도 미리 설계해 둡니다. 이런 방식은 더 큰 기술 부채로 이어질 요소의 범위를 제한하고, 시스템의 복잡도를 낮춥니다. 결과적으로 주도적인 태도가 곧 코드의 품질을 좌우하고, 조직 전체의 기술 자산을 지키는 실력으로 이어집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 계산할 수 있는 신뢰의 가치&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;개발 과정에서 ‘확정된 기획’은 매우 중요합니다. 설계 과정에서 고민해야 할 범위를 줄여 주고, 시스템의 복잡도를 낮춰 주니까요. 협업에서도 상황은 크게 다르지 않습니다. 동료에게 가장 신뢰받는 사람은 &lt;strong&gt;결과물의 수준과 시점을 예측 가능하게 만드는 사람&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런 관점으로, 주도적인 사람은 협업에서 발생하는 변수를 예측 가능한 형태로 바꿔 줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;일이 지연될 것 같으면 문제가 터지기 전에 미리 상황을 공유합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;불확실한 요구사항은 코드를 작성하기 전에 질문해 명확히 합니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;본인의 작업이 다른 파트(QA, 디자인, 인프라)에 미칠 영향을 먼저 점검합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이러한 행동은 동료들의 컨텍스트 스위칭(Context Switching) 비용을 크게 낮춰 줍니다. 리더의 입장에서도 이런 팀원은 사사건건 확인하지 않아도, 스스로 완벽한 결과를 가져오는 가장 든든한 동료가 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이처럼 주도적인 사람은 조직의 &lt;strong&gt;커뮤니케이션 부채&lt;/strong&gt;를 줄여 줍니다. 미리 공유되는 리스크와 진행 상황 덕분에 리더는 확인을 위한 불필요한 회의를 줄이며, 본질적인 의사결정에 집중할 수 있게 됩니다. 이것이 바로 주도성이 만들어 내는 ‘계산할 수 있는 신뢰’의 가치입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 전문성을 확장하는 가장 빠른 경로&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;전문가는 자기 분야를 깊게 파는 사람(I자형 인재)을 넘어, 인접 분야와도 소통할 수 있는 사람(T자형 인재)으로 진화해야 합니다. 이 과정에서 주도성은 소통을 돕는 가장 중요한 요소입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;프론트엔드 개발자가 API 응답 속도가 느리다고 불평만 하는 대신, 직접 백엔드 코드를 열어보거나 쿼리 실행 계획을 함께 고민해 본다면 어떨까요? 그는 자연스럽게 네트워크 프로토콜, 데이터베이스(DB) 인덱싱, 서버 아키텍처까지 이해하게 됩니다. 이렇게 자신의 R&amp;amp;R을 넘어선 주도적인 관심은 &lt;strong&gt;기술적 시야를 넓히는 가장 빠른 경로&lt;/strong&gt;가 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;결국 전문성이란 내가 하는 일의 앞과 뒤를 이해하는 힘입니다. 내 코드가 어디서 시작되고, 어디로 흘러가는지를 고민할 때, 비로소 전체 아키텍처를 설계할 수 있는 진짜 실력이 생깁니다.&lt;/p&gt;&lt;hr&gt;&lt;p style="text-align:justify;"&gt;이처럼 주도성은 나를 둘러싼 환경의 불확실성을 줄이고, 내 전문성의 영역을 넓혀 가는 행동입니다. 이러한 태도는 개발뿐 아니라 기획, 디자인 등 모든 직무에 동일하게 적용됩니다. ‘안 된다’며 제약 뒤에 숨어 방어적으로 대응하기보다, 제한된 자원 안에서 최선의 결과를 만들기 위한 구체적인 시나리오를 먼저 제시하는 것. 이것이 바로 주도성의 본질입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;주도성을 만들어주는 조직&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;많은 리더는 “우리 팀에는 주도적인 사람이 없어요”라며 한탄합니다. 하지만 팀원들의 이야기는 다르죠. “의견을 내봤자 바뀌는 건 없고, 일만 늘어나요.”라고 합니다. 이 간극은 어디서 오는 걸까요? 주도성이 건강하게 작동하려면 개인의 태도만큼이나 조직의 반응 또한 중요한 이유입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. ‘피곤한 오지랖’으로 보지 않는 환경&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;주도적인 사람은 기존 방식에 의문을 제기하는 경우가 많습니다. “이 방법이 최선일까요?” 혹은 “다른 방법은 없을까요?”라고 묻습니다. 이때 조직이 이런 질문을 도전이나 피곤한 오지랖으로 받아들인다면, 그 조직에서 주도성은 점점 사라지게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;정체된 조직:&lt;/strong&gt; 시키는 대로 하세요. 위에서 다 이유가 있어서 그렇게 정한 겁니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;성장하는 조직:&lt;/strong&gt; 좋은 지적입니다. 그 대안을 실행했을 때 예상되는 리스크는 무엇인가요?&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;주도성을 발휘하다가도 일만 더 떠맡거나, 혹은 비난만 받는 경험이 반복되면 인재들은 학습된 무기력에 빠집니다. 결국 유능하고 주도적이던 사람들은 조직을 떠나고, 자리를 지키는 수동적인 인력만 남습니다. 주도성을 존중하지 않는 조직의 끝은 결국 &lt;strong&gt;시스템의 경직과 도태&lt;/strong&gt;뿐입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;만약 지금 여러분이 속한 조직이 주도성을 오지랖으로 치부하며 억압하고 있다 해도 포기하지 마세요. 그곳에서의 주도적인 시도를 단순히 회사를 위한 헌신으로 여기기 보다, 자신의 이력서를 채울 ‘주도적 문제 해결 사례’를 모으는 과정으로 써볼 수 있습니다. 당장 환경을 바꾸지는 못해도 그 과정에서 쌓이는 시장 가치는 조직에 귀속되지 않는 온전한 나의 자산입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 틀려도 괜찮고 몰라도 비난받지 않는다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;주도적으로 행동하려면 ‘내 의견이 틀릴 수도 있다’는 부담을 이겨내야 합니다. 내가 던진 질문이 누군가에게는 당연한 상식일 수도 있고, 공들여 낸 아이디어가 보기 좋게 거절당할 수도 있습니다. 조직이 이때 해줄 수 있는 것은 거창한 제도가 아닙니다. &lt;strong&gt;“틀려도 괜찮고, 몰라도 비난받지 않는다”&lt;/strong&gt;라는 아주 기본적인 약속입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;성공적인 협업이 이루어지는 팀의 공통점은 질문의 비용이 매우 낮다는 것입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;경직된 조직:&lt;/strong&gt; 질문 하나를 던지기 위해 “내가 이걸 모른다고 하면 무시당하지 않을까?”를 백 번 고민해야 합니다. 실수라도 하면 “누가 이렇게 하라고 했어?”라는 비난이 돌아옵니다. 이런 환경에서 주도성은 사치입니다. 가만히 있으면 중간이라도 가는데, 굳이 나서서 욕 먹을 이유가 없으니까요.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;유연한 조직:&lt;/strong&gt; “이 부분이 이해되지 않는데 도와주실 수 있나요?” 혹은 “이 방법은 리스크가 크지만 시도해 볼 가치가 있을까요?”라는 말이 당연합니다. 여기서 주도성은 실패에 대한 두려움보다 &lt;strong&gt;문제를 더 잘 해결하고 싶다는 욕구&lt;/strong&gt;를 따라 움직입니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;주도적인 시도가 비난받지 않고, 오히려 “좋은 시도였다”는 피드백으로 돌아올 때 팀원들은 비로소 마음 놓고 경계를 넘나들기 시작합니다. 결국 주도성을 이끌어내는 것은 조직의 배려가 아니라 &lt;strong&gt;실수를 대하는 조직의 수준&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 문화로 퍼지는 전염성&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;다행히 &lt;strong&gt;주도성은 전염&lt;/strong&gt;됩니다. 정체된 팀에 주도적인 인재 한 명이 합류하면 초기에는 마찰이 생길 수도 있습니다. 그러나 그가 만들어 내는 예측 가능한 결과물과 명확한 소통은 동료들에게 새로운 자극이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“아, 저렇게 일하니까 일이 훨씬 깔끔하게 끝나는구나”, “저 사람과 협업하니 내 업무 효율도 올라가네”라는 경험이 쌓이면 팀 전체의 기준선이 자연스럽게 올라갑니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 리더의 역할도 중요합니다. 단순히 채용 공고에 ‘주도적인 분’이라고 적는 것이 전부가 아닙니다. 주도적인 인재가 만들어 낸 작은 가능성을 혁신의 신호로 읽어 내고, 그들이 마음껏 선을 넘나들 수 있도록 심리적 가이드라인을 쳐줘야 합니다. 한 사람의 주도성이 팀 전체의 오너십으로 번질 때, 조직은 관리자의 지시 없이도 스스로 움직이기 시작합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;나를 위한 주도성을 기르기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;이렇듯 ‘주도성’은 단순한 인성 평가의 기준이 아닙니다. 개인에게는 성장의 지름길이며, 팀에게는 효율적인 운영 시스템입니다. 물론 주도성을 오지랖으로 치부하는 환경에서 오너십을 유지하기는 쉽지 않습니다. 그러나 이런 환경일수록 주도적인 태도는 더욱 강력한 차별화 요소가 됩니다. 환경에 매몰되어 수동적으로 변하는 순간 멈춰 버리는 것은 조직의 성장이 아니라 바로 ‘나 자신의 시장 가치’이기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;정말로 중요한 사실은, 주도적인 태도로 가장 이득을 보는 것은 회사가 아니라 바로 자신이라는 점니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;1. 주도성이 시장가치를 결정한다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;채용 시장에서는 연차가 쌓일수록 연봉의 격차를 만드는 것이 기술의 개수에 달려 있지 않습니다. 그 기술을 활용해 ‘&lt;strong&gt;비즈니스 문제를 얼마나 주도적으로 해결했는가’&lt;/strong&gt;라는 경험의 차이입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;수동적으로 5년을 일한 개발자와 주도적으로 3년을 고민한 개발자가 면접장에서 만났다고 가정해 보겠습니다. 수동적인 개발자는 “어떤 기술을 써봤나요?”라는 질문에 기술 스택의 목록을 읊조릴 겁니다. 반면 주도적인 개발자는 “그 기술을 왜 선택했고, 도입 과정에서 무슨 한계를 어떻게 극복했는지”까지 전체 과정을 함께 설명합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기업은 단순히 코드를 생산하는 사람보다, 문제를 정의하고 해결책을 제시하는 문제 해결사에게 더 높은 값을 지불합니다. 주도성은 우리를 대체 불가능한 존재로 만드는 가장 확실한 개인 브랜딩 방법입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;2. 성장에는 주도성이 필요하다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;많은 직장인이 “이 회사에서는 더 이상 성장할 수 없을 것 같다”며 매너리즘에 빠집니다. 하지만 냉정하게 말해 &lt;strong&gt;성장은 회사가 시켜 주는 것이 아닙니다.&lt;/strong&gt; 성장은 내가 업무의 밀도를 높이고 고민의 깊이를 더할 때 자연스럽게 따라오는 결과에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;내가 주도권을 잡고 일의 맥락을 파악하기 시작하면 같은 업무라도 완전히 다른 경험이 됩니다. 단순히 티켓을 처리하는 노동이 아니라, 시스템 구조를 이해하고 문제를 해결하는 진짜 공부가 되기 때문입니다. 결국 주도적인 태도는 회사를 위한 헌신이 아니라 내 실력을 키우는 가장 확실한 수단입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;3. 주도적인 사람이 되는 시작&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;처음부터 대단한 일을 할 필요는 없습니다. 사실 주도성은 아주 작은 접미사 하나를 바꾸는 것에서 시작됩니다. 동료나 상사의 요청에 무의식적으로 “그건 안 돼요”라는 말이 나오려 할 때, 잠깐 멈추고 뒤에 이 말을 붙여 보세요.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;“...그런데, 어떻게 하면 되게 할 수 있을까요?”&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;“어떻게 하면 될까?”라는 질문은 단순한 긍정적 말버릇이 아닙니다. 이 질문을 던지는 순간, 당신의 시선은 내가 쓴 코드 한 줄에서 서비스 전체 흐름과 비즈니스 구조로 확장됩니다. 이 작은 질문을 반복하는 것만으로도 우리는 단순히 지시를 수행하는 부품에서, 어떤 문제든 해결하는 ‘대체 불가능한 전문가’로 성장할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>코딩 에이전트 여럿 쓰게 해주는 오케스트레이터 도구 3가지</title><link>https://yozm.wishket.com/magazine/detail/3655</link><description>Claude Code에 프롬프트를 던집니다. 에이전트가 일할 때면 저는 기다리는 게 일이 됩니다. 기능 A가 끝나야 기능 B를 시킬 수 있으니까요. 성능 좋은 에이전트를 써도 작업 구조는 싱글 스레드이기 때문입니다. 그래서 필요한 게 에이전트를 여러 명 동시에 굴리게 해주는 관리자입니다. 이 역할을 하는 도구를 오케스트레이터라고 부릅니다. 이 글에서는 오케스트레이터가 왜 필요한지부터 짚고, 어떤 문제를 해결해 주는지 정리해보려고 합니다. 그리고 코딩 에이전트를 여럿 동시에 쓰게 해주는 오케스트레이터 도구 3가지를 비교해 보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3655</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;Claude Code에 프롬프트를 던집니다. 에이전트가 일할 때면 저는 기다리는 게 일이 됩니다. 기능 A가 끝나야 기능 B를 시킬 수 있으니까요. 내 손은 키보드 위에 있지만 다음 지시를 줄 타이밍만 재고 있고는 합니다. 성능 좋은 에이전트를 써도 작업 구조는 싱글 스레드이기 때문입니다. 이 똑똑한 에이전트를 써도 개발 프로세스는 여전히 대기열로 굴러가는 셈입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런데 현실의 개발은 원래 이렇게 안 굴러갑니다. 백엔드는 API를 만들고, 프론트엔드는 화면을 붙이고, 테스트는 케이스를 짜고, 문서는 사용법을 정리합니다. 이 일들은 서로 완전히 끝날 때까지 기다릴 필요가 없습니다. 오히려 동시에 움직일 때 속도가 나고 병목도 빨리 드러납니다. 그러니까, 개발은 원래 멀티플레이가 기본이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 필요한 게 에이전트를 여러 명 동시에 굴리게 해주는 관리자입니다. 이 역할을 하는 도구를&amp;nbsp;&lt;strong&gt;에이전트 오케스트레이터(Agent Orchestrator)&lt;/strong&gt;라고 부릅니다. 어쩌면 앞으로는 에이전트가 코딩한다는 말보다 오케스트레이터가 팀을 굴린다는 말이 더 자주 나올지도 모릅니다. 그만큼 중요해질지도 모른다는 뜻입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 글에서는 오케스트레이터가 왜 필요한지부터 짚고, 어떤 문제를 해결해 주는지 정리해보려고 합니다. 그리고 코딩 에이전트를 여럿 동시에 쓰게 해주는 오케스트레이터 도구 3가지를 비교해 보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3655/agent_orchestrator_recommend.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가, Gemini로 제작&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;오케스트레이터가 ‘병렬 개발’하게 만드는 3가지 핵심 기능&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;막연히 코딩 에이전트를 여러 명 붙이면 속도가 빨라질 것 같나요? 현실은 다를 수도 있습니다. 무작정 같은 브랜치, 같은 폴더를 동시에 만지는 순간 충돌이 기하급수적으로 늘어나기 때문입니다. 게다가 미친듯이 쏟아내는 결과물을 사람이 판단할 수 없다면 꽝이기도 하니까요. 그래서 오케스트레이터는 이런 역할들을 해야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;격리(Isolation): 에이전트마다 코드 작업 공간 분리하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;병렬 개발의 기본은 &lt;strong&gt;격리&lt;/strong&gt;입니다. 에이전트별로 별도 환경을 만들어, 각자 독립 작업 공간에서만 일하게 해야 합니다. Git 워크트리를 가를 수도 있고, 폴더를 다르게 배정할 수도 있습니다. 쉽게 말해 서로의 코드를 건드리지 않게 환경부터 갈라주는 겁니다. 그래야 한 에이전트의 수정이 다른 에이전트의 작업을 망치지 않습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;비유로 보면 더 단순합니다. 한 주방에서 요리사 5명이 칼 하나로 요리하면 속도는커녕 사고만 나고 난리가 나겠죠. 그래서 오케스트레이터는&amp;nbsp;애초에&amp;nbsp;도마, 칼, 재료를 각자 세팅해 주는 역할부터 합니다. 작업 공간을 분리해 주면, 그제야 진짜 병렬이 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;가시성(Visibility): 지금, 누가, 뭘 하는지 보여주기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;에이전트가 늘어날수록 더 무서운 건 충돌보다 깜깜함입니다. 지금 누가 뭘 하는지, 어디서 막혔는지 안 보이면 사람이 통제할 수 없습니다. 그래서 좋은 오케스트레이터의 기준은 &lt;strong&gt;가시성&lt;/strong&gt;입니다. 한눈에 에이전트별 상태를 보여줘야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들면 이런 식입니다. 어떤 에이전트는 작업 중이고,&amp;nbsp;어떤 에이전트는 대기 중이며,&amp;nbsp;어떤 에이전트는 에러로 멈춰 있습니다. 또 어떤 결과물은 리뷰를 기다리고 있을 수 있죠. 원래 개발팀이라면 손이라도 들거나 메시지라도 보낼 텐데, 에이전트는 그것마저 시키지 않으면 잘 못합니다. 결국 지금 상황을 한 번에 파악하게 해주는 게 핵심입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;리뷰와 머지(Review &amp;amp; Merge): 작성자에서 통합자로 이동하기&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이렇게 오케스트레이터가 잘 돌아가면 사람의 역할이 바뀝니다. 코드를 직접 치는 시간보다, &lt;strong&gt;변경점 확인&lt;/strong&gt;에 더 많은 시간을 쓰게 됩니다. 방향이 틀어지면 코멘트로 수정하고 충돌을 정리해 &lt;strong&gt;머지&lt;/strong&gt;합니다. 마지막엔 “지금 릴리스해도 되는가”를 판단하겠죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 오케스트레이터를 단순히 "에이전트 추가 버튼" 정도로 여겨서는 안 됩니다. 엄밀히 말하면 이는 개인에게 개발&amp;nbsp;팀 리드 수준의 역할을 부여하는 도구에 가깝습니다. 여러 에이전트가 만든 결과물을 모아 한 제품으로 만드는 책임이 생기니까요. 병렬 개발의 끝은 결국, 리뷰와 통합의 품질에서 갈립니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;p style="text-align:justify;"&gt;그럼 이제 본격적으로 이러한 일을 해주는 도구 3가지를 알아보겠습니다. 지금은 초기 단계인 만큼 각자 특성이 뚜렷하게 드러나는 편입니다. 게다가 지금 막 새로 등장한 영역인 만큼 모두가 깃헙 레포 수준으로 존재하기도 합니다. 그러니 오케스트레이터들이 어떤 방향으로 나아가고 있는지, 바라본다는 관점에서 살펴봐도 좋겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/conductor/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;&lt;strong&gt;Conductor&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;: GUI 대시보드로 여러 에이전트를 지휘하기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Conductor는 여러 코딩 에이전트를 한 화면에서 지휘하게 해주는 도구입니다. &lt;strong&gt;Claude Code나 Codex를 병렬로 띄워 두고, 각 에이전트가 지금 뭘 하는지 GUI에서 확인하며 조율&lt;/strong&gt;합니다. 터미널 창을 여러 개 띄워 감으로 관리하던 일을 관제탑 화면으로 바꿔주는 방식입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/conductor/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;&lt;img src="https://www.wishket.com/media/news/3655/Conductor_product_valley.png"&gt;&lt;/a&gt;&lt;figcaption&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/conductor/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;Conductor&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;이 도구를 쓰면 뭐가 어떻게 편해질까?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;오케스트레이터의 핵심은 결국 여럿을 동시에 굴리는 것이죠. &lt;a href="https://yozm.wishket.com/magazine/product-valley/products/conductor/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;Conductor&lt;/a&gt;는 그중에서도 &lt;strong&gt;가시성(대시보드)에 강점&lt;/strong&gt;이 있습니다. 누가 어떤 작업을 맡았고, 어디서 멈췄는지 한눈에 보이면 자연스럽게 다음 지시가 빨라질 겁니다. 결과적으로 사람은 코드를 치기보다 흐름을 점검하고 우선순위를 바꾸는 쪽에 더 가까워집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;좋은 점은 기존 &lt;strong&gt;Claude Code 로그인 방식&lt;/strong&gt;을 그대로 쓴다는 겁니다. API 키를 쓰든, Pro/Max 같은 구독을 쓰든, 익숙한 인증 흐름 위에서 돌아갑니다. 새로 계정을 파거나 별도의 복잡한 연결을 요구하지 않는 쪽에 가깝습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;설정도 “설치 → 바로 병렬 실행”에 가깝습니다. 처음부터 스크립트를 짜거나, tmux 세션을 설계하지 않아도 됩니다. 그래서 병렬화를 ‘한 번이라도’ 해보고 싶은 사람에게 진입 장벽이 낮습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;누가, 언제 쓰면 좋은가&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이런 특징으로 Conductor는 터미널이나 스크립트보다, 작업을 시각적으로 관리하고 싶은 개발자에게 잘 맞습니다. 특히 “지금 뭐가 돌아가고 있지?”를 계속 확인해야 하는 상황에서요. 화면이 곧 상태판이 되니 머릿속으로 컨텍스트를 붙잡는 부담이 줄어듭니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어 백엔드, 프론트, 테스트처럼 서로 다른 일을 동시에 굴릴 때가 그렇습니다. 각각의 진행 상황을 ‘눈으로’ 확인하며, 막힌 곳부터 풀어주고 작업을 재배치할 수 있습니다. 인간 세상에서 Jira와 Notion으로 갖은 고생을 하며 확인하는 이유, 누가 어디까지 했지?가 덜해집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;만능은 아닌 Conductor의 단점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;물론 만능은 아닙니다. 첫 번째 제약은 &lt;strong&gt;macOS 전용&lt;/strong&gt;이라는 점입니다. 팀이 Windows나 Linux를 섞어 쓰면 도입 자체가 어려울 수 있습니다. 개인은 괜찮아도, 팀 단위 표준 도구로 삼기엔 환경 장벽이 생깁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;비용 곱셈&lt;/strong&gt;입니다. 에이전트를 늘리면 그만큼 API 사용도 늘어납니다. 더 무서운 건, 대시보드가 편할수록 병렬 작업을 과하게 켤 유혹이 커진다는 점입니다. 별 생각없이 딸깍딸깍 켜다보면 비용이 새는 습관으로 옮겨가기 쉽습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;정리하면 Conductor는 병렬화를 가장 쉽게 시작하는 버튼에 가깝습니다. 대신 플랫폼과 비용이라는 현실적인 제약을 감수해야 합니다. 내 작업이 정말 병렬에 어울리는지, 그리고 그 병렬이 얼마짜리인지부터 같이 계산해보는 게 안전합니다.&lt;/p&gt;&lt;hr&gt;&lt;h3 style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/claude-squad/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;&lt;strong&gt;Claude Squad&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;: tmux 기반으로 터미널에서 ‘멀티플렉싱’하기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Claude Squad는 tmux 위에서 여러 개의 Claude Code를 동시에 띄웁니다. 쉽게 말해, &lt;strong&gt;한 터미널 화면을 여러 칸으로 쪼개고 각 칸에 에이전트를 한 명씩 앉히는 방식&lt;/strong&gt;입니다. 그래서 백엔드 작업을 시키는 동안 옆 칸에서는 프론트엔드 수정도 같이 굴릴 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/claude-squad/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;&lt;img src="https://www.wishket.com/media/news/3655/Claude-squad_product_valley.png"&gt;&lt;/a&gt;&lt;figcaption&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/claude-squad/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;Claude Squad&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;이 도구를 쓰면 뭐가 어떻게 편해질까?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;오케스트레이터가 보통 해결하는 건 격리·가시성·리뷰/머지 세 가지라고 했습니다. &lt;a href="https://yozm.wishket.com/magazine/product-valley/products/claude-squad/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;Claude Squad&lt;/a&gt;는 그중에서도 특히 &lt;strong&gt;운영의 단순함&lt;/strong&gt;에 무게가 실려 있습니다. 별도 서버나 복잡한 UI를 올리기보다 tmux라는 이미 익숙한 도구 위에 얹는 쪽을 택했기 때문입니다. 대신 한눈에 보는 가시성 측면에서는 대시보드 대신 사용자가 터미널 화면을 관찰하며 확보하는 방식을 택했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Claude Squad에는 GUI 대시보드가 없습니다. 그런데 터미널이 익숙한 개발자라면, 이게 오히려 장점이 될 수 있습니다. 마우스로 창을 찾고 클릭하는 대신 키보드로 패널을 휙휙 넘기며 컨텍스트 스위칭(작업 맥락 전환)을 빠르게 할 수 있기 때문입니다. 관리 화면을 배우는 비용이 거의 없다는 뜻이기도 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;따지자면 Claude Squad는 큰 화면 한 장 대신 여러 개의 무전 채널을 동시에 듣는 쪽에 가깝습니다. 각 에이전트의 대화와 로그가 패널마다 흘러가고, 나는 필요한 채널로 바로 들어가서 지시를 바꿉니다. 상황판은 없지만 대신 손이 빠르면 운영이 빨라집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지원 환경도 실용적입니다. &lt;strong&gt;Mac·Linux를 지원&lt;/strong&gt;하니 팀 내 개발 환경이 섞여 있어도 도입 장벽이 낮습니다. 게다가 &lt;strong&gt;오픈소스 무료&lt;/strong&gt;라서 일단 몇 명만 써보자 같은 실험에 부담이 적습니다. 에이전트를 늘려보는 단계에서 도구 비용이 발목을 잡지 않는다는 점이 큽니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;만능은 아닌 Claude Squad의 단점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;대신 단점도 분명합니다. &lt;strong&gt;상태를 한눈에 보는 대시보드가 없기&lt;/strong&gt; 때문에 에이전트가 늘어날수록 사람의 관리 능력이 성능을 좌우합니다. 누가 무엇을 하고 있는지, 어디서 막혔는지, 지금 개입해야 하는지 등을 사용자가 직접 정리해야 합니다. 팀이 커지거나 에이전트 수가 많아지면 이 부담은 생각보다 빨리 커집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또 하나는 &lt;strong&gt;리뷰/머지 흐름&lt;/strong&gt;입니다. 여러 에이전트가 동시에 코드를 만들면, 결국 사람은 합치기 전에 검토하고 충돌을 정리해야 합니다. Claude Squad가 이 과정을 자동으로 매끈하게 이어준다고 기대하면 곤란합니다. 필요하다면 별도의 도구나 팀 규율로 리뷰와 머지의 리듬을 따로 설계해야 합니다.&lt;/p&gt;&lt;hr&gt;&lt;h3 style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/agent-orchestrator/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;&lt;strong&gt;Agent Orchestrator&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;: 에이전트를 로컬이 아니라 ‘CI/CD 프로세스’에 붙이기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;Agent Orchestrator는 &lt;strong&gt;에이전트를 내 로컬에서 부리는 도구에서 꺼내&amp;nbsp;CI/CD 프로세스에 붙입니다.&lt;/strong&gt; 사람이 시키기 전에 무언가 일을 해야 할 ‘사건’이 먼저 에이전트를 부르는 구조입니다. 그래서 자동화가 필요한 팀일수록 체감이 크게 옵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;이 도구는 외부 서비스를 AI 에이전트에 붙여주는 Composio를 만든 ComposioHQ에서 공개한 오픈소스 레포지토리입니다. Composio 서비스 전체를 사지 않아도 쓸 수 있으니 걱정 마세요.&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/agent-orchestrator/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;&lt;img src="https://www.wishket.com/media/news/3655/agent-orchestrator_product_valley.png"&gt;&lt;/a&gt;&lt;figcaption&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/agent-orchestrator/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;agent-orchestrator&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;이 도구를 쓰면 뭐가 어떻게 편해질까?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이 오케스트레이터를 쓴 다음, CI가 실패하면 에이전트가 먼저 로그를 읽고 원인을 찾습니다. 그리고 수정안을 만들어 PR에 반영하거나 다음 실행을 위한 커밋을 준비합니다. 사람은 왜 깨졌나 확인하는 일부터 시작하지 않아도 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;한편 리뷰어가 코멘트를 남기면, 그 코멘트가 다시 에이전트를 호출하기도 합니다. 에이전트는 지적받은 부분을 고치고, 변경 이유를 설명하는 식으로 반영합니다. 리뷰가 대화로 끝나는 대신 수정으로 이어지기 쉬워집니다. 정리하면, 사람이 에이전트에게 시키는 구조에서 이벤트가 에이전트를 호출하는 구조로 이동시켜주는 도구입니다. CI 실패, 리뷰 코멘트 같은 신호가 트리거가 됩니다. 오케스트레이터의 역할이 더 강해지는 지점이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;a href="https://yozm.wishket.com/magazine/product-valley/products/agent-orchestrator/?utm_source=yozmit&amp;amp;utm_medium=content&amp;amp;utm_campaign=base"&gt;Agent Orchestrator&lt;/a&gt;는 &lt;strong&gt;YAML 양식으로 개발 자동화 흐름을 정의&lt;/strong&gt;합니다. 그러니까 버튼을 눌러 설정하는 대신 “이런 일이 생기면 이렇게 해”를 글로 적어두는 방식입니다. 선언적으로 적어두면 팀이 커져도 흐름이 덜 흔들립니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지원하는 에이전트 폭도 넓습니다. &lt;strong&gt;Claude Code만이 아니라 Codex, Aider까지 연결&lt;/strong&gt;해 쓸 수 있습니다. 팀이 이미 쓰는 에이전트가 제각각이어도 한 흐름으로 묶기 좋습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;누가, 언제 쓰면 좋은가&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;테스트/린트/빌드/리뷰가 어느 정도 표준화된 팀에 잘 맞습니다. 반복 작업이 많고, 깨지면 고치고 다시 돌리는 루틴이 잦을수록 효과가 큽니다. 이런 코드 수정의 자동화는 결국 반복이 많을 때 가장 빨리 이득이 납니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 “실패 처리”가 많은 프로젝트에서 빛을 봅니다. 예를 들어 레거시, 의존성 지옥, flaky test처럼 자주 흔들리는 환경입니다. 이런 곳은 사람의 집중력이 먼저 닳기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;만능은 아닌&amp;nbsp;Agent Orchestrator의 단점&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;물론 당연히 모든 일을 처리해 주지는 않겠죠. CI/CD에 자동으로 개입한다는 건 범위가 넓은 일입니다. 그만큼 당연히&amp;nbsp;&lt;strong&gt;초기 설정이 복잡&lt;/strong&gt;해질 수 있습니다. 처음에 흐름을 잘못 잡으면, 자동화가 오히려 혼란을 키울 거고요. 그래서 도입 초반에는 작은 범위부터 시작하는 편이 안전합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또 프로덕션/조직 환경에서는 &lt;strong&gt;권한 관리&lt;/strong&gt;가 더 중요합니다. 에이전트가 무엇을 어디까지 수정할 수 있는지를 명확히 해야 합니다. 접근 범위를 넓게 주는 순간, 잠시 편의성이 생길지 몰라도 리스크가 무지막지하게 커집니다.&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;물론 오케스트레이터를 무조건 써야 하는 건 아닙니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;오케스트레이터 도입의 ROI는 결국 “도구가 좋아서”가 아닙니다. 내가 하는 일 중에서 &lt;strong&gt;병렬로 쪼개도 되는 일의 비율&lt;/strong&gt;이 얼마나 되느냐에 달려 있습니다. 동시에 돌려야 하는 덩어리가 많으면 Conductor나 Claude squad가 빛을 봅니다. 반면 쪼갤 게 적으면 오케스트레이터를 도입하는 체감이 없습니다. 오히려 비용과 운영 복잡도만 늘 수 있죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;병렬화는 공짜가 아니다&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;많이들 오케스트레이터나 코딩 에이전트의 하네스를 얹어주는 도구를 볼때, 그 도구 자체의 가격부터 봅니다. 그런데 실제로 더 크게 튀는 건 &lt;strong&gt;코딩 에이전트 그 자체의 사용 가격&lt;/strong&gt;입니다. 에이전트가 늘수록 호출이 곱셈으로 늘어나기 때문입니다. 도구 비용이 아니라 돌리는 만큼 나가는 비용이 핵심입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;중간 규모 기능 하나만 잡아도 수동 대비 호출이 한참 더 나올 수도 있습니다. 사람이 한 번에 끝낼 흐름을 에이전트는 더 잘게 쪼개 확인할 수 있으니까요. 그 과정에서 요청과 응답도 계속 쌓입니다.&amp;nbsp;에이전트를 5개 돌리면, 비용도 사실상&amp;nbsp;확실히 커진다는 뜻입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;물론 항상 정확히 5배는 아닙니다. 하지만 아무리 정해진 Max 요금제를 써도 토큰이 선형으로 증가한다는 감각이 오를지도 모릅니다. 병렬화는 속도를 사는 대신 호출을 더 사는 구조입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;왜 호출이 늘어나며 머리가 아파오는가&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;사람 1명이 하던 생각과 탐색 과정을 떠올려 보겠습니다. 코드를 읽고, 가설을 세우고, 한 번 고치고, 다시 확인하죠. 병렬화에서는 이 과정이 에이전트마다 각자 반복됩니다. 즉, 한 사람이 한 번 하던 루프가 여러 번 돌아갑니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;게다가 에이전트는 보통 &lt;strong&gt;격리된 작업 공간&lt;/strong&gt;에서 일합니다. 그러면 각자 빌드하고, 각자 테스트하고, 각자 컨텍스트를 다시 확인합니다. 같은 저장소라도, 서로 다른 방에서 따로 작업하는 셈입니다. 이게 안정성을 주는 대신, 호출과 로그를 폭증시킵니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;한편, 이를 다루는 사람의 입장도 생각해야 합니다. 이렇게 복잡한 사고 흐름을 모두 따라가는 건 당연히 매우 어렵습니다. 더 많은 일을 시키지 못하는 것보다 두려운 건 어느 순간 그 일을 따라잡지 못하는 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;비용을 통제하는 운영 팁&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 &lt;strong&gt;모델 분배&lt;/strong&gt;입니다. 이를테면 복잡한 추론은 Opus에 맡기고, 단순 수정은 Sonnet/Haiku로 내립니다. 쉽게 말해 어려운 일은 비싼 사람, 쉬운 일은 저렴한 사람한테 부탁하는 거죠. 이 한 가지만 해도 비용 곡선이 달라집니다. 꼭 오케스트레이터가 아니어도 비슷할 겁니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째는 &lt;strong&gt;무조건 병렬을 버리는&lt;/strong&gt; 겁니다. 병렬화 가치가 큰 작업부터 쪼개야 합니다. 예를 들어 아래처럼 경계가 명확한 것부터 나누는 식입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;프론트 UI 작업&lt;/li&gt;&lt;li style="text-align:justify;"&gt;백엔드 API 작업&lt;/li&gt;&lt;li style="text-align:justify;"&gt;테스트 작성 작업&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 나누면 오케스트레이터의 장점이 바로 나옵니다. 서로 코드가 덜 부딪히고 합치는 과정도 단순해집니다. 반대로 경계가 흐린 작업을 억지로 병렬화하면 호출만 늘고 머지만 어려워집니다. 물론 이를 명확하게 설계하고 분배하는, 소위 말해 "기획" 단의 일이 더 중요해 지겠죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;오케스트레이터를 단순&amp;nbsp;”에이전트를 한 명 더 고용하는 도구”로 보면, 기대가 자주 어긋납니다. 핵심은 에이전트 수를 늘리는 게 아니라&amp;nbsp;&lt;strong&gt;여럿이 만든 결과물을 충돌 없이 통합&lt;/strong&gt;하는 데 있습니다. 다섯 명이 동시에 코드를 만지면 생산성보다 먼저 “누가 뭘 했지?”와 “어디서 꼬였지?”가 문제로 떠오르거든요. 오케스트레이터는 그 혼선을 줄여서 사람이 마지막에 깔끔하게 합칠 수 있게 돕습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그런 관점에서 &lt;strong&gt;가시성이 필요하면 Conductor&lt;/strong&gt;가 잘 맞습니다. 화면에서 에이전트들이 뭘 하고 있는지, 어디서 막혔는지 흐름을 잡기 쉽습니다.&amp;nbsp;&lt;strong&gt;터미널 중심으로 일한다면 Claude Squad&lt;/strong&gt;가 더 자연스럽습니다. GUI 대신 터미널에서 여러 Claude Code 세션을 병렬로 다루는 방식이라 손이 덜 바뀝니다. 한편&amp;nbsp;&lt;strong&gt;CI까지 묶어 PoC를 잡고 싶다면&amp;nbsp;Agent Orchestrator로 시작&lt;/strong&gt;하는 편이 낫습니다. 단순히 에이전트를 띄우는 걸 넘어 자동화 흐름 자체를 붙일 수 있기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 무엇이든 오케스트레이터의 진가는 여러 기능을 동시에 개발할 때,&amp;nbsp;대규모 리팩토링처럼 할 일이 산더미인 경우에 좋습니다. 바꾸어야 할 파일이 많고, 작업 단위가 반복적일수록 병렬화 이득이 커집니다. 이때 오케스트레이터는 속도를 올리는 도구라기보다, 합치는 비용을 통제하는 도구가 되니까요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다시 한 번 돌이켜 보지만, 결국 중요한 건 에이전트 숫자가 아니라 통합할 수 있는 작업의 구조를 먼저 만드는 일입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>바이브 코딩으로 만든 앱, 글로벌 시장에서 팔리기까지</title><link>https://yozm.wishket.com/magazine/detail/3652</link><description>지난해 요즘IT에 실린 “본업과 부업 사이, 개발자가 퇴근 후 ‘내 서비스’ 만든 방법”이라는 인터뷰, 기억하시는 분들 계실까요? 앱 론칭 100일 만에 400만 원의 수익을 냈다는 이야기로 화제를 모았던 김우영 개발자인데요. 그 이후로도 멈추지 않고, 프롬프트 관리 앱 Promptlight에 이어 최근에는 음성 입력 앱 Mallo(말로)까지 정식 출시하며, 자신만의 서비스를 만들고 있습니다. 세 앱 모두 처음부터 한국이 아닌 영어권 글로벌 시장을 타깃했다는 점이 인상적인데요. 오늘은 바이브 코딩으로 어떻게 글로벌 앱을 빠르게 만들고, 레딧과 X 같은 해외 채널에서 실제 고객을 만들어가고 있는지, 그 생생한 경험담을 직접 들어봤습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3652</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;[바이브코더스] 글로벌 서비스와 앱으로 수익화를 실현한 김우영 님 인터뷰&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지난해 요즘IT에 실린 “&lt;a href="https://yozm.wishket.com/magazine/detail/3439/"&gt;&lt;u&gt;본업과 부업 사이, 개발자가 퇴근 후 ‘내 서비스’ 만든 방법&lt;/u&gt;&lt;/a&gt;”이라는 인터뷰, 기억하시는 분들 계실까요? 앱 론칭 100일 만에 400만 원의 수익을 냈다는 이야기로 화제를 모았던 김우영 개발자인데요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 이후로도 멈추지 않고, 프롬프트 관리 앱 &lt;a href="https://yozm.wishket.com/magazine/product-valley/products/promptlight/"&gt;&lt;u&gt;Promptlight&lt;/u&gt;&lt;/a&gt;에 이어 최근에는 음성 입력 앱 &lt;a href="https://www.mallo.so/ko"&gt;&lt;u&gt;Mallo(말로)&lt;/u&gt;&lt;/a&gt;까지 정식 출시하며, 자신만의 서비스를 만들고 있습니다. 세 앱 모두 처음부터 한국이 아닌 영어권 글로벌 시장을 타깃했다는 점이 인상적인데요. 오늘은 바이브 코딩으로 어떻게 글로벌 앱을 빠르게 만들고, 레딧과 X 같은 해외 채널에서 실제 고객을 만들어가고 있는지, 그 생생한 경험담을 직접 들어봤습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image7.png" alt="바이브 코더스"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:50%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image4.png" alt="김우영 개발자 인터뷰"&gt;&lt;figcaption&gt;김우영 님 &amp;lt;출처: 바이브코더스 인터뷰 화면&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Part 1. 바이브 코딩으로 만든 앱, 글로벌 시장 진출까지&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 안녕하세요! 간단한 자기소개 부탁드립니다.&amp;nbsp;&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;반갑습니다. 저는 바이브 코딩으로 다양한 글로벌 서비스와 앱을 만들고 있는 김우영이라고 합니다. 요즘IT에서는 &lt;a href="https://yozm.wishket.com/magazine/product-valley/products/shotomatic/"&gt;&lt;u&gt;쇼토매틱(Shotomatic)&lt;/u&gt;&lt;/a&gt;이라는 앱으로 먼저 인사드렸었고, 최근에는 다양한 후속 앱들을 계속 만들고 운영하고 있어요. 이렇게 다시 인터뷰할 수 있는 좋은 기회를 주셔서 감사합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 이전 인터뷰에서 소개해 주신 Shotomatic 이후에, 최근 "Mallo(말로)"라는 새로운 앱을 정식 출시하셨다고 들었어요. 어떤 앱인가요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Mallo는 맥 OS에서 쓸 수 있는 Speech To Text 앱인데요. 음성으로 타이핑을 대신해 주는 기능을 가지고 있습니다. 그래서 앱 이름을 만들 때도 "말로 하세요"라는 의미를 담아, '말로'라고 지었습니다. 아직 출시한 지 한 달 정도밖에 되지 않은 따끈따끈한 앱이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 이 앱을 만들게 된 계기는 AI와 함께 코딩하다 떠오른 아이디어에서 시작됐는데요. AI가 점점 발전하면서 어느 순간부터는 제가 의식의 흐름대로만 프롬프트를 입력해도, AI가 알아듣고 코딩을 잘하더라고요. 그리고 AI와 함께 개발하는 시간이 많아질 수록 타이핑조차 너무 귀찮아졌고요. 그냥 생각나는 대로 빠르게 지시하고 싶은데, 생각을 타이핑하는 것보다 말로 하는 게 더 효율적이잖아요. 그래서 몇 가지 서비스를 찾아봤는데, 보통 그런 서비스들은 다 구독형이었어요. 구독 말고 로컬에서도 구현할 수 있을 것 같아, 찾아보니 방법이 있었죠. 그럼 ‘그냥 내가 제품을 만들어 보자’는 생각으로 출시하게 됐어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image3.png" alt="Mallo macOS dictation 앱"&gt;&lt;figcaption&gt;‘Mallo’ macOS dictation 앱 &amp;lt;출처: &lt;a href="https://www.mallo.so/"&gt;&lt;u&gt;mallo&lt;/u&gt;&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. Shotomatic, Promptlight, Mallo까지 짧은 기간에 세 개의 앱을 연달아 출시하셨는데요. 특히 한국 개발자로서 글로벌 시장을 타깃으로 한 점이 인상적이에요. 어떤 계기가 있으셨나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;우선 제게 큰 영감을 준 글이 하나 있어요. 예전에 EO Planet 김태용 대표님이 링크드인에 올리신 글이었는데요. EO가 미국에 진출할 때 들었던 조언 가운데 하나가 “글로벌 진출”이라는 개념은 사실 없고, 세상은 원래 글로벌인데 우리가 한국에 있을 뿐이라는 이야기였다고 하더라고요. 그 말을 듣고 정말 맞는 말이라고 생각했어요. 우리는 이미 글로벌 안에 살고 있는데, 굳이 서비스를 한국에서만 판매할 필요가 있을까 싶었던 거죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그리고 제가 처음으로 제 프로덕트를 만들고, 이걸 사람들에게 팔아보고 싶다고 생각하게 된 계기도 있었어요. 주로 X 같은 플랫폼에서 활동하는 분들을 보며 영감을 많이 받았거든요. 소위 ‘인디 해커’라고 불리는, 직접 프로덕트를 만들고 판매하는 사람들을 봤을 때 그분들은 대부분 영어권 사용자였어요. 그러다 보니 자연스럽게 저도 처음부터 한국에서만 제품을 판매해야겠다는 생각은 들지 않았던 것 같아요. 그렇다고 처음부터 글로벌 시장에만 팔아야 한다고 생각했던 건 아니고요. 그냥 영어로 만들면, 그 자체로 자연스럽게 글로벌화가 된다고 느꼈어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;시간이 지나면서는, 제가 이렇게 시작하길 정말 잘했다고 느낀 계기도 있었는데요. 글로벌로 제품을 판매하다 보니, 생각보다 나라 간 구매력 차이가 크더라고요. 예를 들어, 한국 사용자에게는 소프트웨어에 몇만 원을 쓰는 일이 허들이 될 수 있잖아요. 반면, GDP가 훨씬 높은 국가들에서는 제품 구매를 크게 어렵게 생각하지 않는 사람들도 많다는 걸 봤어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Part 2. 바이브 코딩 도구와 실전 개발 팁&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 최근 AI 개발 도구가 빠르게 바뀌고 있는데요. 우영 님은 어떤 도구로 바이브 코딩을 하시나요? Shotomatic을 개발하던 때와 비교해, 사용하는 도구 조합에도 변화가 있었나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;제가 작년까지만 해도 Cursor를 정말 많이 썼어요. Cursor는 기존 개발 도구인 IDE의 장점을 그대로 갖고 있으면서도, AI를 붙이기 쉬웠거든요. 그래서 한동안은 Cursor를 중심으로 많이 작업했어요. 그때는 기본적으로 코드를 제가 직접 보면서 리뷰도 자주 했던 것 같고요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러다가 Claude Code가 점점 주목받기 시작하면서, 저도 자연스럽게 Claude를 쓰게 됐어요. 실제로 써보니까, 이제는 내가 코드를 직접 다 보지 않아도 괜찮지 않을까 하는 생각이 들더라고요. 그런 경험이 반복되다 보니 굳이 Cursor를 계속 써야 할 필요성을 점점 덜 느끼게 됐고, 자연스럽게 사용 빈도도 줄어들었어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 후 작년 12월쯤 GPT 5.2, 5.3 버전을 쓰기 시작하면서부터는 Claude Code에서 완전히 OpenAI Codex로 넘어갔어요. 제가 Claude Code를 쓸 때는 Claude가 코딩을 더 잘하도록 여러 가지를 꽤 많이 세팅해 뒀거든요. 그런데 Codex를 사용하기 시작하면서, 거기에 붙어 있는 모델이 너무 똑똑하다고 느꼈어요. 이제는 정말 제가 코드를 전혀 보지 않아도 될 정도로 많이 발전했구나 싶더라고요. 그런 생각이 들면서 지금은 Codex를 메인으로 쓰고 있고, Claude Code는 거의 보조 수단처럼 활용하고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다만 글쓰기는 Claude Code가 조금 더 잘해주는 느낌이 있어요. 그래서 블로그 글 같은 걸 쓸 때는 Claude Code의 도움을 받고, 개발은 거의 100% Codex로 하고 있다고 보시면 될 것 같아요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image1.png" alt="AI 코딩 에이전트"&gt;&lt;figcaption&gt;AI 코딩 에이전트, Cursor에서 Claude Code 그리고 Codex까지 &amp;lt;출처: &lt;a href="https://note.com/lab_bit__sutoh/n/n957d85f7e19a"&gt;&lt;u&gt;note.com&lt;/u&gt;&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. Mallo(말로)의 실제 제작 과정을 구체적으로 들려주실 수 있을까요? 아이디어 단계부터 정식 출시까지는 얼마나 걸렸고, 각 단계에서 AI를 어떻게 활용하셨는지도 궁금합니다.&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;Mallo는 아이디어부터 출시까지 약 2주 정도 걸렸던 것 같아요. 이전부터 음성 기반 앱을 한번 만들어보고 싶다는 생각은 있었어요. 처음에는 일기 앱 같은 것들을 떠올렸죠. 예전에는 아직 에이전트가 크게 발달하지 않아서, 이런 건 나중에 한 번 개발해 보고 싶다고 아이디어 노트에 적어만 두고 있었어요. 그런데 요즘 바이브 코딩을 하면서, 이제는 ‘입 코딩’을 좀 해보고 싶다는 생각이 들더라고요. 그 시점에는 AI 모델도 많이 성숙해 있었고, 이제는 충분히 개발해 볼 수 있겠다는 확신이 들었어요. 그래서 Mallo를 만들어야겠다고 마음먹은 뒤에는 2주 안에 모든 걸 다 만든 것 같아요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;기획 단계부터 릴리즈까지는 AI를 거의 100% 활용했어요. 예를 들면, 제가 만들려는 기능과 비슷한 기능을 가진 앱이 무엇인지, 또 어떤 경쟁 앱이 있는지 같은 부분도 AI로 리서치했어요. 물론 제가 직접 찾아볼 수도 있었겠지만, 제가 하는 것보다 AI에게 맡기는 편이 더 빠르고 확실하더라고요. 그렇게 필요한 기능을 조사한 뒤, 그 기능들을 하나씩 구현해 나가는 과정도 이전처럼 AI를 100% 활용했고요. Mallo의 코어 기능이 개발된 이후로는, 이제는 타이핑이 아닌 음성을 통해서 주로 AI와 일하고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 개발뿐 아니라, 제품 출시 단계에서 필요한 작업도 이제는 대부분 AI와 함께할 수 있더라고요. 예를 들어, 앱 이름을 정할 때도 AI와 계속 대화하면서 많이 고민했어요. 이전에 만든 앱인 &lt;a href="https://shotomatic.com/"&gt;&lt;u&gt;Shotomatic&lt;/u&gt;&lt;/a&gt;이나 &lt;a href="https://promptlight.app/"&gt;&lt;u&gt;Promptlight&lt;/u&gt;&lt;/a&gt;는 이름 자체가 비교적 직관적인 편이었는데, Mallo는 조금 다른 느낌으로 가고 싶었어요.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사용자가 이름을 보고 한 번 더 생각하게 만드는 이름이면 좋겠다고 봤죠. 그래서 영어권 사용자가 봤을 때는 한 번에 뜻을 알 수는 없지만 “이게 뭘까?” 하고 궁금해할 수 있고, 한국 사람들에게 설명할 때도 어렵지 않은 이름이면 좋겠다고 생각했어요. 그런 고민 끝에 AI와 함께 Mallo라는 이름을 만들게 됐죠. 그리고 랜딩 페이지를 만드는 일도, 번역하고 배포할 수 있는 환경을 구축하는 일도, 적절한 레퍼런스만 제시하면 AI가 알아서 잘 세팅해 주더라고요. 마케팅을 위해 SNS에 제가 직접 글을 올리는 일을 제외하면, 아이데이션부터 개발, 출시까지 거의 전 과정을 AI로 진행했다고 보시면 될 것 같아요.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 바이브 코딩하실 때 사용하는 Skills와 개발 팁도 공유해 주실 수 있을까요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;아마 많은 분이 이미 아시겠지만, Skills(스킬)는 에이전트형 도구가 구조화된 기능 단위로 반복 가능한 작업을 정의해 둔 것인데요. 저는 개발을 진행할 때 여러 Skills를 직접 만들어서 사용하고 있어요. 그중 몇 가지는 소개해 드릴 만한 것 같아요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;첫 번째는 화면에 있는 앱을 스크린샷으로 찍어서 AI에 입력해 주는 Skills예요. 저는 주로 QA를 하거나, 기능 개발이 제대로 되었는지를 에이전트를 통해 확인할 때 이 Skills를 사용하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image5.png" alt="스크린샷으로 AI에게 인풋을 넣어주는 Skills"&gt;&lt;figcaption&gt;스크린샷으로 AI에게 인풋을 넣어주는 Skills &amp;lt;출처: &lt;a href="https://www.linkedin.com/posts/wooing_agent%EC%97%90%EA%B2%8C-%EB%9D%BC%EC%8B%9D-%EC%88%98%EC%88%A0%EC%9D%84-%ED%95%B4%EC%A3%BC%EB%8A%94-skill%EC%9D%84-%EB%A7%8C%EB%93%A4%EC%97%88%EC%8A%B5%EB%8B%88%EB%8B%A4-seer-activity-7408496935789064193-9CL2/?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAABnA_qMBVbtPXuHRqEAxbdng81tsZWPjA5c"&gt;&lt;u&gt;김우영 님 링크드인&lt;/u&gt;&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;두 번째로는 제가 &lt;a href="https://wikidocs.net/234453"&gt;&lt;u&gt;tmux&lt;/u&gt;&lt;/a&gt;라는 도구를 사용하고 있어요. tmux는 터미널을 여러 개 띄워 놓고 개발할 때, 터미널끼리 서로 상호작용할 수 있게 도와주는 플러그인 같은 도구인데요. 저는 이 tmux를 제어하는 방법을 에이전트에게 알려주는 Skills를 따로 만들었어요. 그래서 커맨드를 통해 터미널 창끼리 소통할 수 있게 해두면, Codex가 직접 로그를 보거나 서버를 껐다 켰다 하면서, 다시 말해 앱을 껐다 켰다 하며 디버깅할 수 있게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;세 번째로는 제가 요즘 Git(깃) 자체를 더 잘 활용하는 방법을 많이 공부하고 있는데요. 아무래도 요즘은 에이전트가 동시에 여러 작업을 병렬로 수행할 수 있다 보니, 브랜치를 따서 동시에 여러 기능을 개발하거나, 하나의 기능을 여러 방식으로 구현해 보는 시도를 많이 하게 되는 것 같아요. 그때 필요한 게 Git에서 제공하는 Worktree(워크트리)라는 도구인데요. 저는 에이전트가 병렬로 여러 기능을 각각 개발할 때, 워크트리를 통해 메인 브랜치와 어떻게 상호작용하면 되는지를 알려주는 Skills를 만들어 사용하고 있어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;저는 바이브 코딩으로 개발할 때, 앞서 말씀드린 Skills를 통해 작업 에이전트가 조금 더 명시적이고 모듈화된 상태로 일할 수 있도록 설정해 두는 편이에요. 제가 생각했을 때는 이런 Skills를 셋업해 두는 일이 작업 흐름에서 정말 중요한 것 같아요. 이렇게 잘 만든 Skills를 잘 세팅해 둘수록, 에이전트를 활용하는 방식도 훨씬 더 고도화되고 쉬워진다고 생각합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image8.png" alt="Skills"&gt;&lt;figcaption&gt;김우영 님이 직접 만들어 사용하는 다양한 Skills &amp;lt;출처: 바이브코더스 인터뷰 화면&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Part 3. 바이브 코더로서 얻은 인사이트와 수익화 전략&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 바이브 코딩을 하는 과정에서, 최근 가장 크게 느낀 변화나 인사이트가 있다면 무엇일까요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;바이브 코딩을 시작한 뒤로는, 확실히 시간을 활용하는 방식이 훨씬 더 효율적으로 바뀌었어요. 최근 몇 개월 사이 AI 모델과 도구가 정말 비약적으로 발전하면서, 예전에는 제가 제약이라고 느꼈던 부분들이 지금은 대부분 해소됐거든요. 예를 들어, Skills 기능을 활용해 AI가 스스로 어떤 루프를 돌게 만들어 놓으면, 제가 계속 옆에서 감독하지 않아도 돼요. 그만큼 다른 업무에 시간을 더 효율적으로 쓸 수 있게 된 거죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;가령 예전에는 퇴근 후 4~5시간을 써서 무언가를 만들어야 했다면, 이제는 그 일을 1시간 정도만 써도 되는 수준이 됐어요. 주어진 시간 자체는 똑같지만, AI 덕분에 시간을 더 효율적으로 쓰고 있죠. 어떻게 보면 시간이&amp;nbsp; 한정돼 있었기 때문에, 오히려 더 효율화할 방법을 찾게 된 걸 수도 있어요. 그런데 그 과정에서 도구와 방식 자체가 정말 많이 발전한 것도 분명하고요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지금은 개발 자체가 막히는 과정은 거의 없어요. 특히 제품을 구현하는 단계에서는 모델들이 너무 잘해주기 때문에, 이제는 무엇을 만들지를 결정하는 일이 훨씬 더 큰 병목이 됐죠. 이걸 만든다고 사람들이 정말 돈을 낼까?, 이 기능이 정말 필요한가? 같은 질문에 훨씬 더 많은 시간을 쓰게 되더라고요. 그래서 요즘은 마케팅 전략을 가장 많이 고민하고 있습니다. 마케팅은 사실 아직도 어려워요. 어떻게 해야 사람들이 이 앱의 존재를 알게 될까, 또 실제로 사용하게 만들 수 있을까 하는 점이 가장 어려운 부분인데요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;개인적으로는 개발에서 조금씩 손을 떼게 되면서, 다른 직군이 맡아온 일의 무게를 더 실감하고 있어요. 정말 대단한 일을 해오셨구나, 그런 생각을 하게 되죠. 혼자서 제품을 런칭해보니 기획, 디자인, 마케팅 어느 것 하나 쉬운 게 없더라고요. 이전에 다른 직군의 동료들과 같이 협업했던 기억을 살려가면서 하나하나 해보고 있는데요. 그래도 개발자라는 정체성은 그대로라, 개발을 통해 다른 모든 것들을 해결하려고 하죠. 그래서 지난주부터 8주 동안 ‘무료 도구 8개 만들기’라는 프로젝트를 시작해, 제 블로그에 올리고 있어요. 앞으로는 SEO(검색 엔진 최적화) 고도화 프로젝트도 진행하면서, 지금보다 홍보와 마케팅에 더 집중할 예정입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image6.png" alt="제품 SEO"&gt;&lt;figcaption&gt;제품 SEO 시작하기 &amp;lt;출처: &lt;a href="https://www.threads.com/@wooing0306/post/DUarJLcDwDb?xmt=AQF0uAA6iZ0UKqndWTcuGBHUYCIzo6vv2vIw0M6BWbKlSg"&gt;&lt;u&gt;김우영 님 스레드&lt;/u&gt;&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. Shotomatic 때는 레딧과 커뮤니티 사이트 등을 통해 수십 명의 고객을 확보하셨다고 들었는데요. Mallo는 어떤 채널로 알리고, 어떻게 수익화할 계획이신가요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;우선은 SNS를 통해서 조금씩 알려보려고 해요. 제가 개발자다 보니, 사실 마케팅을 직접 해본 적은 없어요. 처음에는 어떻게 해야 할지 많이 막막했는데요. 앞서 말씀드린 인디 해커들의 마케팅 방식에서 많은 영향을 받았던 것 같아요. 예를 들어, 어떤 분은 레딧에 글을 올려 첫 고객을 확보했고, 어떤 분은 콜드 이메일로 고객과 연결됐고, 또 어떤 분은 커뮤니티에서 다수의 고객을 찾았더라고요. 그런 사례들을 보면서 저도 ‘이렇게 해봐야겠다’고 생각하게 됐어요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사실 개인적으로 가장 어려웠던 건, 개발자로서 제 자아를 조금 내려놓는 일이었어요. 개발자가 홍보를 어려워하는 이유는 여러 가지가 있겠지만, 약간 철판 까는 걸 힘들어하는 면이 있는 것 같아요. 그런데 가만히 생각해 보면, 내가 만든 제품을 내가 홍보하지 않으면 누가 하겠냐는 생각이 들었죠. 그렇게 이것저것 마케팅과 홍보를 해보면서 점점 익숙해졌고, 지금은 그냥 별것 아닌 일이 된 것 같아요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Mallo는 지금 제 SNS를 통해서만 알리고 있어요. 사실 Mallo 자체에 대해서는 현재 적극적으로 마케팅할 계획은 없어요. 이 앱은 제가 필요해서 만든 거라, 그냥 만든 김에 한번 팔아보자는 생각이었거든요. 그래서 Mallo의 판매 자체보다, 바이브 코딩에 관심 있는 분들께 이런 서비스를 만드는 방법을 공유하고, 그런 내용을 SNS에 포스팅하는 것 자체가 하나의 마케팅 사이클이 되는 경험을 해보려고 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:60%;"&gt;&lt;img src="https://www.wishket.com/media/news/3652/image2.png" alt="사이드프로젝트 수익화"&gt;&lt;figcaption&gt;사이드 프로젝트로 수익화를 이루다 &amp;lt;출처: &lt;a href="https://www.linkedin.com/posts/wooing_%EC%82%AC%EC%9D%B4%EB%93%9C%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A1%9C-%EC%B2%9C%EB%A7%8C-%EC%9B%90%EC%9D%84-%EB%B2%8C%EC%97%88%EC%8A%B5%EB%8B%88%EB%8B%A4-%EB%8C%80%EB%8B%A8%ED%95%9C-%EC%95%84%EC%9D%B4%EB%94%94%EC%96%B4%EB%8F%84-%ED%81%B0-%ED%8C%80%EB%8F%84-%EC%97%86%EC%97%88%EC%8A%B5%EB%8B%88%EB%8B%A4-activity-7417192374105296896-vkZJ?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAABnA_qMBVbtPXuHRqEAxbdng81tsZWPjA5c"&gt;&lt;u&gt;김우영 님 링크드인&lt;/u&gt;&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Part 4. 글로벌 시장 진출과 바이브 코딩&lt;/strong&gt;&lt;/h3&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. “한국에서 만들어서 글로벌에 파는” 1인 개발자가 점점 늘고 있어요. 이 흐름에서 바이브 코딩은 어떤 역할을 하고 있다고 보시나요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;제 생각에 바이브 코딩이 가능하게 만든 건, 예전에는 엄두가 나지 않던 것들을 훨씬 더 쉽게 시도할 수 있게 해준 점인 것 같아요. 예를 들어, 앞서 말씀드린 Mallo 같은 경우도, 음성 인식 앱을 개발하는 일 자체가 사실 쉽지 않거든요. 개발할 때 고려해야 할 것도 많고요. 그런데 요즘에는 AI가 코딩 과정을 너무 잘 도와주니까, 개발에 대한 허들이 거의 없어졌다고 느껴요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Q. 구체적으로 글로벌 시장 진출에는 어떤 도움을 받을 수 있을까요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;우선 서비스 운영 측면에서도 AI 모델들이 언어를 굉장히 잘 다루잖아요. 그래서 제가 한국어로 만든 앱이라고 해도, 번역하는 일이 훨씬 쉬워졌어요. 글로벌 시장을 생각하고 있었지만, 영어가 허들이었던 분들도 이제는 AI의 도움으로 더 쉽게 글로벌로 진출할 수 있지 않을까 싶어요. 이제 바이브 코딩을 통해 아이디어가 많은 분들에게 더 큰 기회가 열리고 있는 셈이죠.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;지금까지 바이브 코딩으로 연달아 세 개의 앱을 출시하고, 영어권 글로벌 시장을 타깃으로 수익화까지 실현한 김우영 님의 이야기를 들어봤는데요. 앞으로 바이브 코더들이 더 집중해야 할 영역과 방향성을 함께 고민해 볼 수 있었습니다. 마지막으로 김우영 님이 바이브 코딩으로 글로벌 시장 진출에 관심 있는 분들께 현실적인 조언을 남겨주셔서, 이를 전하며 마무리하겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;“저는 무엇이 됐든, 일단 만들어 보시라고 말씀드리고 싶어요. 이전 인터뷰에서도 비슷한 얘기를 했던 것 같은데요. 내가 생각한 아이디어를 정말 내가 만들 수 있을까, 혹은 내가 괜찮은 걸 만들 수 있을까? 하는 생각 때문에 주저하게 되는 경우가 많은 것 같아요.&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;그런데 이제는 바이브 코딩을 통해 실행 속도가 훨씬 빨라졌잖아요. 그래서 시간 대비 실패를 너무 걱정하지 않고도, 바로바로 시도해 볼 수 있는 환경이에요. 제 주변에도 아이디어는 정말 많은데 개발을 모르거나, 막연히 엄두가 나지 않아서 실행하지 못하던 분들이 있었거든요. 그런데 지금은 그분들이 바이브 코딩으로 하나둘씩 뭔가를 만들어 보는 걸 보면, 저도 신기하고 기분이 좋더라고요.&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;내가 상상하고 있는 것들을 현실로 꺼내 놓는 이 과정 자체가 저는 정말 즐겁다고 생각해요. 그래서 이 즐거운 과정을 더 많은 분들이 경험해 보셨으면 좋겠습니다.”&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;지금 우리에게 필요한 건 더 많은 고민보다는 상상을 직접 실현해 본다는 즐거움 아닐까요?&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:justify;"&gt;➡️ 영상으로 보기&lt;/p&gt;&lt;figure class="media"&gt;&lt;oembed url="https://www.youtube.com/watch?v=yGodP9rCI-4"&gt;&lt;/oembed&gt;&lt;/figure&gt;&lt;p style="margin-left:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>Vercel react-best-practices 스킬로 코드 리뷰 자동화하기</title><link>https://yozm.wishket.com/magazine/detail/3641</link><description>지난 1월 17일, Vercel의 CEO 기예르모 라우흐(Guillermo Rauch)가 X를 통해 AI 에이전트를 위한 패키지 관리자 skills를 발표했습니다. 개발자가 npm으로 라이브러리를 설치하듯, AI에게 필요한 능력을 명령어 한 줄로 설치할 수 있는 생태계를 만들겠다는 구상입니다. 그 중 하나인 react-best-practices를 실제 프로젝트에 적용해 성능이 어떻게 달라지는지 직접 확인해 보기로 했습니다. 단순 before/after 비교에 그치지 않도록, GitHub Actions 기반 AI 코드 리뷰에 룰셋을 연결했습니다. 그렇게 PR 단계에서 성능 검증이 자동으로 이루어지는 프로세스를 구축하는 과정까지 함께 다루어 보겠습니다.</description><guid>https://yozm.wishket.com/magazine/detail/3641</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;지난 1월, Vercel의 CEO 기예르모 라우흐&lt;span style="color:#757575;"&gt;(Guillermo Rauch)&lt;/span&gt;가 X를 통해 AI 에이전트를 위한 패키지 관리자 skills를 발표했습니다. 개발자가 npm으로 라이브러리를 설치하듯, AI에게 필요한 능력을 명령어 한 줄로 설치할 수 있는 생태계를 만들겠다는 구상입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그 중 하나인 &lt;code&gt;react-best-practices&lt;/code&gt;를 실제 프로젝트에 적용해 성능이 어떻게 달라지는지 직접 확인해 보기로 했습니다. 단순 before/after 비교에 그치지 않도록, GitHub Actions 기반 AI 코드 리뷰에 룰셋을 연결했습니다. 그렇게 PR 단계에서 성능 검증이 자동으로 이루어지는 프로세스를 구축하는 과정까지 함께 다루어 보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image8.png"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href="https://x.com/rauchg/status/2012345679721771474"&gt;Guilleromo Rauch X&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;1. AI 에이전트의 npm, skills의 등장&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;본격적으로 적용 예시를 보기 전, Vercel이 발표한 skills가 무엇인지 살펴보겠습니다. Vercel의 Skills는 AI 에이전트가 자동으로 발견하고 사용할 수 있도록 지침, 스크립트, 리소스를 패키징한 재사용 가능한 오픈 포맷의 스킬 패키지입니다. 이 생태계는 크게 세 가지로 구성됩니다. &lt;strong&gt;스킬을 설치하는 CLI 도구, 표준화된 스킬 정의 포맷, 그리고 이를 검색할 수 있는 레지스트리&lt;/strong&gt;입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러한 스킬들을 한곳에서 모아볼 수 있는 허브가 &lt;a href="http://skills.sh"&gt;skills.sh&lt;/a&gt;입니다. 여기에서는 인기 스킬 순위를 실시간으로 확인할 수 있습니다. Vercel Labs가 만든 도구들뿐 아니라, Anthropic 등 다양한 오픈소스와 기업이 공개한 스킬도 함께 올라와 있어 ‘스킬이 하나의 배포 단위가 되는 흐름’을 체감할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:80%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image7.png"&gt;&lt;figcaption&gt;&amp;lt;출처: &lt;a href="http://skills.sh"&gt;skills.sh&lt;/a&gt;&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 가운데 특히 눈에 띄는 스킬이 오늘 적용해 볼 &lt;strong&gt;react-best-practices&lt;/strong&gt;입니다. 이 스킬을 실제 프로젝트에 적용하면 어떤 변화가 생기는지, 이제 구체적으로 살펴보겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;2. 스킬 소개: react-best-practices&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;&lt;code&gt;react-best-practices&lt;/code&gt;는 Vercel 엔지니어링 팀이 10년 이상 축적해 온 React/Next.js 성능 최적화 노하우를 57개 규칙으로 정리한 스킬입니다. 각 규칙은 체크리스트와 Do/Don't 예시 코드로 구성되어 있으며, 영향도&lt;span style="color:#757575;"&gt;(Impact)&lt;/span&gt; 중심으로 우선순위가 정렬되어 있어 "무엇부터 고쳐야 성능이 가장 좋아지는가"에 대한 명확한 기준을 제공합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;최적화 작업의 우선순위는 왜 중요할까?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이 스킬의 백미는 최적화 작업의 순서를 알아서 알려준다는 점입니다. 개발자들은 종종 &lt;code&gt;useMemo&lt;/code&gt;, &lt;code&gt;useCallback&lt;/code&gt; 같은 마이크로 최적화&lt;span style="color:#757575;"&gt;(Micro-optimizations)&lt;/span&gt;에 과도하게 시간을 쏟곤 합니다. 그러나 이들은 문법적으로는 옳을지 몰라도, 실제 성능 지표에는 미미한 영향만 주는 경우가 많습니다. 이처럼 모든 최적화 작업이 동일한 가치를 지니는 것은 아닙니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;반면 사용자 경험을 해치는 진짜 주범은 눈에 잘 띄지 않는 구조적 병목에 있습니다. 대표적으로 네트워크 워터폴&lt;span style="color:#757575;"&gt;(Waterfalls)&lt;/span&gt;이나 거대한 번들 사이즈 같은 문제가 여기 해당합니다. 이 룰셋은 이처럼 개발자의 시선을 ‘사소한 테크닉’에서 ‘성능에 결정적 영향을 미치는 요소&lt;span style="color:#757575;"&gt;(High Impact)&lt;/span&gt;’로 돌려놓습니다. 즉, 가장 치명적인 문제부터 해결하도록 방향을 잡아 주며 최적화의 우선순위를 바로 세워 줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;즉, &lt;strong&gt;“가장 적은 노력으로 가장 큰 성능 향상을 이끌어낼 수 있는” 순서&lt;/strong&gt;대로 등급을 나누어 제시합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image9.png"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;주요 최적화 사례(Best Practices)&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;&lt;strong&gt;Promise.all()&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;활용:&lt;/strong&gt; 작업 간 의존성이 없다면 순차 실행을 동시 실행으로 전환&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;code&gt;&lt;strong&gt;better-all&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;라이브러리:&lt;/strong&gt; 일부만 의존성이 섞인 비동기 작업을 더 효율적으로 병렬화&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;RSC 컴포넌트 합성:&lt;/strong&gt; 서버 사이드 워터폴을 없애기 위한 병렬 데이터 페칭 구조화&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 RSC&lt;span style="color:#757575;"&gt;(React Server Components)&lt;/span&gt; 같은 작업은 제대로 활용하면 큰 이점을 얻을 수 있지만, 구조가 조금만 어긋나도&lt;span style="color:#757575;"&gt;(의존성, 경계, 조합 방식)&lt;/span&gt; 기대했던 효과가 쉽게 사라집니다. &lt;code&gt;react-best-practices&lt;/code&gt;는 이런 최적화 포인트를 “규칙”으로 고정해, 개발자가 실수하기 쉬운 지점을 반복적으로 교정할 수 있게 해줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;3. 실전 적용: 프로젝트에 바로 도입해보기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;“백문이 불여일타”라고 하죠. 이 스킬을 실제 운영 중인 Next.js 프로젝트에 적용해 보았습니다. 설치는 매우 간단합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;code class="language-plaintext"&gt;npx skills vercel-labs/agent-skills&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;설치가 완료되면 프로젝트 루트의 &lt;code&gt;.claude&lt;/code&gt; 폴더 안에 룰 파일과 메타데이터가 생성됩니다. Claude Code 같은 AI 에이전트는 이 폴더를 자동으로 참조해 코드를 분석합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;진단 요청&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;설치가 끝나고 Claude Code 같은 AI 에이전트에게 다음과 같이 진단을 요청합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;이 레포 전체를 대상으로 .claude에 설치된 vercel-react-best-practices 스킬 기준 성능 리뷰를 해줘.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image2.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;AI는 57개 규칙을 기준으로 코드를 스캔합니다. 그리고 위반 사항을 우선순위&lt;span style="color:#757575;"&gt;(Critical → High → Medium → Low)&lt;/span&gt;별로 분류해 구체적인 개선안을 제시합니다. 이번 테스트에서는 4개의 Critical 이슈를 포함해 다수의 High, Medium, Low 이슈가 검출되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;영향도 중심의 최적화를 검증하기 위해 우선 &lt;strong&gt;4개의 Critical 이슈&lt;/strong&gt;만 수정할 것을 요청했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;적용 결과&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;단 4개의 Critical 이슈를 수정했을 뿐이지만, 성능 지표에서 유의미한 개선 효과를 확인할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;1. 초기 로드 크기 감소(Bundle Size)&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;가장 눈에 띄는 변화는 번들 사이즈의 다이어트였습니다. &lt;strong&gt;페이지별 초기 로드 JavaScript 크기가 최소 19%에서 최대 70%까지 감소&lt;/strong&gt;했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image6.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;무거운 컴포넌트 격리:&lt;/strong&gt; 덩치가 큰 팝업&lt;span style="color:#757575;"&gt;(Dialog)&lt;/span&gt; 컴포넌트를 별도 청크&lt;span style="color:#757575;"&gt;(Chunk)&lt;/span&gt;로 분리하면서, 초기 로딩 시 불필요하게 딸려오던 코드가 제거되었습니다.&lt;/li&gt;&lt;li style="text-align:justify;"&gt;&lt;strong&gt;정교해진 트리 쉐이킹:&lt;/strong&gt; Dynamic Import를 적용하자 전체 청크 파일 개수는 늘어났습니다. 그러나 그만큼 브라우저가 꼭 필요한 코드만 내려받게 되면서&lt;span style="color:#757575;"&gt;(Tree-shaking 효율 증가)&lt;/span&gt; 결과적으로 초기 로딩 속도가 더 빨라졌습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;2. Lighthouse 점수 상승 (UX 개선)&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;사용자가 체감하는 성능 지표&lt;span style="color:#757575;"&gt;(Core Web Vitals)&lt;/span&gt;도 전반적으로 개선되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image5.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;특히 체감도가 큰 LCP는 17% 개선되었고, 상호작용 가능 시간(TTI)은 19% 감소했습니다. 또한 메인 스레드 차단 시간(TBT)은 17% 감소했습니다. 그 결과 전체 Performance 점수도 3점 상승해 77점에서 80점으로 올랐습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Critical 4개 수정만으로 이 정도 변화가 생긴 것을 보니, 문득 이런 생각이 들었습니다. 이 검증 방식을 모든 PR에 자동으로 적용하면 어떨까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;4. CI/CD 통합: ‘개인기’에서 ‘시스템’으로 바꾸기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;AI 활용의 진정한 가치는 단발성 질문과 답변이 아니라 지속 가능한 프로세스를 구축하는 데 있습니다. 한 번의 테스트 점검만으로는 충분하지 않습니다. 코드는 매일 쌓이고, 팀원이 바뀌면 같은 실수가 반복됩니다. 성능 검증이 진짜 효과를 발휘하려면 개발 프로세스 안으로 들어와 있어야 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그래서 &lt;code&gt;react-best-practices&lt;/code&gt; 룰셋을 GitHub Actions 기반 Claude Code Review에 연결해 보기로 했습니다. 앞으로 생성되거나 수정되는 코드가 &lt;strong&gt;PR&lt;/strong&gt;&lt;span style="color:#757575;"&gt;&lt;strong&gt;(Pull Request)&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt; 단계에서 자동으로 성능 관점의 점검을 받도록 구성하는 방식&lt;/strong&gt;입니다. 즉, 개발자가 신경 쓰면 좋다지만, 안 하면 놓치는 성능 이슈를 리뷰 프로세스 자체에 내장하는 접근입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;span style="color:#757575;"&gt;*아직 Claude Code Review를 도입하지 않았다면,&lt;/span&gt; &lt;a href="https://medium.com/musinsa-tech/%EB%AC%B4%EC%8B%A0%EC%82%AC%EC%9D%98-ai-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B5%AC%EC%B6%95%EA%B8%B0-3ddb3c674e56"&gt;무신사의 AI 코드 리뷰 프로세스 구축기&lt;/a&gt;&lt;span style="color:#757575;"&gt;를 참고해 보세요.&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Shift Left: 왜 검증을 앞단(PR)으로 가져와야 하는가&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;검증을 프로세스 앞단으로 당기는 것, 이른바 &lt;strong&gt;Shift Left 전략&lt;/strong&gt;입니다. 검증 시점을 배포&lt;span style="color:#757575;"&gt;(Right)&lt;/span&gt; 단계가 아니라 개발·리뷰&lt;span style="color:#757575;"&gt;(Left)&lt;/span&gt; 단계로 앞당겨야 하는 이유는 분명합니다. 뒤에서 고칠수록 비용이 기하급수적으로 늘어나기 때문입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;배포 이후 모니터링 도구&lt;span style="color:#757575;"&gt;(Datadog, Sentry 등)&lt;/span&gt;에서 경고를 받고야 대응하면, 원인 추적을 위한 로그 분석부터 재현 환경 구성, 핫픽스 적용과 재배포, 그리고 검증까지 긴 사이클을 반복해야 합니다. 반면 검증 시점을 PR 단계로 앞당기면 병합 전에 문제를 해결할 수 있습니다. 대응을 위한 긴 사이클 자체를 줄일 수 있고, 기술 부채가 쌓이는 속도도 크게 늦출 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;한 줄 짜리 적용법&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;방법은 단순합니다. 현재 사용 중인 Claude Code Review GitHub Action의 프롬프트에 지침을 한 줄 추가하면 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;i&gt;.claude/skills/vercel-react-best-practices 가이드라인을 참고해주세요.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image1.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;리뷰 품질의 변화&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;결과는 어땠을까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;1. 규칙 위반 시: 명확한 근거 제시&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 리뷰 과정에서 AI는 “Vercel Best Practice 위반”이라는 명확한 근거와 함께 구체적인 개선 방향도 안내합니다. 그 결과 리뷰어의 주관적 의견이 아니라, 검증 가능한 기준 기반의 리뷰가 이루어집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image3.png"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;2. 규칙 준수 시: 칭찬의 디테일&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;당연하지만, 잘 작성된 코드에 대해서도 피드백 방식이 달라집니다. “어떤 Rule을 충족했는지”, 그리고 “해당 규칙의 영향도와 참고 링크”가 리뷰에 함께 등장합니다. 그 결과 리뷰가 훨씬 더 구조화됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3641/image4.jpg"&gt;&lt;figcaption&gt;&amp;lt;출처: 작가&amp;gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이처럼 스킬 기반 리뷰가 프로세스에 내장되면, 성능 최적화는 더 이상 특정 개발자의 ‘개인기’가 아니게 됩니다. 팀 전체가 함께 공유하는 ‘시스템’으로 자리 잡게 됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며: 성능 최적화, 더 이상 ‘값비싼 선택’이 아닙니다&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;지금까지 성능 최적화 작업은 늘 &lt;strong&gt;개발자의 시간을 담보로 하는 트레이드오프&lt;/strong&gt;에 가까웠습니다. 기능 개발을 잠시 멈추고 원인을 찾아, 개선안을 설계해 적용하고, 리그레션까지 확인해야만 했기 때문입니다. 게다가 시간이 지나 코드가 쌓이거나 팀 구성이 바뀌면 비슷한 문제가 다시 나타나기 쉬웠습니다. 그래서 성능 최적화는 중요하지만 늘 뒤로 밀리는 일이 되곤 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제는 상황이 달라지고 있습니다. &lt;code&gt;npx skills add&lt;/code&gt; 한 줄로 검증된 룰셋을 설치하고 CI에 연결하면, 성능 검증이 개발 프로세스 안에 자연스럽게 녹아듭니다. AI가 코드를 만들고, 또 다른 AI가 정해진 기준에 따라 그 코드를 리뷰합니다. 성능 최적화가 별도의 큰 작업이 아니라, PR 단계에서 자동으로 점검되는 기본 절차가 되는 것입니다. AI 시대에 접어든 지금, 성능 최적화 역시 더는 값비싼 선택이 아닐지도 모릅니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 한 발 더 나아가면 어떨까요? Vercel이 제공한 스킬은 여러 개입니다. 이 글에서는 &lt;code&gt;react-best-practices&lt;/code&gt;를 중심으로 살펴봤지만, &lt;a href="https://skill.sh"&gt;skills.sh&lt;/a&gt;에는 지금도 다양한 영역의 스킬이 계속 올라오고 있습니다. 어쩌면 앞으로는 프로젝트의 성격과 상황에 맞는 스킬을 골라 조합하고, AI 에이전트가 이를 일관되게 적용하도록 구성하는 일 자체가 개발자의 새로운 역량이 되지는 않을까요?&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예전에는 어떤 라이브러리를 선택하느냐가 개발자의 중요한 판단이었다면, 이제는 어떤 스킬을 조합해 사용할지 결정하는 일 또한 그에 못지않은 판단이 되는 시대가 올지도 모르겠습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-left:0px;text-align:center;"&gt;&lt;span style="color:rgb(153,153,153);"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item><item><title>VLM, 눈 달린 LLM을 만나보자!</title><link>https://yozm.wishket.com/magazine/detail/3638</link><description>LLM이 시각, 언어 동시 처리 능력을 가질 수 있는 기술이 바로 VLM (Vision Language Model)이라는 기술인데, 텍스트 기반 LLM에 비해 VLM은 상대적으로 활용 사례나 기술적 인지도가 낮은 편입니다. 의외로 모르시는 분들도 꽤 많습니다. 그래서 이번 글에서 VLM이 어떠한 원리로 동작이 되고, 실제로 어떻게 활용할 수 있는지를 저의 VLM 기반 발표 피드백 Agent를 개발했던 경험을 토대로 한번 소개하는 내용을 적어보고자 합니다. </description><guid>https://yozm.wishket.com/magazine/detail/3638</guid><content:encoded>&lt;![CDATA[&lt;b&gt;&lt;p style="text-align:justify;"&gt;이 글은 PyCon Korea 2025에서 진행된 &amp;lt;VLM, 눈 달린 LLM을 만나보자!&amp;gt; 세션을 정리한 내용입니다. VLM이 어떻게 작동하고 어떻게 활용되는지에 대해 공유합니다. 발표 자료는 &lt;a href="https://2025.pycon.kr/presentations/ae847a02-4470-42a8-a383-9fed6bbdedda#VLM-%EB%88%88-%EB%8B%AC%EB%A6%B0-LLM%EC%9D%84-%EB%A7%8C%EB%82%98%EB%B3%B4%EC%9E%90"&gt;&lt;u&gt;PyCon Korea 2025 공식 홈페이지&lt;/u&gt;&lt;/a&gt;에서 확인할 수 있으며, 파이콘 한국 유튜브 채널을 통해 &lt;a href="https://youtu.be/g4NrEAYXb7E?si=wg0oXaKrQgy4p7ts"&gt;&lt;u&gt;영상&lt;/u&gt;&lt;/a&gt;으로도 만나보실 수 있습니다. &lt;span style="color:#999999;"&gt;(모든 이미지의 출처는 발표자에게 있습니다.)&lt;/span&gt;&lt;/p&gt;&lt;div class="page-break" style="page-break-after:always;"&gt;&lt;span style="display:none;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;VLM, 눈 달린 LLM을 만나보자!&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;김대현 개발자&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="text-align:justify;"&gt;&lt;br&gt;안녕하세요, 저는 김대현입니다. AI, Cloud 분야를 지망하는 학생 개발자이자, 현재 GDG, AWSKRUG 등 여러 개발자 커뮤니티에서 활동하고 있습니다. 이번 글에서 제가 파이콘 한국 2025에서 발표했던 내용인 ‘VLM, 눈 달린 LLM을 만나보자’라는 주제로 얘기해 보고자 합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;최근에 우리는 개발, 일상적인 업무, 궁금한 내용이 있을 때 LLM을 많이 활용하면서 텍스트(프롬프트)로 LLM에 질의응답 (또는 QA) 하면서 질문하고 답을 받는 방식에 대하여 익숙해졌습니다. 그러면서 많은 LLM에 사진(시각 정보)를 첨부해 질문을 던지면, 모델이 텍스트와 이미지를 모두 이해해 답변을 내놓는 경험도 손쉽게 할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/1.jpg" alt="gpt5"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이러한 LLM이 시각, 언어 동시 처리 능력을 가질 수 있는 기술이 바로 VLM (Vision Language Model)이라는 기술인데, 텍스트 기반 LLM에 비해 VLM은 상대적으로 활용 사례나 기술적 인지도가 낮은 편입니다. 의외로 모르시는 분들도 꽤 많습니다. 그래서 이번 글에서 VLM이 어떠한 원리로 동작이 되고, 실제로 어떻게 활용할 수 있는지를 저의 VLM 기반 발표 피드백 Agent를 개발했던 경험을 토대로 한번 소개하는 내용을 적어보고자 합니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이번 글에서 다루는 내용은 아래와 같습니다. 2의 내용은 난이도가 있을 수 있으니 참고해 주세요!&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;VLM이 뭔지?&lt;/li&gt;&lt;li&gt;VLM의 동작 방식&lt;/li&gt;&lt;li&gt;VLM을 활용한 발표 피드백 Agent 개발기&lt;/li&gt;&lt;/ol&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Vision Language Model은 무엇일까요?&lt;/strong&gt;&lt;/h3&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/2.jpg" alt="Vision Language Model"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Vision Language Model, 줄여서 VLM은 이미지 (Vision) &amp;amp; 텍스트(Language)를 동시에 처리하고 이해할 수 있는 AI 모델을 의미합니다. 즉, 컴퓨터 비전(CV)을 활용한 시각적 정보처리와 자연어 처리(NLP)를 활용한 텍스트 정보처리와 같은 여러 형태의 데이터를 동시에 처리하고 이해할 수 있는 AI 시스템인 멀티모달 AI 형태입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;그러면, 왜 VLM이 등장했을까요? 이것은 바로 멀티모달 AI 시대가 등장했기 때문인데요. 그 이유를 보면, 인터넷에서 '시각 데이터'가 폭발적으로 증가하고 있다는 것을 알 수 있습니다. “Cisco Visual Networking Index (VNI) 2017–2022”라는 Cisco에서 발간한 인터넷 트래픽 관련 보고서를 보면, 실제로 2022년에는 IP 트래픽의 82%가 영상 콘텐츠로 예측되었다고 합니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 사람들은 단순히 텍스트를 이용하는 것을 넘어, Google Lens와 같은 도구로 눈에 보이는 대상을 바로 검색하기도 합니다. 이렇게 시각 정보가 폭증하고 데이터의 형태가 다변화되는 시대에서는 글만 이해하는 기존의 LLM으로는 한계가 뚜렷합니다. 이미지와 텍스트를 동시에 처리하고 이해하는 AI, 즉 멀티모달 AI가 반드시 필요한 이유입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;VLM vs LLM 무엇이 다른가?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;그러면 VLM과 우리가 일반적으로 아는 ChatGPT, Claude, Gemini와 같은 LLM (Large Language Model)에 대해서 알아보겠습니다. 둘의 가장 큰 차이점은 입력, 학습, 출력에서 나타납니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/3.jpg" alt="llm vlm"&gt;&lt;/figure&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;VLM은 이미지와 텍스트를 결합해 정보를 처리하는 모델로, 실제로 이미지를 ‘이해’하고 설명하거나 그림에서 정보를 추출하는 등의 복합 작업이 가능합니다. 반면 LLM은 텍스트 기반 입력만을 처리하며, 언어 생성이나 요약, 번역, 질의응답처럼 순수 언어적인 작업에 특화되어 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;VLM은 멀티모달(이미지+언어) 입력을 모두 다뤄 복잡하고 실제적인 상황 (예: 사진 해석, 시각 정보를 기반으로 한 질문)에 활용되고, LLM은 언어적 패턴만 이해해서 지식 생성에 쓰입니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;어떠한 VLM 모델들이 있을까요?&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;우리에게 많이 친숙한 모델, Gemini 2.5 Pro (Google), GPT-5 (OpenAI), Claude 3.5 Sonnet (Antropic), 오픈소스로도 많이 쓰이는 Qwen3-VL, LLaMa 4-Vision이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/4.jpg" alt="AI 모델"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;Vision Language Model의 구조 &amp;amp; 작동 원리&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;VLM의 구조는 크게 3가지로 구성되어 있습니다. 이미지 인코더(Image Encoder 이미지 인코더), 텍스트 인코더(Text Encoder), 그리고 각각의 모달리티, Image와 텍스트 데이터를 하나의 같은 의미 공간에서 합쳐서 처리해 주는 멀티모달 퓨전으로 구성되어 있습니다. 참고로 Decoder는 들어가 있는 모델도 있고, 들어가지 않은 모델도 있습니다. 대표적으로 Decoder가 없는 모델은 Clip이 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Image &amp;amp; Text Encoder&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;먼저, Encoder의 전체적인 개념에 대해서 설명 드리겠습니다. Encoder (인코더)는 입력한 정보(시퀀스)를 모델이 이해할 수 있는 벡터 형태로 변환하는 구성 요소입니다. 즉, 입력된 정보를 압축해서 의미적 표현(Semantic Representation)으로 만드는 역할을 합니다. 또한 요즘 활용되는 생성형 언어 모델에서 Encoder를 사용한다고 하면, 대부분은 Transformer(트랜스포머) 아키텍처를 많이 활용합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/5.jpg" alt="Image &amp;amp; Text Encoder"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이미지 인코더는 입력된 이미지를 모델이 이해할 수 있는 벡터 임베딩(Vector Embedding)으로 변환하는 구성 요소입니다. 초창기에는 CNN 기반 인코더가 주로 사용되었습니다. CNN은 '슬라이딩 윈도우' 방식을 사용하여, 합성곱 필터(Convolution Filter)로 작은 행렬로 이미지의 특정 영역을 훑어가며 단계적으로 특징을 추출합니다. 이 과정은 Convolution Layer와 Pooling Layer를 거치며 객체의 경계나 질감 같은 단순한 지역적 특징에서부터 점차 복잡하고 추상적인 특징까지 계층적으로 학습하여 최종적인 Feature Map을 생성합니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;하지만 최근에는 ViT(Vision Transformer) 기반 인코더가 주목받고 있습니다. ViT는 이미지를 텍스트 시퀀스처럼 일정 크기의 작은 패치(patch) 단위로 분할하고, 각 패치를 텍스트의 '토큰'처럼 취급하여 시퀀스 데이터로 변환합니다. 이후 각 패치의 위치 정보를 알려주는 Positional Encoding을 더한 뒤, 트랜스포머 구조의 핵심인 Multi-head Self-Attention을 통해 이미지 전체 패치들 간의 맥락적 관계를 한 번에 학습합니다. 이러한 방식 덕분에 ViT는 이미지의 전역적인 정보를 효과적으로 파악할 수 있으며, 추출된 시각적 특징을 텍스트 임베딩과 쉽게 결합할 수 있는 동일 차원의 벡터로 매핑하는 데 매우 유리합니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/6.jpg" alt="인코더"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;텍스트 인코더는 입력된 텍스트를 모델이 이해할 수 있는 벡터 임베딩으로 변환합니다. 먼저, 문장은 단어 또는 서브워드 단위의 토큰(Token)으로 분할되며, 이때 문장의 시작과 끝을 알리는 [CLS]나 [SEP] 같은 특수 토큰이 함께 추가됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 생성된 토큰 시퀀스는 트랜스포머 인코더로 입력되어, Self-Attention 메커니즘을 통해 문장 내 단어 간의 복잡한 의미적 관계와 문맥을 학습합니다. 마지막으로, 모델은 [CLS] 토큰의 최종 임베딩을 사용하거나 모든 토큰의 임베딩을 평균 풀링(Average Pooling)하여 문장 전체를 대표하는 하나의 벡터를 생성합니다. 이 텍스트 임베딩은 이미지 임베딩과 동일한 공통 의미 공간(Common Embedding Space)으로 매핑되어, 모델이 텍스트와 이미지 간의 연관성을 이해할 수 있게 해줍니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Multimodal Fusion&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;멀티모달 퓨전(Multimodal Fusion)은 '멀티모달 프로텍터(Multimodal Protector)'라고도 불리며, VLM에서 이미지와 텍스트처럼 서로 다른 종류의 데이터를 효과적으로 결합하여 하나의 통합된 표현(Embedding)으로 만드는 핵심 기술입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Text Encoder와 Image Encoder에서 나온 정보를 결합하는 전략은 크게 세 가지로 나뉩니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/7.jpg" alt="Multimodal Fusion"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;1. 초기 융합(Early Fusion)&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 방식은 모델의 입력 단계에서부터 서로 다른 모달리티 데이터를 하나의 통합된 특성 벡터로 결합합니다. 장점은 모델이 학습 초기부터 두 데이터를 결합된 벡터로 받기 때문에, 모달 간의 상관관계 패턴을 더 쉽고 빠르게 학습할 수 있습니다. (각각을 병렬 처리하는 것보다 직접적인 학습이 가능)&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;단점은 각 모달리티가 고유의 특성을 충분히 학습하기도 전에 원시 데이터가 섞여버릴 수 있습니다. 이로 인해 각 데이터의 고유한 특징이 손실되거나, 한쪽 모달리티의 정보가 무시되는 '모달리티 붕괴(Modality Collapse)' 현상이 발생할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;2. 중간 융합(Mid Fusion)&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 방식은 Joint Fusion 또는 Intermediate Fusion이라고도 하며, 모델의 중간 계층에서 각 모달리티를 결합하여 상호작용을 학습합니다. 장점은 각 모달에서 고유한 특징이 어느 정도 추출된 상태(표현이 나타난 상태)에서 결합이 이루어집니다. 따라서 데이터 간의 복잡하고 의미 있는 상관관계를 잘 학습할 수 있으며, Early Fusion과 Late Fusion의 장점을 절충한 형태로 평가받습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;단점은 모델 구조가 복잡해지고 구현이 어렵습니다. 중간 계층에서 서로 다른 Feature Space의 차원을 맞춰야 하는 문제가 있고, Cross-modal Attention이나 Co-attention같이 상관관계를 학습하기 위한 별도 모듈이 필요합니다. 이는 더 많은 파라미터, 계산량, 메모리 사용량 증가로 이어집니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;3. 후기 융합(Late Fusion)&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 방식은 각 모달리티를 완전히 독립적인 서브 모델로 처리하여 각각의 예측을 수행한 뒤, 그 최종 결과(예: 확률값, 점수)를 결합하거나 가중평균하는 방식입니다. 장점은 각 모달리티가 별도의 모델로 처리되므로, 고유한 특징을 학습 과정 내내 독립적으로 유지할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;단점은 최종 단계에서 단순히 결과를 합치는 구조이므로, 두 데이터가 학습 과정에서 서로의 표현을 정렬하거나 미세한 상호작용을 탐색하기 어렵습니다. 따라서 데이터 간의 깊은 연관성을 반영하는 데 한계가 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;VLM 모델들의 Learning Strategies(학습 전략)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;VLM 모델들의 학습 전력에 대한 개념을 간단히, 설명드리면 이건 여러 모달(데이터)를 처리하는 모델이 서로 다른 모달들을 어떻게 학습해 서로 잘 이해하게 만들지를 정하는 방법입니다. 주로 사전 학습(Pretraining) 단계에서 주로 사용되며, 이후 Image Captioning, VQA, Multimodal Search와 같은 다양한 작업에 적용됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/8.jpg" alt="VLM 모델들의 Learning Strategies"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;VLM 모델 중에서도 Transformer 기반 아키텍처를 사용하는 모델들은 Mid Fusion과 Cross-Modal Attention 전략을 활용합니다. 이 전략은 트랜스포머의 핵심 메커니즘인 어텐션(Attention) 구조를 확장한 것으로, 모달리티 내부뿐 아니라, 서로 다른 모달리티 간의 관계까지 함께 학습할 수 있도록 설계되어 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;예를 들어, 이미지와 텍스트가 있을 때, 이미지의 특정 영역이 어떤 단어와 연관되는지, 또 반대로 문장의 특정 단어가 이미지의 어느 부분을 참조하는지를 Cross-Attention으로 학습합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이 과정에서 트랜스포머의 Query, Key, Value 구조가 사용됩니다. 보통 한 모달리티(예를 들어 텍스트)가 Query, 다른 모달리티(예: 이미지)가 Key와 Value를 제공합니다. Query와 Key의 내적(dot-product)을 통해 어텐션 맵(Attention Map) 을 만들고, 이 가중치를 기반으로 Value를 조합해 최종적인 멀티모달 표현(Multimodal Representation)을 생성합니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/9.jpg" alt="Cross-Modal Attention"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 Cross-Modal Attention을 제외한 3가지 전략이 더 있는데요. 대조 학습(Contrastive Learning), PrefixLM, Masked Language Modeling / Image-Text Matching 방식이 있습니다. 간단하게 설명드리면, 대조 학습(Contrastive Learning)은 이미지와 텍스트 쌍의 유사도를 학습해, 같은 의미의 쌍은 임베딩 공간에서 가깝게, 다른 쌍은 멀어지게 만드는 방법이고,&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;PrefixLM은 이미지나 비디오의 특징을 텍스트 입력의 앞부분(Prefix)에 넣고, 이어지는 텍스트를 생성하도록 학습하는 방식. Masked Language Modeling / Image-Text Matching은 텍스트 일부를 가리고 복원하거나, 이미지–텍스트 쌍이 서로 일치하는지 판별하도록 학습하는 방법입니다. 이렇게 VLM이 어떠한지, 어떠한 원리로 동작되는지 알아봤습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;VLM을 활용한 AI 발표 피드백 Agent 개발기&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;처음에 이 Agent를 개발하게 된 계기가 작년 10월 이였는데 이때 파이콘 발표를 준비하고 있었는데, 연습을 하면서 제가 말하는 속도나 제스처가 부자연스럽다는 고민을 하고 있었어요. 이때 '”발표하는 제스처에 대해 피드백을 주는 AI 에이전트를 개발해 보면 어떨까?' 하는 아이디어에서 시작했습니다. 그래서 온라인 발표에 피드백을 주는 AI 에이전트를 개발하는 방향으로 프로젝트 주제를 정하게 되었고, 개발하게 되었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;처음에는 컴퓨터 비전 모델만으로 발표자 행동을 자동으로 분석하려고 했습니다. 하지만 분석 결과를 사용자에게 전달하려면, 텍스트 형태의 피드백이 반드시 필요하다’는 사실을 깨달았습니다. 즉, 단순히 잘못된 동작을 감지하는 것을 넘어서, 어떤 발표 행동이 문제인지, 그리고 구체적으로 어떻게 개선해야 하는지 알려줘야 한다는 거죠.&lt;br&gt;&lt;br&gt;또한 그리고 GPU 서버를 사용할 수가 없었습니다. 시간당 비용도 문제고 인프라팀에서 구축하기 까다롭다는 리소스 이슈가 있어, 사용을 못 한다는 사실에 고민을 많이 해보았습니다. 그때 떠오른 아이디어가 바로 ‘Vision-Language Model’을 추론 API(Inference API) 형태로 활용해 보자는 아이디어였습니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;VLM이라면 영상 속 행동을 이해하고, 그에 대한 해석을 텍스트로 생성할 수 있지 않을까 하는 생각이 들었거든요. 또한 Inference API 형태로 활용하면, GPU 서버를 돌리는 것보다, GPU 서버 구축 및 유지 비용 대비 Inference API 호출 방식이 비용 효율성 측면에서 유리하다고 판단하여 해당 방식을 채택했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;VLM Model 테스트&lt;/strong&gt;&lt;/h4&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/10.jpg" alt="VLM Model 테스트"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;실제로 2024년 기준으로 GPT-4o 모델에 이미지를 입력하면 관련 내용을 텍스트로 설명해 주는 기능이 있다는 걸 알았고, 이후로 여러 VLM 모델들을 직접 스터디하고 테스트했습니다. LLaVA-Next, PLLaVA, Video-LLaMA, PailGemma 등 다양한 모델을 돌려보며, 시각 정보와 언어 정보를 어떻게 결합해야 가장 정확한 피드백을 얻을 수 있을지 살펴봤습니다. 다만, 사진에 나와있는 모델들은? GPU를 사용해야 한다는 이슈가 있어. API 형태로 사용 가능한 GPT-4(Vision) 모델과 Pailgemma 모델을 테스트해 보았습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;1분 길이의 영상을 3초 간격으로 프레임 단위를 나누어, 각 구간에 대해 모델에게 ‘이 프레임의 상황을 설명해 달라’는 식으로 프롬프트 기반 질의를 반복했습니다. 그 결과, 2분 분량의 영상 기준으로 GPT-4o-mini 모델이 가장 빠르고 정확한 응답을 보여 최종 선정되었습니다. 실제 평균 처리시간은 약 1분 40초, 다른 모델들 대비 3배 이상 효율적인 속도를 보였습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Video Processing Pipeline&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;영상 처리 Pipeline 부분에 대해서 설명드리도록 하겠습니다. 세션 후 Q&amp;amp;A에서 구체적으로 Pipeline이 어떻게 되는지 질문해 주시는 분들이 많아서 실제 Pycon 발표 자료에서 소개된 Flow보다는 구체적으로 다시 만들어서 보여드립니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;구체적으로 총 다섯 단계로 구성되어 있는데요. 먼저 OpenCV를 사용해 입력된 영상을 1초 단위로 프레임 단위로 분할합니다. 이 단계에서 FPS와 전체 영상 길이(duration)를 계산해 분석 기준을 설정합니다. 그다음으로 Mediapipe를 통해 각 프레임에서 손, 어깨, 자세, 시선 등 주요 Key Point 좌표를 추출합니다. 이 좌표들을 이용해 연속된 프레임 간 좌표 변화량(Δx, Δy) 을 계산합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기서 행동 탐지를 위한 임곗값(Threshold) 을 산출하는데요, 이 값은 평균 이동 변화량에 보정 계수 α를 곱해 계산합니다. 변화량이 이 임곗값을 초과하면, 해당 프레임을 ‘문제 행동 프레임’으로 분류하게 됩니다. 이후 문제 행동 프레임이 추출되면, 이를 GPT-4 Vision API에 전달해 프롬프트 기반 문맥적 피드백을 생성합니다. 이때 Prompt에는 시스템 지침(System Instruction)이 포함되어 있어 행동의 의도나 맥락을 고려한 자연어 피드백이 출력됩니다. 최종적으로 시각적 분석 결과와 텍스트 피드백이 함께 반환되어 사용자가 이해하기 쉬운 형태의 Behavior Feedback Output으로 정리됩니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;문제 행동 탐지 조건 검사&lt;/strong&gt;&lt;/h4&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/12.jpg" alt="문제 행동 탐지 조건 검사"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 영상에서 행동 이상을 탐지하는 핵심 로직인 프레임 간 좌표 변화량 분석 부분에 대해서 설명해 드리겠습니다. OpenCV를 이용해 1초 단위로 프레임을 분할하고, 각 프레임에 대해 Mediapipe 라이브러리를 통해 신체 주요 좌표(Keypoint) 예를 들어, 시선, 어깨, 손, 자세의 위치를 추출합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이후 연속된 두 프레임 간의 좌표 변화량 Δx, Δy를 계산하고, 그 평균 이동량에 보정 계수 α = 0.1을 곱해 Threshold를 산출합니다. 이 임곗값은 움직임의 크기를 수치화한 기준으로, 이를 초과하는 프레임은 ‘문제 행동 프레임(Problem Behavior Frame)’으로 분류합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;Threshold의 범위는 세 단계로 나뉩니다. 0.0에서 0.3 사이는 안정적, 즉 문제가 없는 상태, 0.3에서 0.7 사이는 경고, 약간의 개선이 필요한 상태, 그리고 0.7 이상은 심각 단계로, 즉각적인 개선이 필요한 상황으로 판단합니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/13.jpg" alt="판정 근거"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;문제 행동 프레임(Problem Behavior Frame)으로 분류된 프레임은 이후 GPT-4 Vision 모델에 전달되어, 행동의 맥락을 이해하고 정성적인 피드백을 생성하는 단계로 넘어갑니다. 또한 행동 분석 기준을 적용해, 각 프레임 간 좌표 변화(Δx, Δy) Threshold 값을 기반으로 판정 근거 &amp;amp; 피드백으로 매핑합니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;구체적으로는 Mediapipe가 제공하는 랜드마크(눈‧코‧어깨‧손목‧손가락)를 기준으로 각 여러 행동 카테고리에 대하여 판정한 후, 이 판정 결과는 곧바로 자연어 피드백 템플릿에 반영되어 Json 형태로 Client에 반환합니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/14.jpg" alt="문제 행동 프레임(Problem Behavior Frame)"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이제 문제 행동 탐지 조건 검사에 대해 좀 더 자세히 말씀드릴게요. MediaPipe를 통해 매 프레임마다 여러 점수를 계산합니다. 그리고 이 점수들이 사전에 설정한 임곗값을 초과하는지 확인하는 로직을 추가했습니다. 보시는 코드처럼, posture_score(자세 점수), gaze_score(시선 점수), gestures_score(제스처 점수), sudden_movement_score(돌발 행동 점수) 중 하나의 행동 중 특정 임곗값을 넘어서면 해당 프레임을 문제 프레임으로 간주합니다. 하나라도 임곗값 0.7을 넘으면 해당 프레임을 문제 프레임으로 간주했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;여기에 추가적으로 hand_out_of_frame과 hand_raised라는 플래그를 별도의 로직으로 정의했습니다. hand_out_of_frame 플래그는 손 랜드마크가 전혀 감지되지 않을 때, hand_raised 플래그는 손이 화면 상단으로 과도하게 올라갔을 때 각각 활성화됩니다. 별로의 로직으로 분류한 이유는 일반적인 손동작(gestures)과 달리 독립적인 '문제 행동'으로 볼 수도 있기 때문이었습니다. 갑자기 온라인 발표 중에 손을 높게 들거나, 과장된 제스처를 하면 얼굴만 나오는 온라인 발표의 특성상, 흐름 방해 요소로 간주될수 있다고 판단했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 임곗값을 넘은 문제가 있는 프레임과 해당 행동별 점수 정보를 Vision API에 전달하면, 모델은 '이 프레임에서 손이 시야에서 벗어났습니다' 또는 '손이 너무 높이 올려졌습니다' 같은 구체적인 피드백을 반환합니다. 이러한 방식을 통해 전체 영상을 모두 보내지 않고도 핵심 문제 행동을 담은 프레임만 분석할 수 있게 되었고, 그 결과 응답 속도와 정확도를 크게 올릴 수 있었습니다. 위의 사진을 보시면, 개선 후 문제 행동을 감지해 낸 모습을 확인하실 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Prompt Engineering&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;이제 모델에게 어떻게 모델에게 프롬프트를 주었는지, 그 부분에 대한 고민과 해결 방법에 대해 말씀드릴게요. 일단 저는 온라인 발표에서 어떠한 점에 대해서 피드백을 줄 수 있는지 생각을 해봤고, 제스처, 표정, 시선 처리, 자세 등에 대한 피드백을 제공하는 것을 목표로 삼았고, 모델에게 피드백을 요청할 때는 크게 세 부분으로 나누어 Prompt를 설계했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/15.jpg" alt="Prompt Engineering"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;먼저 페르소나 부여(Persona Assignment)입니다. 모델에게 '15년 이상의 경력을 가진 온라인 발표 전문 코치'라는 구체적인 역할을 부여했습니다. 이 코치는 비언어적 커뮤니케이션 전문가로서, 발표자의 행동이 청중에게 어떤 영향을 주는지 깊이 이해하고 있죠. 이 페르소나를 통해 AI가 더 전문적이고 실용적인 피드백을 제공하도록 유도했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;다음으로, System Instruction에 대해 설명드릴게요. System Instruction은 모델에게 전체 프롬프트와 함께, 앞으로 어떤 행동을 하고, 어떤 방식으로 응답하며, 어떻게 분석해야 할지에 대한 전반적인 지침을 제공하는 부분으로 설계했는데요.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/16.jpg" alt="Prompt Engineering"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;위 사진에 보이는 것처럼, 다음과 같은 지침을 모델에게 주었습니다. 비언어적 행동을 평가하고, 다섯 가지 카테고리를 기준으로 피드백을 제공, 1~2줄로 간결하게 작성하되, 부적절한 행동이 감지되면 해당 문제 행동의 키워드를 포함했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;추가로, 부적절한 행동을 지적할 때는 구체적인 예시와 함께 개선 방안을 제시하고, 긍정적인 행동은 제외하고 개선이 필요한 행동에 집중하도록 요청했습니다. 마지막으로, 피드백의 명확성을 높이기 위해 가능한 한 구체적인 예시를 들고, 하나의 카테고리에서 여러 문제가 감지되면, 모두 언급해 사용자가 명확하게 이해할 수 있도록 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/17.jpg" alt="Prompt Engineering"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;마지막으로 퓨샷 프롬프팅(Few-Shot Prompting) 기법을 활용했는데요. 이 기법은 모델에게 새로운 작업을 수행할 때, 몇 개의 예시를 제공하여 작업의 맥락과 요구사항을 이해할 수 있게 구체적인 예시를 제공하는 것입니다. 예를 들어, '과도한 시선 이동'이라는 문제 행동에 대해, '발표자가 중요한 내용을 설명할 때마다 자주 화면 밖을 보거나 주변을 둘러본다'는 예시를 주고, '발표자의 눈이 카메라를 바라보지 않고 다른 곳을 응시하는 것'을 감지 기준으로 제시하는 식입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;또한 어떤 형식과 스타일로 피드백을 제공해야 하는지 직접적인 예시를 보여주는 것도 피드백의 정확도와 일관성을 높이기 위해 Few-Shot Prompting 기법을 적용하여 구체적인 예시를 포함했습니다. 화면에서 보시는 것처럼, '개선이 필요한 점'과 '권장 사항'을 구분하여 피드백 형식을 구체적으로 제시했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style="text-align:justify;"&gt;&lt;strong&gt;Conclusion(Test &amp;amp; Result)&lt;/strong&gt;&lt;/h4&gt;&lt;p style="text-align:justify;"&gt;서버 개발 환경 스펙에 대해서 간단히 설명드리면&amp;nbsp; AWS EC2 t3.large 단일 인스턴스, Docker 기반 컨테이너 환경을 사용하였고 CI/CD는 Jenkins를 사용하였습니다. 테스트는 직접 촬영한 온라인 발표 영상 20개 데이터로 구성했습니다. 영상에는 시선, 자세, 손동작, 표정 등 다양한 행동 패턴이 포함되도록 설계했습니다.&lt;/p&gt;&lt;p style="text-align:center;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/18.jpg" alt="Conclusion(Test &amp;amp; Result)"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;성능 개선 이후 테스트를 통해 나온 결과를 예시를 통해 보여드리겠습니다. 화면 왼쪽은 VLM만을 사용한 프로토타입 단계의 시선 처리 피드백이고, 오른쪽은 CV와 VLM을 함께 적용해 성능을 개선한 버전의 결과입니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;프로토타입 단계의 피드백을 보시면, '발표자의 시선이 자주 화면 바깥으로 나가는 경향이 보였습니다. 카메라를 바라보며 청중과의 눈 맞춤을 유지하는 것이 중요합니다'라고 나옵니다. 반면, 성능 개선 버전의 피드백은 '발표 중 시선이 카메라로 유지되지 않아 청중과의 연결이 되지 않는 것처럼 보입니다'라고 더 구체적으로 진단하고 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;권장 사항 역시 '발표할 때 카메라를 바라보는 습관을 기르시면 청중과의 연결이 더욱 강화될 것입니다'에서 '카메라를 향해 시선을 고정하고, 중요한 포인트에서 잠시 멈추어 시선을 두는 연습을 해보세요'로 더욱 명확해졌습니다. 이처럼 MediaPipe 기반의 정확한 시선 감지를 통해 피드백의 정확도와 구체성이 향상된 것을 확인할 수 있습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class="image image_resized" style="width:100%;"&gt;&lt;img src="https://www.wishket.com/media/news/3638/19.jpg" alt="피드백"&gt;&lt;/figure&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;먼저 영상 피드백 품질을 비교한 결과입니다. 사람의 주관에 기반한 정성적 평가로 품질 평가를 했으며, 기존의 VLM Foundation 모델 단독 추론 대비, 제안한 Mediapipe + VLM 시스템은 정확성 3.0에서 4.5로, 일관성 2.5에서 3.5로, 구체성 3.5에서 4.0으로 향상되었습니다. 즉, 단순 비전 모델만 사용했을 때보다 좌표 기반의 행동 피처를 함께 활용할 경우 모델이 맥락을 더 정교하게 이해하고, 구체적인 피드백을 생성할 수 있음을 확인했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style="text-align:justify;"&gt;&lt;strong&gt;마치며&lt;/strong&gt;&lt;/h3&gt;&lt;p style="text-align:justify;"&gt;지금까지 VLM을 소개하고, 제가 VLM을 활용한 AI 발표 피드백 Agent 개발을 했던 내용을 살펴보았습니다. 이 프로젝트를 진행하면서 사용자에게 신뢰할 수 있는 피드백을 제공하기 위해 해결해야 할 명확한 한계점들 또한 마주할 수 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;1. 평가 지표의 한계&lt;/strong&gt;: 현재 영상 피드백은 프롬프트 기반의 정성 평가 중심으로 이루어져 있습니다. 또한 평가도 기준이 정해져 있는 정량적 평가가 아닌, 사람의 주관에 기반한 정성적 평가로 품질 평가를 했습니다. 추후 이 시스템의 신뢰도를 높이기 위해서는 향후 실제 온라인 발표 영상의 정답 라벨과 비교할 수 있는 객관적인 정량 평가 지표 or 벤치마크에 대한 설계가 필요하다고 생각했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;2. 시간적 맥락(Context) 유지의 한계&lt;/strong&gt;: 현 구조는 프레임 단위(Frame-level)로 동작합니다. 이로 인해 "3초간 손을 들고 있는" 것과 같은 연속된 동일/유사 행동을 하나의 문제 상황으로 연결하고 상황적 맥락을 반영하는 데 명확한 한계가 있었습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&lt;strong&gt;3. VLM 환각(Hallucination) 이슈&lt;/strong&gt;: 일부 상황에서 VLM 모델의 환각으로 인해 피드백의 정확성이 떨어지는 사례가 발생했습니다. (예: 사용자가 카메라를 정면으로 응시하고 있음에도 "카메라를 바라보고 말하세요"라고 잘못된 피드백을 제공) 이러한 hallucination 이슈를 해결해 보려고 했으나, 개발 기간의 제약으로 인해 해결책을 실제 시스템에 적용하지 못한 점은 아쉬움이 남습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이러한 한계점을 극복하기 위해, 프레임 간의 관계를 학습하는 시계열 모델링(Temporal Modeling)에서 그 실마리를 찾고자 했습니다. 예를 들어, 각 프레임의 스켈레톤(Skeleton) 정보를 시계열(Time-series)로 묶어 LSTM과 같은 모델로 패턴을 학습시킨다면, "3초간 손을 들고 있는" 행동을 프레임 간의 관계와 패턴을 학습시키는 것으로 문제를 해결할 수 있을까라고 생각해 보기도 했습니다.&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;이렇게 VLM이라는 생성형 AI 기술을 적용하며 마주한 한계점과 이를 극복하기 위한 기술적 고민들을 함께 나누어 보았는데요. 앞서 소개한 내용들이 VLM을 활용한 애플리케이션을 고민하는 여러분께 좋은 인사이트가 되고, 각자의 프로젝트에 적용해 볼 새로운 아이디어를 얻는 계기가 되길 바랍니다. 감사합니다.&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:justify;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;span style="color:#999999;"&gt;©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.&lt;/span&gt;&lt;/p&gt;&lt;/b&gt;]]&gt;</content:encoded></item></channel></rss>