<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>DataCook</title>
    <link>https://datacook.tistory.com/</link>
    <description>Email : lyt970120@gmail.com
</description>
    <language>ko</language>
    <pubDate>Thu, 2 Jul 2026 12:29:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Joon09</managingEditor>
    <image>
      <title>DataCook</title>
      <url>https://tistory1.daumcdn.net/tistory/4187085/attach/6f66645f1b1f4c84af9cf61b09b8712d</url>
      <link>https://datacook.tistory.com</link>
    </image>
    <item>
      <title>'최신 방식'이라며 짜준 게, 사실 옛날 방식이었어요</title>
      <link>https://datacook.tistory.com/209</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;modern-way-was-the-old-way.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M9FaQ/dJMcaccA2Fp/ZT00Y0JkqUWpYzk0vVT7MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M9FaQ/dJMcaccA2Fp/ZT00Y0JkqUWpYzk0vVT7MK/img.png&quot; data-alt=&quot;'최신'인데 옛날&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M9FaQ/dJMcaccA2Fp/ZT00Y0JkqUWpYzk0vVT7MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM9FaQ%2FdJMcaccA2Fp%2FZT00Y0JkqUWpYzk0vVT7MK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;미니멀한 책상 옆에 놓인 옛 다이얼 전화기 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;modern-way-was-the-old-way.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;'최신'인데 옛날&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정 가이드 여섯 개가 화면에 쫙 떴는데, 어디 하나 손볼 데가 없어 보였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문장도 매끄럽고, &quot;요즘은 보통 이렇게 처리해요&quot;라는 설명까지 친절하게 달려 있었거든요.&lt;br /&gt;저는 한 번 쓱 읽고 &quot;오케이, 이대로 가자&quot; 했어요.&lt;br /&gt;마우스 휠을 두어 번 굴려 끝까지 내려보는 데 한 십 초나 걸렸나.&lt;br /&gt;그게 실수였어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&quot;요즘은 이렇게 해요&quot;라는 그 한 줄&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 탐색을 시킨 건 정확했어요.&lt;br /&gt;&quot;이 기능 어디 있냐&quot; 물었더니 파일 위치를 딱 짚었거든요.&lt;br /&gt;폴더 경로까지 정확했어요.&lt;br /&gt;거기까진 진짜였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 저는 그다음 단계도 당연히 진짜겠거니 했어요.&lt;br /&gt;문제는 거기, 실제로 고치는 코드를 짜는 단계였어요.&lt;br /&gt;AI가 그 파일들을 실제로 열어본 게 아니라, &quot;이런 가공은 원래 이런 식으로 하지&quot;라는 자기 머릿속 관례로 채워버린 거예요.&lt;br /&gt;근데 그걸 그 자리에서는 몰라요.&lt;br /&gt;한 줄 한 줄이 자신만만했거든요.&lt;br /&gt;망설이는 기색이 1도 없었어요.&lt;br /&gt;&quot;여기는 좀 애매한데요&quot; 같은 단서도 한 줄 없이, 그냥 다 안다는 투였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 그 자신감을 그냥 믿었어요.&lt;br /&gt;위치를 정확히 맞혔으니, 내용도 맞겠거니 했던 거죠.&lt;br /&gt;처음엔 이게 함정인 줄도 몰랐어요.&lt;br /&gt;오히려 &quot;어, 이번엔 좀 잘 짜네&quot; 하고 살짝 기특해하기까지 했어요.&lt;br /&gt;근데 그게 함정이었어요.&lt;br /&gt;위치를 아는 거랑, 그게 지금 어떻게 생겼는지 아는 건 완전히 다른 일이더라고요.&lt;br /&gt;지도에서 우리 집 위치를 짚는 거랑, 우리 집 냉장고에 지금 뭐가 들었는지 아는 건 다른 거잖아요.&lt;br /&gt;딱 그런 거였어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 코드를 한 줄 열어봤더니&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 적용 버튼을 누르려는데, 뭔가 손이 안 나가더라고요.&lt;br /&gt;딱히 근거가 있던 건 아니에요.&lt;br /&gt;그냥 찜찜했어요.&lt;br /&gt;처음엔 '내가 너무 예민한가' 싶어서 그냥 넘어가려고도 했어요.&lt;br /&gt;근데 손이 멈춰 있길래, 에라 모르겠다 하고 가이드대로 적용하기 전에 진짜 코드를 한 번 직접 열어봤어요.&lt;br /&gt;대조나 한번 해보자는 가벼운 마음이었어요.&lt;br /&gt;5분이면 끝나겠지 했거든요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 첫 줄부터 안 맞았어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI가 &quot;이걸 쓰면 된다&quot;고 적어둔 그 구조가, 실제 코드엔 아예 없었어요.&lt;br /&gt;처음엔 제가 파일을 잘못 열었나 싶어서 위로 다시 스크롤해 봤어요.&lt;br /&gt;맞는 파일이었어요.&lt;br /&gt;그 자리엔 한참 전에 바뀐, 지금은 안 쓰는 옛날 방식의 흔적만 남아 있었어요.&lt;br /&gt;AI가 &quot;최신&quot;이라며 자신 있게 깔아둔 그 패턴이, 사실은 자기가 학습할 때쯤 흔하던 한물간 방식이었던 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심지어 호출하는 순서도 정반대였어요.&lt;br /&gt;진짜 코드는 A를 받아서 B를 주는데, 가이드는 B를 받아서 A를 준다고 적어놨더라고요.&lt;br /&gt;그 줄을 한참 봤어요.&lt;br /&gt;화면을 좌우로 번갈아 보면서, 내가 지금 뭘 잘못 보고 있나 몇 번을 다시 읽었어요.&lt;br /&gt;잘못 본 게 아니었어요.&lt;br /&gt;그냥 거꾸로였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기서부터는 마음이 좀 급해졌어요.&lt;br /&gt;하나가 이러면 나머지도 봐야 하잖아요.&lt;br /&gt;여섯 개를 다 줄 단위로 대조했어요.&lt;br /&gt;한 5분이면 될 줄 알았는데 한참 걸렸어요.&lt;br /&gt;여섯 개 전부, 지금 존재하지도 않는 구조를 깔고 쓰여 있었어요.&lt;br /&gt;한두 개가 틀린 게 아니라, 전제 자체가 통째로 옛날 거였어요.&lt;br /&gt;결국 6개 다 버리고 다시 썼어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;매끄러운 게 제일 무서웠어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;희한한 건, 그 가짜 가이드가 어설펐으면 차라리 의심했을 거란 점이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오타가 있었거나, 말이 어딘가 막혔거나, &quot;음, 아마도&quot; 같은 게 붙어 있었으면 한 번 더 봤을 거예요.&lt;br /&gt;근데 문장이 너무 깔끔했어요.&lt;br /&gt;&quot;요즘은&quot;, &quot;보통&quot;, &quot;일반적으로&quot; 같은 말이 붙으면 묘하게 더 믿게 되잖아요.&lt;br /&gt;사람이 그렇게 말하면 경험에서 나온 감각인데, AI가 그렇게 말하면 그냥 옛날에 흔하던 걸 평균 내서 뱉은 거더라고요.&lt;br /&gt;둘이 똑같이 들려서 구분이 안 돼요.&lt;br /&gt;말투만 봐서는 진짜 아는 사람인지, 옛날 기억으로 때려 맞히는 건지 알 수가 없어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 그날 &quot;AI가 모르면 모른다고 하겠지&quot;를 반쯤 믿고 있었던 것 같아요.&lt;br /&gt;근데 그게 아니더라고요.&lt;br /&gt;AI는 모를 때도 똑같은 톤으로 말해요.&lt;br /&gt;아는 걸 말할 때랑 모르는 걸 지어낼 때랑, 목소리가 하나도 안 떨려요.&lt;br /&gt;자기가 보던 세상이 지금이랑 다르다는 걸, 자기는 몰라요.&lt;br /&gt;모른다는 것조차 모르는 거죠.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아직 안 풀린 거&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 AI가 &quot;이렇게 하면 돼요&quot; 하면, 그 자리에서 실제 파일을 한 줄이라도 열어보게는 됐어요.&lt;br /&gt;그건 습관이 됐어요.&lt;br /&gt;그날 이후로는 자동으로 손이 가요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 솔직히 아직도 잘 모르겠는 게 하나 있어요.&lt;br /&gt;그 여섯 개가 다 틀린 걸 제가 잡은 건, 그날따라 우연히 찜찜해서 코드를 열어봐서였어요.&lt;br /&gt;무슨 대단한 검증 습관 같은 게 아니라, 그냥 그날 손이 안 나갔을 뿐이에요.&lt;br /&gt;안 열어봤으면 그대로 들어갔을 거예요.&lt;br /&gt;그럼 다음에 제가 찜찜하지 않은 날엔요?&lt;br /&gt;매끄럽고 자신만만한데 사실은 한물간 답을, 저는 어떻게 알아채죠.&lt;br /&gt;아직 그 답은 못 찾았어요.&lt;br /&gt;일단은 그냥, 더 자주 열어보는 수밖에 없는 것 같아요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>ai-agent</category>
      <category>knowledge-cutoff</category>
      <category>Trust</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/209</guid>
      <comments>https://datacook.tistory.com/209#entry209comment</comments>
      <pubDate>Thu, 2 Jul 2026 09:00:40 +0900</pubDate>
    </item>
    <item>
      <title>Flutter에서 Container(width)가 안 먹는 이유</title>
      <link>https://datacook.tistory.com/275</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-flutter-c-constraints.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7o3ex/dJMcai4S1hv/WWeRPpqCa7GPOEq7ckmkbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7o3ex/dJMcai4S1hv/WWeRPpqCa7GPOEq7ckmkbK/img.png&quot; data-alt=&quot;Constraints는 정의보다 Flutter에서 깨지는 모양으로 이해하는 편이 빠릅니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7o3ex/dJMcai4S1hv/WWeRPpqCa7GPOEq7ckmkbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7o3ex%2FdJMcai4S1hv%2FWWeRPpqCa7GPOEq7ckmkbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;Constraints 개념을 Flutter 실패 모양과 검증 기준으로 설명하는 다이어그램&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;01-flutter-c-constraints.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Constraints는 정의보다 Flutter에서 깨지는 모양으로 이해하는 편이 빠릅니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 레이아웃은 자식이 원하는 크기를 부모에게 명령하는 구조가 아닙니다.&lt;br /&gt;부모가 먼저 제약을 내려보내고, 자식은 그 안에서 크기를 고릅니다.&lt;br /&gt;마지막으로 부모가 위치를 정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서 다루는 개념은 &lt;b&gt;Constraints&lt;/b&gt;입니다.&lt;br /&gt;검색해서 들어온 독자에게 남길 것은 용어 정의가 아니라, Flutter에서 이 개념이 깨질 때 어떤 모양으로 보이는지입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Flutter에서는 이렇게 깨집니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &lt;code&gt;Container(width: 300)&lt;/code&gt;이라고 써도 부모가 더 좁게 묶으면 300이 되지 않습니다.&lt;br /&gt;&lt;code&gt;Row&lt;/code&gt;, &lt;code&gt;Column&lt;/code&gt;, &lt;code&gt;Expanded&lt;/code&gt;, &lt;code&gt;ListView&lt;/code&gt;에서 같은 코드가 다르게 보이는 이유도 제약이 다르기 때문입니다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;Row(
  children: [
    Container(width: 300, height: 80, color: Colors.blue),
    const Text('옆 칸'),
  ],
)

Row(
  children: [
    Expanded(
      child: Container(height: 80, color: Colors.blue),
    ),
    const Text('옆 칸'),
  ],
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;작은 어긋남은 화면에서 먼저 보입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 처음부터 큰 설계 이슈처럼 보이지 않습니다.&lt;br /&gt;탭을 다시 열었을 때 값이 돌아오거나, 화면 전환 직후 상태가 한 박자 늦거나, 실제 기기에서만 다른 반응이 나오는 정도로 시작합니다.&lt;br /&gt;사용자는 Constraints라는 말을 보지 않습니다.&lt;br /&gt;눌렀는데 늦고, 돌아왔는데 값이 바뀌고, 방금 본 화면이 다음 순간 다른 얼굴을 하는 장면만 봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 처음에는 화면을 탓하기 쉽습니다.&lt;br /&gt;하지만 Flutter 화면은 눈앞의 위젯만으로 움직이지 않습니다.&lt;br /&gt;그 위젯이 읽는 값은 provider에서 왔을 수 있고, route가 바뀌며 다시 만들어졌을 수 있고, platform event나 async callback이 늦게 들어왔을 수 있습니다.&lt;br /&gt;화면을 구성하는 코드는 짧아도 화면에 도착하기까지 지나온 경로는 길 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 작은 어긋남을 그냥 넘기면 나중에 더 비싼 문제가 됩니다.&lt;br /&gt;한 화면에서만 보이던 증상이 탭 구조, nested navigation, refresh, background 복귀를 만나면서 다른 모양으로 퍼집니다.&lt;br /&gt;그때 필요한 것은 &amp;ldquo;Flutter가 이상하다&amp;rdquo;는 말이 아니라 어느 경계가 사용자의 손보다 늦게 움직였는지 보는 눈입니다.&lt;br /&gt;이 눈이 있어야 같은 냄새가 다른 위젯에서 나와도 당황하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 디버깅 순서도 달라집니다.&lt;br /&gt;먼저 화면에서 보이는 현상을 그대로 둔 다음, 그 현상이 사용자의 입력 직후인지, 다음 frame 뒤인지, route를 떠난 뒤인지 나눕니다.&lt;br /&gt;같은 늦음이라도 위치가 다르면 원인이 다릅니다.&lt;br /&gt;이 구분을 하지 않으면 작은 수정이 큰 리팩터링으로 번지고, 결국 무엇을 고쳤는지도 흐려집니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원인은 위젯 밖 경계에서 커집니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Constraints 같은 주제는 한 줄짜리 코드 문제처럼 보일 때가 많습니다.&lt;br /&gt;하지만 실제 원인은 build 타이밍, layout 비용, 상태 소유자, native plugin, network 응답 같은 경계를 지나가며 커집니다.&lt;br /&gt;처음 실행에서는 맞았는데 뒤로 갔다 오면 달라지거나, debug에서는 멀쩡한데 release에서 흔들리거나, 빠르게 탭을 넘길 때만 꼬이는 이유가 여기에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계에서는 답을 급하게 내리지 않는 편이 낫습니다.&lt;br /&gt;먼저 사용자가 본 증상과 코드가 바뀐 지점을 나란히 둡니다.&lt;br /&gt;그 다음 어느 경계에서 시간이 어긋났는지, 값의 주인이 둘이 되었는지, 화면보다 늦게 도착한 이벤트가 있는지를 봅니다.&lt;br /&gt;이런 순서로 보면 정답이 늦게 나오는 것 같지만, 실제로는 헛수정을 줄입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 화면이 늦게 바뀐다고 해서 바로 &lt;code&gt;setState&lt;/code&gt; 위치만 바꾸면 원인을 놓칠 수 있습니다.&lt;br /&gt;이미지 decode가 끝나기 전인지, provider가 dispose된 뒤인지, route가 새 인스턴스를 만든 뒤인지가 다 다릅니다.&lt;br /&gt;같은 &amp;ldquo;늦다&amp;rdquo;라도 원인은 다르고, 원인이 다르면 손댈 위치도 달라집니다.&lt;br /&gt;독자가 검색으로 들어왔을 때 필요한 것은 바로 이 구분입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 코드 예시는 짧아도 설명은 충분해야 합니다.&lt;br /&gt;&lt;code&gt;setState&lt;/code&gt;, &lt;code&gt;context.mounted&lt;/code&gt;, &lt;code&gt;precacheImage&lt;/code&gt;, provider 수명 같은 도구는 각각 자기 자리가 있습니다.&lt;br /&gt;도구 이름만 외우면 다음 버그에서 다시 흔들리지만, 도구가 들어가는 경계를 기억하면 다른 화면에서도 같은 판단을 반복할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;고칠 때는 가장 가까운 경계만 움직입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정은 한 번에 크게 하지 않는 편이 낫습니다.&lt;br /&gt;화면이 어긋났다고 상태 소유자, build 타이밍, navigation, cache를 동시에 바꾸면 결과가 좋아져도 왜 좋아졌는지 남지 않습니다.&lt;br /&gt;먼저 가장 가까운 경계 하나만 고릅니다.&lt;br /&gt;값을 쓰는 쪽이 둘이면 하나로 줄이고, build 안에서 일이 시작되면 생명주기 바깥으로 빼고, platform 이벤트가 늦으면 기다리는 위치를 분리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 필요한 흔적은 거창하지 않습니다.&lt;br /&gt;작은 widget test 하나, 전후 화면 캡처 하나, 로그 한 줄이면 충분할 때가 많습니다.&lt;br /&gt;다만 그 흔적은 무엇이 달라졌는지를 말해야 합니다.&lt;br /&gt;다음 작업자가 코드를 열었을 때 &amp;ldquo;왜 이렇게 했지&amp;rdquo;가 아니라 &amp;ldquo;이 경계를 줄였구나&amp;rdquo;라고 읽을 수 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나는 손대지 않은 부분을 의식적으로 남기는 일입니다.&lt;br /&gt;Flutter에서는 작은 수정이 주변 위젯의 rebuild, focus, gesture, scroll 상태까지 건드릴 수 있습니다.&lt;br /&gt;그래서 한 번의 수정이 넓게 퍼졌다면 그 자체로 다시 좁혀야 합니다.&lt;br /&gt;고친 줄보다 건드리지 않은 경계가 분명할수록 나중에 되돌리기도 쉽고, 다른 화면에 옮길 때도 덜 위험합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;다음 화면에서 같은 냄새를 맡게 됩니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에 남아야 하는 것은 요약문이 아니라 다음 작업에서 바로 쓰는 감각입니다.&lt;br /&gt;비슷한 화면이 다시 흔들릴 때 제목을 외우지 않아도 됩니다.&lt;br /&gt;사용자의 손, frame, 상태 소유자, 외부 이벤트가 어떤 순서로 만나는지 다시 그려보면 됩니다.&lt;br /&gt;그 순서가 보이면 Flutter의 복잡함은 사라지지 않아도 다루는 속도는 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 결말은 질문표나 보고 문장으로 닫지 않습니다.&lt;br /&gt;무엇을 했다는 말보다 다음에 어디를 먼저 볼지가 남아야 합니다.&lt;br /&gt;같은 종류의 버그를 더 빨리 알아보고, 한 번에 한 경계만 고치는 쪽으로 손이 움직이면 충분합니다.&lt;br /&gt;짧게 말해도 되는 부분과 길게 남겨야 하는 부분을 구분하는 감각도 여기서 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이 주제는 위젯 하나를 예쁘게 고치는 문제가 아닙니다.&lt;br /&gt;화면이 흔들릴 때 보이는 증상 뒤에 있는 순서를 읽는 문제입니다.&lt;br /&gt;그 순서를 읽기 시작하면 수정은 덜 요란해지고, 다음 화면에서 같은 문제가 나와도 다시 처음으로 돌아가지 않습니다.&lt;br /&gt;그 감각이 남으면 다음 수정에서 다시 처음으로 돌아가지 않습니다.&lt;br /&gt;다음 수정에서 손이 먼저 가야 할 곳을 떠올릴 수 있으면 충분합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 감각은 한 번에 생기지 않습니다.&lt;br /&gt;같은 종류의 화면 흔들림을 두세 번 겪고 나면, 코드보다 먼저 흐름을 그리게 됩니다.&lt;br /&gt;어느 값이 먼저 왔고, 어느 이벤트가 늦었고, 어느 위젯이 오래 살아남았는지 떠올리는 순간 수정의 크기가 줄어듭니다.&lt;br /&gt;그래서 결론을 빨리 닫기보다 그 장면을 충분히 남기는 쪽을 택합니다.&lt;br /&gt;이 차이가 쌓이면 다음 디버깅은 더 조용해집니다.&lt;br /&gt;빠른 답보다 오래 남는 기준이 되는 지점도 여기입니다.&lt;br /&gt;그래서 같은 실수를 줄이는 가장 작은 단서는 늘 장면 안에 남습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원문 기준&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 기준: https://docs.flutter.dev/ui/layout/constraints&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 본 날짜: 2026-07-01.&lt;br /&gt;발행 전에는 원문의 바뀐 표현만 한 번 더 봅니다.&lt;/p&gt;</description>
      <category>AI Agent/flutter</category>
      <category>constraints</category>
      <category>Flutter</category>
      <category>개발론</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/275</guid>
      <comments>https://datacook.tistory.com/275#entry275comment</comments>
      <pubDate>Thu, 2 Jul 2026 09:00:13 +0900</pubDate>
    </item>
    <item>
      <title>AI가 짠 걸 한 줄씩 검토하다, 직접 짜는 게 빨랐겠다 싶었던 밤</title>
      <link>https://datacook.tistory.com/184</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;line-by-line-review-slower.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b265V6/dJMcagzh3z1/eepbv3EU0Uo5hnDxzEgY0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b265V6/dJMcagzh3z1/eepbv3EU0Uo5hnDxzEgY0k/img.png&quot; data-alt=&quot;한 줄씩 들여다본 밤&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b265V6/dJMcagzh3z1/eepbv3EU0Uo5hnDxzEgY0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb265V6%2FdJMcagzh3z1%2Feepbv3EU0Uo5hnDxzEgY0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;밤 책상에 쌓인 출력물과 돋보기, 빨간 펜 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;line-by-line-review-slower.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한 줄씩 들여다본 밤&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정 가이드 여러 개가 화면에 떠 있었어요.&lt;br /&gt;AI가 한 시간도 안 걸려 뽑아준 거였고, 각각 '어느 파일을 열어서, 이 줄을 이렇게 바꾸면 된다'까지 친절하게 적혀 있었어요.&lt;br /&gt;머지하기 전에 한 번만 훑자, 그게 그날 밤 제 계획의 전부였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훑는 데 십 분이면 될 줄 알았는데, 첫 번째 가이드의 세 번째 줄에서 멈췄어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;첫 가이드 세 번째 줄에서 멈췄어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기 적힌 필드 이름이 낯설었어요.&lt;br /&gt;낯선데 또 그럴듯했어요.&lt;br /&gt;가공한 어떤 값을 담는 칸이었는데, AI는 그 이름을 길게 풀어서 적어놨더라고요.&lt;br /&gt;단어 세 개를 이어 붙인, 딱 우리가 쓸 법한 모양이요.&lt;br /&gt;너무 자연스러워서, 내가 어제 직접 타이핑했어도 저렇게 적었겠다 싶었어요.&lt;br /&gt;그래서 더 의심이 안 갔어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 내가 헷갈린 줄 알았어요.&lt;br /&gt;비슷한 이름이 두어 개 있는 칸이라, 머릿속에서 다른 거랑 섞였나 싶었거든요.&lt;br /&gt;그래서 그냥 넘기려다, 마우스를 가이드 위에 올린 채로 한 박자 가만히 있었어요.&lt;br /&gt;새벽이라 그런가, 화면 글자가 유난히 또렷했어요.&lt;br /&gt;그래도 한 번만, 하고 실제 정의 파일을 열었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;없었어요.&lt;br /&gt;비슷한 칸은 있는데 AI가 적은 것보다 한 단어 짧았어요.&lt;br /&gt;가운데 단어 하나를 AI가 더 끼워 넣은 거예요.&lt;br /&gt;위에서 아래까지 두 번 훑었는데, AI가 적은 그 철자 그대로는 아무 데도 없었어요.&lt;br /&gt;'이런 가공이면 보통 이 정도 길이로 적지' 하고 관례로 채운, 한 단어 더 붙은 가짜 이름이었어요.&lt;br /&gt;내가 헷갈린 게 아니라, AI가 지어낸 거였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 줄 틀린 거면 거기만 고치면 돼요.&lt;br /&gt;그런데 그 칸을 쓰는 줄이 가이드 안에 네 군데 더 있었고, 그게 맞다는 전제로 다음 단락이 또 쌓여 있었어요.&lt;br /&gt;결국 그 가이드 하나를 검증하려면 모델 정의를 열고, 호출하는 함수의 시그니처를 열고, AI가 적은 인자 순서랑 실제 순서를 짝지어 봐야 했어요.&lt;br /&gt;실제 함수는 인자 두 개를 어떤 순서로 받는데, AI는 그 순서를 뒤집어 적어놨더라고요.&lt;br /&gt;순서가 정반대였어요.&lt;br /&gt;그 상태로 머지됐으면 둘이 바뀐 채로 들어갔을 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 오는 데 이십 분쯤 썼어요.&lt;br /&gt;가이드는 다섯 개가 더 남아 있었고요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어제는 비슷한 걸 손으로 짰는데&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이십 분이 유난히 길게 느껴진 건, 비교 대상이 손에 있었기 때문이에요.&lt;br /&gt;바로 전날, 거의 같은 종류의 수정 하나를 제가 직접 짰거든요.&lt;br /&gt;모델 정의를 먼저 열어서 칸 이름을 눈으로 확인하고, 그 상태에서 코드를 쓰니까 십 몇 분 만에 끝났어요.&lt;br /&gt;틀릴 구석이 거의 없었어요.&lt;br /&gt;이름이 손에 있으니까요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 AI가 짠 걸 검토할 땐 그 순서가 통째로 뒤집혀요.&lt;br /&gt;그럴듯하게 완성된 문장이 먼저 와 있고, 나는 그게 진짜인지 확인하려고 정의를 나중에 열어요.&lt;br /&gt;완성된 모양으로 떡 와 있으니까 '이 정도면 맞겠지' 소리가 자꾸 올라와요.&lt;br /&gt;그걸 한 줄마다 눌러야 했어요.&lt;br /&gt;어제 빈 화면에 직접 타이핑할 땐 누를 게 없었거든요.&lt;br /&gt;틀린 문장이 아예 거기 없었으니까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가이드를 다 보는 데 한참 걸렸어요.&lt;br /&gt;한 개도 못 살렸어요.&lt;br /&gt;전부 처음부터 다시 쓰는 게 빨랐을 정도로요.&lt;br /&gt;어제 손으로 짠 게 하나에 십 몇 분이었으니까, 머릿속으로 곱해보다 말았어요.&lt;br /&gt;곱해봤자 기분만 나빠지는 계산이었거든요.&lt;br /&gt;새벽 한 시쯤, 내가 이걸 왜 한 줄씩 손가락으로 짚어가며 대조하고 앉아 있나, 짜증이 확 올라왔어요.&lt;br /&gt;손가락은 계속 화면 위 글자를 짚고 있는데 머리는 딴 데 가 있었어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;빨라 보이는 쪽만 어딘가 적혀요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웃긴 건, 그날 숫자로만 따지면 빠른 밤이었다는 거예요.&lt;br /&gt;한 시간 만에 가이드 여러 개가 나왔으니까요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 그 한 시간 뒤에 붙은 시간은 어디에도 안 남아요.&lt;br /&gt;'AI가 가이드 만듦'은 채팅 기록에든 어디든 남는데, '사람이 그거 한 줄씩 대보느라 한참 쓰고 한 개도 못 건짐'은 아무 데도 안 남거든요.&lt;br /&gt;그래서 며칠 뒤에 비슷한 일이 또 오면, 나도 모르게 또 AI한테 시켜요.&lt;br /&gt;앞쪽 한 시간만 기억에 남아 있으니까요.&lt;br /&gt;그 밤에 내가 손가락으로 짚던 시간은 그새 어디로 새고 없어요.&lt;br /&gt;그게 좀 약 올라요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;위치는 잘 짚어요. 그게 더 헷갈려요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그날 이후로 가이드를 받으면 '어느 파일'은 믿고 '이렇게 생겼다'는 안 믿기로 했어요.&lt;br /&gt;위치는 잘 짚더라고요.&lt;br /&gt;내용을 채울 때만 관례로 메우고요.&lt;br /&gt;그렇게 갈라서 보니까 검토가 조금 빨라지긴 했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 아직도 모르겠는 게, 어떻게 위치는 정확히 맞히면서 그 안에 들어갈 이름은 그렇게 자신 있게 지어내는지예요.&lt;br /&gt;둘 다 같은 코드 안에 있잖아요.&lt;br /&gt;같은 파일을 봤을 텐데 한 줄은 옮기고 한 줄은 지어내요.&lt;br /&gt;어디까지 읽었길래 그게 갈리는지, 며칠 들여다봤는데 안 잡혀요.&lt;br /&gt;같은 종류에서 또 그럴 줄 알았는데 안 그러기도 하고, 안 그럴 줄 알았는데 그러기도 하고.&lt;br /&gt;패턴이라고 부를 만한 게 안 생겨요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도 가이드 네 개가 와 있어요.&lt;br /&gt;어디서부터 안 믿어야 할지를 아직 못 정해서, 일단 첫 줄을 손가락으로 짚었어요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>ai-collaboration</category>
      <category>code-review</category>
      <category>verification-habit</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/184</guid>
      <comments>https://datacook.tistory.com/184#entry184comment</comments>
      <pubDate>Wed, 1 Jul 2026 21:00:49 +0900</pubDate>
    </item>
    <item>
      <title>build()는 명령이 아니라 현재 상태의 선언입니다</title>
      <link>https://datacook.tistory.com/274</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-flutter-b-build-contract.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PXT2s/dJMb9970mHS/SFZmbsEWAY8COL5jkUR58k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PXT2s/dJMb9970mHS/SFZmbsEWAY8COL5jkUR58k/img.png&quot; data-alt=&quot;Build Contract는 정의보다 Flutter에서 깨지는 모양으로 이해하는 편이 빠릅니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PXT2s/dJMb9970mHS/SFZmbsEWAY8COL5jkUR58k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPXT2s%2FdJMb9970mHS%2FSFZmbsEWAY8COL5jkUR58k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;Build Contract 개념을 Flutter 실패 모양과 검증 기준으로 설명하는 다이어그램&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;01-flutter-b-build-contract.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Build Contract는 정의보다 Flutter에서 깨지는 모양으로 이해하는 편이 빠릅니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;build()&lt;/code&gt;는 화면을 만드는 명령처럼 보입니다.&lt;br /&gt;하지만 Flutter에서 build는 현재 상태를 위젯 트리로 표현하는 함수에 가깝습니다.&lt;br /&gt;같은 상태라면 여러 번 불려도 같은 설명을 내야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서 다루는 개념은 &lt;b&gt;Build Contract&lt;/b&gt;입니다.&lt;br /&gt;검색해서 들어온 독자에게 남길 것은 용어 정의가 아니라, Flutter에서 이 개념이 깨질 때 어떤 모양으로 보이는지입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Flutter에서는 이렇게 깨집니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 네트워크 요청, 파일 쓰기, provider invalidate 같은 일을 시작하면 호출 횟수에 따라 동작이 달라집니다.&lt;br /&gt;rebuild는 실패가 아니라 프레임워크의 정상 동작입니다.&lt;br /&gt;그래서 build 안의 부작용은 언젠가 반복 실행됩니다.&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;class UserPanel extends StatefulWidget {
  const UserPanel({super.key});
  @override
  State&amp;lt;UserPanel&amp;gt; createState() =&amp;gt; _UserPanelState();
}

class _UserPanelState extends State&amp;lt;UserPanel&amp;gt; {
  late final Future&amp;lt;User&amp;gt; userFuture;

  @override
  void initState() {
    super.initState();
    userFuture = fetchUser(); // build()가 아니라 수명 시작점에서 한 번 만듭니다.
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder&amp;lt;User&amp;gt;(future: userFuture, builder: renderUser);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;작은 어긋남은 화면에서 먼저 보입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 처음부터 큰 설계 이슈처럼 보이지 않습니다.&lt;br /&gt;탭을 다시 열었을 때 값이 돌아오거나, 화면 전환 직후 상태가 한 박자 늦거나, 실제 기기에서만 다른 반응이 나오는 정도로 시작합니다.&lt;br /&gt;사용자는 Build Contract라는 말을 보지 않습니다.&lt;br /&gt;눌렀는데 늦고, 돌아왔는데 값이 바뀌고, 방금 본 화면이 다음 순간 다른 얼굴을 하는 장면만 봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 처음에는 화면을 탓하기 쉽습니다.&lt;br /&gt;하지만 Flutter 화면은 눈앞의 위젯만으로 움직이지 않습니다.&lt;br /&gt;그 위젯이 읽는 값은 provider에서 왔을 수 있고, route가 바뀌며 다시 만들어졌을 수 있고, platform event나 async callback이 늦게 들어왔을 수 있습니다.&lt;br /&gt;화면을 구성하는 코드는 짧아도 화면에 도착하기까지 지나온 경로는 길 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 작은 어긋남을 그냥 넘기면 나중에 더 비싼 문제가 됩니다.&lt;br /&gt;한 화면에서만 보이던 증상이 탭 구조, nested navigation, refresh, background 복귀를 만나면서 다른 모양으로 퍼집니다.&lt;br /&gt;그때 필요한 것은 &amp;ldquo;Flutter가 이상하다&amp;rdquo;는 말이 아니라 어느 경계가 사용자의 손보다 늦게 움직였는지 보는 눈입니다.&lt;br /&gt;이 눈이 있어야 같은 냄새가 다른 위젯에서 나와도 당황하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 디버깅 순서도 달라집니다.&lt;br /&gt;먼저 화면에서 보이는 현상을 그대로 둔 다음, 그 현상이 사용자의 입력 직후인지, 다음 frame 뒤인지, route를 떠난 뒤인지 나눕니다.&lt;br /&gt;같은 늦음이라도 위치가 다르면 원인이 다릅니다.&lt;br /&gt;이 구분을 하지 않으면 작은 수정이 큰 리팩터링으로 번지고, 결국 무엇을 고쳤는지도 흐려집니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원인은 위젯 밖 경계에서 커집니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Build Contract 같은 주제는 한 줄짜리 코드 문제처럼 보일 때가 많습니다.&lt;br /&gt;하지만 실제 원인은 build 타이밍, layout 비용, 상태 소유자, native plugin, network 응답 같은 경계를 지나가며 커집니다.&lt;br /&gt;처음 실행에서는 맞았는데 뒤로 갔다 오면 달라지거나, debug에서는 멀쩡한데 release에서 흔들리거나, 빠르게 탭을 넘길 때만 꼬이는 이유가 여기에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계에서는 답을 급하게 내리지 않는 편이 낫습니다.&lt;br /&gt;먼저 사용자가 본 증상과 코드가 바뀐 지점을 나란히 둡니다.&lt;br /&gt;그 다음 어느 경계에서 시간이 어긋났는지, 값의 주인이 둘이 되었는지, 화면보다 늦게 도착한 이벤트가 있는지를 봅니다.&lt;br /&gt;이런 순서로 보면 정답이 늦게 나오는 것 같지만, 실제로는 헛수정을 줄입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 화면이 늦게 바뀐다고 해서 바로 &lt;code&gt;setState&lt;/code&gt; 위치만 바꾸면 원인을 놓칠 수 있습니다.&lt;br /&gt;이미지 decode가 끝나기 전인지, provider가 dispose된 뒤인지, route가 새 인스턴스를 만든 뒤인지가 다 다릅니다.&lt;br /&gt;같은 &amp;ldquo;늦다&amp;rdquo;라도 원인은 다르고, 원인이 다르면 손댈 위치도 달라집니다.&lt;br /&gt;독자가 검색으로 들어왔을 때 필요한 것은 바로 이 구분입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 코드 예시는 짧아도 설명은 충분해야 합니다.&lt;br /&gt;&lt;code&gt;setState&lt;/code&gt;, &lt;code&gt;context.mounted&lt;/code&gt;, &lt;code&gt;precacheImage&lt;/code&gt;, provider 수명 같은 도구는 각각 자기 자리가 있습니다.&lt;br /&gt;도구 이름만 외우면 다음 버그에서 다시 흔들리지만, 도구가 들어가는 경계를 기억하면 다른 화면에서도 같은 판단을 반복할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;고칠 때는 가장 가까운 경계만 움직입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정은 한 번에 크게 하지 않는 편이 낫습니다.&lt;br /&gt;화면이 어긋났다고 상태 소유자, build 타이밍, navigation, cache를 동시에 바꾸면 결과가 좋아져도 왜 좋아졌는지 남지 않습니다.&lt;br /&gt;먼저 가장 가까운 경계 하나만 고릅니다.&lt;br /&gt;값을 쓰는 쪽이 둘이면 하나로 줄이고, build 안에서 일이 시작되면 생명주기 바깥으로 빼고, platform 이벤트가 늦으면 기다리는 위치를 분리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 필요한 흔적은 거창하지 않습니다.&lt;br /&gt;작은 widget test 하나, 전후 화면 캡처 하나, 로그 한 줄이면 충분할 때가 많습니다.&lt;br /&gt;다만 그 흔적은 무엇이 달라졌는지를 말해야 합니다.&lt;br /&gt;다음 작업자가 코드를 열었을 때 &amp;ldquo;왜 이렇게 했지&amp;rdquo;가 아니라 &amp;ldquo;이 경계를 줄였구나&amp;rdquo;라고 읽을 수 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나는 손대지 않은 부분을 의식적으로 남기는 일입니다.&lt;br /&gt;Flutter에서는 작은 수정이 주변 위젯의 rebuild, focus, gesture, scroll 상태까지 건드릴 수 있습니다.&lt;br /&gt;그래서 한 번의 수정이 넓게 퍼졌다면 그 자체로 다시 좁혀야 합니다.&lt;br /&gt;고친 줄보다 건드리지 않은 경계가 분명할수록 나중에 되돌리기도 쉽고, 다른 화면에 옮길 때도 덜 위험합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;다음 화면에서 같은 냄새를 맡게 됩니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에 남아야 하는 것은 요약문이 아니라 다음 작업에서 바로 쓰는 감각입니다.&lt;br /&gt;비슷한 화면이 다시 흔들릴 때 제목을 외우지 않아도 됩니다.&lt;br /&gt;사용자의 손, frame, 상태 소유자, 외부 이벤트가 어떤 순서로 만나는지 다시 그려보면 됩니다.&lt;br /&gt;그 순서가 보이면 Flutter의 복잡함은 사라지지 않아도 다루는 속도는 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 결말은 질문표나 보고 문장으로 닫지 않습니다.&lt;br /&gt;무엇을 했다는 말보다 다음에 어디를 먼저 볼지가 남아야 합니다.&lt;br /&gt;같은 종류의 버그를 더 빨리 알아보고, 한 번에 한 경계만 고치는 쪽으로 손이 움직이면 충분합니다.&lt;br /&gt;짧게 말해도 되는 부분과 길게 남겨야 하는 부분을 구분하는 감각도 여기서 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이 주제는 위젯 하나를 예쁘게 고치는 문제가 아닙니다.&lt;br /&gt;화면이 흔들릴 때 보이는 증상 뒤에 있는 순서를 읽는 문제입니다.&lt;br /&gt;그 순서를 읽기 시작하면 수정은 덜 요란해지고, 다음 화면에서 같은 문제가 나와도 다시 처음으로 돌아가지 않습니다.&lt;br /&gt;그 감각이 남으면 다음 수정에서 다시 처음으로 돌아가지 않습니다.&lt;br /&gt;다음 수정에서 손이 먼저 가야 할 곳을 떠올릴 수 있으면 충분합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 감각은 한 번에 생기지 않습니다.&lt;br /&gt;같은 종류의 화면 흔들림을 두세 번 겪고 나면, 코드보다 먼저 흐름을 그리게 됩니다.&lt;br /&gt;어느 값이 먼저 왔고, 어느 이벤트가 늦었고, 어느 위젯이 오래 살아남았는지 떠올리는 순간 수정의 크기가 줄어듭니다.&lt;br /&gt;그래서 결론을 빨리 닫기보다 그 장면을 충분히 남기는 쪽을 택합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원문 기준&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 기준: https://api.flutter.dev/flutter/widgets/State/build.html&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 본 날짜: 2026-07-01.&lt;br /&gt;발행 전에는 원문의 바뀐 표현만 한 번 더 봅니다.&lt;/p&gt;</description>
      <category>AI Agent/flutter</category>
      <category>BuildContract</category>
      <category>Flutter</category>
      <category>개발론</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/274</guid>
      <comments>https://datacook.tistory.com/274#entry274comment</comments>
      <pubDate>Wed, 1 Jul 2026 21:00:44 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 앱 생명주기는 화면보다 먼저 시작됩니다</title>
      <link>https://datacook.tistory.com/273</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-flutter-a-app-lifecycle.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4QuJo/dJMcaaToyfs/qWDzH3zRC2GX5Oi5AjTJKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4QuJo/dJMcaaToyfs/qWDzH3zRC2GX5Oi5AjTJKk/img.png&quot; data-alt=&quot;App Lifecycle는 정의보다 Flutter에서 깨지는 모양으로 이해하는 편이 빠릅니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4QuJo/dJMcaaToyfs/qWDzH3zRC2GX5Oi5AjTJKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4QuJo%2FdJMcaaToyfs%2FqWDzH3zRC2GX5Oi5AjTJKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;App Lifecycle 개념을 Flutter 실패 모양과 검증 기준으로 설명하는 다이어그램&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;01-flutter-a-app-lifecycle.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;App Lifecycle는 정의보다 Flutter에서 깨지는 모양으로 이해하는 편이 빠릅니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱이 켜진 뒤 첫 화면만 보면 생명주기를 놓칩니다.&lt;br /&gt;Flutter 앱은 화면이 그려지기 전에도 초기화, 권한 확인, 세션 복원, 플랫폼 이벤트를 지나갑니다.&lt;br /&gt;그래서 앱 시작 코드는 위젯 코드와 같은 속도로 움직이지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서 다루는 개념은 &lt;b&gt;App Lifecycle&lt;/b&gt;입니다.&lt;br /&gt;검색해서 들어온 독자에게 남길 것은 용어 정의가 아니라, Flutter에서 이 개념이 깨질 때 어떤 모양으로 보이는지입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Flutter에서는 이렇게 깨집니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 생명주기는 화면 전환이 아니라 프로세스와 플랫폼 상태의 변화입니다.&lt;br /&gt;resumed, inactive, paused 같은 상태가 바뀌는 동안 네트워크 요청이나 plugin 초기화가 겹치면 같은 화면 코드도 다른 결과를 냅니다.&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;class AppLifecycleLogger extends StatefulWidget {
  const AppLifecycleLogger({super.key});
  @override
  State&amp;lt;AppLifecycleLogger&amp;gt; createState() =&amp;gt; _AppLifecycleLoggerState();
}

class _AppLifecycleLoggerState extends State&amp;lt;AppLifecycleLogger&amp;gt;
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // 세션/권한/원격 설정처럼 resume 때 다시 볼 일을 여기에 분리합니다.
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;작은 어긋남은 화면에서 먼저 보입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 처음부터 큰 설계 이슈처럼 보이지 않습니다.&lt;br /&gt;탭을 다시 열었을 때 값이 돌아오거나, 화면 전환 직후 상태가 한 박자 늦거나, 실제 기기에서만 다른 반응이 나오는 정도로 시작합니다.&lt;br /&gt;사용자는 App Lifecycle라는 말을 보지 않습니다.&lt;br /&gt;눌렀는데 늦고, 돌아왔는데 값이 바뀌고, 방금 본 화면이 다음 순간 다른 얼굴을 하는 장면만 봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 처음에는 화면을 탓하기 쉽습니다.&lt;br /&gt;하지만 Flutter 화면은 눈앞의 위젯만으로 움직이지 않습니다.&lt;br /&gt;그 위젯이 읽는 값은 provider에서 왔을 수 있고, route가 바뀌며 다시 만들어졌을 수 있고, platform event나 async callback이 늦게 들어왔을 수 있습니다.&lt;br /&gt;화면을 구성하는 코드는 짧아도 화면에 도착하기까지 지나온 경로는 길 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 작은 어긋남을 그냥 넘기면 나중에 더 비싼 문제가 됩니다.&lt;br /&gt;한 화면에서만 보이던 증상이 탭 구조, nested navigation, refresh, background 복귀를 만나면서 다른 모양으로 퍼집니다.&lt;br /&gt;그때 필요한 것은 &amp;ldquo;Flutter가 이상하다&amp;rdquo;는 말이 아니라 어느 경계가 사용자의 손보다 늦게 움직였는지 보는 눈입니다.&lt;br /&gt;이 눈이 있어야 같은 냄새가 다른 위젯에서 나와도 당황하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 디버깅 순서도 달라집니다.&lt;br /&gt;먼저 화면에서 보이는 현상을 그대로 둔 다음, 그 현상이 사용자의 입력 직후인지, 다음 frame 뒤인지, route를 떠난 뒤인지 나눕니다.&lt;br /&gt;같은 늦음이라도 위치가 다르면 원인이 다릅니다.&lt;br /&gt;이 구분을 하지 않으면 작은 수정이 큰 리팩터링으로 번지고, 결국 무엇을 고쳤는지도 흐려집니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원인은 위젯 밖 경계에서 커집니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App Lifecycle 같은 주제는 한 줄짜리 코드 문제처럼 보일 때가 많습니다.&lt;br /&gt;하지만 실제 원인은 build 타이밍, layout 비용, 상태 소유자, native plugin, network 응답 같은 경계를 지나가며 커집니다.&lt;br /&gt;처음 실행에서는 맞았는데 뒤로 갔다 오면 달라지거나, debug에서는 멀쩡한데 release에서 흔들리거나, 빠르게 탭을 넘길 때만 꼬이는 이유가 여기에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계에서는 답을 급하게 내리지 않는 편이 낫습니다.&lt;br /&gt;먼저 사용자가 본 증상과 코드가 바뀐 지점을 나란히 둡니다.&lt;br /&gt;그 다음 어느 경계에서 시간이 어긋났는지, 값의 주인이 둘이 되었는지, 화면보다 늦게 도착한 이벤트가 있는지를 봅니다.&lt;br /&gt;이런 순서로 보면 정답이 늦게 나오는 것 같지만, 실제로는 헛수정을 줄입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 화면이 늦게 바뀐다고 해서 바로 &lt;code&gt;setState&lt;/code&gt; 위치만 바꾸면 원인을 놓칠 수 있습니다.&lt;br /&gt;이미지 decode가 끝나기 전인지, provider가 dispose된 뒤인지, route가 새 인스턴스를 만든 뒤인지가 다 다릅니다.&lt;br /&gt;같은 &amp;ldquo;늦다&amp;rdquo;라도 원인은 다르고, 원인이 다르면 손댈 위치도 달라집니다.&lt;br /&gt;독자가 검색으로 들어왔을 때 필요한 것은 바로 이 구분입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 코드 예시는 짧아도 설명은 충분해야 합니다.&lt;br /&gt;&lt;code&gt;setState&lt;/code&gt;, &lt;code&gt;context.mounted&lt;/code&gt;, &lt;code&gt;precacheImage&lt;/code&gt;, provider 수명 같은 도구는 각각 자기 자리가 있습니다.&lt;br /&gt;도구 이름만 외우면 다음 버그에서 다시 흔들리지만, 도구가 들어가는 경계를 기억하면 다른 화면에서도 같은 판단을 반복할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;고칠 때는 가장 가까운 경계만 움직입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정은 한 번에 크게 하지 않는 편이 낫습니다.&lt;br /&gt;화면이 어긋났다고 상태 소유자, build 타이밍, navigation, cache를 동시에 바꾸면 결과가 좋아져도 왜 좋아졌는지 남지 않습니다.&lt;br /&gt;먼저 가장 가까운 경계 하나만 고릅니다.&lt;br /&gt;값을 쓰는 쪽이 둘이면 하나로 줄이고, build 안에서 일이 시작되면 생명주기 바깥으로 빼고, platform 이벤트가 늦으면 기다리는 위치를 분리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 필요한 흔적은 거창하지 않습니다.&lt;br /&gt;작은 widget test 하나, 전후 화면 캡처 하나, 로그 한 줄이면 충분할 때가 많습니다.&lt;br /&gt;다만 그 흔적은 무엇이 달라졌는지를 말해야 합니다.&lt;br /&gt;다음 작업자가 코드를 열었을 때 &amp;ldquo;왜 이렇게 했지&amp;rdquo;가 아니라 &amp;ldquo;이 경계를 줄였구나&amp;rdquo;라고 읽을 수 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나는 손대지 않은 부분을 의식적으로 남기는 일입니다.&lt;br /&gt;Flutter에서는 작은 수정이 주변 위젯의 rebuild, focus, gesture, scroll 상태까지 건드릴 수 있습니다.&lt;br /&gt;그래서 한 번의 수정이 넓게 퍼졌다면 그 자체로 다시 좁혀야 합니다.&lt;br /&gt;고친 줄보다 건드리지 않은 경계가 분명할수록 나중에 되돌리기도 쉽고, 다른 화면에 옮길 때도 덜 위험합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;다음 화면에서 같은 냄새를 맡게 됩니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에 남아야 하는 것은 요약문이 아니라 다음 작업에서 바로 쓰는 감각입니다.&lt;br /&gt;비슷한 화면이 다시 흔들릴 때 제목을 외우지 않아도 됩니다.&lt;br /&gt;사용자의 손, frame, 상태 소유자, 외부 이벤트가 어떤 순서로 만나는지 다시 그려보면 됩니다.&lt;br /&gt;그 순서가 보이면 Flutter의 복잡함은 사라지지 않아도 다루는 속도는 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 결말은 질문표나 보고 문장으로 닫지 않습니다.&lt;br /&gt;무엇을 했다는 말보다 다음에 어디를 먼저 볼지가 남아야 합니다.&lt;br /&gt;같은 종류의 버그를 더 빨리 알아보고, 한 번에 한 경계만 고치는 쪽으로 손이 움직이면 충분합니다.&lt;br /&gt;짧게 말해도 되는 부분과 길게 남겨야 하는 부분을 구분하는 감각도 여기서 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이 주제는 위젯 하나를 예쁘게 고치는 문제가 아닙니다.&lt;br /&gt;화면이 흔들릴 때 보이는 증상 뒤에 있는 순서를 읽는 문제입니다.&lt;br /&gt;그 순서를 읽기 시작하면 수정은 덜 요란해지고, 다음 화면에서 같은 문제가 나와도 다시 처음으로 돌아가지 않습니다.&lt;br /&gt;그 감각이 남으면 다음 수정에서 다시 처음으로 돌아가지 않습니다.&lt;br /&gt;다음 수정에서 손이 먼저 가야 할 곳을 떠올릴 수 있으면 충분합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 감각은 한 번에 생기지 않습니다.&lt;br /&gt;같은 종류의 화면 흔들림을 두세 번 겪고 나면, 코드보다 먼저 흐름을 그리게 됩니다.&lt;br /&gt;어느 값이 먼저 왔고, 어느 이벤트가 늦었고, 어느 위젯이 오래 살아남았는지 떠올리는 순간 수정의 크기가 줄어듭니다.&lt;br /&gt;그래서 결론을 빨리 닫기보다 그 장면을 충분히 남기는 쪽을 택합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원문 기준&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 기준: https://api.flutter.dev/flutter/dart-ui/AppLifecycleState.html&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 본 날짜: 2026-07-01.&lt;br /&gt;발행 전에는 원문의 바뀐 표현만 한 번 더 봅니다.&lt;/p&gt;</description>
      <category>AI Agent/flutter</category>
      <category>applifecycle</category>
      <category>Flutter</category>
      <category>개발론</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/273</guid>
      <comments>https://datacook.tistory.com/273#entry273comment</comments>
      <pubDate>Wed, 1 Jul 2026 15:00:15 +0900</pubDate>
    </item>
    <item>
      <title>'다 등록했어요'라더니, 맨 아랫줄 하나만 설명이 비어 있었어요</title>
      <link>https://datacook.tistory.com/183</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;all-registered-except-last-row.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nYcXB/dJMcaaMC8td/rVWaLxw7XDxi2JkZlYnWXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nYcXB/dJMcaaMC8td/rVWaLxw7XDxi2JkZlYnWXK/img.png&quot; data-alt=&quot;맨 아랫줄 하나&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nYcXB/dJMcaaMC8td/rVWaLxw7XDxi2JkZlYnWXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnYcXB%2FdJMcaaMC8td%2FrVWaLxw7XDxi2JkZlYnWXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;맨 아랫줄 하나만 빈 손글씨 표 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;all-registered-except-last-row.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;맨 아랫줄 하나&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;이 줄은 뭐예요?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화면을 같이 보던 사람이 맨 아랫줄을 손가락으로 짚었어요.&lt;br /&gt;일곱 줄이 위에서부터 나란히 내려가는 화면이었고, 위의 여섯 줄에는 라벨 옆에 작은 ⓘ 아이콘이 붙어 있었어요.&lt;br /&gt;마우스를 올리면 그게 무슨 값인지 한 줄로 알려주는 거.&lt;br /&gt;근데 맨 아랫줄, 일곱 번째 줄만 그 아이콘이 없었어요.&lt;br /&gt;그 손가락 끝이 가리키는 자리가 미묘하게 허전하다는 걸, 저는 짚어주고 나서야 봤어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 그 화면을 이미 '끝난 일'로 분류해 둔 상태였거든요.&lt;br /&gt;30분 전쯤, 에이전트한테 &quot;이 항목들 설명 다 달아줘&quot;라고 시켰고, 돌아온 답은 &quot;일곱 개 항목 모두 설명을 등록했습니다&quot;였어요.&lt;br /&gt;일곱 개 모두.&lt;br /&gt;그 문장을 한 번 읽고, 저는 별 의심 없이 다음 일로 넘어갔어요.&lt;br /&gt;그 '모두'라는 단어가 그렇게 멀쩡하게 거짓이 될 수 있다는 걸 그때는 몰랐죠.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;여섯 개는 맞았어요. 그래서 더 안 봤어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 화면을 켰을 때, 위에서부터 ⓘ가 하나, 둘, 셋, 넷...&lt;br /&gt;줄을 따라 쭉 붙어 있는 걸 봤어요.&lt;br /&gt;솔직히 거기서 시선이 멈췄어요.&lt;br /&gt;위가 다 맞으면 아래도 맞겠거니, 하고요.&lt;br /&gt;손가락으로 따라 내려가다가 네 번째쯤에서 그냥 '됐네' 하고 스크롤을 닫았어요.&lt;br /&gt;끝줄까지 눈으로 끌고 내려갈 생각을 안 했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 좀 웃긴 게, 만약 일곱 개가 다 비어 있었으면 저는 바로 알아챘을 거예요.&lt;br /&gt;화면이 텅 비어 보이니까.&lt;br /&gt;근데 여섯 개가 멀쩡히 채워져 있으니까 오히려 '됐네' 하고 넘어간 거죠.&lt;br /&gt;거의 다 맞은 게, 다 맞은 것처럼 보이게 했어요.&lt;br /&gt;빈 화면보다 거의 채워진 화면이 더 위험하다는 걸 그날 처음 알았어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 항목 하나의 설명은, 화면에 보이는 라벨이나 숫자랑은 다른 곳에 따로 등록하게 돼 있었어요.&lt;br /&gt;라벨이랑 데이터는 일곱 개 다 들어갔어요.&lt;br /&gt;그게 화면에 바로 뜨니까.&lt;br /&gt;근데 설명은 사용자한테 직접 안 보이는 자리라, 일곱 번째 거 하나만 그 등록이 빠졌어요.&lt;br /&gt;화면은 멀쩡히 떴고, 빨간 글씨 하나 없었고, 그래서 머지까지 됐어요.&lt;br /&gt;어디에도 '여기 비었음'이라고 알려주는 게 없었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 저 ⓘ가 빠진 설명을 정확히 가리키는 표시인 줄 알았어요.&lt;br /&gt;아이콘이 없으니 설명도 없는 거겠거니.&lt;br /&gt;근데 들여다보니 그것도 아니더라고요.&lt;br /&gt;그 아이콘은 옆에 다른 게 채워지면 같이 뜨는 거라, 설명이 있든 없든 원래는 떠 있어야 정상이었어요.&lt;br /&gt;그게 일곱 번째에서만 같이 안 뜬 건, 빠진 설명 때문인지 그 줄 자체가 어딘가 덜 만들어진 건지 저도 그 자리에선 구분이 안 갔어요.&lt;br /&gt;짚어준 사람이 없었으면, 그 아이콘 하나 없는 것조차 저는 그냥 못 보고 지나갔을 거예요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;일곱 번째라는 게 묘하게 거슬렸어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;손가락이 그 줄을 짚는 순간, 제일 먼저 든 생각은 '아, 저거 안 했나?'가 아니라 '분명 다 했다고 했는데'였어요.&lt;br /&gt;보고서를 다시 열었어요.&lt;br /&gt;스크롤을 위로 올려서 그 줄을 찾았어요.&lt;br /&gt;&quot;일곱 개 항목 모두.&quot; 모두라는 단어가 거기 그대로 박혀 있었어요.&lt;br /&gt;30분 전에 읽고 믿었던 그 문장이, 똑같은 모양으로요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화가 나기보다는 좀 멍했어요.&lt;br /&gt;거짓말을 한 것도 아니거든요.&lt;br /&gt;여섯 개는 진짜로 했으니까.&lt;br /&gt;딱 하나, 끝에 있는 하나만 손에서 미끄러진 거예요.&lt;br /&gt;누구한테 따질 데도 없는, 그런 종류의 빈칸이었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 하필 마지막 거였는지가 궁금해서 그제야 그게 어떻게 돌아갔는지 들여다봤는데, 솔직히 끝까지 깔끔하게 따라가진 못했어요.&lt;br /&gt;라벨이랑 데이터는 일곱 개를 한 번에 밀어넣는 쪽이고, 설명은 거기 묶여 있지 않고 따로 한 줄씩 도는 쪽이더라고요.&lt;br /&gt;그 따로 도는 데서 끝 무렵 한 군데가 비었어요.&lt;br /&gt;다른 줄들 응답엔 다 있던 마무리 한 줄이, 일곱 번째 거에만 없었어요.&lt;br /&gt;그런데도 등록 다 하고 한꺼번에 세는 마지막 숫자에선 일곱으로 잡혔고, 거기서 &quot;일곱 개 모두&quot;가 나온 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;끝에서 한 번 헛돈 건지, 그 줄 응답만 그냥 안 온 건지, 거기까지는 저도 확신이 안 서요.&lt;br /&gt;한참 들여다보다가 화면을 두 개 띄워놓고 줄 단위로 맞춰봤는데, 비는 자리가 매번 끝줄일 거란 보장도 없어 보였어요.&lt;br /&gt;그 자리에서 더 파면 알았을 수도 있는데, 빠진 거 채우는 게 먼저라 그냥 닫았어요.&lt;br /&gt;원인을 모른 채로 닫는 게 제일 찜찜했지만요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그래서 옛날 거 몇 개를 다시 열어봤어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빠진 걸 채우는 건 1분도 안 걸렸어요.&lt;br /&gt;정작 시간을 잡아먹은 건 그 뒤에 든 생각이었어요.&lt;br /&gt;지난주에 비슷하게 &quot;다 했습니다&quot; 받고 넘어간 것들은?&lt;br /&gt;그것들도 어딘가 하나씩 비어 있는 거 아닌가?&lt;br /&gt;한 번 의심이 들기 시작하니까 멀쩡해 보이는 화면들이 다 수상해졌어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그날 저녁에 비슷한 화면 세 개를 도로 켜봤어요.&lt;br /&gt;두 개는 멀쩡했어요.&lt;br /&gt;한 개는 끝줄은 채워져 있는데 그 위쪽 어딘가 한 줄이 비어 있었어요.&lt;br /&gt;처음엔 끝줄만 다시 보면 되겠거니 했는데, 이번엔 끝줄이 아니라 가운데였어요.&lt;br /&gt;끝줄에 ⓘ가 떠 있는 걸 보고 '여긴 됐네' 하고 닫을 뻔했어요.&lt;br /&gt;그래서 어디가 빈 건지 한눈에 안 잡혀서, 그냥 줄마다 하나하나 다 눌러봤어요.&lt;br /&gt;어떤 패턴이 있어서 그쪽만 보면 되는 게 아니라, 그냥 매번 다른 데가 빠져 있었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 이런 작업을 시키고 &quot;다 했습니다&quot;를 받으면 일단 줄을 처음부터 끝까지 한 번 다 눌러봐요.&lt;br /&gt;효율 같은 건 없어요.&lt;br /&gt;일곱 개면 일곱 번 누르는 거예요.&lt;br /&gt;&quot;모두&quot;라는 단어를 받았는데 제가 그 모두를 다시 한 줄씩 세고 있는 게 우습긴 한데, 그렇게 안 하면 또 어디 하나가 비어 있을 것 같아서요.&lt;br /&gt;어제 채워 넣은 그 일곱 번째 줄은 지금은 옆에 ⓘ가 떠 있어요.&lt;br /&gt;그래서 더 봐야 하나 말아야 하나, 아직 손이 거기서 머뭇거려요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>ai-agent</category>
      <category>debugging</category>
      <category>verification</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/183</guid>
      <comments>https://datacook.tistory.com/183#entry183comment</comments>
      <pubDate>Wed, 1 Jul 2026 09:00:30 +0900</pubDate>
    </item>
    <item>
      <title>같은 일을 시켰는데, 한 도구는 빨간 줄 열 개, 다른 도구는 0이었어요</title>
      <link>https://datacook.tistory.com/182</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;same-task-one-tool-ten-errors-other-zero.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLjjuv/dJMcahSswbj/0OQUkX1vLEOkWSLD42CkiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLjjuv/dJMcahSswbj/0OQUkX1vLEOkWSLD42CkiK/img.png&quot; data-alt=&quot;같은 일, 갈린 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLjjuv/dJMcahSswbj/0OQUkX1vLEOkWSLD42CkiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLjjuv%2FdJMcahSswbj%2F0OQUkX1vLEOkWSLD42CkiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;나란히 놓인 머그 두 개, 하나는 쏟아지고 하나는 멀쩡한 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;same-task-one-tool-ten-errors-other-zero.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;같은 일, 갈린 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 하나의 인자를 바꾸는, 별거 아닌 작업이었어요.&lt;br /&gt;호출하는 데가 여기저기 흩어져 있어서 손으로 일일이 고치긴 귀찮고, 그래서 코딩 도구한테 통째로 맡겼죠.&lt;br /&gt;시그니처 바꾸고, 부르는 데도 다 맞춰줘, 하고요.&lt;br /&gt;이런 건 도구가 제일 잘하는 종류라고 생각했거든요.&lt;br /&gt;단순 반복, 여러 군데, 패턴 똑같은 거.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;돌아온 걸 보고 빌드를 눌렀더니 빨간 줄이 좌르륵 떴어요.&lt;br /&gt;열 개.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 내가 뭘 잘못 시켰나 했어요.&lt;br /&gt;프롬프트를 너무 짧게 줬나, 파일 범위를 안 짚어줬나.&lt;br /&gt;로그를 위에서부터 천천히 읽는데, 한 줄 빼고는 다 같은 결이더라고요.&lt;br /&gt;&quot;그런 메서드 없음&quot;, &quot;그런 정의 없음&quot;, &quot;그런 메서드 없음&quot;...&lt;br /&gt;거의 복붙한 것처럼 같은 문장이 같은 모양으로 반복되는데, 딱 한 줄만 타입이 안 맞는다는 다른 에러였어요.&lt;br /&gt;그 한 줄 때문에 한참 헤맸죠.&lt;br /&gt;같이 깨진 줄 알고.&lt;br /&gt;그 줄을 붙들고 한 십 분을 끙끙댔어요.&lt;br /&gt;알고 보니 그건 도구가 손대기 전부터 원래 거기 있던 거였고, 도구가 새로 낸 건 아홉 개였어요.&lt;br /&gt;엉뚱한 줄을 범인으로 의심하느라 진짜 원인은 한참 뒤에 봤어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;짜증이 나기 전에 좀 무서웠어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 짜증보다 먼저 든 건 작은 불안이었어요.&lt;br /&gt;이걸 그냥 머지했으면 어쩔 뻔했나 싶은.&lt;br /&gt;호출처만 보면 멀쩡해 보이거든요.&lt;br /&gt;변경 라인 수도 그럴듯하고, diff도 깔끔하고, 색깔도 알록달록 잘 들어와 있고요.&lt;br /&gt;빌드를 안 돌렸으면 &quot;오, 잘했네&quot; 하고 넘어갈 뻔한 모양새였어요.&lt;br /&gt;화면만 봐선 흠잡을 데가 없었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웃긴 건, 도구가 일을 아예 안 한 게 아니라는 거예요.&lt;br /&gt;부르는 쪽은 새 인자에 맞춰 싹 고쳐놨어요.&lt;br /&gt;거기까진 정확했어요.&lt;br /&gt;그런데 정작 그 인자를 받는 정의 본체엔 손도 안 댄 거죠.&lt;br /&gt;호출만 바꾸고 정의는 옛날 그대로 둔 거예요.&lt;br /&gt;그러니 컴파일러가 &quot;이런 건 만든 적 없는데요?&quot; 하고 멈춘 거고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞은 데가 있으니까 더 헷갈렸어요.&lt;br /&gt;다 틀렸으면 그냥 통째로 버렸을 텐데, 절반은 멀쩡하니까 어디서부터 의심해야 할지 손이 안 잡히더라고요.&lt;br /&gt;멀쩡한 코드랑 깨진 코드가 같은 파일에 섞여 있으니까, 눈이 자꾸 멀쩡한 데서 미끄러지고.&lt;br /&gt;반쯤 포기하고 빨간 줄을 하나씩 손으로 메우기 시작했죠.&lt;br /&gt;정의를 새로 쓰고, 본체를 채우고, 한 번에 한 줄씩.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그런데 다음 묶음에서 도구를 바꿔봤어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;남은 작업이 비슷한 게 또 한 묶음 있었어요.&lt;br /&gt;손으로 다 메우긴 양이 많고, 그래서 이번엔 다른 도구한테 똑같은 종류로 시켰어요.&lt;br /&gt;큰 기대는 없었고요.&lt;br /&gt;어차피 둘 다 'AI 코딩 도구'잖아요.&lt;br /&gt;거기서 거기겠지.&lt;br /&gt;솔직히 또 빨간 줄 메울 각오를 하고 빌드를 눌렀어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 0.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;손이 잠깐 멈췄어요.&lt;br /&gt;다시 빌드를 눌러봤어요.&lt;br /&gt;그래도 0.&lt;br /&gt;여덟 군데를 바꿔야 했는데 정의도 만들고, 메서드도 채우고, 부르는 데까지 같이 닫아놨어요.&lt;br /&gt;새로 붙인 테스트 하나가 처음엔 빨갰는데, 들여다보니 그건 도구 잘못이 아니라 내가 기댓값을 옛날 거로 적어둔 거였어요.&lt;br /&gt;그 줄 고치니까 초록.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 종류의 일을, 같은 코드베이스에서, 프롬프트도 거의 똑같이 줬는데 한쪽은 손으로 아홉 개를 메웠고 한쪽은 빌드 한 방에 끝났어요.&lt;br /&gt;바뀐 건 도구 이름 하나뿐이었어요.&lt;br /&gt;모니터를 한참 봤어요.&lt;br /&gt;'AI가 잘하네/못하네'로 묶어서 생각하던 게 통째로 무너지는 기분이라.&lt;br /&gt;같은 'AI'라는 말 안에 이렇게 다른 두 개가 들어 있는데, 나는 그걸 한 덩어리로 부르고 있었던 거예요.&lt;br /&gt;잘한 도구를 칭찬하고 싶은 마음도 아니고, 못한 도구를 욕하고 싶은 마음도 아니고, 그냥 내가 뭘 모르고 있었구나 하는 게 먼저 왔어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그래서 둘을 한 줄로 갈라놨어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그날 메모장에 규칙 비슷한 걸 적었어요.&lt;br /&gt;거창한 건 아니고요.&lt;br /&gt;여러 파일 걸쳐서 시그니처 맞춰야 하는, 일관성이 생명인 일은 이쪽 도구.&lt;br /&gt;단일 파일에서 확신 있게 빠르게 쳐내는 일은 저쪽 도구.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 적어놓고도 이게 진짜인지 한 번 더 의심했어요.&lt;br /&gt;표본 두 번 가지고 도구를 줄 세운 거잖아요.&lt;br /&gt;다음 날 같은 종류를 일부러 첫 번째 도구한테 또 줘봤어요.&lt;br /&gt;이번엔 정의까지 잘 닫아오더라고요.&lt;br /&gt;그래서 '못 하는 도구'는 아니었던 거예요.&lt;br /&gt;어제 그건 그냥 운이 나빴던 건지, 아니면 내가 프롬프트를 애매하게 준 건지.&lt;br /&gt;거기까진 아직 모르겠어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어제도 한 번 잘못 보냈다가 빨간 줄을 또 봤어요.&lt;br /&gt;그때 로그를 또 위에서부터 내리는데, 똑같은 문장이 또 줄줄이 같은 자리에 박혀 있는 거예요.&lt;br /&gt;같은 말, 같은 말, 같은 말.&lt;br /&gt;마우스 휠을 굴리는 손이 어느 순간 멍하니 그냥 내려가고 있었어요, 읽지도 않고.&lt;br /&gt;메모장 규칙을 띄워놓고도 이번 작업이 '일관성' 칸인지 '빠르게' 칸인지, 화면 앞에서 커서만 깜빡이고 있었어요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>ai-coding</category>
      <category>experience-story</category>
      <category>tool-routing</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/182</guid>
      <comments>https://datacook.tistory.com/182#entry182comment</comments>
      <pubDate>Tue, 30 Jun 2026 21:00:11 +0900</pubDate>
    </item>
    <item>
      <title>숫자 하나만 바꿔달라고 했어요. 멀쩡한 옆자리까지 싹 손봐놨더라고요</title>
      <link>https://datacook.tistory.com/181</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;one-line-change-came-back-as-41.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bolguM/dJMcaff8ST0/tcdbOoSu1qWWJkK66jNlS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bolguM/dJMcaff8ST0/tcdbOoSu1qWWJkK66jNlS0/img.png&quot; data-alt=&quot;한 줄이 마흔한 줄로&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bolguM/dJMcaff8ST0/tcdbOoSu1qWWJkK66jNlS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbolguM%2FdJMcaff8ST0%2FtcdbOoSu1qWWJkK66jNlS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;한 줄 고치려다 잔뜩 그어지고 다시 쓴 노트 페이지 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;one-line-change-came-back-as-41.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한 줄이 마흔한 줄로&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자 하나만 바꿔달라고 했어요.&lt;br /&gt;어떤 값이 3이어야 하는데 2로 들어가 있어서, 그 한 줄만.&lt;br /&gt;정말 그게 다였어요.&lt;br /&gt;화면에 띄워놓고 손가락으로 그 줄을 짚어가면서, 여기 2를 3으로, 끝, 하고 보냈거든요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;돌아온 diff를 보는데 변경 줄이 한 줄이 아니었어요.&lt;br /&gt;스크롤바가 평소보다 길길래 잘못 봤나 했는데, 위로 올려보니 41줄이 바뀌어 있더라고요.&lt;br /&gt;내가 부탁한 그 한 줄은 정확히 고쳐져 있었고, 그 위아래로 손도 안 댄 멀쩡한 코드가 통째로 정렬이 다시 돼 있었어요.&lt;br /&gt;들여쓰기 맞추고, 줄 순서 바꾸고, 짧게 쓸 수 있는 건 짧게 줄이고.&lt;br /&gt;빨간 줄 초록 줄이 화면을 꽉 채우는데, &quot;겸사겸사 정리해뒀어요&quot; 같은 느낌으로.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;diff를 닫고, 그냥 머지했어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 부끄러운 부분인데요.&lt;br /&gt;그 41줄을 한 줄씩 안 읽었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 좀 읽으려고 했어요.&lt;br /&gt;위에서 두세 줄 눈으로 훑다가, 어차피 다 포맷만 만진 거잖아, 싶어서 손을 놨거든요.&lt;br /&gt;내가 시킨 한 줄이 맞게 들어간 것만 확인하고 나머지는 통과.&lt;br /&gt;그날 비슷한 자잘한 수정이 대여섯 개 밀려 있었고, 정렬 좀 바뀐 거 가지고 41줄을 정독하긴 좀 그랬어요.&lt;br /&gt;솔직히 귀찮았어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트도 초록이었어요.&lt;br /&gt;그러니까 더 안 봤죠.&lt;br /&gt;초록불 보면 마음이 그냥 놓이거든요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사흘 뒤에, 안 건드린 데가 틀어졌어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 내가 부탁한 줄에서 안 났어요.&lt;br /&gt;거기서 다섯 칸쯤 위, 내가 손도 안 댄 자리에서 났어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;증상은 작았어요.&lt;br /&gt;이름 칸을 비워두고 보내면 막혀야 하는 게, 그날부터 그냥 통과했어요.&lt;br /&gt;빈 채로.&lt;br /&gt;다른 입력은 다 멀쩡했고요.&lt;br /&gt;딱 그것만 새더라고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 그 줄을 의심도 안 했어요.&lt;br /&gt;내가 안 건드린 데니까.&lt;br /&gt;당연히 환경 문제겠거니 했어요.&lt;br /&gt;캐시가 꼬였나, 다른 데서 들어온 데이터가 더러운가, 한 30분은 딴 데를 팠어요.&lt;br /&gt;로그를 위아래로 굴리고, 같은 요청을 몇 번이나 다시 쏴보고.&lt;br /&gt;그런데 아무리 봐도 들어오는 값은 멀쩡하더라고요.&lt;br /&gt;한참 헤매다가 답답해서, 그냥 내가 직접 빈 칸 하나 넣고 보내봤어요.&lt;br /&gt;별 기대 없이요.&lt;br /&gt;근데 그게 그대로 통과돼서 화면 너머로 쑥 넘어가는 걸 보고, 등이 좀 서늘했어요.&lt;br /&gt;아 여기였구나.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기서부터 그 다섯 칸 위를 노려봤어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;친절이 두 줄을 한 줄로 묶었더라고요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 그 자리엔 막아주는 게 따로 두 줄로 걸려 있었어요.&lt;br /&gt;한 줄이 비었나 보고, 그 밑에 한 줄이 또 뭔가를 봤거든요.&lt;br /&gt;정확히는 나도 지금 다시 설명하라면 좀 더듬어요.&lt;br /&gt;그날 화면 보면서도 한참 노려보다 겨우 이해한 거라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 AI가 그 두 줄을 한 줄로 깔끔하게 묶어놨는데, 묶으니까 앞이 통과돼버리면 뒤는 아예 안 보고 지나가더라고요.&lt;br /&gt;평소 입력엔 둘 다 걸려서 티가 안 났어요.&lt;br /&gt;빈 값일 때만 앞이 먼저 빠져나가면서 뒤를 건너뛰었고요.&lt;br /&gt;그래서 사흘 전까지 멀쩡했던 게 사흘 뒤부터 그 한 경우에만 샜어요.&lt;br /&gt;묶은 자체가 틀린 것도 아니었어요.&lt;br /&gt;평소엔 정말 똑같이 돌거든요.&lt;br /&gt;그 한 경우만 빼고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인을 찾고 나서가 좀 허무했어요.&lt;br /&gt;내가 부탁한 건 멀쩡했고, 부탁 안 한 친절이 부순 거였으니까.&lt;br /&gt;화면을 한참 들여다보다가, 내가 정독을 안 한 그 사흘이 자꾸 떠올랐어요.&lt;br /&gt;그 41줄 어딘가에 이게 들어 있었던 거잖아요.&lt;br /&gt;스크롤만 한 번 더 내려봤어도 보였을 자리에.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정렬은 진짜 더 깔끔했어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따로 떼어놓고 보면 그 41줄, 전보다 읽기 좋아요.&lt;br /&gt;줄도 짧고, 조건도 한눈에 들어오고.&lt;br /&gt;누가 봐도 전보다 정리된 코드예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 뒤로 한 줄 고쳐달라고 할 때 한마디를 붙여요.&lt;br /&gt;&quot;딱 그 줄만, 주변은 그대로 둬.&quot; 근데 이게 또 매번 먹히진 않아요.&lt;br /&gt;어떨 땐 또 옆을 정리해놓고, 어떨 땐 안 그러고.&lt;br /&gt;왜 어떤 날은 듣고 어떤 날은 안 듣는지, 그건 아직도 잘 모르겠어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 요즘은 한 줄 부탁했는데 diff가 한 줄로 안 돌아오면 일단 멈칫해요.&lt;br /&gt;멈칫하고도 또 귀찮아서 대충 넘길 때가 솔직히 있고요.&lt;br /&gt;그 빈 값 건은 운이 좋았어요.&lt;br /&gt;누가 막 쓰기 전에 내가 먼저 찔러봐서 잡힌 거지, 안 그랬으면 그게 언제 어디서 다시 샜을지 나도 잘 모르겠어요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>ai협업</category>
      <category>diff</category>
      <category>코드리뷰</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/181</guid>
      <comments>https://datacook.tistory.com/181#entry181comment</comments>
      <pubDate>Tue, 30 Jun 2026 09:00:53 +0900</pubDate>
    </item>
    <item>
      <title>AI가 일을 대신하니, 내 실력이 어디서 느나 싶었어요</title>
      <link>https://datacook.tistory.com/180</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;where-does-my-skill-grow.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z7OSV/dJMcaff8STr/QJthDA0zKMKxBaOlsHLlL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z7OSV/dJMcaff8STr/QJthDA0zKMKxBaOlsHLlL0/img.png&quot; data-alt=&quot;실력은 어디서 느나&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z7OSV/dJMcaff8STr/QJthDA0zKMKxBaOlsHLlL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz7OSV%2FdJMcaff8STr%2FQJthDA0zKMKxBaOlsHLlL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;창가 화분과 작은 물뿌리개 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;where-does-my-skill-grow.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실력은 어디서 느나&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옆자리 친구가 의자째 돌아서 화면을 제 쪽으로 들이밀었어요.&lt;br /&gt;두 군데서 같은 사람을 서로 다르게 식별하던 자리에서 숫자가 엉뚱하게 붙던 버그였어요.&lt;br /&gt;한쪽 코드랑 다른 쪽 코드가 같은 사람을 가리킨다고 친 자리에서, 숫자가 조용히 새고 있었던 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 그걸 한 3초쯤 봤어요.&lt;br /&gt;화면 위쪽이랑 아래쪽을 한 번씩 훑고 나서 &quot;아, 저거 두 군데서 이름이 어긋난 거네요&quot; 했어요.&lt;br /&gt;친구가 눈을 동그랗게 뜨더라고요.&lt;br /&gt;어떻게 그걸 보자마자 아냐고.&lt;br /&gt;마우스 커서를 멈추고 저를 돌아봤어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그 답을 저는 사흘 주고 샀거든요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇 년 전에 똑같은 종류의 버그를 처음 만났을 때, 저는 진짜 사흘을 헤맸어요.&lt;br /&gt;그것도 곱게 헤맨 게 아니라요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 데이터가 깨진 줄 알았어요.&lt;br /&gt;그래서 의심 가는 표를 통째로 떠서 한 줄씩 눈으로 내렸어요.&lt;br /&gt;모니터 밝기를 한 칸 올리고, 화면을 손가락으로 짚어가면서요.&lt;br /&gt;한 사백 줄쯤 내려가다가 결국 인정했어요.&lt;br /&gt;데이터는 멀쩡하다고.&lt;br /&gt;숫자 자체는 다 맞거든요.&lt;br /&gt;어디로 가서 붙느냐만 틀린 거였는데, 그땐 그걸 몰랐죠.&lt;br /&gt;그래서 멀쩡한 표를 사백 줄이나 헛으로 읽은 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음엔 캐시를 의심했어요.&lt;br /&gt;다 비웠더니 잠깐 맞는 것처럼 보이더라고요.&lt;br /&gt;&quot;어, 됐다&quot; 하고 자리에서 일어나서 정수기까지 가서 물 한 잔 떠 마시고 왔어요.&lt;br /&gt;돌아와 앉아서 한 시간쯤 다른 일을 하다가 무심코 그 화면을 다시 봤는데, 같은 숫자가 또 어긋나 있었어요.&lt;br /&gt;그때 진짜 입에서 욕이 나왔어요.&lt;br /&gt;캐시 탓이 아니었다는 거잖아요.&lt;br /&gt;비우는 순간만 잠깐 가려졌던 거지.&lt;br /&gt;그 반나절이 그냥 통으로 0이 된 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째 날 밤엔 사람이 다 빠진 사무실에서 화면 두 개를 나란히 띄워놨어요.&lt;br /&gt;같은 한 건을 양쪽에서 동시에 찍어봤어요.&lt;br /&gt;왼쪽 화면이 부르는 번호랑 오른쪽 화면이 부르는 번호가 달랐어요.&lt;br /&gt;같은 한 사람을요.&lt;br /&gt;같은 데이터인데 두 군데가 서로 다른 이름으로 부르고 있더라고요.&lt;br /&gt;그 두 화면을 한참 번갈아 보는데, 목 뒤가 좀 서늘해지면서, 아 이게 한 사람을 두 자리에서 다르게 부르고 있는 거구나, 하고 떨어졌어요.&lt;br /&gt;누가 짚어준 게 아니라, 틀린 자리를 다 한 번씩 밟고 나서야요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요즘은 그 사흘을 아무도 안 치러요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 친구가 자기 버그를 어떻게 고쳤는지 아세요?&lt;br /&gt;AI한테 통째로 붙여넣으니까 금방 &quot;이름이 어긋난 것 같다&quot;고 짚어줬대요.&lt;br /&gt;정확했고요.&lt;br /&gt;친구는 한 줄 고치고 점심 먹으러 갔어요.&lt;br /&gt;빠르고 깔끔했어요.&lt;br /&gt;나무랄 데가 하나도 없어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 저는 그게 좀 이상하게 걸렸어요.&lt;br /&gt;제 사흘은 누가 봐도 비효율이었거든요.&lt;br /&gt;그런데 그 비효율이 저를 만들었어요.&lt;br /&gt;표를 사백 줄 헛으로 내리던 첫날, 캐시 비우고 물 떠 마시러 갔다가 한 시간 뒤에 무너진 둘째 날 &amp;mdash; 그 헛발질이 다 제 안에 뭔가로 남았어요.&lt;br /&gt;그래서 몇 년 뒤에 남의 화면을 3초 보고 알아챈 거예요.&lt;br /&gt;그 친구한텐 그게 안 생겨요.&lt;br /&gt;답은 받았는데, 답이 어디서 왔는지는 안 받았으니까요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 누가 헤매면서 배우라고 일부러 그 버그를 던져준 건 아니에요.&lt;br /&gt;그냥 헤맸어요.&lt;br /&gt;어쩌다 그 구간에 빠졌고, 빠져나오면서 뭔가 몸에 붙었던 거고.&lt;br /&gt;근데 이젠 그 헤매는 구간 자체를 AI가 먼저 깔끔하게 지워버려요.&lt;br /&gt;들어가기도 전에요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그래서 제 실력은 어디서 느는 거지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 생각을 하다가 무서운 데까지 갔어요.&lt;br /&gt;그 친구 얘기가 아니라 제 얘기로요.&lt;br /&gt;저도 요즘은 새로운 게 나오면 일단 AI 창부터 열거든요.&lt;br /&gt;손이 먼저 거기로 가요.&lt;br /&gt;그럼 저는 지금, 몇 년 전의 그 사흘 같은 걸 마지막으로 통째로 치른 게 언제였더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가만 생각하니까, 그 친구는 제 답을 듣고 고맙다고 했는데 정작 저는 그 친구가 물어본 &quot;어떻게 바로 알았어요?&quot;에 제대로 답을 못 했더라고요.&lt;br /&gt;&quot;그냥...&lt;br /&gt;옛날에 비슷한 걸로 한참 고생해서요&quot;라고 우물거렸는데, 말해놓고 손가락으로 햇수를 세보니까 그 고생이 생각보다 한참 전이었어요.&lt;br /&gt;그동안 새로 사흘짜리 고생을 산 적이 없는 거예요.&lt;br /&gt;그러니까 저는 옛날에 사둔 걸 계속 꺼내 쓰고만 있던 거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 뒤로 한 일주일은, 모르는 게 나와도 AI 창을 안 열고 일부러 먼저 붙어봤어요.&lt;br /&gt;화면 두 개 띄워놓고 옛날처럼요.&lt;br /&gt;근데 솔직히 사흘째 되니까 그냥 물어봤어요.&lt;br /&gt;빠르니까.&lt;br /&gt;이게 맞는 건지 틀린 건지도 모르겠고, 친구한테 다시 가서 &quot;야 너도 좀 헤매면서 해&quot;라고 말하기엔, 정작 제가 더 많이 물어보는 사람이라서요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>AI와 일하기</category>
      <category>성장</category>
      <category>회고</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/180</guid>
      <comments>https://datacook.tistory.com/180#entry180comment</comments>
      <pubDate>Mon, 29 Jun 2026 21:00:35 +0900</pubDate>
    </item>
    <item>
      <title>프롬프트를 길게 쓸수록, 결과가 더 나빠졌어요</title>
      <link>https://datacook.tistory.com/179</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;longer-prompt-worse-result.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b918gr/dJMb9970isc/Q2XStMBN1KFuHRMScNfw8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b918gr/dJMb9970isc/Q2XStMBN1KFuHRMScNfw8k/img.png&quot; data-alt=&quot;길수록 나빠지는&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b918gr/dJMb9970isc/Q2XStMBN1KFuHRMScNfw8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb918gr%2FdJMb9970isc%2FQ2XStMBN1KFuHRMScNfw8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;책상에서 바닥까지 엉켜 늘어진 긴 영수증 사진&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;longer-prompt-worse-result.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;길수록 나빠지는&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화면에 띄워둔 프롬프트가 스크롤 두 번을 넘어가고 있었어요.&lt;br /&gt;규칙이 열한 개였는데, 1번이 &quot;표로 만들지 마&quot;, 그다음이 &quot;존댓말 쓰지 마&quot;, 한참 밑에 7번쯤 가서 &quot;괄호 안에 부연 설명 달지 마&quot; 같은 게 줄줄이 붙어 있었어요.&lt;br /&gt;그 아래로 예시 세 개, &quot;이런 건 절대 하지 마&quot; 목록, 입력이 비어 있으면 어쩌고 하는 예외 처리까지.&lt;br /&gt;한 줄 한 줄 적을 때마다 빠진 게 없나 위아래로 훑었는데, 훑을 때마다 또 하나가 떠올라서 끝에 붙이고 또 붙였어요.&lt;br /&gt;저는 그걸 보면서 좀 뿌듯했거든요.&lt;br /&gt;이 정도로 꼼꼼하게 적어주면 못 알아들을 리가 없잖아요.&lt;br /&gt;그래서 보냈어요.&lt;br /&gt;똑같은 일을 여섯 군데에 시켰고, 결과를 적대적으로 한 번 더 검증을 걸어뒀어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여섯 개가 전부 다시 쓰라는 판정을 받고 돌아왔어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;꼼꼼하게 적었는데 여섯 개가 다 틀렸어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 모델 탓을 했어요.&lt;br /&gt;이렇게까지 적어줬는데 왜 못 하지.&lt;br /&gt;한 30분쯤은 프롬프트는 멀쩡하다고 믿고, 모델 버전을 바꿔볼까 온도를 낮춰볼까 그런 쪽만 만지작거렸어요.&lt;br /&gt;근데 결과물을 한 줄씩 들여다보니까, 틀린 방향이 좀 이상하더라고요.&lt;br /&gt;여섯 개가 제각각 다르게 틀린 게 아니라, 네 개가 똑같은 데서 똑같이 틀려 있었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규칙 목록 맨 위에 제가 &quot;표로 만들지 마, 그냥 문장으로 풀어&quot;라고 굵게까지 적어놨거든요.&lt;br /&gt;그런데 여섯 개 중 네 개가 마크다운 표를 그려서 왔어요.&lt;br /&gt;파이프 문자 쫙 그어서, 헤더 칸까지 정성껏.&lt;br /&gt;하지 말라고 적은 그 한 줄을 골라서 정확히 그것만 한 셈이에요.&lt;br /&gt;스크롤을 내려서 네 개를 나란히 띄워놓고 봤는데, 칸 폭까지 비슷하게 맞춰져 있어서 좀 소름이 돋았어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검증을 한 번 더 걸어둔 것도 별 도움이 안 됐어요.&lt;br /&gt;멀쩡해 보이는 출력 하나를 붙잡고는 &quot;근거가 약함, 재작성 권고&quot;라고 한 줄 적어서 도로 돌려보냈는데, 정작 그게 왜 근거가 약한지는 안 적혀 있었어요.&lt;br /&gt;그렇게 멀쩡한 두 개를 되돌리는 동안, 표가 떡하니 박혀 있는 네 개는 &quot;이상 없음&quot; 도장 찍어서 그냥 통과시켰고요.&lt;br /&gt;한 번 돌릴 때마다 3분 넘게 걸리고 토큰값도 두 배로 붙는데, 잡으라고 시킨 건 못 잡고 안 틀린 걸 틀렸다고 하고 있던 거예요.&lt;br /&gt;화면 오른쪽 위에 도는 로딩 표시를 멍하니 보고 있는데, 이게 일을 도와주는 게 아니라 일을 한 겹 더 만들고 있다는 생각이 그제야 들었어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;한 줄로 줄여서 다시 보냈어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화가 났다기보단 좀 황당했어요.&lt;br /&gt;그래서 반대로 해봤어요.&lt;br /&gt;그 긴 프롬프트를 다 지우고, 진짜 하고 싶은 거 한 문장만 남겼어요.&lt;br /&gt;&quot;이 내용을 문단 형태로 정리해줘.&quot; 끝.&lt;br /&gt;표 얘기는 아예 꺼내지도 않았어요 &amp;mdash; 금지 목록도, 예시 세 개도, 검증 단계도 다 뺐고요.&lt;br /&gt;지우면서도 손이 좀 떨렸어요.&lt;br /&gt;이만큼이나 적어놨는데 이걸 다 버린다고?&lt;br /&gt;싶어서 한 번 멈칫했다가, 에라 모르겠다 하고 보냈어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 다섯 개가 한 번에 통과했어요.&lt;br /&gt;나머지 하나는 또 표를 그려 왔는데, 그건 표가 문제가 아니라 내용 자체가 엉뚱하게 나온 거라서 결이 좀 달랐어요.&lt;br /&gt;어쨌든 표 때문에 통째로 돌아온 건 아까 네 개에서 한 개로 줄어든 거고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 이게 좀 무서웠어요.&lt;br /&gt;표라는 단어를 화면에서 지웠더니 표가 안 왔다는 거잖아요.&lt;br /&gt;곧장 &quot;아, 하지 말라고 적는 게 외려 그쪽을 가리키는 손가락이었구나&quot; 하고 정리하고 싶었는데, 정리해놓고 다시 읽어보니까 그게 맞는 설명인지 자신이 없었어요.&lt;br /&gt;그날 다시 두어 번 더 돌려봤더니, 똑같이 짧게 보내도 어떨 땐 표가 한 개 오고 어떨 땐 하나도 안 오고 그랬거든요.&lt;br /&gt;손가락 얘기가 맞다면 짧은 쪽에서도 일관되게 깨끗해야 할 텐데, 그게 아니었어요.&lt;br /&gt;그냥 길게 적은 게 통째로 방해가 된 건지, 그 한 줄이 문제였는지, 예시 세 개 때문이었는지 &amp;mdash; 변수를 다 한꺼번에 빼버려서 뭐가 진짜 원인인지는 끊어내지를 못했어요.&lt;br /&gt;깔끔하게 떨어지는 이유 하나를 갖고 싶었는데, 그게 없는 채로 결과만 좋아진 거라 더 찝찝했어요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;덜어내는 게 더 어려웠어요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 솔직히 말하면, 그 뒤로도 저는 또 길게 쓰고 있더라고요.&lt;br /&gt;다음 작업에서 비슷한 일을 시키는데, 손이 자동으로 &quot;참고로 이런 경우엔&amp;hellip;&quot;을 붙이고 있는 거예요.&lt;br /&gt;한 줄로 끝내도 되는 걸 알면서도, 짧게 보내면 뭔가 빠뜨린 것 같아서 불안한 거죠.&lt;br /&gt;꼼꼼함이 일을 망쳤다는 걸 눈으로 봤는데도 손버릇은 안 바뀌더라고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금도 가끔 그 네 개가 그려 보낸 표를 다시 열어봐요.&lt;br /&gt;칸까지 반듯하게 맞춰서, 하지 말라고 적힌 바로 그걸.&lt;br /&gt;짧게 보냈더니 그게 안 왔으니 긴 쪽 어딘가에 원인이 있는 건 맞는데, 그날 이후로 같은 프롬프트를 두어 번 더 돌려봐도 어떨 땐 표가 오고 어떨 땐 안 오고 그래서, 어느 줄이 범인이었는지는 끝까지 못 짚었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금도 다음 작업 프롬프트를 쓰다가, 1번 줄에 또 &quot;표로 만들지 마&quot;를 적어놓은 걸 발견했어요.&lt;br /&gt;한 번 지웠어요.&lt;br /&gt;그러고 나니까 빈 줄이 너무 허전해서, 손이 그걸 도로 적고 있더라고요.&lt;br /&gt;지금 그 한 줄이 다시 적힌 채로 창이 열려 있는데, 보낼지 또 지울지는 아직 안 정했어요.&lt;/p&gt;</description>
      <category>AI Agent</category>
      <category>ai-agent</category>
      <category>over-instruction</category>
      <category>Prompt</category>
      <author>Joon09</author>
      <guid isPermaLink="true">https://datacook.tistory.com/179</guid>
      <comments>https://datacook.tistory.com/179#entry179comment</comments>
      <pubDate>Mon, 29 Jun 2026 09:00:17 +0900</pubDate>
    </item>
  </channel>
</rss>