
비판적 사고로 에이전트의 결과물에 마주하기
요약
코딩 에이전트의 활용으로 개발 속도는 빨라졌으나, 의도와 다른 결과물을 생성하는 문제가 발생하고 있습니다. 이를 해결하기 위해 논리적 사고를 넘어 결과물의 방향성을 검증하는 비판적 사고와 셀프 리뷰의 중요성을 강조합니다.
핵심 포인트
- 에이전트가 생성한 코드의 논리적 정합성뿐만 아니라 의도 부합 여부를 확인해야 함
- 논리적 사고는 선로를 까는 힘이며, 비판적 사고는 목적지가 맞는지 묻는 힘임
- 결과물을 스스로 설명하고 디렉션할 수 있는 이해력이 엔지니어의 필수 역량임
- 논리와 비판을 반복하는 루프를 통해 개발 낭비를 최소화해야 함
코딩 에이전트 (Coding Agent) 덕분에 개발 속도는 분명히 빨라졌습니다. 지시하면 올바르게 동작하는 코드가 짧은 시간 안에 돌아옵니다. 반면, 의도하지 않은 것이 만들어져 대폭 다시 작업해야 하는 상황도 늘어났습니다.
의도하지 않은 것을 만들어 버리는 것 자체는 개발 속도가 느렸던 AI 이전부터 있었던 문제입니다. 그것이 에이전트의 침투로 한 번에 만들 수 있는 물량이 늘어난 결과, 인식 차이를 지적하는 횟수도 늘어나게 되었습니다. 예전부터 있었던 문제가 결과물의 증폭에 의해 무시할 수 없는 수준으로 표면화된 것입니다. 물론 다시 만드는 비용도 줄었지만, 이 선로를 다시 까는 작업은 본래 비용 낭비입니다. 선로의 분기처럼, 빠른 단계에서 올바른 길로 이동하는 것이 낭비가 되지 않는다는 점은 인간도, 에이전트도 마찬가지입니다.
엔지니어는 지금까지 논리적 사고 (Logical Thinking)로 정보를 정리하고 현재 코드와의 정합성을 맞추는 기술을 연마해 왔습니다. 에이전트가 논리적인 부분을 담당하게 되면, 스스로 설명할 수 없는 코드를 그대로 결과물로서 제출할 수 있게 됩니다. 왜 이것으로 충분한지 스스로 설명하지 못하면, 의도나 설계를 확인하는 업무는 리뷰하는 쪽으로 넘어가게 되어 PdM (Product Manager)이나 테크 리드 (Tech Lead)에게 부하가 집중됩니다. 자신의 결과물을 스스로 디렉션하고 설명할 수 있다면, 그만큼 전체적인 부하가 가벼워집니다. 여기서 필요해지는 것이 결과물을 설명하고 설득할 수 있는 이해력입니다.
이 이해를 깊게 하는 데 필수적인 것이 「다시 묻는 힘」, 즉 비판적 사고 (Critical Thinking)입니다. 지금까지 PdM나 디자이너, 혹은 테크 리드와 같은 일부 엔지니어가 담당해 온 영역이었지만, 지금은 누구에게나 요구되는 것이 되어가고 있습니다. 이 기사에서는 제가 에이전트에게 실제로 수행하고 있는 '다시 묻기'와, 그 토대가 되고 있는 셀프 리뷰 (Self-review) 습관을 소개합니다. 또한, 전제로 하고 있는 것은 팀에서 고객을 위한 프로덕트를 만드는 상황입니다. 타겟이 자신뿐인 개인 개발이라면 이 정도로 다시 묻지 않아도 곤란하지 않습니다.
논리적 사고는 목적지까지 선로를 까는 힘이라고 생각합니다. 요구사항을 충족하고, 모순 없이, 버그 없이 동작하는 곳까지 데려다줍니다. 에이전트가 잘하게 된 것은 바로 이 부분입니다. 지시하면 현실적으로 성립하는 선로를 즉시 깔아줍니다.
다만, 논리만으로 깐 선로의 종점이 타고 있는 사람이 정말로 도달하고 싶었던 목적지라고 단정할 수는 없습니다. 아쉬운 지점에서 종점이 된다면, 타고 있던 사람은 거기서부터 도보로 이동할 수밖에 없습니다. 그 선로로 괜찮은지를 다시 묻고, 나아갈 방향을 다시 선택하는 것이 비판적 사고입니다. 지금 있는 전제를 의심하고, 다른 루트와 비교하여 가치가 높은 쪽으로 분기를 전환해 나가는 것입니다.
요구사항 정의부터 구현까지, 어느 단계에도 분기가 있습니다. 이 그림의 리뷰에는 두 가지 층이 있습니다. 요구사항을 충족하는지, 모순이나 버그가 없는지를 확인하는 것이 논리적 사고의 리뷰입니다. 그 선로로 괜찮은지, 나아갈 방향 그 자체를 다시 묻는 것이 비판적 사고의 리뷰입니다. 전자만으로는 올바르게 동작하지만 의도와는 어긋난 결과물을 향해 곧장 나아가게 됩니다.
이 전환에는 두 종류가 있습니다. 선로를 활용한 채로 분기에서 다른 루트를 다시 선택하는 전환. 그리고 선로 자체가 틀려서 다시 깔아야 하는 케이스입니다. 깨닫는 것이 늦어질수록 후자에 가까워지며, 깔아둔 선로 전체를 다시 깔게 됩니다.
중요한 것은 논리와 비판은 어느 하나를 선택하는 것이 아니라, 몇 번이고 반복하는 것이라는 점입니다. 논리로 한 줄 깔고, 비판으로 분기를 다시 선택하고, 다시 논리로 다듬는다. 이는 작게 만들어서 검증을 반복하는 린 개발 (Lean Development)이나 스크럼 (Scrum)과 같은 애자일 (Agile) 방식과도 통합니다. 루프를 빠르게 돌릴 수 있을수록 다시 까는 선로는 짧아집니다.
에이전트에게 제가 실제로 자주 던지는 '다시 묻기'가 있습니다.
에이전트는 주어진 전제 위에서 최단 루트를 긋습니다. 하지만 그 전제 자체가 어긋나 있을 때가 있습니다. 예를 들어, 사용자가 입력할 수 있는 설정 테이블을 만들어 달라고 했을 때의 일입니다. 첫 번째 태스크가 로딩 설정 추가였기 때문에, 테이블 이름도 그대로 로딩 (Loading)이 되었습니다. 설정이 여러 개로 나뉘어 있다는 점이나, 향후 확장해 나갈 예정이라는 점은 에이전트에게 컨텍스트 (Context)로 전달되지 않았습니다. 실제로는 페이지 전체의 설정을 가진 테이블인데, 이름만 보면 로딩 전용처럼 보이는 상태였습니다. 그래서 기능 전체의 본질을 바탕으로 다시 정의하도록 했습니다. 에이전트와의 세션 (Session)은 태스크별로 나뉘는 경우가 많으며, 그렇게 되면 한 기능에 대한 시야는 아무래도 좁아지게 됩니다. 세션 밖에 있는 문맥을 가져와 전제를 점검하는 것은 우리의 역할입니다.
지시한 해결 수단이 정말 그 과제에 대한 최선인지 다시 질문해야 합니다. 에이전트(Agent)는 "어떻게 구현할 것인가"에는 강하지만, 주어진 프롬프트(Prompt) 시점에서 나아갈 방향이 결정되어 버립니다. 그렇기 때문에 수단 그 자체를 다시 질문하는 것은 우리의 몫입니다.
예를 들어, 신기능 개발 시 사전 리서치에 있었던 유스케이스(Use case)를 바탕으로 구현을 진행하도록 했습니다. 그런데 그것이 구현 불가능하다는 사실이 나중에 밝혀진 적이 있습니다. 외부 서비스 측의 앱 제약 사항에 걸려 있었기 때문입니다. 외부 트래픽이 필요한 기능이었고, 서버를 세우고 사람이 직접 테스트하지 않으면 확인할 수 없는 항목이었기에, 구현이 상당히 진행된 후에야 이를 깨달았습니다. 에이전트는 거기까지 검증하지 못한 채 일단 만들어 버립니다. 지시한 수단 자체가 성립하지 않는다는 것을 깨닫고, 다른 경로를 그 자리에서 고안하는 것은 우리의 일이었습니다. 결과적으로 구현 내용뿐만 아니라 사용자 행동 플로우(Flow)까지 재검토하게 되었습니다. 제약을 회피하기 위해 계정 등록 절차 자체가 늘어났기 때문입니다. 플로우가 복잡해진 만큼, 그 동선을 설명하는 기능까지 필요하게 되었습니다. 원래라면 상세 설계가 진행된 후가 아니라, 프로토타입(Prototype) 단계에서 해결했어야 했습니다. 사람이 직접 확인해야 하는 항목을 디스커버리(Discovery, 만드는 것을 결정하기 전의 탐색 단계)의 수락 기준에 넣어 두었다면, 구현 단계까지 넘어오지 않았을 것입니다.
프롬프트에 적혀 있지 않은 요구사항은 에이전트에게는 존재하지 않는 것과 같습니다. 예를 들어 성능이나 보안 같은 비기능 요구사항(Non-functional requirement)이나, "이 부분은 하지 않는다"라는 스코프(Scope)의 경계 설정은 명시하지 않으면 그냥 지나쳐 버립니다. 플랜 모드(Plan mode, 구현 전에 계획을 세워 확인하게 하는 동작)라면 깊이 있게 확인해 주기도 하지만, 일반적인 대화에서는 누락되어 지시를 글자 그대로만 따라간 아웃풋(Output)이 되기 쉽습니다.
예를 들어, 어떤 데이터 관리 기능에서 항목별 이미지 설정이 처음부터 만들어져 있었던 적이 있습니다. 요청하지 않은 기능이었지만, 다른 기능에서 비슷한 이미지 설정을 만들 예정이었기에 구현 중에는 그것을 위한 것이라고 착각하고 통과시켜 버렸습니다. 결국 사람의 리뷰(Review)에서 과잉 구현이라는 지적을 받아 제거해야 하는 상황이 되었습니다. "이 부분은 하지 않는다"라고 처음에 선을 그어 두었다면 만들어지지 않았을 것이고, 선을 그어 두었다면 자신의 착각도 깨달을 수 있었을 것입니다.
이 세 가지 재질문에는 부산물이 있습니다. 재질문할 때마다 언어화(Verbalization) 능력이 단련된다는 점입니다. "이 편이 더 낫지 않을까"라고 느낄 때, 거기에는 대개 어떤 이유가 있습니다. 그 이유를 언어로 풀어내지 않으면 에이전트에게는 아무것도 전달되지 않습니다. 저의 경우, 감각을 이유로 풀어낼 때는 "이 명명(Naming)은 한정적인 기능처럼 보이지만, 실제로는 더 넓은 범위를 가지고 있는 것이 아닌가"와 같은 형식을 취할 때가 많습니다. 앞서 말한 로딩 설정 테이블도 이런 방식으로 전달했습니다. 보이는 것과 실체의 괴리를 말하는 것만으로도 상대에게는 충분히 전달됩니다. 이름으로 의도를 전달한다는 발상은 『리더블 코드(Readable Code)』가 일관되게 주장해 온 것이기도 합니다.
사람 사이라면 오감을 사용한 커뮤니케이션이 가능합니다. 표정이나 말투, 그 현장의 분위기로 "왠지 신경 쓰인다"는 것이 전달되기도 합니다. 하지만 LLM(대규모 언어 모델)에 전달할 수 있는 것은 텍스트나 이미지뿐입니다. 표정이나 말투, 현장의 분위기에 해당하는 입력은 없습니다. 미래에 그 부분이 채워진다면 이야기가 달라지겠지만, 현재로서는 의도를 전달하는 수단이 거의 언어에 국한됩니다. 그렇기 때문에 우리가 언어화를 강화할 수밖에 없습니다. 생각해보면 언어 그 자체가 인간 사이를 잇는 가장 오래된 인터페이스와 같습니다. 지성이란 정보의 압축이라는 관점이 있습니다. 경험을 짧은 말로 꺼낼 수 있는 형태로 정리해 두는 것이라고 생각하십시오. 압축된 정보를 표현하는 것이 언어라면, 에이전트와의 대화는 언어화 훈련 그 자체라고 할 수 있습니다.
테크 리드(Tech Lead)와 같은 상위 엔지니어일수록 상대에게 전달하기 위한 언어화 능력이 높다고 느낍니다. 머릿속에 압축된 정보를 스스로 전개하여 말로 할 수 있습니다. 주니어(Junior)가 같은 단계에 도달하려면 경험을 쌓아 뇌에 압축시키는 길이 있습니다. 다만, 그 길만 있는 것은 아닙니다. 언어화를 통한 지름길을 사용할 수 있습니다. 예를 들어 UI 개수를 전달할 때입니다. 스크린샷을 찍어 "여기"라고 가리키는 것보다, 브레드크럼(Breadcrumb), 헤딩(Heading), 다이얼로그(Dialog), 목록 화면과 상세 화면의 구분과 같은 UI 디자인 용어로 지정하는 것이 수정 지시의 속도를 높여줍니다. 해당 영역에서 통하는 용어는 설명하는 수고를 포함해 정보를 압축해 줍니다. 언어화의 지름길은 재능이 아니라 어휘의 문제입니다.
예를 들어 요리입니다. 레시피라는 언어화가 있기에 초보자도 실패할 확률이 낮아졌습니다. "양파를 캐러멜색(飴色)이 될 때까지 볶는다"라는 한마디가 불 조절과 시간, 색의 변화를 한꺼번에 전달해 줍니다. 절차를 처음부터 일일이 설명하지 않아도 되는 이유는 그 말 속에 경험이 압축되어 있기 때문입니다. 그리고 계속 만들다 보면 레시피를 보지 않고도 만들 수 있게 됩니다. 말에 압축되어 있던 것이 자신의 뇌 쪽에도 압축된 상태가 된 것입니다. 에이전트(Agent)에 대한 재질문은 이러한 언어화를 일상 속에서 끊임없이 이끌어내 줍니다.
그렇다면 재질문 너머에 있는 '좋은 것'이란 무엇일까요? 저는 비판적 사고(Critical Thinking)를 작동시키는 것이 디자인이나 도메인 모델(Domain Model)을 고민하는 것과 닮았다고 느낍니다. UI/UX 디자인도 도메인 모델링(Domain Modeling, 업무의 개념을 모델로 설계하는 것)도, 움직이는 결과물을 앞에 두고 "이것이 정말 최선인가"를 재질문하는 행위이기 때문입니다. 도메인 모델링의 원전인 『에릭 에반스의 도메인 주도 설계 (Domain-Driven Design)』 역시 모델을 만드는 것으로 끝나는 것이 아니라, 끊임없이 재질문하며 모델과 코드를 심화시켜 나가는 책이었습니다.
오랜 프로그래밍 경험칙으로서, 좋은 디자인은 하나의 판단으로 여러 문제를 해결합니다. 중요한 로직을 하나의 클래스(Class)에 모아서 그 클래스를 통해서만 호출할 수 있도록 만든 적이 있습니다. 이전에는 동일한 처리가 여기저기 흩어져 있었습니다. 하나로 모은 것만으로 중복이 사라졌고, 후속 구현도 헤매지 않게 되었습니다. 적은 수고로 많은 것을 해결할 수 있는 것은 대개 심플(Simple)합니다. 이는 나중에 언급할 분리형의 심플함이지만, 좋은 구현은 버리기 쉽고, 독립적이며, 다른 것과 간섭하지 않습니다. 비유하자면 건전지입니다. 규격이 정해져 있어 단독으로 교체할 수 있고, 다 쓰면 버리고 갈아 끼우기만 하면 기기 쪽은 건드릴 필요가 없습니다. 다만, 도메인 자체가 복잡한 경우도 있습니다. 이때 무리하게 단순화하면 심플해진 것이 아니라 요구사항을 깎아낸 것에 불과한 상황이 발생합니다.
반면 에이전트의 생성물은 양이 많아지기 쉽습니다. 그대로 두면 심플한 구현에서 멀어지게 됩니다. 과도하게 만들어 버리는 것 자체는 오버엔지니어링 (Over-engineering, 필요 이상으로 공을 들여 만드는 것)으로서 예전부터 알려진 문제입니다. 에이전트는 그것을 짧은 시간에 양산할 수 있습니다. 에러 핸들링(Error Handling)과 같은 중요한 처리는 물론 필요하지만, 그것 역시 재사용할 수 있는 형태로 모으고 싶습니다. 목표로 하는 것은 『프로그래밍의 원칙 (The Principles of Programming)』에서도 소개된 KISS 원칙 (Keep It Simple, Stupid. 단순하게 유지하라)입니다.
더 나아가 저는 구현은 하면 할수록 좋은 것이 아니라, 하지 않을수록 좋다고 생각합니다. 고객에게 제공하는 프로덕트(Product)에서는 작성한 코드의 양만큼 운영 비용이 증가합니다. 게다가 그 부담은 작성한 본인뿐만 아니라 팀 전체에 미칩니다. 에이전트는 부탁하면 얼마든지 써주지만, "애초에 쓰지 않는다"라는 선택지는 우리가 재질문하지 않으면 나오지 않습니다.
단, 심플함에는 두 종류가 있습니다. Mac의 유니파이드 메모리(Unified Memory)처럼 나누어져 있던 것을 통합하여 구조 자체를 없애는 심플함. 그리고 그래픽 카드(GPU), 메모리, CPU가 분리된 일반적인 부품 구성처럼, 미시적으로 보면 각 부품이 단순한 분리의 심플함입니다. 건전지는 후자에 해당합니다. 『UNIX 철학』에서 설파하는 "하나의 프로그램은 한 가지 일을 잘하게 한다"라는 정리(Theorem)도 이 분리의 심플함입니다. 『모놀리스에서 마이크로서비스로 (Monolith to Microservices)』가 다루는 분할의 판단도 이 선상에 있습니다. 어느 쪽을 선택할지는 문맥(Context)에 따라 달라집니다. 저의 기준은 변경 이유가 같은 것은 통합하고, 별개로 교체되는 것은 분리하는 것입니다. 다만 눈앞의 것이 어느 쪽인지 간파하는 판단은 주니어에게는 어려운 일입니다.
통합과 분리의 판단력을 기르기 위해서는 재질문의 축적과 더불어 적극적인 인풋(Input)이 필요합니다. 여기서 말하는 인풋은 탐구심으로 바꿔 말할 수 있을지도 모릅니다. 왜 그렇게 되어 있는가 하는 'Why'를 스스로 해결하러 가는 힘입니다. 단순히 받아들이기만 해서는 안 되며, 자신만의 방식으로 생각하고 유사한 구조를 찾아 나서야 합니다. 실제로 이 통합과 분리의 대비도 하드웨어 구성이라는 다른 분야에서 찾아낸 상사(Similarity)입니다. 분야가 다른 것 안에서 동일한 구조를 발견했을 때, 그 구조는 자신의 것이 됩니다.
그리고 이러한 탐구심을 통해 정보의 압축을 사전에 마친 사람일수록 LLM과의 대화 능력이 올라갑니다. LLM은 증폭기(Amplifier)라고 자주 불립니다. 저는 그 이유가 바로 여기에 있다고 이해합니다. 증폭되는 것은 자신이 내면에 압축하여 축적해 온 것이기 때문입니다.
예를 들어, 프로덕트의 도메인과 유비쿼터스 언어 (Ubiquitous Language, 팀 내에서 의미를 통일하여 사용하는 언어)를 정리하여 에이전트의 설정 파일에서 참조할 수 있도록 해둔 적이 있습니다. 그것만으로도 수정을 지시할 때, 저와 에이전트가 동일한 용어로 대화할 수 있게 되었습니다. 용어를 저의 언어로 다시 번역하는 왕복 과정이 줄어들었습니다. 제가 전달한 것은 새로운 정보가 아니라, 이미 프로덕트에 대해 압축되어 있던 정보였습니다. 언어화(Verbalization) 장에서 언급한 UI 디자인 어휘도 마찬가지였습니다. 압축을 마친 영역일수록 짧은 말이 긴 설명을 대신합니다.
반대의 경우도 발생합니다. 모르는 단어나 개념이 나왔을 때는 작업을 멈추고 의미를 묻는 공정이 끼어듭니다. 그만큼 진행은 느려집니다. 그렇다고 그 공정을 생략하면, 모르는 채로 앞으로 나아가게 됩니다. 여기서 아낀 시간은 나중에 자신에게 되돌아옵니다.
DORA (개발 조직의 퍼포먼스를 지속적으로 조사하는 연구 프로그램)의 2025년 리포트에서도 AI의 주요 역할은 증폭기(Amplifier)이며, 조직이 이미 가지고 있는 강점과 약점 모두를 확대한다고 기술하고 있습니다. 강한 팀은 더욱 빨라지고, 약한 팀은 기존의 문제가 심각해집니다. 조직의 이야기이지만, 개인에게서도 똑같은 일이 일어나고 있다고 생각합니다.
특별한 일을 하고 있다고 생각하지 않습니다. 제가 아직 직접 코드를 작성하던 시절부터 이어온 셀프 리뷰 (Self-review) 습관이 그대로 유지되고 있을 뿐입니다.
코드 리뷰 (Code review)를 내기 전에는 반드시 자신의 차이점(diff)을 다시 확인했습니다. 에이전트가 유행하기 훨씬 전부터, 차이점의 모든 것을 비판적 사고로 다시 질문하며 납득할 때까지 리뷰 요청을 보내지 않았습니다. 출발점은 자신의 아웃풋을 먼저 신뢰하지 않는 것입니다. 그 위에서 메커니즘이나 로직, 언어화를 통해 자기 자신을 납득시켜 나갑니다. 설계도 한 차례 끝난 뒤 전체를 조망하며 다시 확인합니다. 이것을 습관화하면 쓰고 있을 때의 시점과 다시 확인할 때의 시점이 분리됩니다. 손을 움직이는 플레이어의 시점에서, 전체를 보는 디렉터(Director)의 시점으로 머리가 전환되는 감각입니다. 여기서 디렉터는 게임 디렉터를 상상하는 것이 가깝습니다. 만드는 것의 방향이나 좋고 나쁨을 결정하는 입장에서, 웹 개발로 치면 매니저의 역할과 겹칩니다.
디렉터 측에 서면 반드시 나오는 질문이 있습니다. "애초에 이걸 왜 만들고 있었지?" 손을 움직이다 보면 어느샌가 사라져 버리는 이 질문에 스스로 답할 수 있게 될 때까지 제출하지 않습니다. 이것은 제가 직접 코드를 작성하던 시절에도, 에이전트에게 쓰게 하는 지금도 전혀 변함이 없습니다.
에이전트 시대에는 인간이 작성하던 시절과는 비교도 안 될 정도의 양의 코드가 짧은 시간에 나오기 때문에, 리뷰해야 할 총량 자체가 늘어났습니다.
다만, 보는 양은 스스로 컨트롤할 수 있습니다. 태스크를 분할하고 스코프 (Scope)를 먼저 정합니다. 차이점이 크게 나왔을 때도, 우선 API 주변만, 그다음은 컴포넌트만 하는 식으로 영역을 좁혀서 코멘트를 남깁니다. 수정의 이터레이션 (Iteration)을 거듭해 나가는 방식입니다. 그렇게 하면 한 번에 마주하는 것은 '보게 되는 양' 안에 들어오게 됩니다.
그럼에도 리뷰를 생략해 버리는 경우가 있습니다. 그 정체를 저는 이해 부채 (Comprehension debt)라고 생각합니다. 리포지토리 (Repository)를 잘 모르기 때문에, 나온 코드의 좋고 나쁨도 판단하지 못하고 무심코 지나칩니다. 리뷰를 최적화하는 것은 에이전트의 출력보다 리포지토리 전체를 더 잘 아는 것입니다. 자신의 판단이 빨라질 뿐만 아니라, 나중에 보는 사람에게 전달할 성과물의 정밀도도 높아집니다.
이 이해 부채에 대한 대책은 메커니즘 측면에서도 시도 중입니다. 개발 단계에서는 요구사항 정의나 설계 문서를 에이전트가 자동 생성하게 하고 있습니다. 덕분에 태스크를 넘나드는 정보에도 접근할 수 있게 되었습니다. 다만 단점도 있습니다. 문서가 너무 많아서 주니어(Junior)가 파악하기 어렵습니다. 적혀 있는 내용의 이해가 따라가지 못해 지적 단계까지 도달하지 못하는 일도 일어나고 있습니다. 지금은 문장의 가독성을 높이는 노력과 더불어, 인간의 파악 그 자체를 하네스 (Harness, 에이전트를 지원하는 주변 메커니즘 일체)에 포함할 수 없을지 검토하고 있는 단계입니다.
문서를 읽다가 막혔을 때의 도피처도 필요합니다. 작업의 본류를 멈추지 않고 옆에서 질문할 수 있는 수단을 갖춰두는 것을 추천합니다. Claude Code에는 /btw가 있어, 대화에 추가하지 않는 사이드 퀘스천 (Side question)으로 질문할 수 있습니다. 추가 설정이 필요 없으므로 모르는 단어나 개념이 나왔을 때 그 자리에서 바로 해소할 수 있습니다. 배움을 시작하는 첫걸음으로서 딱 적당한 무게입니다. 손이 멈추는 시간을 아까워하며 그냥 지나치기보다, 모르는 영역을 줄여나가는 것이 결국에는 더 빠릅니다.
같은 문제 의식을 다룬 기사로, Geoffrey Litt의 「이해야말로 새로운 병목 (Understanding is the new bottleneck)」이라는 강연록이 있습니다. 퀴즈나 게임 같은 형태로 이해를 즐겁게 진행하는 기법도 소개되어 있어, 일고 볼 가치가 있었습니다.
"에이전트가 똑똑해지면 이런 노력은 불필요해지지 않을까"라고 생각하는 사람도 있을지 모릅니다. 저는 그렇게 생각하지 않습니다. 아무리 똑똑한 사람이라도 입사 직후에는 모르는 것투성이일 것입니다. 조직이나 커뮤니티에 막 들어왔을 때는 누구라도 그렇습니다. 처음에는 이해 부채 (Understanding debt)로부터 시작합니다. 에이전트도 마찬가지로, 성능이 올라가더라도 이러한 노력을 계속해야 합니다. 오히려 인간의 프레임워크나 메커니즘을 도입하는 것이, 에이전트가 저비용으로 인간의 아웃풋 (Output)에 다가갈 수 있는 지름길이 됩니다. 신입 사원이 온보딩 (Onboarding)을 통해 자리 잡을 수 있는 것도, 문서나 선배에게 질문하기와 같이 인간을 위해 만들어진 메커니즘이 있기 때문입니다. 따라서 문서나 질문 경로와 같이 텍스트로 완결되는 메커니즘은 LLM (Large Language Model)에게도 유효하다고 생각합니다.
조직을 메커니즘으로 파악하는 이야기는 지난번 기사에서도 썼습니다.
좋은 가성비란 전체 비용이 낮아지는 노력을 말합니다. 여기서 '전체'란 스테이크홀더 (Stakeholder), 즉 만드는 것에 대해 연락이나 보고를 주고받는 사람들 모두를 포함합니다. 나쁜 가성비는 그 반대로, 자신만 빨라지면 된다는 이기심으로 다른 스테이크홀더의 비용을 늘려버리는 노력입니다. 혼자만 사용법이나 방식이 다르거나, 확인하는 방식이 평소와 다르거나, 연락이 되지 않는 식의 일하는 방식입니다. 비유하자면 용병 같은 일처리입니다. 좋은 가성비는 그 반대로, 개척자처럼 길을 열어 나갑니다. 사용법을 팀의 표준에 맞추고, 확인 경로를 누구나 통할 수 있는 형태로 만들며, 병목 지점을 미리 공유합니다. 나중에 오는 사람의 몫까지 길이 닦여 있는 일하는 방식입니다.
개척자 측 움직임의 대표적인 예가 방향성의 어긋남에 대한 즉각적인 피드백입니다. 어긋난 채로 다 만들어 놓고 나서 수정하는 것은, 서두에서 언급했듯이 비용 낭비입니다. 빠른 분기점에서 리뷰 (Review)를 돌려준다면, 선로 자체를 다시 깔지 않아도 됩니다. 스테이크홀더 전원의 재작업 비용이 낮아집니다.
그리고 앞서 말한 이해 부채를 방치하게 만드는 것이, 특히 주니어 시절에 느끼는 "시간이 부족하다"라는 초조함입니다. 빨리 내야 해, 가성비 좋게 진행해야 해, 라는 마음이 리포지토리 (Repository)를 이해하는 시간을 뒤로 미루게 만듭니다. 그런데 이 가성비 의식이 오히려 효율을 떨어뜨립니다. 학습에 대입하면 이해하기 쉬울 것입니다. 기억에 오래 남는 것은 한꺼번에 쏟아부었을 때가 아니라, "배우기 $\rightarrow$ 쉬기 $\rightarrow$ 복습"의 사이클을 돌렸을 때입니다. 쉬는 동안 뇌가 정보를 정리해 줍니다. 시냅스의 가소성 (Synaptic plasticity)을 다룬 연구이기에 업무 방식에 그대로 적용하는 것은 외삽 (Extrapolation)이지만, 벼락치기가 정착되지 않는다는 구조는 같다고 생각합니다.
에이전트도 메모리 (Memory)나 컴팩트 (Compact, 길어진 문맥의 압축)를 사용하여 문맥을 정리하며 진행합니다. 계속 밀어넣기만 하지 않고, 정리하는 메커니즘을 사이에 끼워 넣습니다. 인간 측에도 똑같은 메커니즘이 필요합니다.
지금까지 인간 측의 이야기를 해왔지만, 이 재검토의 구조는 에이전트를 구성하는 방식 그 자체에도 적용할 수 있습니다. 방법은 몇 가지가 있습니다.
한 번의 출력으로 끝내지 않는 것입니다. "방금 작성한 코드를 다른 관점에서 비판해 봐"라고 재검토를 끼워 넣어, 계획과 실행과 검증의 루프 (Loop)를 돌리게 합니다. 횟수 그 자체보다, 지적이 나오지 않을 때까지 돌리는 것이 본질입니다. 저의 경우 그것이 3회 정도였는데, 그 정도로 반복하면 명확한 지적이 다 나온 상태에서 인간의 리뷰를 시작할 수 있게 되었습니다. 안을 하나로 좁히지 못하게 하는 것도 유효합니다. 여러 방침을 병렬로 내놓게 하여 비교해 보면, 논리만으로는 보이지 않았던 장단점이 드러납니다. 다만, 같은 세션에서 계속 비판하게 하면 관점이 편향됩니다. 지적이 다 끝난 것이 아니라, 낼 수 있는 범위 내에서 다 낸 것뿐일 수도 있습니다. 문맥을 공유하지 않은 리뷰 담당 서브 에이전트 (Sub-agent)를 별도로 세우는 것이 효과적인 이유는, 이러한 편향을 외부에서 깨뜨릴 수 있기 때문입니다.
제가 실제로 하고 있는 것은 스킬 (Skill)이나 훅 (Hooks, 특정 타이밍에 처리를 자동 실행하는 메커니즘)에 내장하는 것입니다. Claude Code에 가까운 이야기입니다만, 훅 (Hooks)을 통해 회고를 자동화한 이후로는 세션의 끝에 모델이 회고 (Retrospective)를 수행해 줍니다. 그 외에도 워크플로우 (Workflow) 도중에 재검토 단계를 포함시킨 스킬이나, 주장에는 반드시 근거를 리서치하게 하는 스킬에서 효과를 보고 있습니다.
이러한 루프 (Loop)는 사실 에이전트 구축의 기본 요소입니다. Claude Code와 같은 코딩 에이전트도 문맥을 수집하고, 실행하며 확인하는 반복을 통해 이루어집니다. 인간이 머릿속에서 수행하던 시행착오를 그대로 프로그래밍할 수 있게 된 것입니다.
마지막으로 정리하겠습니다. 논리적 사고 (Logical Thinking)와 비판적 사고 (Critical Thinking)는 어느 하나를 선택하는 것이 아니라, 서로 루프시키는 것입니다. 논리로 선로를 깔고, 비판으로 분기점을 전환합니다. 에이전트가 논리적인 측면을 맡아주는 지금, 전환하는 쪽으로 돌아가는 것은 엔지니어 자신입니다. 이것은 새로운 기술이라기보다, 셀프 리뷰 (Self-review)라는 오래된 습관을 통해 단련되는 확장된 역할이라고 생각합니다.
내일부터 딱 한 가지만 시도해 본다면, 차이 (Diff)를 내기 전에 "애초에 이걸 왜 만들고 있었지?"라고 스스로에게 질문해 보기를 권합니다. 대답할 수 없다면 아직 결과물을 내놓을 때가 아닙니다. 다시 질문할 때마다 언어가 늘어나고, 늘어난 언어가 다음 질문을 다시 더 빠르게 만듭니다.
비판적으로 다시 질문하는 능력과 문맥을 정리하며 탐색하는 구조. 이 두 가지 측면에서 인간과 에이전트는 생각보다 닮아 있습니다. 그렇다면 에이전트와 잘 지내는 것은 자기 자신의 사고방식을 되돌아보는 일이기도 할 것입니다.
- 에반스, 에릭. 에릭 에반스의 도메인 주도 설계 (Domain-Driven Design). 이마세키 츠요시 감역, 와치 우케, 마키노 유코 역. 쇼에이샤, 2011.
- 간커스, 마이크. UNIX라는 사고방식: 그 설계 사상과 철학. 요시오 카츠라 역. 오옴샤, 2001.
- 보즈웰, 더스틴; 포셰, 트레버. 리더블 코드 (Readable Code): 더 나은 코드를 쓰기 위한 심플하고 실천적인 테크닉. 카쿠 마사노리 역. 오라일리 재팬, 2012.
- 뉴먼, 샘. 모놀리스에서 마이크로서비스로: 모놀리스를 진화시키는 실천적 이행 가이드. 시마다 코지 역. 오라일리 재팬, 2020.
- 우에다 이사오. 프린시플 오브 프로그래밍 (Principle of Programming): 3년 차까지 익히고 싶은 평생 유용한 101가지 원리 원칙. 슈와 시스템, 2016.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기