<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>heene</title>
    <link>https://tbang.tistory.com/</link>
    <description>IT, 건강, 책을 좋아하는 사람의 기록 블로그</description>
    <language>ko</language>
    <pubDate>Wed, 19 Aug 2026 15:17:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>T없이맑은I</managingEditor>
    <item>
      <title>웹소켓을 통한 HTML: 자바스크립트를 거의 사용하지 않는 실시간 SPA</title>
      <link>https://tbang.tistory.com/460</link>
      <description>&lt;p&gt;&lt;strong&gt;HTML over WebSockets: 거의 JavaScript 없이 실시간 SPA 만들기&lt;/strong&gt; (Andros Fenollosa)&lt;/p&gt;
&lt;h3&gt;핵심 아이디어&lt;/h3&gt;
&lt;p&gt;전통적인 SPA는 JS 프레임워크가 뷰를 그리고, API가 JSON을 주고받으며 두 코드베이스가 계약을 맞춰야 한다.&lt;br&gt;이 글은 그 대신 &lt;strong&gt;서버가 이미 렌더링한 HTML을 WebSocket으로 보내고, 클라이언트는 그걸 제자리에 꽂기만 하는&lt;/strong&gt; 방식(HTML over the wire / hypermedia)을 소개한다.&lt;/p&gt;
&lt;h3&gt;동작 방식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트의 JS 역할은 렌더링이 아니라 &lt;strong&gt;WebSocket 채널 생성 + 받은 HTML 삽입&lt;/strong&gt;(애니메이션, 이벤트 처리 등 보조 작업 포함).&lt;/li&gt;
&lt;li&gt;서버가 템플릿 엔진으로 HTML을 만들고 WebSocket으로 전송.&lt;/li&gt;
&lt;li&gt;채널이 항상 열려 있어서 서버가 클라이언트의 요청 없이도 변경사항을 푸시(broadcast)할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;전통적인 흐름(요청 → JSON → 클라이언트 렌더링)과 달리, 렌더링 로직과 상태가 전부에 집중된다.&lt;/p&gt;
&lt;h3&gt;장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;렌더링 엔진이 하나뿐이라 복잡도 감소&lt;/li&gt;
&lt;li&gt;API/계약 불필요&lt;/li&gt;
&lt;li&gt;상태가 서버에 존재 (htmx처럼 stateless하지 않음)&lt;/li&gt;
&lt;li&gt;DB에 직접 연결&lt;/li&gt;
&lt;li&gt;진정한 실시간 + broadcast 용이 (채팅, 대시보드, 멀티플레이 등)&lt;/li&gt;
&lt;li&gt;연결 유지로 handshake/헤더 반복 감소 → 트래픽·지연 감소&lt;/li&gt;
&lt;li&gt;React/Vue 등 무거운 프레임워크 없이 SPA 가능&lt;/li&gt;
&lt;li&gt;초기 HTML이 서버 렌더링이라 SEO에 유리 (단, 이후 WebSocket 업데이트는 크롤러가 못 봄)&lt;/li&gt;
&lt;li&gt;XSS에 상대적으로 안전 (서버에서 이스케이프된 HTML 전송)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서버 리소스 소모 큼 (클라이언트당 프로세스 + 상태 유지). 수평 확장 시 Redis 등 채널 레이어 필요&lt;/li&gt;
&lt;li&gt;네트워크 지연이 크면 “즉시성”이 떨어짐&lt;/li&gt;
&lt;li&gt;오프라인 불가 (재연결 설계 필요)&lt;/li&gt;
&lt;li&gt;WebSocket 서버 + LiveView 패턴 학습 곡선&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;관련 기술 비교&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTTP&lt;/strong&gt;: htmx, django-unicorn (요청-응답)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSE&lt;/strong&gt;: Datastar 등 (서버→클라이언트 단방향, 인프라 부담 적음)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebSocket&lt;/strong&gt;: Phoenix LiveView, Django LiveView, Blazor Server, Laravel Livewire+Reverb 등 (양방향 실시간)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SSE는 알림·피드·AI 스트리밍처럼 &lt;strong&gt;서버→클라이언트 푸시&lt;/strong&gt;만 필요할 때 더 가볍고 추천된다. 양방향·저지연이 필요하면 WebSocket이 적합하다.&lt;/p&gt;
&lt;h3&gt;결론&lt;/h3&gt;
&lt;p&gt;모든 문제에 대한 만능 해결책은 아니다.&lt;br&gt;실시간 양방향이 필요하면 WebSocket, 단방향 푸시면 SSE, 단순 요청-응답이면 HTTP(htmx)를 선택하면 된다.&lt;br&gt;핵심은 &lt;strong&gt;JSON 대신 HTML을 보내고, 단일 언어로 유지하며 API·계약·프론트엔드 복잡성을 줄이는 것&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;글 작성자는 자신이 만든 &lt;strong&gt;Django LiveView&lt;/strong&gt;를 포함해 여러 언어의 구현체들을 표로 정리해 두었다.&lt;/p&gt;
&lt;p&gt;출처: &lt;a href=&quot;https://en.andros.dev/blog/ef4968f5/html-over-websockets-real-time-spas-with-barely-any-javascript/&quot;&gt;https://en.andros.dev/blog/ef4968f5/html-over-websockets-real-time-spas-with-barely-any-javascript/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Dev</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/460</guid>
      <comments>https://tbang.tistory.com/460#entry460comment</comments>
      <pubDate>Fri, 14 Aug 2026 16:43:38 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 앱에서 고급 React 상태 경계 설정하기</title>
      <link>https://tbang.tistory.com/459</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;대부분 정적인 Next.js 앱을 서버 렌더링 위주 + RSC + URL 상태 중심으로 구성했을 때, &lt;b&gt;경계(boundary)&lt;/b&gt;에서 생기는 실제 문제들을 다룬 글입니다. 훅 자체가 복잡한 게 아니라, React 상태 &amp;middot; 서버 데이터 &amp;middot; 브라우저 API &amp;middot; URL 상태 &amp;middot; 클라이언트 캐시가 한 제품에서 만날 때 &amp;ldquo;누가 상태를 소유하고, 무엇이 반응하게 하며, 변경을 누구에게 알려야 하는가&amp;rdquo;가 핵심 질문입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 경계 사례&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;URL 변경 시 Popover 자동 닫기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;usePathname&lt;/code&gt;으로 경로 변화를 감지.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useEffect&lt;/code&gt;로 &lt;code&gt;setIsOpen(false)&lt;/code&gt; 하는 방식은 한 프레임 늦게 반영되고, ESLint도 경고.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;key={pathname}&lt;/code&gt;으로 리마운트하면 애니메이션&amp;middot;자식 상태가 깨짐.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최종 패턴&lt;/b&gt;: 열었을 때의 pathname을 저장해 두고, &lt;code&gt;open={isOpen &amp;amp;&amp;amp; openedAtPathname === pathname}&lt;/code&gt;으로 조건부로 닫기. Effect나 렌더 중 setState 없이 바로 반영.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;브라우저 전용 API 감지 (&lt;code&gt;navigator.share&lt;/code&gt;)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSR에서는 존재하지 않음.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; 사용: &lt;code&gt;getServerSnapshot&lt;/code&gt;은 &lt;code&gt;false&lt;/code&gt;, 클라이언트 &lt;code&gt;getSnapshot&lt;/code&gt;은 &lt;code&gt;&quot;share&quot; in window.navigator&lt;/code&gt;, subscribe는 no-op.&lt;/li&gt;
&lt;li&gt;서버&amp;middot;클라이언트 모두 안전하게 값을 읽음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Infinite Query 캐시에서 파생 상태 만들기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마스터-디테일 뷰에서 무한 스크롤 리스트의 이미 로드된 페이지를 기반으로 prev/next ID를 계산.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;queryClient.getQueriesData&lt;/code&gt;는 단순 읽기라 캐시가 바뀌어도 리렌더가 안 됨.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;InfiniteQueryObserver&lt;/code&gt; + &lt;code&gt;useSyncExternalStore&lt;/code&gt;로 캐시 변경을 구독. 스냅샷 함수에서 파생값을 계산하고, 서버 스냅샷은 안정적인 빈 값 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RSC Auth 스냅샷을 클라이언트 Context로 전달&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버에서 &lt;code&gt;await withAuth()&lt;/code&gt;로 가져온 값을 ClientAuthProvider에 넘겨 Context로 노출.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주의&lt;/b&gt;: 실시간 auth 상태가 아니라 요청 시점의 스냅샷. 로그인/로그아웃 후에는 해당 라우트를 새로고침하거나 revalidate해야 갱신됨.&lt;/li&gt;
&lt;li&gt;가능하면 라이브러리의 공식 클라이언트 Provider/훅을 쓰고, 이 패턴은 서버 전용 소스가 필요할 때만 제한적으로 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RSC + TanStack Query를 넘나드는 Optimistic Update&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;좋아요 버튼처럼 초기값은 RSC, 같은 데이터가 클라이언트 쿼리에도 있는 경우.&lt;/li&gt;
&lt;li&gt;Context + &lt;code&gt;useOptimistic&lt;/code&gt;으로 즉각 피드백 제공.&lt;/li&gt;
&lt;li&gt;성공 시 로컬 상태 커밋 + 관련 쿼리 invalidate, 실패 시 롤백.&lt;/li&gt;
&lt;li&gt;서버 지속성, React 즉각 피드백, Query 캐시 일관성을 명확히 분리.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 메시지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js 앱이 복잡해질수록 &lt;b&gt;상태 소유권&lt;/b&gt;이 중요해집니다. 값이 두 곳에 동시에 존재하면서 서로 동기화 책임이 불명확할 때 가장 까다로운 버그가 생깁니다. &lt;code&gt;usePathname&lt;/code&gt;, &lt;code&gt;useSyncExternalStore&lt;/code&gt;, RSC 스냅샷, optimistic state 등은 각각 &amp;ldquo;올바른 반응 경계&amp;rdquo;를 선택하는 도구입니다.&lt;br /&gt;&lt;br /&gt;출처: &lt;a href=&quot;https://www.nirtamir.com/articles/advanced-react-questions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.nirtamir.com/articles/advanced-react-questions&lt;/a&gt;&lt;/p&gt;</description>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/459</guid>
      <comments>https://tbang.tistory.com/459#entry459comment</comments>
      <pubDate>Wed, 12 Aug 2026 14:13:30 +0900</pubDate>
    </item>
    <item>
      <title>하이드레이션과 렌더링 전략별 차이</title>
      <link>https://tbang.tistory.com/455</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 기본 전략&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Static Generation (SSG)&lt;/b&gt;: 빌드 타임에 HTML을 미리 생성 &amp;rarr; CDN에서 초고속 서빙. ISR(Incremental Static Regeneration)로 freshness 문제 해결 (revalidate). Edge Rendering으로 지연도 최소화.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Client-Side Rendering (CSR / SPA)&lt;/b&gt;: 서버는 빈 shell만 주고, 클라이언트에서 JS 번들 + 데이터 페칭 후 모든 UI 생성. &lt;b&gt;하이드레이션 없음&lt;/b&gt;. 하지만 첫 페인트 느리고 SEO 불리.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Server-Side Rendering (SSR)&lt;/b&gt;: 서버에서 HTML 생성 후 클라이언트에서 &lt;b&gt;하이드레이션&lt;/b&gt; (React가 DOM에 이벤트 핸들러 등 붙임). 콘텐츠 즉시 보이고 SEO 좋지만, &lt;b&gt;작업 중복&lt;/b&gt; (서버 렌더 &amp;rarr; 클라이언트 재렌더)과 &lt;b&gt;하이드레이션 mismatch&lt;/b&gt; 문제가 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 현대적 개선 전략&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Streaming SSR + Suspense&lt;/b&gt;: 페이지 전체를 기다리지 않고 &lt;b&gt;청크 단위로 스트리밍&lt;/b&gt;. Suspense boundary로 느린 부분(skeleton) 분리 &amp;rarr; perceived performance 크게 향상. Progressive hydration (스크롤/인터랙션 시 지연 하이드레이션) 결합 가능.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Islands Architecture&lt;/b&gt; (Astro 대표): 대부분 &lt;b&gt;정적 HTML&lt;/b&gt;로 두고, 인터랙티브한 부분만 &quot;섬&quot;처럼 JS + 하이드레이션. &lt;code&gt;client:visible&lt;/code&gt;, &lt;code&gt;client:load&lt;/code&gt; 등 directive로 제어. &lt;b&gt;JS 번들 최소화&lt;/b&gt;에 최고 (콘텐츠 중심 사이트: 블로그, docs, 마케팅 페이지에 이상적).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;React Server Components (RSC)&lt;/b&gt;: 서버 전용 컴포넌트는 &lt;b&gt;클라이언트에 JS 전혀 안 보냄&lt;/b&gt; (Flight 형식으로 UI 설명만 직렬화). &lt;code&gt;&quot;use client&quot;&lt;/code&gt;만 JS 번들. DB 직접 쿼리 가능, 번들 크기 대폭 감소. Partial Prerendering (React 19)으로 static shell + dynamic hole 결합.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기타&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Fine-grained reactivity&lt;/b&gt; (e.g. Solid): 한 번 하이드레이션 후 re-render 거의 없음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Resumability&lt;/b&gt; (Qwik): 하이드레이션 자체를 거의 안 함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TanStack Start&lt;/b&gt;: ownership flipped 접근.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Next.js 16.3&lt;/b&gt;: Instant navigations 등으로 마지막 갭 메움.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;선택 가이드 (How to actually choose)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;콘텐츠 중심&lt;/b&gt; (블로그, docs, 마케팅): SSG/Islands/Astro&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터랙티브 앱&lt;/b&gt; (대부분 동적): RSC + Streaming SSR (Next.js)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;극한 성능&lt;/b&gt;: Fine-grained/Resumability 고려&lt;/li&gt;
&lt;li&gt;항상 &lt;b&gt;Lighthouse 점수&lt;/b&gt;, &lt;b&gt;JS 번들 크기&lt;/b&gt;, &lt;b&gt;인터랙션 지연&lt;/b&gt;을 기준으로 판단.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처: &quot;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://neciudan.dev/hydration-and-rendering-strategies&quot;&gt;Different hydration and rendering strategies&lt;/a&gt;&quot; (Neciu Dan, 2026.6.28)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹 앱의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;초기 로딩 속도&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;인터랙티브성&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;사이의 트레이드오프를 해결하기 위해 진화해 온 다양한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;렌더링 + 하이드레이션 전략&lt;/b&gt;을 체계적으로 비교&amp;middot;설명합니다. 핵심은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;HTML이 보이는 순간&quot;과 &quot;실제로 클릭이 되는 순간&quot; 사이의 갭(하이드레이션)&lt;/b&gt;을 줄이는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 페이지를 하나의 전략으로 해결하려 하지 말고, 페이지 특성에 맞게 (또는 부분별로) 최적의 조합을 선택.&lt;/p&gt;</description>
      <category>Dev</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/455</guid>
      <comments>https://tbang.tistory.com/455#entry455comment</comments>
      <pubDate>Mon, 6 Jul 2026 15:59:51 +0900</pubDate>
    </item>
    <item>
      <title>2026년 7월</title>
      <link>https://tbang.tistory.com/454</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.lmsys.org/blog/2026-07-02-agent-assisted-sglang-development&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SGLang 개발시 AI 에이전트 드리븐 개발을 위한 가이드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://neciudan.dev/hydration-and-rendering-strategies&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;다양한 하이드레이션 및 렌더링 전략&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.arcbjorn.com/state-of-cli-coding-agents-2026&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CLI 코딩 에이전트 현황&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.vybe.build/blog/learn-what-not-to-tokenize&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;모든 것에 토큰을 사용할 필요는 없다.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 결정론적 프로그래밍이 필요한 영역을 이해하고 AI 영역과 분리해서 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aarontgrogg.github.io/NoLoJS/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JS 없이 구현 가능한 최신 UI&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://davidpoblador.com/deep-dives/what-happened-to-the-frontend/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;프론트엔드가 걸어온 과정&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://performance.dev/chatgpt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;chatGPT 웹 역공학으로 분석&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://anthonyhobday.com/sideprojects/saferules/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;언제나 안심하고 따를수 있는 시각 디자인 규칙&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wren.wtf/shower-thoughts/stop-using-opencode/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OpenCode를 그만 써라&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://backstage.orus.eu/react-composition-patterns-at-orus/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Composition Ladder: 컴포넌트 계층 사다리&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://earendil.com/posts/prompt-caching/\&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;에이전트 프롬프트 캐싱&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소소한 정보</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/454</guid>
      <comments>https://tbang.tistory.com/454#entry454comment</comments>
      <pubDate>Sat, 4 Jul 2026 01:19:09 +0900</pubDate>
    </item>
    <item>
      <title>Gemma 4 12B LoRA 파인튜닝</title>
      <link>https://tbang.tistory.com/453</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 맥북에서 Gemma 4 12B 모델을 내려받고, 작은 데이터셋으로 LoRA 파인튜닝을 진행했다. 실험은 체스 다음 수를 맞히는 형태로 구성했다. 다만 목표는 체스 엔진을 만드는 것이 아니라, 모델이 정해진 출력 형식을 더 잘 따르게 만들 수 있는지 확인하는 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 실험에서 사용한 출력 형식은 UCI 체스 표기다. 예를 들어 일반 체스 표기에서는 &lt;code&gt;Nf3&lt;/code&gt;라고 쓰지만, UCI 표기에서는 출발 칸과 도착 칸을 모두 포함해 &lt;code&gt;g1f3&lt;/code&gt;라고 쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램에서 후처리하려면 &lt;code&gt;Nf3&lt;/code&gt;보다 &lt;code&gt;g1f3&lt;/code&gt;가 더 명확하다. 그래서 모델에게 &amp;ldquo;답은 UCI 형식으로만 출력하라&amp;rdquo;는 작은 규칙을 학습시키는 실험을 진행했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사용한 모델&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용한 모델은 MLX용 Gemma 4 12B 모델이다.&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;code&gt;mlx-lm&lt;/code&gt; CLI만으로 바로 실행하려고 했다. 하지만 Gemma 4 12B의 &lt;code&gt;gemma4_unified&lt;/code&gt; 모델 타입을 읽지 못하는 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 프로젝트 전용 Python 가상환경을 만들고, &lt;code&gt;mlx-optiq&lt;/code&gt;와 GitHub 최신 &lt;code&gt;mlx-lm&lt;/code&gt;을 설치해서 해결했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 명령은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;.venv/bin/python -m pip install -U mlx-optiq &quot;mlx-lm @ git+https://github.com/ml-explore/mlx-lm.git&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 실행 코드에서 &lt;code&gt;import optiq&lt;/code&gt;를 먼저 호출하는 것이었다. 이 import가 Gemma 4 unified 모델 타입을 등록해준다. 이 과정을 거친 뒤에는 모델 로딩과 생성이 정상 동작했다.&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;구성은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;학습 데이터: 32개&lt;/li&gt;
&lt;li&gt;검증 데이터: 8개&lt;/li&gt;
&lt;li&gt;테스트 데이터: 8개&lt;/li&gt;
&lt;li&gt;전후 비교용 평가 데이터: 16개&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 채팅 형식 JSONL로 만들었다. 한 줄은 하나의 학습 예제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;messages&quot;: [
    {
      &quot;role&quot;: &quot;system&quot;,
      &quot;content&quot;: &quot;You are a chess next-move assistant. Return exactly one legal UCI move and no explanation.&quot;
    },
    {
      &quot;role&quot;: &quot;user&quot;,
      &quot;content&quot;: &quot;Chess drill italian_develop_knight. Moves so far: 1. e4 e5. Side to move: White. Plan: develop the king-side knight toward the center. Reply with the best next move in UCI.&quot;
    },
    {
      &quot;role&quot;: &quot;assistant&quot;,
      &quot;content&quot;: &quot;g1f3&quot;
    }
  ]
}&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;파인튜닝 전 모델에 평가 질문 16개를 먼저 입력했다. 이 값을 베이스라인으로 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 0개 정답이었다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;베이스라인: 0/16 = 0.0%&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 결과만 보면 모델이 체스를 전혀 모르는 것처럼 보일 수 있다. 하지만 실제 출력은 그렇지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 정답이 &lt;code&gt;g1f3&lt;/code&gt;인 문제에서 모델은 &lt;code&gt;Nf3&lt;/code&gt;라고 답했다. 정답이 &lt;code&gt;e7e6&lt;/code&gt;인 문제에서는 &lt;code&gt;e6&lt;/code&gt;라고 답했다. 정답이 &lt;code&gt;c7c6&lt;/code&gt;인 문제에서는 &lt;code&gt;c6&lt;/code&gt;라고 답했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 체스 수 자체는 어느 정도 맞췄지만, 내가 요구한 UCI 형식은 지키지 못했다. 이번 평가에서는 출력 형식을 엄격하게 봤기 때문에 &lt;code&gt;Nf3&lt;/code&gt;, &lt;code&gt;e6&lt;/code&gt;, &lt;code&gt;c6&lt;/code&gt;는 모두 오답으로 처리했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;LoRA 튜닝 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 실험에서는 다음 설정으로 LoRA 튜닝을 진행했다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;iters: 300
num_layers: 16
batch_size: 1
learning_rate: 1e-4
max_seq_length: 1024
mask_prompt: on&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;mask_prompt&lt;/code&gt; 옵션을 켠 것이 중요했다. 이 옵션은 질문 부분보다 assistant의 답변 부분에 학습을 집중하게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 실험의 목적은 질문을 외우게 하는 것이 아니라, 답을 UCI 형식으로 출력하게 만드는 것이었다. 그래서 &lt;code&gt;mask_prompt&lt;/code&gt;를 켠 설정이 더 적합했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 가능한 파라미터는 전체 모델의 0.092%였다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Trainable parameters: 0.092% (10.930M / 11907.350M)&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;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;단계&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;시간&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;베이스라인 평가&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;8초&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LoRA 튜닝&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;84초&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LoRA 적용 후 평가&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;10초&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전체 실행&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;214초&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;LoRA 튜닝 후 같은 16개 평가 질문을 다시 입력했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;LoRA 적용 후: 10/16 = 62.5%&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;베이스라인은 0/16이었고, LoRA 적용 후에는 10/16을 맞췄다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0.0% -&amp;gt; 62.5%&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표현을 바꿔서 물어본 평가 데이터에서도 8개 중 6개를 맞췄다. 단순히 학습 문장을 그대로 외운 결과만은 아니라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 모든 문제가 해결된 것은 아니다. French Defense나 English Opening 관련 일부 케이스에서는 여전히 다른 UCI 수를 출력했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결과 해석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 결과는 Gemma 4 12B의 체스 실력이 전반적으로 좋아졌다는 뜻은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 실험에서 확인한 것은 더 좁은 내용이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은 체스 지시 데이터에서, 모델이 UCI 형식으로 답하는 능력이 개선됐다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;베이스라인 모델은 체스적으로 그럴듯한 수를 일반 표기로 답하는 경우가 많았다. LoRA 튜닝 후에는 지정한 UCI 형식으로 답하는 비율이 올라갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이 실험은 &amp;ldquo;체스 엔진 성능 개선&amp;rdquo;이 아니라 &amp;ldquo;출력 형식 교정&amp;rdquo; 실험으로 보는 것이 맞다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터셋이 작다.&lt;/li&gt;
&lt;li&gt;오프닝 중심의 단순한 예제만 사용했다.&lt;/li&gt;
&lt;li&gt;합법수 검증을 별도로 하지 않았다.&lt;/li&gt;
&lt;li&gt;Stockfish 같은 체스 엔진과 비교하지 않았다.&lt;/li&gt;
&lt;li&gt;체스 실력 전체가 아니라 출력 형식만 평가했다.&lt;/li&gt;
&lt;/ul&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;이번 실험에서는 로컬 Apple Silicon 환경에서 Gemma 4 12B LoRA 튜닝을 실제로 실행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 실험은 작은 규모였지만, 로컬 맥북에서 모델 다운로드, 평가, LoRA 튜닝, 결과 비교까지 한 번에 진행할 수 있다는 점을 확인했다.&lt;/p&gt;</description>
      <category>Dev</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/453</guid>
      <comments>https://tbang.tistory.com/453#entry453comment</comments>
      <pubDate>Tue, 16 Jun 2026 13:48:50 +0900</pubDate>
    </item>
    <item>
      <title>우리는 모두 시스템 아키텍처 전문가가 되어야 한다</title>
      <link>https://tbang.tistory.com/452</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI 시대가 본격화되면서 개발자의 역할이 근본적으로 바뀌고 있다. 과거에는 &lt;b&gt;개인 전문성&lt;/b&gt;에 의존해 직접 코드를 작성하고 문제를 해결했다면, 이제는 &lt;b&gt;전문성 에이전트(Expert Agents)&lt;/b&gt; 를 설계하고, 이들이 제품 개발 생애주기(SDLC) 전체에서 원활하게 협력할 수 있는 &lt;b&gt;시스템 아키텍처&lt;/b&gt;를 구축하는 것이 핵심 역량이 되었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;과거의 개발 방식 (Pre-AI)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프론트엔드 개발자는 디자인 시안과 백엔드 API 설계도를 받아 제품을 &lt;b&gt;직접 완성&lt;/b&gt;했다.&lt;/li&gt;
&lt;li&gt;개발 완료 후 QA 팀에게 &lt;b&gt;수동 핸드오프&lt;/b&gt;를 했다.&lt;/li&gt;
&lt;li&gt;각 역할(기획, 디자인, 프론트, 백엔드, QA)이 비교적 명확하게 분리되어 있었고, 개인의 숙련도와 경험에 크게 의존했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;현재의 개발 방식 (AI 에이전트 시대)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프론트엔드 개발자는 더 이상 UI를 하나하나 코딩하지 않는다. 대신 &lt;b&gt;프론트엔드 전문 에이전트&lt;/b&gt;를 설계&amp;middot;구현한다.&lt;/li&gt;
&lt;li&gt;이 에이전트는 주어진 디자인 시스템, 컴포넌트 라이브러리, API 스펙을 이해하고, 요구사항에 따라 화면을 자동으로 생성&amp;middot;수정한다.&lt;/li&gt;
&lt;li&gt;개발이 완료되면 &lt;b&gt;QA 에이전트&lt;/b&gt;에게 자동으로 핸드오프된다.&lt;/li&gt;
&lt;li&gt;QA 에이전트는 기능 검증, 엣지 케이스 테스트, 성능&amp;middot;접근성&amp;middot;보안 체크 등 최종 출시를 위한 검증을 수행한다.&lt;/li&gt;
&lt;li&gt;전체 과정은 &lt;b&gt;시스템적으로 관리&lt;/b&gt;되며, 각 에이전트 간의 입력&amp;middot;출력 인터페이스, 상태 관리, 에러 핸들링, 재시도 로직 등이 명확하게 정의된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 메시지: &lt;b&gt;시스템 아키텍처 사고방식의 전환&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 개발자에게 가장 중요한 역량은 다음과 같다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;에이전트 설계 능력&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 도메인(프론트엔드, 백엔드, QA, DevOps 등)의 전문성을 에이전트 형태로 추출하고 체계화하는 능력&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시스템 오케스트레이션 능력&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 에이전트가 SDLC 전 단계(기획 &amp;rarr; 디자인 &amp;rarr; 개발 &amp;rarr; 테스트 &amp;rarr; 배포 &amp;rarr; 모니터링)에서 자연스럽게 연결되고 협력할 수 있는 워크플로우 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터페이스와 거버넌스 설계&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에이전트 간 데이터 교환 형식, 프롬프트 엔지니어링 표준, 검증 기준, 인간 개입 지점(Human-in-the-Loop) 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전체 시스템의 신뢰성&amp;middot;확장성 확보&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에이전트가 실패했을 때의 fallback 전략, 성능 병목 지점 관리, 비용 최적화 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 시대의 진짜 고수는 더 이상 &lt;b&gt;코드 잘 쓰는 사람&lt;/b&gt;이 아니다.&lt;br /&gt;&lt;b&gt;최고의 전문 에이전트들을 설계하고, 그들이 하나의 유기적인 시스템으로 작동하도록 아키텍처를 그릴 수 있는 사람&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이제 &lt;b&gt;개인 생산성 시대&lt;/b&gt;를 넘어 &lt;b&gt;시스템 생산성 시대&lt;/b&gt;로 진입하고 있다.&lt;br /&gt;이 변화에 빠르게 적응하는 개발자만이 앞으로도 경쟁력을 유지할 수 있을 것이다.&lt;/p&gt;</description>
      <category>Dev</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/452</guid>
      <comments>https://tbang.tistory.com/452#entry452comment</comments>
      <pubDate>Sat, 6 Jun 2026 08:41:51 +0900</pubDate>
    </item>
    <item>
      <title>2026년 6월</title>
      <link>https://tbang.tistory.com/450</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://spin.atomicobject.com/code-cheap-whats-left/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;코드가 저렴해지면 무엇이 남는가?&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.elastic.co/search-labs/blog/agent-memory-elasticsearch&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;엘라스틱서치의 영구적인 에이전트 메모리 계층 설계&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.oreilly.com/radar/kubernetes-in-the-age-of-ai/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AI 시대에 쿠버네티스 활용&lt;/a&gt;&lt;br /&gt;- LLM 개발: Kubernetes는&amp;nbsp;확장성과&amp;nbsp;유연성을&amp;nbsp;바탕으로&amp;nbsp;AI&amp;nbsp;및&amp;nbsp;LLM&amp;nbsp;모델의&amp;nbsp;사전&amp;nbsp;학습,&amp;nbsp;미세&amp;nbsp;조정,&amp;nbsp;배포&amp;nbsp;및&amp;nbsp;신속한&amp;nbsp;엔지니어링을&amp;nbsp;위한&amp;nbsp;효율적인&amp;nbsp;플랫폼으로&amp;nbsp;매우&amp;nbsp;적합&lt;br /&gt;- AI 에이전트 오케스트레이션: 클라우드&amp;nbsp;네이티브&amp;nbsp;기술과&amp;nbsp;널리&amp;nbsp;사용되는&amp;nbsp;프로토콜을&amp;nbsp;결합함으로써&amp;nbsp;이제&amp;nbsp;에이전트는&amp;nbsp;임시&amp;nbsp;데모에서&amp;nbsp;쿠버네티스와&amp;nbsp;같은&amp;nbsp;시스템에서&amp;nbsp;실행되는&amp;nbsp;복잡한&amp;nbsp;에이전트&amp;nbsp;클러스터로&amp;nbsp;발전하고&amp;nbsp;있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://kubernetes.io/blog/2026/03/20/running-agents-on-kubernetes-with-agent-sandbox/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kubernetes.io/blog/2026/03/20/running-agents-on-kubernetes-with-agent-sandbox/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sympozium-ai/sympozium&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/sympozium-ai/sympozium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.langchain.com/blog/the-art-of-loop-engineering&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;루프 엔지니어링&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프롬프트 &amp;gt; 컨텍스트 &amp;gt; 하네스 &amp;gt; 루프&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.sethi.io/blog/react-performance-from-sluggish-to-lightning&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;리액트 성능 개선&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://github.com/haxlys/skills/blob/main/skills/react-performance/SKILL.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;내용을 바탕으로 스킬로 별도로 제작.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.pathtostaff.com/p/everything-a-senior-engineer-needs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;시니어 엔지니어에게 필요한 LLM의 모든것.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.adarsha.dev/blog/tanstack-mental-model-for-nextjs-developers&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tanstack Start 의 멘탈 모델, Nextjs 개발자를 위한.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Tanstack Start: 더 명시적이고 타입 안정성이고 라우터 퍼스트.&lt;br /&gt;- Next.js: 더 암시적이고 엄격한 컨벤션이며 서버 퍼스트.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tanstack.com/blog/tanstack-table-v9-memory-performance&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tanstack Table 에서 메모리를 90% 줄인 방법&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 테이블에서 발생하는 수백만개의 객체의 중복된 메서드들을 매번 새로 생성 -&amp;gt; 테이블에서 하나의 인스턴스로 프로토타입을 생성하여 모든 객체가 동일한 메서드를 가지고 값(데이터)만 별도로 정의.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ruurtjan.com/articles/p99-0ms-autocomplete-for-240-million-domain-names&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2억 4천만 개의 도메인 이름에 대한 p99 0ms 자동 완성&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인기 있는 상위 도메인 (Tranco Top 1M): 메모리 기반 Trie(트라이) 구조로 초고속 검색.&lt;br /&gt;- 전체 도메인 (2.4억 개, CZDS): SSD에 메모리 맵핑 + 블록 인덱싱으로 효율적으로 검색 (디스크 2.5GB).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/humanlayer/12-factor-agents&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LLM 앱을 만들기 위한 12가지 원칙&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://12factor.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://12factor.net/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.jayfreestone.com/writing/you-might-not-need-a-service-worker/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;서비스 워커가 필요없을 수도?&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오프라인 지원&amp;middot;푸시 알림&amp;middot;백그라운드 싱크 같은 핵심 기능 외에는 대부분 HTTP 캐싱, 콘텐츠 해싱, 서버사이드 처리 등 더 간단한 방법으로 대체할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소소한 정보</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/450</guid>
      <comments>https://tbang.tistory.com/450#entry450comment</comments>
      <pubDate>Thu, 4 Jun 2026 09:36:59 +0900</pubDate>
    </item>
    <item>
      <title>Linear 앱의 초고속 성능을 가능하게 하는 핵심 웹 성능 최적화 방법</title>
      <link>https://tbang.tistory.com/449</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;브라우저 내 데이터베이스 (Local-First Architecture) &amp;mdash; 가장 중요한 기반&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;IndexedDB&lt;/b&gt;를 실제 DB로 사용하고, &lt;b&gt;MobX observable&lt;/b&gt;로 in-memory 그래프를 만듦.&lt;/li&gt;
&lt;li&gt;UI는 항상 &lt;b&gt;로컬 데이터&lt;/b&gt;를 읽음 &amp;rarr; 네트워크 요청 없이 즉시 반영.&lt;/li&gt;
&lt;li&gt;Mutation(변경)은 &lt;b&gt;로컬에서 먼저 적용&lt;/b&gt; &amp;rarr; UI 즉시 re-render &amp;rarr; 백그라운드에서 서버 동기화.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;issue.title = &quot;new title&quot;; issue.save();&lt;/code&gt; 형태 (optimistic update).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버는 &lt;b&gt;Sync Target&lt;/b&gt; (동기화 대상)이지 Truth Source가 아님.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Sync Engine&lt;/b&gt;: WebSocket으로 delta(변경분)만 주고받음. 변경 시 granular re-render (필드 단위 MobX observer).&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;효과&lt;/b&gt;: Spinner, skeleton, loading state를 거의 없앰. 네트워크가 가장 큰 병목인데, 이를 사용자 경험에서 완전히 숨김.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실무 적용 팁&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TanStack Query + SWR의 optimistic update로 비슷하게 구현 가능.&lt;/li&gt;
&lt;li&gt;대규모 데이터는 lazy hydration (Issue, Comment 테이블 등).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;초기 로드(First Load) 극한 최적화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linear는 &lt;b&gt;Client-Side Rendering(CSR)&lt;/b&gt;을 유지하면서도 첫 로드가 매우 빠름.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;번들 최적화&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Parcel &amp;rarr; Rollup &amp;rarr; Vite &amp;rarr; Rolldown으로 여러 번 마이그레이션.&lt;/li&gt;
&lt;li&gt;Legacy 브라우저 지원 포기 (polyfill, ES5 transpilation 제거) &amp;rarr; JS 크기 50% 감소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Aggressive Code Splitting&lt;/b&gt;: Route-level + Vendor per package chunk.&lt;/li&gt;
&lt;li&gt;결과: Cold cache 로드 10~30% 빨라짐, 메모리 70-80% 감소.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Preloading &amp;amp; Parallel Fetch&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;link rel=&quot;modulepreload&quot;&amp;gt;&lt;/code&gt;로 entry script가 필요로 하는 모든 chunk를 병렬로 미리 로드.&lt;/li&gt;
&lt;li&gt;Waterfall 방지 &amp;rarr; import 시 이미 캐시에 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Service Worker Precache&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그인 화면에서 background로 ~1,200개 asset (route chunks, icons, fonts) precache.&lt;/li&gt;
&lt;li&gt;이후 navigation은 &lt;b&gt;네트워크 완전 스킵&lt;/b&gt; (Cache-first).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오프라인 지원&lt;/b&gt;까지 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Inlined App Shell&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;에 critical CSS + JS 인라인 (테마, sidebar width, login 상태 등 localStorage 기반).&lt;/li&gt;
&lt;li&gt;첫 페인트 전에 사용자 맞춤 shell 렌더링 &amp;rarr; &quot;앱이 바로 준비된&quot; 느낌.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Font 최적화&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Variable Font (Inter Variable.woff2 하나로 100-900 weight).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;font-display: swap&lt;/code&gt; + &lt;code&gt;crossorigin&lt;/code&gt; preload로 FOUT/FOIT 방지.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Render First, Auth Second&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로컬에 데이터 있으면 바로 렌더링 &amp;rarr; 백그라운드에서 auth/ sync 검증.&lt;/li&gt;
&lt;li&gt;Happy path 가정 (optimistic auth).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. &lt;b&gt;Designed for Speed (설계/UX 측면)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능은 엔지니어링뿐 아니라 &lt;b&gt;디자인&lt;/b&gt; 문제:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Keyboard-first&lt;/b&gt;: 거의 모든 액션에 shortcut (단축키).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Command Palette&lt;/b&gt; (&lt;code&gt;⌘K&lt;/code&gt;): 로컬 MobX 데이터 검색 &amp;rarr; 네트워크 없이 초고속.&lt;/li&gt;
&lt;li&gt;마우스 경로 최소화 &amp;rarr; 사용자 체감 속도 극대화.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. &lt;b&gt;Animations&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;100ms 이하 duration (인간이 즉시 반응으로 느끼는 threshold).&lt;/li&gt;
&lt;li&gt;GPU acceleration (transform, opacity 위주).&lt;/li&gt;
&lt;li&gt;Layout shift 유발 속성 (width, height 등) 애니메이션 금지.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전체 아키텍처 요약 (성능의 본질)&lt;/h3&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;계층&lt;/th&gt;
&lt;th&gt;전통적 방식&lt;/th&gt;
&lt;th&gt;Linear 방식&lt;/th&gt;
&lt;th&gt;성능 영향&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;데이터&lt;/td&gt;
&lt;td&gt;Server &amp;rarr; API&lt;/td&gt;
&lt;td&gt;Browser (IndexedDB + MobX)&lt;/td&gt;
&lt;td&gt;즉시 반영&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutation&lt;/td&gt;
&lt;td&gt;Await network&lt;/td&gt;
&lt;td&gt;Optimistic + background sync&lt;/td&gt;
&lt;td&gt;No spinner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Load&lt;/td&gt;
&lt;td&gt;Heavy bundle + sequential&lt;/td&gt;
&lt;td&gt;Tiny chunks + preload + SW&lt;/td&gt;
&lt;td&gt;Instant feel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;Full re-render&lt;/td&gt;
&lt;td&gt;Granular observable&lt;/td&gt;
&lt;td&gt;Smooth even with many changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigation&lt;/td&gt;
&lt;td&gt;Network each time&lt;/td&gt;
&lt;td&gt;SW cache&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 교훈&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;네트워크를 숨겨라&lt;/b&gt; (Local-first + Optimistic + Preload/SW).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;작은 것들의 집합&lt;/b&gt;이 큰 성능 차이를 만든다 (번들, font, shell, animation 등 세부 디테일).&lt;/li&gt;
&lt;li&gt;단순함을 유지 (React + MobX + Postgres, fancy framework 최소).&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 접근은 모든 웹 앱에 적용할 수 있습니다. 특히 생산성 도구, 대시보드, 협업 앱에서 Local-first + Optimistic update + 철저한 code splitting + SW를 조합하면 Linear에 가까운 경험을 낼 수 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 구체적인 부분(예: sync engine 세부나 코드 예시)이 필요하시면 말씀해주세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://performance.dev/how-is-linear-so-fast-a-technical-breakdown&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://performance.dev/how-is-linear-so-fast-a-technical-breakdown&lt;/a&gt;&lt;/p&gt;</description>
      <category>Dev</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/449</guid>
      <comments>https://tbang.tistory.com/449#entry449comment</comments>
      <pubDate>Fri, 29 May 2026 14:58:12 +0900</pubDate>
    </item>
    <item>
      <title>2026년 5월</title>
      <link>https://tbang.tistory.com/447</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://alifeengineered.substack.com/p/4-behaviors-that-make-you-look-junior&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;경력과 상관없이 당신을 아마추어 처럼 보이게 하는 4가지 행동&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://memory.cobanov.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;에이전트 메모리 작동 방식&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://newsletter.techworld-with-milan.com/p/the-20-software-engineering-laws&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;20가지 엔지니어링 법칙&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소소한 정보</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/447</guid>
      <comments>https://tbang.tistory.com/447#entry447comment</comments>
      <pubDate>Fri, 8 May 2026 11:52:53 +0900</pubDate>
    </item>
    <item>
      <title>2026년 4월</title>
      <link>https://tbang.tistory.com/446</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tanstack.com/blog/tanstack-ai-code-mode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tanstack ai code mode&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AI 에이전트 구축시 코딩이나 수학적 계산에 특화된 에이전트를 개발할 때 매우 유용할 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.skypilot.co/research-driven-agents/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Research-driven Agents&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.b-list.org/weblog/2026/apr/09/llms/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LLM에 대해서 이야기 해봅시다&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 저자는 LLM이 본질적 어려움을 해결하지는 못하고 있다고 본다. 본질적 어려움(명세&amp;middot;설계&amp;middot;테스트)을 공략해야 한다고 말한다. 미래에 나타날 모델은 이런 부분까지 해결해줄 수 있을지 모르겠지만 현재로선 저자의 주장에 동의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ccunpacked.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;유출된 Claude Code 아키텍처와 정보를 쉽게 확인할 수 있는 웹사이트&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://david.coffee/i-still-prefer-mcp-over-skills/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여전히 MCP를 더 선호합니다. Skills 보다.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LLM Wiki&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 안드레이 카파시의 RAG의 한계를 극복하기 위한 제안&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://lukasniessen.medium.com/iam-everything-you-need-to-know-5d537b007d84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IAM 의 모든 것&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://martinfowler.com/fragments/2026-04-02.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;마티파울러가 말하는 지금 AI 시대에 승리할 수 있는 길&lt;/a&gt;&lt;br /&gt;- 최근 읽었던 글들 중 가장 심플하면서 임팩트 있는 글.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jakub.kr/writing/details-that-make-interfaces-feel-better&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;더 나은 UI 스킬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ntik.me/posts/voice-agent&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;보이스 에이전트&lt;/a&gt;&lt;br /&gt;- 일레븐랩스의 scratch 를 통해서 어떻게 500ms 레이턴시 응답을 구축했나?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://peterszasz.com/agentic-engineering-management/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AEM(Agentic Engineering Management)은 무엇이고 어떻게 할 수 있나?&lt;/a&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;AEM을 구현하려면 회피보다는 발견과 복구에 더 많은 투자를 하는 특정한 조직 문화와 사고방식이 필요합니다. 에이전트의 자율성은 설계상 저위험 영역을 목표로 하며, 적절한 관측성과 신속한 복구를 병행하면 실제 리스크는 상당히 낮습니다. 하지만 이러한 에이전트를 도입하고 자율적으로 작동하게 하려면, 실수를 일상적인 일로 받아들이고 신속한 완화, 복구 및 학습에 초점을 맞추는 문화적 변화가 필요합니다. 두려움과 안전에 기반한 예방 중심의 문화는 이러한 접근 방식을 도입하는 데 어려움을 겪을 것입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 너무 공감하는 내용이다. 실수를 적극적으로 회피할수록 시스템은 경직되고 변화 유연성을 희생해야만 한다. 누구나 실수한다. 이 실수를 빠르게 복구하고 대처할 수 있는 시스템을 구축하는게 더 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://www.koshyjohn.com/blog/ai-should-elevate-your-thinking-not-replace-it/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AI가 사고방식을 대체하는 것이 아니다&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소소한 정보</category>
      <author>T없이맑은I</author>
      <guid isPermaLink="true">https://tbang.tistory.com/446</guid>
      <comments>https://tbang.tistory.com/446#entry446comment</comments>
      <pubDate>Sat, 11 Apr 2026 16:16:17 +0900</pubDate>
    </item>
  </channel>
</rss>