<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 김이더</title>
    <description>The latest articles on DEV Community by 김이더 (@_53fb7c03dd741a6124e4e).</description>
    <link>https://dev.to/_53fb7c03dd741a6124e4e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3805054%2F1dd90bc3-aa4f-4db2-901c-4b52816158cb.png</url>
      <title>DEV Community: 김이더</title>
      <link>https://dev.to/_53fb7c03dd741a6124e4e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_53fb7c03dd741a6124e4e"/>
    <language>en</language>
    <item>
      <title>The Strongest Model Yet Beat Pokémon With Vision Alone — Breaking Down Fable 5</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Wed, 10 Jun 2026 00:46:15 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/the-strongest-model-yet-beat-pokemon-with-vision-alone-breaking-down-fable-5-4fmc</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/the-strongest-model-yet-beat-pokemon-with-vision-alone-breaking-down-fable-5-4fmc</guid>
      <description>&lt;p&gt;More posts at &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;. Original announcement on &lt;a href="https://www.anthropic.com/news/claude-fable-5-mythos-5" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Claude just beat Pokémon FireRed from start to finish.&lt;/p&gt;

&lt;p&gt;No maps. No navigation aids. No game-state feed. Just raw screen pixels.&lt;/p&gt;

&lt;p&gt;Here's why that's a big deal: older Claude models flailed at Pokémon even when you handed them a harness stuffed with helper tools. This new one finished the game on a bare, vision-only harness.&lt;/p&gt;

&lt;p&gt;The model is called &lt;strong&gt;Fable 5&lt;/strong&gt;. Anthropic shipped it today, June 9.&lt;/p&gt;

&lt;p&gt;And there's a catch. If you're on a paid plan you get it for free right now — but &lt;strong&gt;only through June 22.&lt;/strong&gt; From the 23rd you pay separately. More on that trap later.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Mythos Is — The Tier They Kept Locked
&lt;/h2&gt;

&lt;p&gt;Anthropic's lineup was Opus, Sonnet, Haiku. Big, medium, fast.&lt;/p&gt;

&lt;p&gt;But there's another tier sitting &lt;em&gt;above&lt;/em&gt; Opus: &lt;strong&gt;Mythos.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem was that Mythos was so strong Anthropic deliberately kept it off the public shelf. When they revealed Mythos Preview back in April, they didn't hand it to regular users — they routed it through a cybersecurity program called Project Glasswing, to a small vetted set of organizations.&lt;/p&gt;

&lt;p&gt;The reason is blunt. This tier is freakishly good at finding and exploiting software vulnerabilities. In a cyber defender's hands it hardens defenses. In an attacker's hands it's a weapon.&lt;/p&gt;

&lt;p&gt;So Fable 5 is &lt;strong&gt;Mythos with guardrails bolted on.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The naming is a nice touch. Fable comes from the Latin &lt;em&gt;fabula&lt;/em&gt; — "that which is told" — which shares a root with the Greek &lt;em&gt;mythos&lt;/em&gt;. Same model, split into two names by whether the safety classifiers are on. The unguarded original is &lt;strong&gt;Mythos 5&lt;/strong&gt;, still restricted to a vetted few.&lt;/p&gt;

&lt;p&gt;Game-dev analogy: if Mythos 5 is the dev build with all cheats on, Fable 5 is that same build shipped to the public with the dangerous console commands disabled. Same engine. Different doors locked.&lt;/p&gt;

&lt;p&gt;Concretely, when a query touches cybersecurity, biology, chemistry, or distillation, Fable 5 doesn't answer directly — it &lt;strong&gt;hands off to Opus 4.8.&lt;/strong&gt; You don't get a flat refusal; a slightly-lower (but still very strong) model catches the request, and you're told it happened.&lt;/p&gt;

&lt;p&gt;How often does that fallback fire? Anthropic says &lt;strong&gt;under 5% of sessions.&lt;/strong&gt; Flip that around: in 95%+ of sessions nothing gets routed away, and in those you're effectively running the same thing as Mythos 5.&lt;/p&gt;

&lt;p&gt;They stress-tested the guardrails with an external bug bounty — &lt;strong&gt;over 1,000 hours&lt;/strong&gt; of attempts and no universal jailbreak found. (Though the UK AISI reportedly made some progress in a short window, to be fair.)&lt;/p&gt;




&lt;h2&gt;
  
  
  Pricing — $10/$50, Looks Steep But There's Context
&lt;/h2&gt;

&lt;p&gt;Down to business. The number you actually care about.&lt;/p&gt;

&lt;p&gt;Fable 5 and Mythos 5 both cost &lt;strong&gt;$10 per million input tokens and $50 per million output tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lined up against the rest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fable 5 / Mythos 5   $10 / $50
Opus 4.8             $5  / $25   (Fast Mode is $10 / $50)
Sonnet 4.6           $3  / $15
Haiku 4.5            $1  / $5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On paper it's the most expensive publicly-available model ever. But two things matter alongside that.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;it's the same rate as Opus 4.8 Fast Mode.&lt;/strong&gt; Fast Mode runs Opus at ~2.5x speed for $10/$50 — so for that same money you're getting Fable, which sits a tier &lt;em&gt;above&lt;/em&gt; Opus. Same price, stronger engine.&lt;/p&gt;

&lt;p&gt;Second, it's &lt;strong&gt;less than half the price of Mythos Preview.&lt;/strong&gt; They raised the tier and halved the cost at the same time.&lt;/p&gt;

&lt;p&gt;And token rates aren't the whole story. Prompt caching shaves up to 90% off cached input, and the batch API is a flat 50% off. Any workflow with heavy repeated context lands well below the sticker price.&lt;/p&gt;

&lt;p&gt;Anyone who's run servers knows this: judging "expensive" by hourly instance rate is a trap. The real cost is how many hours the job takes. Fable is built to compress exactly those hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance — A 50-Million-Line Codebase Migrated in a Day
&lt;/h2&gt;

&lt;p&gt;One demo settles the performance question.&lt;/p&gt;

&lt;p&gt;In early testing, Stripe ran a codebase-wide migration on a &lt;strong&gt;50-million-line Ruby codebase.&lt;/strong&gt; A human team doing it by hand would've spent over two months. Fable 5 did it in &lt;strong&gt;a day.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human team:  2+ months
Fable 5:     1 day
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The thing that makes this possible is "long-horizon" — the ability to work for days without losing the thread. It plans in stages, delegates to sub-agents, and tests and verifies its own output.&lt;/p&gt;

&lt;p&gt;That Planner/Generator/Evaluator harness you sweat over building by hand? The model ships with a chunk of it baked in. It holds together for days without you orchestrating from the outside.&lt;/p&gt;

&lt;p&gt;The benchmarks back it up. Cognition's FrontierCode eval doesn't just check whether a model solves a coding task — it checks whether it solves it &lt;strong&gt;while meeting production-grade codebase standards.&lt;/strong&gt; Fable 5 tops frontier models there, and it does so at &lt;em&gt;medium&lt;/em&gt; effort. First place without even going full power.&lt;/p&gt;

&lt;p&gt;It's not just coding. It posted the top score on Hebbia's senior-level finance reasoning benchmark, and one partner called it the &lt;strong&gt;first model to break 90%&lt;/strong&gt; on their analytics benchmark — a 10-point jump over Opus.&lt;/p&gt;

&lt;p&gt;Token efficiency improved too. A physics research partner said Fable reached in &lt;strong&gt;36 hours&lt;/strong&gt;, using a third of the reasoning tokens, what GPT-5.5 took four days to reach.&lt;/p&gt;




&lt;h2&gt;
  
  
  Proven Through Games — This Is the Fun Part
&lt;/h2&gt;

&lt;p&gt;As a game programmer, the most interesting thing is that they validated this model &lt;em&gt;through games.&lt;/em&gt; It's far more intuitive than a benchmark number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pokémon FireRed.&lt;/strong&gt; The one from the intro. No map, no pathfinding, pure screen pixels, start to finish. Instead of claiming vision is state-of-the-art with a score, they showed it by pushing a whole game to the credits. There's also a demo of it rebuilding a web app's entire source code from screenshots alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slay the Spire.&lt;/strong&gt; A roguelike deckbuilder — every run is fresh and you learn across attempts. The interesting bit here is the memory experiment. When they gave it persistent file-based memory, the performance boost was &lt;strong&gt;3x larger&lt;/strong&gt; than the same memory gave Opus 4.8. It also reached the game's final act three times as often.&lt;/p&gt;

&lt;p&gt;Why does that matter? Bolt the same memory system onto two models and they use it differently. Handing over a save file is pointless unless the model has the head to read it and apply it next run. Fable's ability to exploit memory is on another level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factorio.&lt;/strong&gt; The factory-automation game engineers obsess over. Fable strategized and built an automated factory on its own, no human input. Anyone who's played it knows that's not a "clear the level" task — it's &lt;strong&gt;systems design plus long-term optimization.&lt;/strong&gt; The days-long, never-dropping long-horizon stamina shows up right inside the game.&lt;/p&gt;

&lt;p&gt;There's more. Deriving a solar-system simulation from physics first principles to predict eclipses. Building a browser CAD editor and then designing a 3D-printable model inside it. Writing a fluid simulation synced to an EDM beat — using code, having never actually heard music.&lt;/p&gt;

&lt;p&gt;Games and simulations don't lie. With a benchmark you can at least suspect overfitting; finishing a game either works or it doesn't. I think that's exactly why Anthropic put the game demos front and center.&lt;/p&gt;




&lt;h2&gt;
  
  
  So What Should a Subscriber Do — June 22 Is the Line
&lt;/h2&gt;

&lt;p&gt;The practical part. Back to that trap.&lt;/p&gt;

&lt;p&gt;If you're on Pro, Max, Team, or a seat-based Enterprise plan, Fable 5 is included in your plan limits at no extra cost &lt;strong&gt;from June 9 through June 22.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On June 23, Anthropic &lt;strong&gt;pulls Fable from those plans.&lt;/strong&gt; After that, using it requires usage credits, billed at API rates ($10/$50).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jun 9 – Jun 22   included, free
Jun 23 –         removed from plans, drawn from credits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason, as always, is capacity. Demand is hard to predict, so they're rolling out conservatively in stages and say they'll restore Fable as a standard plan feature once there's headroom. No date on that, though.&lt;/p&gt;

&lt;p&gt;Some of the community is calling it a bait-and-switch — give it for two weeks, then yank it. Opinions split. Either way, the user move is obvious.&lt;/p&gt;

&lt;p&gt;If you're going to try it, do it before June 22.&lt;/p&gt;

&lt;p&gt;Throw a task at it you've never been able to tackle. A days-long migration, a gnarly multi-agent workflow, a big refactor. The long-horizon work where Opus used to gas out mid-run — you get two free weeks to test exactly that.&lt;/p&gt;

&lt;p&gt;One last note. Business traffic gets a new 30-day data retention policy. Mythos-class models retain data for 30 days for safety purposes (not used for training). If you're running sensitive code, factor that in.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Same price, a stronger engine, free for two weeks.&lt;br&gt;
Not trying it is the actual loss.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>fable5</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>역대 최강 모델이 포켓몬을 비전만으로 깼다 — Fable 5 가격·성능 정리</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Wed, 10 Jun 2026 00:46:14 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/yeogdae-coegang-modeli-pokesmoneul-bijeonmaneuro-ggaessda-fable-5-gagyeogseongneung-jeongri-3nch</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/yeogdae-coegang-modeli-pokesmoneul-bijeonmaneuro-ggaessda-fable-5-gagyeogseongneung-jeongri-3nch</guid>
      <description>&lt;p&gt;더 많은 글은 &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;에서. 원문은 &lt;a href="https://www.anthropic.com/news/claude-fable-5-mythos-5" rel="noopener noreferrer"&gt;Anthropic 공식 발표&lt;/a&gt;에서.&lt;/p&gt;




&lt;p&gt;Claude가 포켓몬 파이어레드를 처음부터 끝까지 클리어했다.&lt;/p&gt;

&lt;p&gt;맵도, 길찾기 보조도, 게임 상태 정보도 없이. 그냥 화면 스크린샷만 보고.&lt;/p&gt;

&lt;p&gt;이게 왜 충격이냐면, 예전 Claude 모델들은 포켓몬 하나 깨려고 별별 보조 도구를 다 붙인 하네스를 만들어줘도 헤맸기 때문이다. 근데 이번에 나온 모델은 비전만 쓰는 최소 하네스로 끝을 봤다.&lt;/p&gt;

&lt;p&gt;그 모델 이름이 &lt;strong&gt;Fable 5&lt;/strong&gt;다. 오늘(6월 9일) Anthropic이 풀었다.&lt;/p&gt;

&lt;p&gt;그리고 함정이 하나 있다. 지금 구독 플랜이면 공짜로 쓸 수 있는데, &lt;strong&gt;6월 22일까지만&lt;/strong&gt; 그렇다. 23일부터는 돈을 따로 내야 한다. 이 얘긴 뒤에서 제대로 다루겠다.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mythos가 뭐길래 — 그동안 안 풀던 등급
&lt;/h2&gt;

&lt;p&gt;Anthropic 모델 라인은 Opus, Sonnet, Haiku였다. 큰 거, 중간 거, 빠른 거.&lt;/p&gt;

&lt;p&gt;근데 그 위에 &lt;strong&gt;Mythos&lt;/strong&gt;라는 등급이 하나 더 있다. Opus보다 윗줄이다.&lt;/p&gt;

&lt;p&gt;문제는 이 Mythos가 너무 세서, Anthropic이 일부러 공개를 안 했다는 거다. 4월에 Mythos Preview를 처음 공개했을 때도 일반 사용자한테 안 풀고, Project Glasswing이라는 사이버보안 프로그램으로 검증된 소수 기관한테만 줬다.&lt;/p&gt;

&lt;p&gt;이유가 명확하다. 이 등급 모델이 소프트웨어 취약점을 찾고 익스플로잇하는 데 비정상적으로 강해서다. 사이버 방어자 손에 들어가면 방어를 강화하지만, 공격자 손에 들어가면 그대로 무기가 된다.&lt;/p&gt;

&lt;p&gt;그래서 Fable 5는 &lt;strong&gt;Mythos에 가드레일을 씌운 버전&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;이름 유래가 재밌다. Fable은 라틴어 &lt;em&gt;fabula&lt;/em&gt;(이야기되는 것)에서 왔고, 이게 그리스어 &lt;em&gt;mythos&lt;/em&gt;랑 같은 뿌리다. 같은 모델인데, 안전장치 유무로 이름을 나눈 거다. 가드레일 없는 원본은 &lt;strong&gt;Mythos 5&lt;/strong&gt;고, 그건 여전히 검증된 소수한테만 간다.&lt;/p&gt;

&lt;p&gt;게임으로 비유하면 이렇다. Mythos 5가 치트 다 켠 개발자 빌드라면, Fable 5는 그 빌드에서 위험한 콘솔 명령어만 막아놓고 일반 배포한 버전이다. 엔진은 같다. 막아놓은 문만 다르다.&lt;/p&gt;

&lt;p&gt;구체적으로 뭘 막느냐면, 사이버보안·생물학·화학·디스틸레이션 관련 질문이 들어오면 Fable 5가 직접 답을 안 하고 &lt;strong&gt;Opus 4.8한테 넘긴다.&lt;/strong&gt; 답을 거부당하는 게 아니라, 한 단계 낮은(그래도 충분히 센) 모델이 대신 받아준다. 사용자한테는 "이거 넘어갔어요"라고 알려준다.&lt;/p&gt;

&lt;p&gt;이 폴백이 얼마나 자주 터지냐. Anthropic 말로는 &lt;strong&gt;세션의 5% 미만&lt;/strong&gt;이다. 거꾸로 말하면 95% 넘는 세션에선 폴백이 한 번도 안 걸리고, 그 세션에선 사실상 Mythos 5랑 똑같은 성능을 쓰는 셈이다.&lt;/p&gt;

&lt;p&gt;가드레일이 얼마나 단단한지는 외부 버그바운티로 검증했다. &lt;strong&gt;1,000시간 넘게&lt;/strong&gt; 뚫으려 했는데 범용 탈옥(universal jailbreak)을 못 찾았다고 한다. 물론 영국 AISI가 짧은 테스트 창에서 진전을 봤다는 단서는 달려 있긴 하다.&lt;/p&gt;




&lt;h2&gt;
  
  
  가격 — $10/$50, 비싸 보이지만 맥락이 있다
&lt;/h2&gt;

&lt;p&gt;본론. 너가 궁금해할 가격부터 깐다.&lt;/p&gt;

&lt;p&gt;Fable 5와 Mythos 5는 똑같이 &lt;strong&gt;입력 100만 토큰당 $10, 출력 100만 토큰당 $50&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;다른 모델이랑 나란히 놓고 보면 이렇다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fable 5 / Mythos 5   $10 / $50
Opus 4.8             $5  / $25   (Fast Mode는 $10 / $50)
Sonnet 4.6           $3  / $15
Haiku 4.5            $1  / $5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;숫자만 보면 역대 일반 공개 모델 중 제일 비싸다. 근데 두 가지를 같이 봐야 한다.&lt;/p&gt;

&lt;p&gt;첫째, &lt;strong&gt;Opus 4.8 Fast Mode랑 단가가 똑같다.&lt;/strong&gt; Opus 4.8을 2.5배 빠르게 돌리는 모드가 $10/$50인데, 그 돈이면 Opus보다 윗줄인 Fable을 쓴다는 얘기다. 같은 값에 더 센 엔진.&lt;/p&gt;

&lt;p&gt;둘째, Mythos Preview 대비 &lt;strong&gt;절반 이하 가격&lt;/strong&gt;이다. 등급은 그대로 올리면서 가격은 반 토막 냈다.&lt;/p&gt;

&lt;p&gt;그리고 토큰 단가가 끝이 아니다. 프롬프트 캐싱 켜면 캐시된 입력은 최대 90% 깎이고, 배치 API는 전체 50% 할인이다. 반복 컨텍스트가 많은 워크플로우면 실제 청구액은 sticker 가격보다 훨씬 내려간다.&lt;/p&gt;

&lt;p&gt;서버 운영해본 사람은 안다. 인스턴스 시간당 단가만 보고 "비싸다"고 하면 틀린다. 같은 일을 몇 시간 만에 끝내냐가 진짜 비용이다. Fable은 바로 그 "몇 시간"을 줄이는 쪽으로 만든 모델이다.&lt;/p&gt;




&lt;h2&gt;
  
  
  성능 — 5천만 줄 코드베이스를 하루 만에 마이그레이션
&lt;/h2&gt;

&lt;p&gt;성능 얘기는 데모 하나로 끝난다.&lt;/p&gt;

&lt;p&gt;Stripe가 초기 테스트에서 &lt;strong&gt;5천만 줄짜리 Ruby 코드베이스&lt;/strong&gt;를 코드베이스 전체 마이그레이션 돌렸다. 사람 팀이 손으로 했으면 두 달 넘게 걸릴 작업을, Fable 5가 &lt;strong&gt;하루&lt;/strong&gt; 만에 끝냈다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;사람 팀:  2개월+
Fable 5:  1일
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이게 가능한 핵심이 "롱호라이즌"이다. 며칠씩 끊기지 않고 일하는 능력. 단계별로 계획 짜고, 서브에이전트한테 일 나눠주고, 자기 결과물을 스스로 테스트하고 검증한다.&lt;/p&gt;

&lt;p&gt;너가 Planner/Generator/Evaluator 하네스 직접 짜면서 고생했던 그 구조를, 모델이 어느 정도 내장하고 들어온 거다. 외부에서 오케스트레이션 안 해줘도 혼자 며칠을 버틴다.&lt;/p&gt;

&lt;p&gt;벤치마크도 받쳐준다. Cognition의 FrontierCode 평가가 있는데, 이건 단순히 코딩 문제를 푸느냐가 아니라 &lt;strong&gt;고품질 프로덕션 코드베이스 기준을 맞추면서&lt;/strong&gt; 푸느냐를 본다. Fable 5는 여기서 프론티어 모델 중 1위인데, 그것도 medium effort에서 그렇다. 풀 파워가 아니라 중간만 켜고도 1등이라는 뜻이다.&lt;/p&gt;

&lt;p&gt;코딩만 잘하는 것도 아니다. Hebbia의 시니어급 금융 추론 벤치마크에서 최고점을 받았고, 한 파트너는 자기네 분석 벤치마크에서 &lt;strong&gt;처음으로 90%를 넘긴 모델&lt;/strong&gt;이라며 Opus 대비 10점 점프라고 했다.&lt;/p&gt;

&lt;p&gt;토큰 효율도 좋아졌다. 한 물리 연구 파트너는 GPT-5.5가 4일 걸려 도달한 지점을 Fable이 &lt;strong&gt;36시간&lt;/strong&gt;에, 그것도 추론 토큰을 3분의 1만 쓰고 도달했다고 했다.&lt;/p&gt;




&lt;h2&gt;
  
  
  게임으로 증명한 부분 — 여기가 진짜 재밌다
&lt;/h2&gt;

&lt;p&gt;게임 프로그래머 입장에서 제일 흥미로운 건 이 모델을 게임으로 검증했다는 점이다. 벤치마크 숫자보다 이게 훨씬 직관적이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;포켓몬 파이어레드.&lt;/strong&gt; 앞에서 말한 그거다. 맵도 길찾기도 없이, 순수 화면 픽셀만 보고 처음부터 끝까지 깼다. 비전이 SOTA라는 걸 점수로 말하는 대신, 게임 하나 끝까지 미는 걸로 보여준 거다. 스크린샷만 보고 웹앱 소스코드를 통째로 재구성하는 데모도 같이 나왔다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slay the Spire.&lt;/strong&gt; 로그라이크 덱빌더다. 여기서 흥미로운 건 메모리 실험이다. 파일 기반 영구 메모리를 붙여줬더니, 그 메모리가 성능을 끌어올린 폭이 Opus 4.8보다 &lt;strong&gt;3배&lt;/strong&gt; 컸다. 게임 최종 막까지 도달한 빈도도 3배 높았다.&lt;/p&gt;

&lt;p&gt;이게 왜 중요하냐. 메모리 시스템을 똑같이 붙여도, 그걸 활용하는 능력이 모델마다 다르다는 거다. 세이브 파일을 줘도 그걸 읽고 다음 판에 써먹는 머리가 있어야 의미가 있다. Fable은 그 활용력이 다르다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factorio.&lt;/strong&gt; 엔지니어들이 환장하는 공장 자동화 게임이다. Fable이 사람 개입 없이 혼자 전략 짜고 자동화 공장을 지었다. Factorio 해본 사람은 이게 단순 클리어가 아니라 &lt;strong&gt;시스템 설계 + 장기 최적화&lt;/strong&gt; 문제라는 걸 안다. 끊김 없이 며칠 버티는 롱호라이즌 능력이 게임 안에서 그대로 드러난다.&lt;/p&gt;

&lt;p&gt;데모는 더 있다. 물리 1원리부터 유도해서 태양계 시뮬레이션을 만들고 일식을 예측하거나, 브라우저 CAD 에디터를 만들고 그 안에서 3D 프린팅 모델을 설계하거나, 한 번도 음악을 들어본 적 없는데 코드로 EDM 비트에 맞춘 유체 시뮬레이션을 짜거나.&lt;/p&gt;

&lt;p&gt;게임과 시뮬레이션은 거짓말을 못 한다. 벤치마크는 오버핏 의심이라도 하지, 게임을 끝까지 미는 건 그냥 되거나 안 되거나다. Anthropic이 굳이 게임 데모를 전면에 깐 이유가 이거라고 본다.&lt;/p&gt;




&lt;h2&gt;
  
  
  그래서 구독자는 뭘 해야 하나 — 6월 22일이 끝이다
&lt;/h2&gt;

&lt;p&gt;여기가 실용 파트다. 다시 그 함정.&lt;/p&gt;

&lt;p&gt;지금 Pro, Max, Team, seat 기반 Enterprise 구독이면 Fable 5가 &lt;strong&gt;6월 9일부터 22일까지&lt;/strong&gt; 추가 비용 없이 플랜 한도 안에서 그냥 쓰인다.&lt;/p&gt;

&lt;p&gt;6월 23일이 되면 Anthropic이 구독 플랜에서 Fable을 &lt;strong&gt;빼버린다.&lt;/strong&gt; 그 이후로 쓰려면 사용 크레딧(usage credit)이 필요하고, API 단가($10/$50) 기준으로 차감된다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6/9 ~ 6/22   구독에 포함, 공짜
6/23 ~       플랜에서 빠짐, 크레딧 차감
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이유는 늘 그렇듯 용량이다. 수요 예측이 안 되니까 일단 보수적으로 단계 배포하는 거고, 인프라 여유가 생기면 다시 구독 기본 기능으로 되돌리겠다고는 했다. 근데 복구 날짜는 안 정해졌다.&lt;/p&gt;

&lt;p&gt;커뮤니티에선 "2주 줬다가 뺏는 거냐"는 반응도 있다. 미끼냐는 거다. 입장은 갈리는데, 어쨌든 사용자 입장에서 할 일은 명확하다.&lt;/p&gt;

&lt;p&gt;쓸 거면 6월 22일 안에 굴려봐라.&lt;/p&gt;

&lt;p&gt;평소 손 못 대던 작업, 한 번 던져보면 된다. 며칠짜리 마이그레이션, 복잡한 멀티에이전트 워크플로우, 큰 리팩토링. Opus가 중간에 퍼지던 롱호라이즌 작업을 이 2주 동안 공짜로 테스트할 수 있다.&lt;/p&gt;

&lt;p&gt;마지막으로 하나. 비즈니스 트래픽은 30일 데이터 보존 정책이 새로 붙는다. Mythos 등급 모델은 안전 목적상 30일간 데이터를 보관한다(학습엔 안 쓴다). 민감한 코드 돌릴 거면 이건 알고 가자.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;같은 값에 더 센 엔진을 2주간 공짜로 준다.&lt;br&gt;
안 굴려보는 게 손해다.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>fable5</category>
    </item>
    <item>
      <title>GPT-5.5 Is Out — What the Numbers Actually Say</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Fri, 24 Apr 2026 01:54:00 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/gpt-55-is-out-what-the-numbers-actually-say-42l</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/gpt-55-is-out-what-the-numbers-actually-say-42l</guid>
      <description>&lt;p&gt;More posts at &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Yesterday (April 23, 2026) OpenAI released GPT-5.5. Codename "Spud."&lt;/p&gt;

&lt;p&gt;The surprising part isn't the model itself. GPT-5.4 shipped six weeks ago.&lt;/p&gt;

&lt;p&gt;OpenAI's Chief Scientist Jakub Pachocki said during the briefing that the last two years have actually been slow. That one line is the real context for this release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Six Weeks, and "Spud"
&lt;/h2&gt;

&lt;p&gt;GPT-5.4 came out six weeks ago. The release before that was in December. Before that, November.&lt;/p&gt;

&lt;p&gt;The era when model releases were quarterly events is over. They're weekly-to-monthly events now.&lt;/p&gt;

&lt;p&gt;The reason this pace is possible is simple. AI is accelerating AI development. According to OpenAI, Codex has 4 million weekly active users and ChatGPT has 9 million paying business users. Real usage feedback at that scale flows straight back into the next training cycle.&lt;/p&gt;

&lt;p&gt;Look at Pachocki's statement again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The last two years have been surprisingly slow."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He's not saying the present is slow. He's declaring that the future will be faster. GPT-5.5 arrived in six weeks and even that, he's saying, was slow.&lt;/p&gt;

&lt;p&gt;Greg Brockman described it in the same briefing as "a new class of intelligence" and "a big step toward agentic and intuitive computing." Strip the marketing and one thing remains: the model refresh cycle is now shorter than most product planning cycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benchmarks, As Published
&lt;/h2&gt;

&lt;p&gt;Here are the numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terminal-Bench 2.0&lt;/strong&gt; — complex command-line workflows requiring planning, tool use, and iteration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5         82.7%
GPT-5.4         75.1%
Claude Opus 4.7 69.4%
Gemini 3.1 Pro  68.5%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OSWorld-Verified&lt;/strong&gt; — how well the model operates a computer autonomously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5         78.7%
Claude Opus 4.7 78.0%
GPT-5.4         75.0%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SWE-Bench Pro&lt;/strong&gt; — resolving real GitHub issues in a single pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5   58.6%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Terminal-Bench, GPT-5.5 leads Opus 4.7 by 13.3 points. That's a big jump. But on OSWorld, the gap is 0.7 points. Dominant on one axis, barely ahead on another.&lt;/p&gt;

&lt;p&gt;Not "crushing it" — just leading. And the era of ranking models by a single benchmark is already behind us. Computer use has been an area Anthropic invested in heavily, and the more honest reading is that OpenAI just about caught up rather than blew past.&lt;/p&gt;

&lt;p&gt;Also: benchmarks are marketing material. OpenAI picked the numbers favorable to them. Real-world feel is something each team has to verify on their own workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  1M Context and Weird Token Economics
&lt;/h2&gt;

&lt;p&gt;The pricing is interesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5        $5 / $30   per 1M tokens (input / output)
GPT-5.5 Pro    $30 / $180 per 1M tokens (input / output)
Context window 1M
Batch / Flex   half the standard rate
Priority       2.5x the standard rate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's more expensive than GPT-5.4. But OpenAI claims it does the same work with fewer tokens. Their own post states that GPT-5.5 matches GPT-5.4 per-token latency in production serving.&lt;/p&gt;

&lt;p&gt;Translation: the unit price went up, but token consumption goes down enough that the final bill could be similar or lower. What actually hits your wallet depends on your workload. Long-running agent tasks with lots of reasoning might come out ahead. Apps with tons of short one-shot calls might just get more expensive.&lt;/p&gt;

&lt;p&gt;And 1M context. OpenAI caught up to territory Anthropic entered earlier. Long document analysis, full-repo understanding, long-running agent sessions — there are real workloads where 1M matters.&lt;/p&gt;

&lt;p&gt;Worth noting is the GPT-5.5 Pro pricing. $30 input, $180 output. That's not priced for hobby developers. It's squarely an enterprise workload tier — agents running all day, complex research pipelines, nothing else makes sense at those rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mythos, Code Red, and the Shape of Competition
&lt;/h2&gt;

&lt;p&gt;The most telling line in the Axios report is this.&lt;/p&gt;

&lt;p&gt;Internally at OpenAI, Anthropic's rise was reportedly treated as a "code red" moment, and that moment drove a pivot toward enterprise customers.&lt;/p&gt;

&lt;p&gt;In the GPT-5.5 briefing OpenAI explicitly referenced Anthropic's Mythos. Mythos is Anthropic's latest frontier model, announced earlier this month but with a limited rollout due to cybersecurity capabilities. OpenAI's reason for bringing it up is clear: the signal they want to send is "we have Mythos-class cyber capability too."&lt;/p&gt;

&lt;p&gt;The frontier model race right now isn't tech versus tech. It's enterprise budget versus enterprise budget. Fortune's piece quotes the CIO of Bank of New York, where they're running Anthropic and OpenAI side by side across 220+ AI use cases. Customers like that are the ones actually moving the market.&lt;/p&gt;

&lt;p&gt;The real reason models ship every six weeks is here. It's not technical necessity. It's that your competitor can ship every six weeks. The moment you slow down, enterprise contracts start sliding over.&lt;/p&gt;

&lt;p&gt;The interesting part is that this competitive dynamic is a win for users. A better model every six weeks, with pricing pressure arriving alongside it. Just having multiple frontier labs active keeps the whole field healthier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Left Behind the Numbers
&lt;/h2&gt;

&lt;p&gt;So what do you actually do with this.&lt;/p&gt;

&lt;p&gt;Building your stack around a single model is an increasingly bad bet. There's a very high probability that a better model ships in six weeks. Might be OpenAI. Might be Anthropic. Might be Google. You can't predict which one.&lt;/p&gt;

&lt;p&gt;The investment goes one layer up. Harness design, multi-agent orchestration, tool chains, evaluation pipelines, context engineering. These layers survive model swaps. Better yet, they get better as models get better.&lt;/p&gt;

&lt;p&gt;Releases like GPT-5.5 are no longer news — they're environment. Infrastructure that updates on a schedule. Building your workflow on that assumption is the realistic stance for 2026.&lt;/p&gt;

&lt;p&gt;The people who don't get emotionally tossed around by a 1-2 point benchmark swing are the ones who go the distance. If Terminal-Bench 82.7% becomes 85% in a few months, your workflow design mostly still applies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Models get replaced. Workflows compound."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>gpt</category>
      <category>benchmarks</category>
    </item>
    <item>
      <title>GPT-5.5가 공개됐다, 숫자로 뜯어보면</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Fri, 24 Apr 2026 01:53:28 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/gpt-55ga-gonggaedwaessda-susjaro-ddeudeobomyeon-7o7</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/gpt-55ga-gonggaedwaessda-susjaro-ddeudeobomyeon-7o7</guid>
      <description>&lt;p&gt;더 많은 글은 &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;에서.&lt;/p&gt;




&lt;p&gt;어제(2026/4/23) OpenAI가 GPT-5.5를 공개했다. 코드네임 "Spud".&lt;/p&gt;

&lt;p&gt;놀라운 건 모델 자체가 아니다. GPT-5.4가 나온 게 6주 전이다.&lt;/p&gt;

&lt;p&gt;OpenAI 수석과학자 Jakub Pachocki는 브리핑에서 "지난 2년이 오히려 느렸다"고 말했다. 이 한 문장이 이 릴리스의 진짜 맥락이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  6주, 그리고 "Spud"
&lt;/h2&gt;

&lt;p&gt;GPT-5.4는 6주 전에 나왔다. 그 전 릴리스는 12월, 그 전은 11월.&lt;/p&gt;

&lt;p&gt;모델이 분기 단위 이벤트였던 시대는 지나갔다. 지금은 주 단위, 길어야 한 달 단위 이벤트다.&lt;/p&gt;

&lt;p&gt;이 속도가 가능한 이유는 단순하다. AI가 AI 개발을 가속하고 있다. OpenAI 발표에 따르면 Codex 주간 사용자가 4백만, ChatGPT 유료 업무 사용자가 9백만이다. 이 규모의 실사용 피드백이 바로 다음 학습 사이클로 돌아간다.&lt;/p&gt;

&lt;p&gt;Pachocki의 발언을 다시 보자.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"지난 2년이 오히려 느렸다."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이건 지금이 느리다는 말이 아니다. 앞으로는 더 빨라질 거라는 선언이다. GPT-5.5도 6주 만에 나왔는데, 이것조차 느렸다는 말이다.&lt;/p&gt;

&lt;p&gt;Greg Brockman은 같은 브리핑에서 "새로운 종류의 지능이고, 에이전틱하고 직관적인 컴퓨팅으로 가는 큰 한 걸음"이라고 표현했다. 마케팅 수사를 걷어내면 남는 건 하나다. 모델 교체 주기가 제품 기획 주기보다 짧아지고 있다.&lt;/p&gt;

&lt;h2&gt;
  
  
  벤치마크 숫자, 있는 그대로
&lt;/h2&gt;

&lt;p&gt;수치부터 정리해보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terminal-Bench 2.0&lt;/strong&gt; — 복잡한 커맨드라인 워크플로우(계획 → 도구 사용 → 반복) 평가:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5         82.7%
GPT-5.4         75.1%
Claude Opus 4.7 69.4%
Gemini 3.1 Pro  68.5%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OSWorld-Verified&lt;/strong&gt; — 모델이 컴퓨터를 독립적으로 조작하는 능력 평가:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5         78.7%
Claude Opus 4.7 78.0%
GPT-5.4         75.0%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SWE-Bench Pro&lt;/strong&gt; — 실제 GitHub 이슈를 단일 시도로 해결:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5   58.6%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminal-Bench에서 Opus 4.7 대비 +13.3%p 차이. 큰 점프다. 그런데 OSWorld에서는 Opus 4.7과 0.7%p 차이. 어떤 축에서는 크게 앞서고, 어떤 축에서는 턱걸이다.&lt;/p&gt;

&lt;p&gt;"압도"가 아니라 "리드"다. 그리고 벤치마크 하나로 모델을 줄 세우는 시대는 이미 지났다. 컴퓨터 조작 능력은 Anthropic이 꾸준히 투자해온 영역이고, 그 격차를 OpenAI가 이번에 이번에 거의 따라붙었다 — 정도의 해석이 오히려 더 정확하다.&lt;/p&gt;

&lt;p&gt;그리고 벤치마크는 마케팅 자료다. OpenAI가 자기에게 유리한 지표를 골라서 내놓는다. 실제 워크플로우에서 체감은 각자 검증해야 한다.&lt;/p&gt;

&lt;h2&gt;
  
  
  1M 컨텍스트와 이상한 토큰 경제
&lt;/h2&gt;

&lt;p&gt;API 가격표가 재밌다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT-5.5        $5 / $30   per 1M tokens (input / output)
GPT-5.5 Pro    $30 / $180 per 1M tokens (input / output)
Context window 1M
Batch / Flex   정가의 절반
Priority       정가의 2.5배
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GPT-5.4보다 비싸다. 그런데 OpenAI는 "같은 일을 더 적은 토큰으로 끝낸다"고 주장한다. 실제 자사 블로그에는 "GPT-5.5가 실제 서빙에서 GPT-5.4와 같은 토큰당 지연시간을 유지한다"는 문장이 있다.&lt;/p&gt;

&lt;p&gt;무슨 말이냐. 단가는 올랐지만 토큰 소비량이 줄어서 결과적으로 청구서가 비슷하거나 더 낮을 수 있다는 주장이다. 실제 지갑에 뭐가 찍힐지는 워크로드마다 다르다. 추론이 긴 에이전트 태스크에서는 유리할 수 있고, 짧은 단답형 콜이 많은 앱에서는 그냥 비싸질 수도 있다.&lt;/p&gt;

&lt;p&gt;그리고 1M 컨텍스트. Anthropic이 먼저 간 구간을 OpenAI도 따라왔다. 긴 문서 분석, 큰 레포지토리 이해, 롱런 에이전트 세션 — 1M이 의미 있는 워크로드는 분명히 존재한다.&lt;/p&gt;

&lt;p&gt;주목할 건 GPT-5.5 Pro 가격이다. 입력 $30, 출력 $180. 이건 일반 개발자용이 아니다. 명백히 엔터프라이즈 워크로드를 위한 가격이다. 에이전트가 하루 종일 돌아가는 케이스, 복잡한 연구 워크플로우 — 이런 데만 의미 있는 티어다.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mythos, code red, 그리고 경쟁의 얼굴
&lt;/h2&gt;

&lt;p&gt;Axios 리포트에서 가장 시사적인 한 문장은 이거다.&lt;/p&gt;

&lt;p&gt;OpenAI 내부에서 Anthropic의 부상이 "code red" 수준으로 인식됐고, 이게 엔터프라이즈 고객 전략을 선회시킨 계기라는 보도.&lt;/p&gt;

&lt;p&gt;GPT-5.5 브리핑에서 OpenAI는 Anthropic의 Mythos를 명시적으로 언급했다. Mythos는 Anthropic이 이달 초 발표한 최신 모델인데, 사이버보안 역량 때문에 출시 범위가 제한된 상태다. OpenAI가 이걸 언급하는 이유는 분명하다. "우리도 Mythos급 사이버 역량이 있다"는 신호를 보내는 거다.&lt;/p&gt;

&lt;p&gt;지금 프론티어 모델 경쟁은 기술 대 기술이 아니다. 엔터프라이즈 예산 대 엔터프라이즈 예산이다. Fortune에 실린 Bank of New York CIO 코멘트를 보면 감이 온다. 그 은행은 Anthropic과 OpenAI를 병행 테스트하고 있고, 220+ AI 유스케이스를 돌리고 있다. 이런 고객이 실제 판을 흔든다.&lt;/p&gt;

&lt;p&gt;6주마다 모델이 나오는 진짜 이유도 여기에 있다. 기술적으로 필요해서가 아니라, 상대가 6주마다 낼 수 있으니까. 한쪽이 멈추는 순간 엔터프라이즈 계약이 이동한다.&lt;/p&gt;

&lt;p&gt;재밌는 건 이 경쟁 구도 자체가 사용자에게는 호재라는 점이다. 6주마다 더 좋은 모델이 나오고, 가격 압력도 같이 들어온다. 프론티어 랩이 여러 개 있다는 사실만으로도 판이 건강해진다.&lt;/p&gt;

&lt;h2&gt;
  
  
  숫자 뒤에 남는 질문
&lt;/h2&gt;

&lt;p&gt;그래서 뭘 해야 하나.&lt;/p&gt;

&lt;p&gt;모델 하나에 스택을 맞추는 건 점점 손해 보는 선택이다. 6주 뒤에 더 좋은 모델이 나올 확률이 매우 높기 때문이다. OpenAI가 낼 수도, Anthropic이 낼 수도, Google이 낼 수도 있다. 누가 낼지 미리 알 수 없다.&lt;/p&gt;

&lt;p&gt;투자 포인트는 그 위 계층이다. 하네스, 멀티 에이전트 오케스트레이션, 툴 체인, 평가 파이프라인, 컨텍스트 엔지니어링. 이 계층은 모델이 바뀌어도 유지된다. 오히려 모델이 좋아질수록 이 계층이 더 잘 돌아간다.&lt;/p&gt;

&lt;p&gt;GPT-5.5 같은 릴리스는 이제 뉴스라기보다 환경이다. 주기적으로 업데이트되는 인프라. 그걸 전제로 워크플로우를 짜는 게 2026년의 현실적인 접근이다.&lt;/p&gt;

&lt;p&gt;벤치마크 1~2%p에 감정적으로 흔들리지 않는 쪽이 길게 간다. Terminal-Bench 82.7%가 몇 달 뒤에 85%로 바뀌어도, 워크플로우 설계는 대부분 그대로 쓸 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"모델은 교체된다. 워크플로우는 축적된다."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>gpt</category>
    </item>
    <item>
      <title>The 12 Hours Claude Code Disappeared from Pro</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Thu, 23 Apr 2026 10:14:22 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/the-12-hours-claude-code-disappeared-from-pro-51jf</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/the-12-hours-claude-code-disappeared-from-pro-51jf</guid>
      <description>&lt;p&gt;The original issue is on &lt;a href="https://github.com/anthropics/claude-code/issues/42796" rel="noopener noreferrer"&gt;GitHub #42796&lt;/a&gt;, and coverage is at &lt;a href="https://www.theregister.com/2026/04/22/anthropic_removes_claude_code_pro/" rel="noopener noreferrer"&gt;The Register&lt;/a&gt;.&lt;br&gt;
More posts at &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;On the afternoon of April 21, 2026, Anthropic quietly removed Claude Code from the Pro plan.&lt;/p&gt;

&lt;p&gt;The "includes Claude Code" line disappeared from the pricing page. The support docs that read "Using Claude Code with your Pro or Max plan" became "Using Claude Code with your Max plan." A few hours later, everything was rolled back. But this wasn't a one-off mistake.&lt;/p&gt;

&lt;p&gt;The adaptive thinking rollout in February. The lowered default effort level in March. The AMD director's public analysis on April 6. The Pro removal experiment on April 21. These four points look like separate incidents, but they connect into one line.&lt;/p&gt;

&lt;p&gt;Anthropic can't handle the economics of the long-running agent era, and they're trying several things at once to handle it.&lt;/p&gt;

&lt;p&gt;Here's how those attempts connect, and how to read this signal if you're someone introducing AI coding tools into a team.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Exactly Happened on April 21
&lt;/h2&gt;

&lt;p&gt;Ed Zitron caught it first. On Anthropic's pricing page, the Pro tier's "includes Claude Code" checkmark had turned into a red X. The support docs were updated too. The Claude Code product page still mentioned Pro, but the core billing page had clearly pivoted to "Max only."&lt;/p&gt;

&lt;p&gt;When The Register started reporting, Anthropic's Head of Growth Amol Avasare posted an explanation on X. "We're running a small test on ~2% of new prosumer signups. Existing Pro and Max subscribers aren't affected."&lt;/p&gt;

&lt;p&gt;The part that came after is more interesting.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When we launched Max a year ago, it didn't include Claude Code, Cowork didn't exist, and agents that run for hours weren't a thing. Max was designed for heavy chat usage, that's it."&lt;/p&gt;

&lt;p&gt;"Since then, we bundled Claude Code into Max and it took off after Opus 4. Cowork landed. Long-running async agents are now everyday workflows. The way people actually use a Claude subscription has changed fundamentally."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Put "it's a 2% test" next to this and it stops sounding like a small experiment. It sounds closer to an admission that the current plan structure can't carry current usage patterns.&lt;/p&gt;

&lt;p&gt;And two weeks before this, another event had already been building the same case.&lt;/p&gt;
&lt;h2&gt;
  
  
  Two Weeks Earlier: An AMD Director Showed Up With Telemetry
&lt;/h2&gt;

&lt;p&gt;On April 2, Stella Laurenzo, director of AMD's AI group, filed issue #42796 against the Claude Code repo. The title: "Claude Code is unusable for complex engineering tasks with the Feb updates."&lt;/p&gt;

&lt;p&gt;Laurenzo didn't write a vibes post about Claude feeling dumber. She brought quantitative analysis of 6,852 Claude Code sessions from her team's past three months, 234,760 tool calls, 17,871 thinking blocks. The former Google OpenXLA lead and current AI head at a $200B+ semiconductor company doesn't file a public GitHub issue on a hunch.&lt;/p&gt;

&lt;p&gt;Three numbers matter. Thinking depth dropped 67% on average starting late February. The reads-per-edit ratio — how many files the model reads before editing one — fell from 6.6 to 2.0, a 70% reduction. And a stop-hook script built to catch "dodging responsibility, premature stopping, and permission-seeking" behavior never fired before March 8, then fired 173 times in the 17 days after.&lt;/p&gt;

&lt;p&gt;Laurenzo's own words sharpen the picture.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When thinking is shallow, the model defaults to the cheapest action available: edit without reading, stop without finishing, dodge responsibility for failures, take the simplest fix rather than the correct one. These are exactly the symptoms observed."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From a game programmer's angle, this data hurts in a specific way. A reads-per-edit of 6.6 is the signature of a workflow that goes "read headers, trace dependencies, grep for usages, read tests, then modify." On a complex codebase — imagine UE5 C++ with its web of headers, cpp files, USTRUCTs, and TMaps — having that number drop to 2.0 effectively means "patch and pray."&lt;/p&gt;

&lt;p&gt;Laurenzo's team eventually moved to another provider. The line she left behind is the one that matters.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Six months ago, Claude was unique in its reasoning quality and execution capabilities. Now, other competitors need to be very seriously considered and evaluated."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Anthropic's Rebuttal, and a Half-Admission
&lt;/h2&gt;

&lt;p&gt;Boris Cherny from the Claude Code team showed up in the issue. His response mixes pushback and concession, and both halves are worth separating.&lt;/p&gt;

&lt;p&gt;The pushback: the redact-thinking header shipped in March is a UI-only change. The actual reasoning still happens under the hood. It doesn't affect the thinking budget or the underlying reasoning mechanism. What Laurenzo measured is the length of redacted thinking signatures, so what she's seeing could be a loss of external observability rather than a real drop in reasoning.&lt;/p&gt;

&lt;p&gt;The concession: two substantive changes did ship. On February 9, Opus 4.6 launched alongside adaptive thinking — instead of a fixed budget, the model now decides how much to think per turn. On March 3, the default effort level dropped from High to Medium (85 out of 100). Boris framed this as "a sweet spot on the intelligence-latency curve."&lt;/p&gt;

&lt;p&gt;When users started sharing actual session transcripts, Boris moved further. He acknowledged that adaptive thinking appears to under-allocate reasoning on specific turns. The fixes he offered: &lt;code&gt;/effort high&lt;/code&gt; or &lt;code&gt;/effort max&lt;/code&gt; in the session, &lt;code&gt;CLAUDE_CODE_EFFORT_LEVEL=max&lt;/code&gt; as an environment variable, and &lt;code&gt;CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1&lt;/code&gt; to force a fixed budget.&lt;/p&gt;

&lt;p&gt;Here's the compressed version. The model itself didn't get dumber, but &lt;strong&gt;the defaults quietly got lower, and users have to turn them back up manually.&lt;/strong&gt; It's structurally the same as a car company lowering your engine's output and telling you to press the gas harder.&lt;/p&gt;

&lt;p&gt;This framing is what connects directly to the April 21 Pro removal.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Line: Quiet Degradation → Explicit Removal Experiment
&lt;/h2&gt;

&lt;p&gt;View the Laurenzo issue and the Pro removal separately and they each look like annoying individual mishaps. View them together and the pattern appears.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feb 9    Opus 4.6 + adaptive thinking ship
Mar 3    Default effort: High → Medium
Early Mar Thinking content redaction fully rolled out
Apr 2    Laurenzo files issue #42796
Apr 6    Boris's official response (UI-only claim + admits default drop)
Apr 21   Claude Code removed from Pro (~12 hours before rollback)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this timeline shows is clear. Anthropic is trying to push down costs through two different mechanisms. One is &lt;strong&gt;quiet degradation&lt;/strong&gt; — making the same price do less thinking. The other is &lt;strong&gt;explicit removal&lt;/strong&gt; — pushing the same feature up into a more expensive tier.&lt;/p&gt;

&lt;p&gt;Quiet degradation works until it gets caught. When it does, you can explain it as "that's a UI change, just flip your effort setting." But when someone like Laurenzo shows up with telemetry, that line stops working.&lt;/p&gt;

&lt;p&gt;Explicit removal is the stronger card. A structural change cuts off future usage at the source. The downside is that it's visible the moment it lands. The instant a red X shows up on the Pro page, X and Hacker News and Reddit light up simultaneously. That's exactly what happened on April 21, and Anthropic backed out within half a day.&lt;/p&gt;

&lt;p&gt;Running both cards at once isn't unusual — it's pretty standard price experimentation. The question is the &lt;strong&gt;order&lt;/strong&gt;. The quiet card went first and didn't fully take, so the explicit card came next. Read Avasare's line one more time: "our current plans weren't built for this." That's not a 2% test sentence. That's a structural overhaul sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Economics: Why the Netflix Model Breaks
&lt;/h2&gt;

&lt;p&gt;To understand why this is happening, you have to go one layer deeper. An AI subscription isn't Netflix.&lt;/p&gt;

&lt;p&gt;Traditional SaaS like Netflix has near-zero marginal cost per user. One more signup rewatching House of Cards is a small bandwidth cost, not a new content production cost. In that model, power users are assets. They drive word-of-mouth, they lower churn, they validate the bundle.&lt;/p&gt;

&lt;p&gt;Agent services are the opposite. Every time a user runs an agent, GPU time actually burns. A Sonnet response is a few cents, Opus is more, and a long-running agent making 200 tool calls can burn through several dollars a day per user. That math runs hot.&lt;/p&gt;

&lt;p&gt;In this structure, power users aren't assets — &lt;strong&gt;they're liabilities.&lt;/strong&gt; The more they use, the more the company loses on them. A user running Claude Code 8 hours a day on a $20 Pro plan consumes far more compute than their subscription pays for. Normally that gets subsidized by lighter users' subscriptions. But once long-running agent workflows become routine, the ratio of "light users" shrinks. The subsidy breaks.&lt;/p&gt;

&lt;p&gt;This isn't Anthropic's problem alone. Sam Altman said last year that even the $200 ChatGPT Pro plan runs at a loss because of usage. OpenAI, Cursor, Replit — they're all hitting the same wall. Cursor moved to credits. Replit moved to effort-based billing. Google Gemini introduced hard caps. The whole industry is migrating to usage-based pricing at roughly the same time.&lt;/p&gt;

&lt;p&gt;Anthropic's options, in broad strokes, are three. Split plans (a Pro Plus tier at $40–$50 between Pro and Max). Shrink what existing plans include (the Pro removal experiment). Or lower the model's defaults (the effort drop). Right now they're running the latter two in parallel while watching community reaction to see if they can move on the first.&lt;/p&gt;

&lt;h2&gt;
  
  
  From a Game Programmer's Angle: How to Read This Signal
&lt;/h2&gt;

&lt;p&gt;If you're pushing AI coding tool adoption inside a company, this episode changes a few operational decisions.&lt;/p&gt;

&lt;p&gt;The first is &lt;strong&gt;bringing measurement back in-house.&lt;/strong&gt; The real lesson Laurenzo left isn't the 67% number itself — it's that she had the infrastructure to produce it. 6,852 session logs were sitting under &lt;code&gt;~/.claude/projects/&lt;/code&gt;, and she could parse the JSONL, correlate the length of thinking block signatures with actual content length (Pearson r=0.971), and run the analysis. Without that, the whole thing would have ended at "Claude feels off lately."&lt;/p&gt;

&lt;p&gt;If your team is on Claude Code, it's worth collecting session logs somewhere and tracking at least the read-to-edit ratio. Anthropic has not officially committed to exposing thinking token counts in API responses. When vendors don't give you the metric, you have to build it.&lt;/p&gt;

&lt;p&gt;The second is &lt;strong&gt;avoiding single-provider lock-in.&lt;/strong&gt; This isn't "I hate Claude" — it's risk hedging. A team using only Claude Code right now has its dev process exposed to whatever pricing experiment Anthropic runs next. Codex is catching up fast. Local model options — DeepSeek, Qwen Coder — have meaningfully closed the gap for coding workloads. Keep Claude as primary, but keep a backup provider your team can actually run.&lt;/p&gt;

&lt;p&gt;The third is &lt;strong&gt;pinning effort and budget settings explicitly.&lt;/strong&gt; Now that adaptive thinking is the default, anything resembling complex engineering work should have &lt;code&gt;/effort high&lt;/code&gt; or &lt;code&gt;CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1&lt;/code&gt; baked into the team standard. Defaults can drop again, and the drop may not come with a loud announcement.&lt;/p&gt;

&lt;p&gt;The fourth is &lt;strong&gt;distrusting "unlimited" marketing.&lt;/strong&gt; The real lesson here: contracts with explicit numeric limits are safer than ones without. "Unlimited on the Pro plan" isn't a promise, it's copy. It gets redefined the moment usage patterns shift. A Max 20x hard cap of "N Opus calls per day" is, long-term, the more defensible contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Gained and What We Lost
&lt;/h2&gt;

&lt;p&gt;One gain. Anthropic now knows &lt;strong&gt;where the community's line is.&lt;/strong&gt; Rolling back in 12 hours means the reaction overshot their model. The next experiment will be built with this data, and it'll be smoother — probably as a Pro Plus tier.&lt;/p&gt;

&lt;p&gt;One loss. A layer of trust. Read Laurenzo's line one more time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Six months ago, Claude was unique in its reasoning quality and execution capabilities. Now, other competitors need to be very seriously considered and evaluated."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a competitive take and a contract take at the same time. The moment you depend on a tool for your dev process, that vendor's pricing experiments become your team's productivity risk. Whether that's an acceptable risk has to be re-calculated every time an event like this hits.&lt;/p&gt;

&lt;p&gt;April 21's 12 hours were Anthropic testing the range of what they can move. They were also us re-measuring how much we can depend.&lt;/p&gt;

&lt;p&gt;Both numbers are worth keeping in mind.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Our current plans weren't built for this." — That's not the end of the pricing experiment. That's the start.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>claudecode</category>
      <category>aitooling</category>
    </item>
    <item>
      <title>Claude Code가 Pro에서 사라진 12시간 - Anthropic의 조용한 하향과 명시적 제거 사이</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Thu, 23 Apr 2026 10:14:21 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/claude-codega-proeseo-sarajin-12sigan-anthropicyi-joyonghan-hahyanggwa-myeongsijeog-jegeo-sai-3mfi</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/claude-codega-proeseo-sarajin-12sigan-anthropicyi-joyonghan-hahyanggwa-myeongsijeog-jegeo-sai-3mfi</guid>
      <description>&lt;p&gt;원문 이슈는 &lt;a href="https://github.com/anthropics/claude-code/issues/42796" rel="noopener noreferrer"&gt;GitHub #42796&lt;/a&gt;에, 관련 보도는 &lt;a href="https://www.theregister.com/2026/04/22/anthropic_removes_claude_code_pro/" rel="noopener noreferrer"&gt;The Register&lt;/a&gt;에서 볼 수 있다.&lt;br&gt;
더 많은 글은 &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;에서.&lt;/p&gt;



&lt;p&gt;2026년 4월 21일 오후, Anthropic이 Claude Pro 요금제 페이지에서 Claude Code를 조용히 지웠다.&lt;/p&gt;

&lt;p&gt;가격 페이지의 "Claude Code 포함" 문구가 사라졌고, 지원 문서의 "Using Claude Code with your Pro or Max plan"이 "Using Claude Code with your Max plan"으로 바뀌었다. 몇 시간 뒤 전부 원복됐지만, 이건 단발성 실수가 아니다.&lt;/p&gt;

&lt;p&gt;2월의 adaptive thinking 도입, 3월의 effort 기본값 하향, 4월 6일 AMD 디렉터의 공개 분석 보고서, 그리고 4월 21일의 Pro 제거 실험까지 — 서로 떨어진 사건처럼 보이는 이 네 개의 점은 하나의 선으로 이어진다.&lt;/p&gt;

&lt;p&gt;Anthropic은 long-running agent 시대의 경제학을 감당하지 못하고 있고, 감당하기 위해 여러 가지를 동시에 시도하고 있다.&lt;/p&gt;

&lt;p&gt;그 시도들이 어떻게 연결되는지, 그리고 회사에 AI 코딩 도구를 도입하는 입장에서 이 시그널을 어떻게 읽어야 하는지를 정리해본다.&lt;/p&gt;


&lt;h2&gt;
  
  
  4월 21일 오후에 정확히 무슨 일이 있었나
&lt;/h2&gt;

&lt;p&gt;Ed Zitron이 가장 먼저 포착했다. Anthropic의 가격 페이지에서 Pro 요금제의 "Claude Code 포함" 체크 표시가 빨간 X로 바뀌어 있었다. 지원 문서도 수정됐다. Claude Code 제품 페이지는 여전히 Pro를 언급하고 있었지만, 핵심 과금 페이지는 명확하게 "Max 전용"으로 돌아서 있었다.&lt;/p&gt;

&lt;p&gt;The Register가 취재에 들어가자 Anthropic의 Head of Growth인 Amol Avasare가 X에 해명을 올렸다. "신규 prosumer 가입자의 약 2%를 대상으로 한 작은 테스트고, 기존 Pro/Max 구독자는 영향 없다."&lt;/p&gt;

&lt;p&gt;그런데 그 해명의 뒷부분이 더 흥미롭다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"우리가 1년 전 Max를 출시했을 때, Claude Code도 Cowork도 없었고 몇 시간씩 돌아가는 에이전트도 없었다. Max는 헤비한 채팅 사용을 위해 설계된 플랜이다, 그게 전부였다."&lt;/p&gt;

&lt;p&gt;"그 뒤로 Claude Code를 Max에 번들링했고 Opus 4 이후 폭발적으로 성장했다. Cowork가 나왔다. 장시간 비동기 에이전트가 일상적인 워크플로우가 됐다. 사람들이 Claude 구독을 실제로 쓰는 방식이 근본적으로 바뀌었다."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;2% 테스트라는 해명과 이 발언을 같이 놓고 보면, "작은 실험"이 아니다. 현재 요금제 구조 자체가 현재 사용 패턴을 감당 못 한다는 고백에 가깝다.&lt;/p&gt;

&lt;p&gt;그리고 이 고백을 뒷받침하는 또 다른 사건이 2주 전에 이미 있었다.&lt;/p&gt;
&lt;h2&gt;
  
  
  2주 전: AMD AI 디렉터가 telemetry를 들고 나타났다
&lt;/h2&gt;

&lt;p&gt;4월 2일, AMD의 AI 그룹 디렉터 Stella Laurenzo가 Claude Code GitHub 레포에 이슈 #42796을 올렸다. 제목: "Claude Code is unusable for complex engineering tasks with the Feb updates."&lt;/p&gt;

&lt;p&gt;Laurenzo는 "요새 멍청해진 것 같다" 같은 감성 토크를 한 게 아니다. 자기 팀이 3개월간 쓴 Claude Code 세션 로그 6,852개, tool call 234,760개, thinking block 17,871개를 정량 분석해서 들고 왔다. 전 Google OpenXLA 리드이자 $200B급 반도체 기업 AI 그룹 수장이 GitHub 이슈를 여는 건, 그냥 감으로 하는 일이 아니다.&lt;/p&gt;

&lt;p&gt;핵심 수치는 세 개다. 첫째, thinking depth가 2월 말부터 평균 67% 감소했다. 둘째, 파일 수정 전 코드를 읽는 비율(reads-per-edit)이 6.6에서 2.0으로 떨어졌다 — 70% 감소다. 셋째, "책임 회피, 중도 포기, 허락 요청" 같은 부적절 행동을 잡아내는 stop hook 스크립트가 3월 8일 이전엔 한 번도 발동하지 않았다가, 이후 17일간 173번 발동했다.&lt;/p&gt;

&lt;p&gt;Laurenzo 본인의 문장으로 보면 그림이 더 선명해진다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Thinking이 얕아지면, 모델은 가장 싼 행동으로 기본값을 잡는다. 읽지 않고 수정하고, 끝내지 않고 멈추고, 실패의 책임을 회피하고, 올바른 수정 대신 가장 간단한 수정을 선택한다. 이것이 관찰된 증상과 정확히 일치한다."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;게임 개발자 입장에서 이 데이터는 특히 아프다. read-to-edit 6.6이라는 숫자는 "헤더 읽고, 의존성 추적하고, grep으로 사용처 찾고, 테스트 읽고, 그제서야 수정한다"는 워크플로우의 서명이다. 복잡한 코드베이스 — 이를테면 UE5 C++처럼 헤더/cpp/USTRUCT/TMap이 얽힌 — 에서 이 워크플로우가 2.0으로 떨어진다는 건 사실상 "대충 고친다"는 뜻이다.&lt;/p&gt;

&lt;p&gt;Laurenzo 팀은 결국 다른 프로바이더로 옮겼다고 썼다. 그러면서 남긴 말이 핵심이다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"6개월 전, Claude는 추론 품질과 실행 능력에서 독보적이었다. 이제는 다른 경쟁자들을 매우 진지하게 고려하고 평가해야 한다."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Anthropic의 반박, 그리고 절반의 인정
&lt;/h2&gt;

&lt;p&gt;Claude Code 팀의 Boris Cherny가 이슈에 등장했다. 그의 설명은 반박과 인정이 섞여 있어서, 양쪽을 나눠서 볼 필요가 있다.&lt;/p&gt;

&lt;p&gt;반박 쪽은 이렇다. 3월에 도입된 redact-thinking 헤더는 UI-only 변경이고 실제 reasoning은 그대로 일어난다. 모델의 thinking budget이나 추론 실행 메커니즘에는 영향을 주지 않는다. Laurenzo가 분석한 지표는 redacted thinking block의 길이를 추정한 것이라, 실제 추론량이 아니라 측정 가능한 외부 신호가 끊긴 결과일 수 있다.&lt;/p&gt;

&lt;p&gt;인정 쪽은 이렇다. 2월에 두 가지 실질적 변경이 있었다. 첫째는 2월 9일 Opus 4.6 출시와 함께 도입된 adaptive thinking — 고정된 thinking budget 대신 모델이 매 턴마다 얼마나 생각할지 스스로 결정하는 방식이다. 둘째는 3월 3일, 기본 effort level을 High에서 Medium(100점 만점에 85)으로 내린 것이다. Boris는 이를 "지능과 지연시간 곡선의 sweet spot"이라고 프레이밍했다.&lt;/p&gt;

&lt;p&gt;사용자들이 실제 대화 로그를 공유하자 Boris는 한 발 더 물러섰다. adaptive thinking이 특정 턴에서 reasoning을 과소할당하는 것 같다고 인정했다. 해결책으로 제시한 건 &lt;code&gt;/effort high&lt;/code&gt;나 &lt;code&gt;/effort max&lt;/code&gt; 명령어, 환경변수 &lt;code&gt;CLAUDE_CODE_EFFORT_LEVEL=max&lt;/code&gt;, 그리고 &lt;code&gt;CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1&lt;/code&gt;이다.&lt;/p&gt;

&lt;p&gt;요약하면 이렇다. 모델 자체가 멍청해진 건 아니지만, &lt;strong&gt;기본 설정이 조용히 내려갔고, 사용자는 매뉴얼하게 되돌려야 한다.&lt;/strong&gt; 자동차 회사가 엔진 출력을 낮춰놓고 "액셀을 더 세게 밟으라"고 하는 것과 구조적으로 같다.&lt;/p&gt;

&lt;p&gt;그리고 바로 이 프레임이, 4월 21일 Pro 제거 실험과 하나의 선으로 연결된다.&lt;/p&gt;
&lt;h2&gt;
  
  
  하나의 선: 조용한 하향 → 명시적 제거 실험
&lt;/h2&gt;

&lt;p&gt;Laurenzo 이슈와 Pro 제거 사건을 따로 보면 각각 그냥 짜증나는 사고처럼 보인다. 같이 놓으면 패턴이 보인다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2월 9일   Opus 4.6 + adaptive thinking 도입
3월 3일   기본 effort level: High → Medium
3월 초    thinking content redaction 전면 적용
4월 2일   Laurenzo 이슈 #42796 공개
4월 6일   Boris의 공식 답변 (UI-only 주장 + 기본값 하향 인정)
4월 21일  Pro 요금제에서 Claude Code 제거 (~12시간 후 롤백)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이 타임라인이 말하는 건 분명하다. Anthropic은 두 개의 다른 방식으로 비용을 누르려 시도 중이다. 하나는 &lt;strong&gt;조용한 하향&lt;/strong&gt; — 같은 가격에 덜 생각하게 만드는 것. 다른 하나는 &lt;strong&gt;명시적 제거&lt;/strong&gt; — 같은 기능을 더 비싼 티어로 밀어 올리는 것.&lt;/p&gt;

&lt;p&gt;조용한 하향은 발각되기 전까지 효과적이다. 발각되면 "이건 UI 변경이고 effort 설정을 바꾸면 됩니다"라고 해명할 수 있다. 하지만 Laurenzo 같은 사람이 telemetry를 들고 나타나면 반박이 어렵다.&lt;/p&gt;

&lt;p&gt;명시적 제거는 더 강한 카드다. 구조를 바꾸면 앞으로의 사용량을 원천 차단할 수 있다. 그런데 단점은 즉시 눈에 띈다는 점이다. Pro 페이지에 X 표시가 뜨는 순간 X, Hacker News, Reddit이 동시에 터진다. 4월 21일에 정확히 그렇게 됐고, Anthropic은 반나절 만에 손을 뗐다.&lt;/p&gt;

&lt;p&gt;두 카드를 같이 쓰는 게 이상한 일은 아니다. 정상적인 가격 실험이기도 하다. 문제는 &lt;strong&gt;조용한 카드가 먼저 시도됐고, 그게 안 먹힌 다음에 명시적 카드가 나왔다는 순서&lt;/strong&gt;다. Avasare의 발언을 한 번 더 보자. "우리 플랜은 이런 사용량을 위해 설계된 게 아니다." 이건 "2% 테스트" 스케일의 문장이 아니다. 구조 개편 스케일의 문장이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  에이전트 경제학: Netflix 모델이 깨지는 이유
&lt;/h2&gt;

&lt;p&gt;왜 이런 일이 벌어지는지 이해하려면 한 단계 더 들어가야 한다. AI 구독 서비스는 Netflix가 아니다.&lt;/p&gt;

&lt;p&gt;Netflix 같은 전통적 SaaS는 사용자가 늘어도 한계비용이 거의 0이다. 한 명이 더 가입해서 House of Cards를 다시 보는 건 서버 대역폭 조금 더 쓰는 거지, 콘텐츠 제작비가 새로 드는 게 아니다. 그래서 파워 유저는 자산이다. 입소문을 내주고, 이탈률을 낮춰주고, 번들 가치를 증명해준다.&lt;/p&gt;

&lt;p&gt;AI 에이전트 서비스는 정반대다. 사용자가 에이전트를 한 번 돌릴 때마다 GPU 시간이 실제로 소모된다. Sonnet 응답 하나는 몇 센트, Opus는 더 비싸고, 장시간 에이전트가 tool call 200번을 돌리면 사용자 한 명에게서 하루에 몇 달러가 사라질 수 있다.&lt;/p&gt;

&lt;p&gt;이 구조에서 파워 유저는 &lt;strong&gt;자산이 아니라 부채다.&lt;/strong&gt; 많이 쓸수록 회사가 손해를 본다. $20 Pro 플랜으로 하루 8시간 Claude Code를 돌리는 사용자는, 구독료보다 훨씬 많은 compute를 소비한다. 그걸 다른 가벼운 사용자들의 구독료로 보조하는 구조인데, 장시간 에이전트 워크플로우가 일상화되면 "가벼운 사용자"의 비율이 줄어든다. 보조가 안 먹힌다.&lt;/p&gt;

&lt;p&gt;이건 Anthropic만의 문제가 아니다. Sam Altman도 작년에 ChatGPT Pro $200 플랜이 사용량 때문에 적자라고 공개적으로 말했다. OpenAI도, Cursor도, Replit도 전부 같은 벽에 부딪히고 있다. Cursor는 크레딧 기반으로, Replit은 effort 기반으로, Google Gemini는 하드캡으로 — 업계 전체가 일제히 사용량 기반 과금으로 움직이는 중이다.&lt;/p&gt;

&lt;p&gt;Anthropic의 선택지도 크게 보면 세 가지다. 플랜을 쪼개거나(Pro Plus $40~50 같은 중간 티어), 기존 플랜 기능을 축소하거나(Pro 제거 실험), 모델 자체의 기본값을 낮추거나(effort 하향). 지금까지는 뒤의 두 개를 동시에 시도 중이고, 커뮤니티 반응을 보면서 첫 번째를 만지작거리고 있다고 보는 게 합리적이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  게임 개발자 관점에서: 이 시그널을 어떻게 읽어야 하나
&lt;/h2&gt;

&lt;p&gt;회사에 AI 코딩 도구 도입을 주도하고 있는 입장에서, 이번 사건은 몇 가지 운영상의 결정을 새로 검토하게 만든다.&lt;/p&gt;

&lt;p&gt;첫 번째는 &lt;strong&gt;측정을 돌려주는 것&lt;/strong&gt;이다. Laurenzo가 이번 사건에서 남긴 진짜 교훈은 67%라는 숫자 자체가 아니라, 그 숫자를 뽑아낼 수 있는 인프라를 갖고 있었다는 점이다. 6,852개 세션 로그가 &lt;code&gt;~/.claude/projects/&lt;/code&gt; 아래에 쌓여 있었고, JSONL을 파싱해서 thinking block의 signature 필드 길이와 실제 content 길이의 상관관계(Pearson r=0.971)를 계산할 수 있었다. 이게 없었으면 "요새 좀 이상한데"로 끝났을 거다.&lt;/p&gt;

&lt;p&gt;팀에 Claude Code를 깔아두고 있다면, 최소한 세션 로그를 어딘가에 모으고 read-to-edit 비율 정도는 추적할 수 있는 구조를 만들어두는 게 낫다. Anthropic이 thinking token 지표를 API 응답에 노출하겠다는 공식 약속은 아직 없다. 지표를 주지 않으면 스스로 만들어야 한다.&lt;/p&gt;

&lt;p&gt;두 번째는 &lt;strong&gt;프로바이더 단일 의존을 피하는 것&lt;/strong&gt;이다. 이건 "Claude 싫어"가 아니라 리스크 헤징의 문제다. 지금 이 시점에 Claude Code만 쓰는 팀은, Anthropic의 요금제 실험 하나에 개발 프로세스가 흔들린다. Codex가 빠르게 따라붙고 있고, 로컬 모델 옵션도 — DeepSeek이나 Qwen Coder 같은 — coding 성능에서 의미 있게 좁혀왔다. 메인은 Claude로 가되, 백업 프로바이더 하나를 팀이 실제로 돌릴 수 있는 상태로 유지하는 게 안전하다.&lt;/p&gt;

&lt;p&gt;세 번째는 &lt;strong&gt;effort/budget 설정을 명시적으로 고정하는 것&lt;/strong&gt;이다. adaptive thinking이 기본값이 된 이상, 복잡한 작업을 돌릴 때는 &lt;code&gt;/effort high&lt;/code&gt; 또는 &lt;code&gt;CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1&lt;/code&gt;을 팀 표준에 박아두는 게 낫다. 기본값이 언제 다시 내려갈지 모르고, 내려가도 즉시 공지가 없을 수 있다.&lt;/p&gt;

&lt;p&gt;네 번째는 &lt;strong&gt;"무제한" 마케팅을 불신하는 것&lt;/strong&gt;이다. 이번 사건의 진짜 교훈은 이거다. 명시적 숫자 제한이 있는 계약이 오히려 안전하다. "Pro 플랜 무제한"은 약속이 아니라 마케팅 문구고, 사용 패턴이 바뀌면 언제든 재정의된다. Max 20x의 "하루 N회 Opus 호출" 같은 명시적 한도가 장기적으로는 더 방어 가능한 조건이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  우리가 얻은 것과 잃은 것
&lt;/h2&gt;

&lt;p&gt;이번 사건에서 얻은 게 하나 있다. Anthropic이 이제 &lt;strong&gt;무엇이 커뮤니티의 한계선인지&lt;/strong&gt;를 알게 됐다. 12시간 만에 롤백한 건, 커뮤니티 반응이 그들의 모델링을 넘어섰다는 증거다. 다음 실험은 이 경험을 학습한 상태에서 나올 거고, 그건 더 부드러울 거다. 아마 Pro Plus 티어 형태로.&lt;/p&gt;

&lt;p&gt;잃은 것도 있다. 신뢰의 계층 하나다. Laurenzo가 남긴 문장을 다시 본다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"6개월 전, Claude는 추론 품질과 실행 능력에서 독보적이었다. 이제는 다른 경쟁자들을 매우 진지하게 고려하고 평가해야 한다."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이건 경쟁 구도 판단이면서 동시에 계약 관점의 판단이다. 도구 하나에 개발 프로세스를 의존하는 순간, 그 도구의 제공자가 요금제를 어떻게 실험할지가 자기 팀의 생산성을 좌우한다. 그게 받아들일 만한 위험인지 아닌지는, 이번 같은 사건이 한 번씩 터질 때마다 재계산해야 한다.&lt;/p&gt;

&lt;p&gt;4월 21일의 12시간은 Anthropic이 움직일 수 있는 범위를 테스트한 시간이었고, 동시에 우리가 어디까지 의존할 수 있는지를 재보는 시간이었다.&lt;/p&gt;

&lt;p&gt;두 숫자를 모두 기억해둘 가치가 있다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"우리 플랜은 이런 사용량을 위해 설계된 게 아니다." — 이건 가격 실험의 끝이 아니라 시작이다.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Claude Opus 4.7이 나왔다 — 게임 프로그래머가 본 실전 변화</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Sun, 19 Apr 2026 08:29:28 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/claude-opus-47i-nawassda-geim-peurogeuraemeoga-bon-siljeon-byeonhwa-35nc</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/claude-opus-47i-nawassda-geim-peurogeuraemeoga-bon-siljeon-byeonhwa-35nc</guid>
      <description>&lt;p&gt;더 많은 글은 &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;에서.&lt;/p&gt;




&lt;p&gt;2026년 4월 16일, Anthropic이 Claude Opus 4.7을 일반 공개했다.&lt;/p&gt;

&lt;p&gt;Opus 4.6이 2월에 나왔으니 딱 두 달 만이다. 2개월 사이클이 굳어지는 분위기다.&lt;/p&gt;

&lt;p&gt;게임 프로그래머 관점에서 이번 릴리스가 왜 중요한가. Claude Code를 UE5 C++ 작업에 쓰는 사람이라면 모델이 바뀔 때마다 프롬프트 튜닝, 하네스 설계, 토큰 예산을 다시 잡아야 한다. 공식 발표글과 마이그레이션 가이드를 기준으로, 게임 개발 업무 관점에서 뭐가 달라지는지 정리한다.&lt;/p&gt;

&lt;h2&gt;
  
  
  한 줄 요약: "긴 태스크를 던져도 되는 모델"
&lt;/h2&gt;

&lt;p&gt;발표글에서 가장 먼저 눈에 들어오는 문장은 이거다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Users report being able to hand off their hardest coding work—the kind that previously needed close supervision—to Opus 4.7 with confidence."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;감시 없이 맡길 수 있다는 얘기다. 이게 과장인지 실제인지는 써봐야 안다. 다만 벤치마크 숫자가 그 방향을 뒷받침한다.&lt;/p&gt;

&lt;p&gt;Cursor의 CursorBench에서 Opus 4.6은 58%였지만 Opus 4.7은 70%를 넘겼다. Rakuten-SWE-Bench에서는 프로덕션 태스크 해결률이 3배로 뛰었다. Devin을 만드는 Cognition 쪽은 "몇 시간 동안 코드 일관성을 유지한다"고 코멘트를 남겼다.&lt;/p&gt;

&lt;p&gt;감각으로 풀면 이렇다. Opus 4.6까지는 한 덩어리 태스크를 주고 30~40분 뒤에 돌아와서 "뭐 이상한 거 없나" 보는 게 안전했다. 4.7은 두세 시간짜리도 던져볼만 하다는 얘기다.&lt;/p&gt;

&lt;p&gt;UE5 작업에서 이게 뭘 의미하는지는 분명하다. 서브시스템 리팩토링, USTRUCT 해시 재구현, 여러 에셋을 가로지르는 enum 삭제 — 이런 태스크를 던져놓고 회의 다녀오는 워크플로우가 현실적으로 된다.&lt;/p&gt;

&lt;h2&gt;
  
  
  xhigh 이펙트 레벨 — 지금 당장 바꿔야 하는 설정
&lt;/h2&gt;

&lt;p&gt;Opus 4.7이 들고 온 가장 중요한 API 변화는 &lt;code&gt;xhigh&lt;/code&gt;다.&lt;/p&gt;

&lt;p&gt;기존에는 effort 레벨이 &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt; 네 개였다. 여기에 &lt;code&gt;high&lt;/code&gt;와 &lt;code&gt;max&lt;/code&gt; 사이로 &lt;code&gt;xhigh&lt;/code&gt;가 추가됐다. "extra high"라는 뜻이다.&lt;/p&gt;

&lt;p&gt;그리고 Claude Code의 모든 플랜에서 기본 effort가 &lt;code&gt;xhigh&lt;/code&gt;로 올라갔다. 공식 가이드도 이렇게 권장한다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When testing Opus 4.7 for coding and agentic use cases, we recommend starting with high or xhigh effort."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이게 왜 중요한가. 지금까지는 Claude Code에서 "답변이 얕다" 싶을 때 &lt;code&gt;/ultrathink&lt;/code&gt; 같은 패턴으로 우회하는 경우가 있었다. 이제는 기본값 자체가 더 깊이 생각하는 쪽으로 옮겨갔다.&lt;/p&gt;

&lt;p&gt;대신 트레이드오프가 있다. Hex의 CTO는 이렇게 표현했다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"low-effort Opus 4.7 is roughly equivalent to medium-effort Opus 4.6."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;같은 품질을 얻고 싶으면 effort를 한 단계 낮춰도 된다는 얘기다. 돈이 빡빡한 팀은 이 지점을 활용할 수 있다. 진짜 어려운 태스크엔 xhigh를 쓰고, 평범한 수정엔 low로 떨어뜨리는 식으로 레벨을 과감하게 쓰는 게 4.7 체감을 바꾸는 포인트다.&lt;/p&gt;

&lt;p&gt;실전에서 어떻게 쓸지 정리하면 이렇다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 코딩 태스크 - 기본값은 xhigh
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-opus-4-7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;thinking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;adaptive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;output_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;effort&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;xhigh&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 간단한 리팩토링이나 포맷팅 - low로 충분
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-opus-4-7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;thinking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;adaptive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;output_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;effort&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;일반적인 가이드라인으로 풀면 기본값은 xhigh, 단순 작업은 low로 내리는 게 맞다. medium을 쓸 상황이 거의 없어진다.&lt;/p&gt;

&lt;h2&gt;
  
  
  토크나이저가 바뀌었다 — 같은 입력이 1.35배로 팽창할 수 있다
&lt;/h2&gt;

&lt;p&gt;이건 조용히 쓰면 월말 청구서에서 놀라는 변화다.&lt;/p&gt;

&lt;p&gt;공식 가이드 원문이다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Opus 4.7 uses an updated tokenizer that improves how the model processes text. The tradeoff is that the same input can map to more tokens—roughly 1.0–1.35× depending on the content type."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;토크나이저가 교체됐다. 더 똑똑해졌지만, 콘텐츠 타입에 따라 같은 입력이 최대 1.35배 토큰으로 매핑된다.&lt;/p&gt;

&lt;p&gt;게임 개발자한테 이게 왜 치명적인가. UE5 C++ 코드베이스를 컨텍스트로 넣을 일이 많다. &lt;code&gt;.h&lt;/code&gt;/&lt;code&gt;.cpp&lt;/code&gt; 쌍, Blueprint 더미, USTRUCT 정의, Slate 위젯 — 이런 코드 덩어리들이 정확히 "토큰 팽창이 잘 일어나는 콘텐츠"다.&lt;/p&gt;

&lt;p&gt;게다가 두 번째 변화가 더 있다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Opus 4.7 thinks more at higher effort levels, particularly on later turns in agentic settings."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;에이전틱 세팅에서, 특히 뒷턴일수록 더 많이 생각한다. 출력 토큰도 늘어난다는 뜻이다.&lt;/p&gt;

&lt;p&gt;대응은 두 갈래다.&lt;/p&gt;

&lt;p&gt;먼저 큰 작업을 던질 때 프롬프트에 "be concise"를 넣거나 task budgets 베타를 쓴다. task budgets는 이번에 같이 공개된 기능인데, 에이전트가 긴 런에서 토큰을 어떻게 배분할지 개발자가 가이드할 수 있다. 퍼블릭 베타 상태라 지금 바로 써볼 수 있다.&lt;/p&gt;

&lt;p&gt;다음으로 &lt;code&gt;CLAUDE.md&lt;/code&gt; 같은 항상 들어가는 컨텍스트를 다시 훑는다. 4.6까지 괜찮던 사이즈가 4.7에선 빡빡해질 수 있다. 안 쓰는 섹션 덜어내고, 예시 코드 더 짧게 자른다.&lt;/p&gt;

&lt;h2&gt;
  
  
  비전이 세진다 — 2,576px, 3.75메가픽셀
&lt;/h2&gt;

&lt;p&gt;이건 컴퓨터 유즈 에이전트 만드는 사람한테 진짜 큰 변화다.&lt;/p&gt;

&lt;p&gt;Opus 4.7은 긴 축 기준 2,576픽셀, 대략 3.75메가픽셀까지 받는다. 이전 Claude 모델들의 3배가 넘는 해상도다.&lt;/p&gt;

&lt;p&gt;왜 중요한지 실전 예를 들면 이렇다. UE5 에디터 스크린샷을 Claude한테 주고 "이 Details 패널 상태를 그대로 재현해줘"라고 하면, 4.6까지는 다운샘플링 때문에 체크박스나 숫자가 뭉개져서 에이전트가 읽지 못했다. 4.7에선 픽셀 단위로 본다.&lt;/p&gt;

&lt;p&gt;XBOW라는 자동 침투 테스트 회사 사례가 극단적이다. 그들의 비주얼 예민도 벤치마크에서 Opus 4.6은 54.5%였는데 4.7은 98.5%를 찍었다. 거의 두 배다.&lt;/p&gt;

&lt;p&gt;게임 쪽에서 써먹을 지점이 여러 개 나온다. UMG/Slate 디자인을 스크린샷으로 주고 코드를 받는 워크플로우. Unreal Insights나 프로파일러 결과 이미지를 읽혀 핫패스를 찾는 패턴. 커밋 diff 스크린샷 리뷰. 스프라이트/애니메이션 결과물의 시각적 디버깅. 전부 4.6까진 해상도 문제로 빠지던 케이스들이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory — 파일시스템 기반 메모리를 더 잘 쓴다
&lt;/h2&gt;

&lt;p&gt;발표글에 이런 문장이 있다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Opus 4.7 is better at using file system-based memory. It remembers important notes across long, multi-session work."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;모델 자체에 망각 곡선을 심는 게 아니라, 파일시스템에 노트를 남기고 에이전트가 그걸 다시 읽는 구조를 강화했다는 얘기다.&lt;/p&gt;

&lt;p&gt;Claude Code 유저라면 이 패턴이 낯설지 않다. 세션이 길어지면 중간에 &lt;code&gt;NOTES.md&lt;/code&gt;나 &lt;code&gt;CONTEXT.md&lt;/code&gt; 같은 걸 만들어두고, 새 세션에서 그걸 다시 읽으면서 상태를 복구한다. 4.7은 이 루틴을 더 능숙하게 돌린다.&lt;/p&gt;

&lt;p&gt;게임 개발 프로젝트에서 이건 꽤 큰 의미가 있다. UE5 프로젝트는 컨텍스트가 방대하다. 네트워킹 규약, USTRUCT 레이아웃, Blueprint 호출 규칙, 렌더링 파이프라인 제약. 한 세션에 다 넣을 수 없다.&lt;/p&gt;

&lt;p&gt;실전 패턴은 이미 알려져 있다. &lt;code&gt;docs/architecture/&lt;/code&gt; 밑에 주제별로 memory 파일을 쪼개둔다. 세션 시작할 때 "오늘은 전투 시스템 작업이다"라고 하면 에이전트가 관련 memory 파일만 골라 읽는다. 4.7은 이걸 덜 힘들이고 한다.&lt;/p&gt;

&lt;p&gt;모델 버전이 올라갈수록 "Memory 파일 구조 설계" 역량이 점점 중요해진다. 단순히 CLAUDE.md 하나에 몰아넣는 시대는 지났다.&lt;/p&gt;

&lt;h2&gt;
  
  
  /ultrareview와 auto mode — Claude Code 자체도 같이 바뀐다
&lt;/h2&gt;

&lt;p&gt;Opus 4.7 출시와 함께 Claude Code에 두 가지 기능이 붙었다.&lt;/p&gt;

&lt;p&gt;먼저 &lt;code&gt;/ultrareview&lt;/code&gt; 슬래시 커맨드다. 전용 리뷰 세션을 열어서 변경사항을 읽고, 꼼꼼한 리뷰어가 잡을 만한 버그와 설계 이슈를 플래그한다. Pro/Max 유저한테 세 번 무료 시도를 준다고 한다.&lt;/p&gt;

&lt;p&gt;팀 컨벤션이 복잡한 프로젝트일수록 &lt;code&gt;/ultrareview&lt;/code&gt; 같은 전용 모드가 잘 먹힌다. 일반 채팅에서는 대충 훑고 지나가는 것들을 리뷰 모드에선 더 깊게 본다. UE5처럼 헤더/소스/Build.cs/Config이 얽혀 있는 구조에선 특히 유용할 가능성이 크다.&lt;/p&gt;

&lt;p&gt;그 다음은 auto mode의 Max 유저 확대다. auto mode는 Claude가 "이 작업은 권한을 물어봐야 하나?"를 스스로 판단하는 기능이다. 전부 허용하는 것보다 안전하고, 매번 묻는 것보다 빠르다.&lt;/p&gt;

&lt;p&gt;게임 개발에서 이게 왜 유용한가. UE5 프로젝트는 파일이 수백 개다. 한 작업에서 &lt;code&gt;.h&lt;/code&gt;, &lt;code&gt;.cpp&lt;/code&gt;, &lt;code&gt;.Build.cs&lt;/code&gt;, &lt;code&gt;Config/*.ini&lt;/code&gt;까지 건드려야 할 때가 많다. 매번 권한을 물으면 흐름이 깨진다. 그렇다고 전부 허용하면 &lt;code&gt;.uproject&lt;/code&gt; 같은 핵심 파일이 망가질 위험이 있다.&lt;/p&gt;

&lt;p&gt;auto mode는 "위험한 파일은 물어보고, 나머지는 진행"이라는 중간 지점을 잡는다. 이론상 게임 프로젝트 워크플로우에 잘 맞을 것 같은 구조다.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mythos Preview 얘기 — Opus 4.7이 왜 "중간 단계"인가
&lt;/h2&gt;

&lt;p&gt;이번 릴리스를 이해하려면 Mythos Preview 얘기를 빼놓을 수 없다.&lt;/p&gt;

&lt;p&gt;지난주 Anthropic은 Claude Mythos Preview를 공개하면서 Project Glasswing이라는 이니셔티브를 같이 발표했다. Mythos는 Anthropic의 가장 강력한 모델인데, 특히 사이버 보안 쪽 능력이 압도적이라 일반 공개를 하지 않는다. 대신 AWS, Apple, Google, Microsoft, Cisco, CrowdStrike, JPMorgan, Linux Foundation, NVIDIA, Palo Alto Networks 같은 핵심 인프라 파트너들한테만 제한적으로 풀었다.&lt;/p&gt;

&lt;p&gt;왜 이렇게까지 했냐. Mythos는 이미 모든 주요 OS와 브라우저에서 수천 개의 제로데이를 찾아낸 상태다. OpenBSD에서 27년 묵은 버그도 찾았다고 한다. Nicholas Carlini가 "지난 몇 주간 평생 찾은 것보다 더 많은 버그를 찾았다"고 했을 정도다. 이 능력이 공격자 손에 들어가는 걸 피하려고 한정 배포 트랙을 만든 거다.&lt;/p&gt;

&lt;p&gt;가격도 Opus 4.7과 완전히 다르다. Mythos Preview는 $25/$125 per million tokens (입력/출력)이고, Opus 4.7은 $5/$25다. 5배 차이 난다.&lt;/p&gt;

&lt;p&gt;여기서 Opus 4.7의 포지션이 선명해진다. Anthropic은 원래 "다음 Opus 모델에 새 사이버 가드레일을 실어서 테스트할 것"이라고 예고했었는데, 그 모델이 바로 4.7이다. Mythos급 모델을 나중에 넓게 풀려면 먼저 안전장치가 실전에서 작동해야 한다. 4.7은 일부러 사이버 능력을 낮춘 상태로 그 가드레일을 검증하는 샘플이다.&lt;/p&gt;

&lt;p&gt;이게 게임 개발자한테 실전적으로 뭘 의미하는가.&lt;/p&gt;

&lt;p&gt;대부분의 게임 개발 작업에는 영향이 없다. 네트워크 프로토콜 설계, 치트 방어, 서버 보안 — 이런 작업은 "방어"쪽이라 일반적으로 통과한다. 다만 보안 소프트웨어가 끼어드는 환경에서 디버깅을 하다 보면 "보안 소프트웨어를 우회하는 방법"으로 오해받을 여지가 있는 질문이 생긴다. 이럴 때 좀 더 섬세하게 맥락을 설명해야 할 수 있다.&lt;/p&gt;

&lt;p&gt;정당한 보안 연구자를 위해 Cyber Verification Program이라는 별도 트랙이 열렸다. 레드팀이나 취약점 연구 쪽 종사자라면 신청해볼 만하다.&lt;/p&gt;

&lt;p&gt;그리고 이게 진짜 중요한 포인트인데, Anthropic의 로드맵이 이 릴리스에서 드러났다는 점이다. Mythos는 당장 퍼블릭 릴리스 계획이 없지만, "Mythos-class 모델을 언젠가 안전하게 대규모 배포하는 것"이 목표라고 명시했다. Opus 4.7은 그 길의 첫 번째 정거장이다. 4.8이든 5.0이든 다음 모델은 Mythos 능력에 더 가까워지면서 더 정교한 가드레일을 태우고 나올 거다.&lt;/p&gt;

&lt;h2&gt;
  
  
  업그레이드 전 체크리스트
&lt;/h2&gt;

&lt;p&gt;이번 릴리스를 받고 해야 할 일을 정리하면 이렇다.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;나 항상 컨텍스트에 들어가는 파일들을 다시 훑는다. 토크나이저가 바뀌면서 예전 사이즈가 과해질 수 있다. 안 쓰는 섹션 정리하고, 예시 코드도 짧게 자른다.&lt;/p&gt;

&lt;p&gt;Claude Code 설정에서 effort 기본값을 &lt;code&gt;xhigh&lt;/code&gt;로 올리고, 단순 작업용 &lt;code&gt;low&lt;/code&gt; 프리셋을 따로 만든다. 양극단을 쓰는 게 4.7 운영의 핵심이다.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/ultrareview&lt;/code&gt;를 PR 하나에 적용해본다. 기존 리뷰 대비 뭐가 더 잡히는지, 얼마나 걸리는지 측정.&lt;/p&gt;

&lt;p&gt;auto mode를 테스트한다. 위험한 파일에서 실제로 멈추는지, 아니면 그냥 넘어가는지.&lt;/p&gt;

&lt;p&gt;마지막으로 이게 제일 중요한데, 기존 프롬프트를 재검토한다. Anthropic이 명시적으로 경고했다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"prompts written for earlier models can sometimes now produce unexpected results: where previous models interpreted instructions loosely or skipped parts entirely, Opus 4.7 takes the instructions literally."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;지시를 문자 그대로 받는다. 4.6 때는 "적당히 알아서 하겠지" 하고 쓴 프롬프트가 4.7에선 문제를 일으킬 수 있다. 특히 &lt;code&gt;CLAUDE.md&lt;/code&gt;에 들어간 지시문들을 다시 봐야 한다. "적절히", "필요하면", "가능한 한" 같은 모호한 표현이 많으면 4.7은 그걸 문자 그대로 해석하려고 하다가 엉뚱한 결과를 낸다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;모델이 바뀌면 프롬프트도 바뀌어야 한다. 하네스는 모델 위에 쌓는 게 아니라, 모델과 함께 다시 짜는 거다.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  관련 링크
&lt;/h2&gt;

&lt;p&gt;Opus 4.7 공식 발표: &lt;a href="https://www.anthropic.com/news/claude-opus-4-7" rel="noopener noreferrer"&gt;anthropic.com/news/claude-opus-4-7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;마이그레이션 가이드: &lt;a href="https://platform.claude.com/docs/en/about-claude/models/migration-guide" rel="noopener noreferrer"&gt;platform.claude.com/docs/en/about-claude/models/migration-guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Project Glasswing: &lt;a href="https://www.anthropic.com/project/glasswing" rel="noopener noreferrer"&gt;anthropic.com/project/glasswing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mythos Preview 기술 블로그 (Red Team): &lt;a href="https://red.anthropic.com/2026/mythos-preview/" rel="noopener noreferrer"&gt;red.anthropic.com/2026/mythos-preview&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>ue5</category>
    </item>
    <item>
      <title>I Built My Own Year-End Review for AI Coding — Memradar Code Report</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Fri, 17 Apr 2026 07:54:21 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/i-built-my-own-year-end-review-for-ai-coding-memradar-code-report-1le3</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/i-built-my-own-year-end-review-for-ai-coding-memradar-code-report-1le3</guid>
      <description>&lt;p&gt;Live app at &lt;a href="https://memradar.vercel.app" rel="noopener noreferrer"&gt;memradar.vercel.app&lt;/a&gt;. Code on &lt;a href="https://github.com/on1659/memradar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;br&gt;
More posts at &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;Every December Cursor pops up with something like "you coded X hours this year, across these languages." GitHub drops Year in Review. Discord puts yearly stats on your profile.&lt;/p&gt;

&lt;p&gt;The numbers are all mine, but flipping through them, I catch myself smiling — "oh, that's how I was." That's what a year-end review does. It's not information delivery — it's a &lt;strong&gt;ritual that pulls out one number at a time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted that for myself. Claude Code and Codex drop JSONL logs into my home directory every day (&lt;code&gt;~/.claude/projects/&lt;/code&gt;, &lt;code&gt;~/.codex/sessions/&lt;/code&gt;), and I had never looked inside. My conversations are on my disk, and I couldn't read them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memradar&lt;/strong&gt; is a local tool that turns those JSONLs into a retrospective. One line (&lt;code&gt;npx memradar&lt;/code&gt;), a browser opens, and along with the dashboard there's a full-screen slide retrospective — &lt;strong&gt;Code Report&lt;/strong&gt; — built in.&lt;/p&gt;

&lt;p&gt;This post is about the details I got obsessive about while building it. The idea is simple, but making people actually &lt;em&gt;feel&lt;/em&gt; something while looking at their own data took a lot of small calls.&lt;/p&gt;
&lt;h2&gt;
  
  
  It had to be Code Report, not Wrapped
&lt;/h2&gt;

&lt;p&gt;When I first built the full-screen retrospective feature, I called it "Wrapped" internally. The folder is still &lt;code&gt;src/components/wrapped/&lt;/code&gt;. Spotify Wrapped was the reference, so the name stuck.&lt;/p&gt;

&lt;p&gt;But shipping a product literally named "Wrapped" has problems. You're borrowing someone else's brand. The word also pins the feature to "year-end summary" as a category.&lt;/p&gt;

&lt;p&gt;While renaming, I wrote this principle into &lt;code&gt;docs/UI-UX-PRINCIPLES.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;9. The dashboard and the Code Report are two moods
   of the same product
- The dashboard is for exploration; the Code Report is
  for emotional retrospective and sharing.
- The Code Report uses its own palette, its own typography,
  and full-screen narrative.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same data, but &lt;strong&gt;the dashboard should feel like an "analysis tool" — calm — while the Code Report should lean into emotion, like a "retrospective experience."&lt;/strong&gt; I separated the palettes and typography so the two screens don't bleed into each other.&lt;/p&gt;

&lt;p&gt;So the name became Code Report. A report &lt;em&gt;on&lt;/em&gt; the code (my AI coding logs). Not tied to a fixed calendar moment — it's &lt;strong&gt;a screen that's a retrospective whenever you open it&lt;/strong&gt;. Wrapped happens once a year; Code Report opens whenever I need it.&lt;/p&gt;

&lt;p&gt;I kept the folder name (&lt;code&gt;wrapped/&lt;/code&gt;) as-is. Renaming internal variables carries too much refactor risk for no real benefit — only the product-facing name got locked to Code Report. That split itself is a small lesson: the inside and the outside of the same feature can have different names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the dashboard alone wasn't enough
&lt;/h2&gt;

&lt;p&gt;The dashboard came first, naturally. Heatmap, hourly chart, word cloud, session browser. Every metric on one screen.&lt;/p&gt;

&lt;p&gt;I loaded my own logs. The numbers were all there. And I felt &lt;strong&gt;nothing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's the dashboard ceiling. Lots of information, zero emotion. You nod and close the tab. The reason Cursor's year-end review makes people laugh with the same kind of data is that &lt;strong&gt;each screen shows one number.&lt;/strong&gt; The space around that number is empty on purpose.&lt;/p&gt;

&lt;p&gt;I locked in a composition principle for Code Report — "one scene, one message." From &lt;code&gt;docs/UI-UX-PRINCIPLES.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Here, "one scene, one message" matters more
  than the dashboard's rules.
- Full-screen, heavy whitespace, big type,
  a dedicated dark story palette.
- End with a shareable image —
  the end of the emotional arc is also the call to action.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are eight slides. Intro with the first session date. Total prompts. Favorite model. Coding hours. Top tools ranking. Personality type. Usage. Shareable card at the end.&lt;/p&gt;

&lt;p&gt;Each slide holds one number or one message. "I talked to Claude 3,200 times" as a small figure in a dashboard corner is one thing. "3,200" counting up on an empty slide is completely another. Same data.&lt;/p&gt;

&lt;p&gt;That was the first obsession. &lt;strong&gt;How do you make a number be felt, not just read?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I scrapped 4 personality types for 8
&lt;/h2&gt;

&lt;p&gt;The climax of Code Report is the personality slide. I started with four: Architect, Speed Runner, Explorer, Night Sage.&lt;/p&gt;

&lt;p&gt;After a couple of runs on different logs, everyone said some version of "...I don't think I'm any of those." MBTI works because its four axes are computed independently — you're I, and N, and F, and P — all at once — which is how INFP appears. One axis (pick one of four buckets) is always going to be coarse.&lt;/p&gt;

&lt;p&gt;So I rewrote it as three axes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;style × scope × rhythm
 ↓       ↓        ↓
care    depth    pace
  8 combinations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The combinations yield names like "Deep-Sea Diver," "Lightning Fixer," "Chaos Creator." Because each axis is computed separately, the result feels more personal.&lt;/p&gt;

&lt;p&gt;Half a day burned on this. The four types weren't wrong — &lt;strong&gt;the feeling of reading the result was weak&lt;/strong&gt;. That's what matters most in Code Report. Before "correct," the viewer has to chuckle and think "yeah, that's me."&lt;/p&gt;

&lt;p&gt;I kept tuning the personality logic against real data. Did my logs produce a result that felt right for me? Did a friend's logs produce something that fit them? Move one threshold and everything shifts. I calibrated that dozens of times.&lt;/p&gt;

&lt;h2&gt;
  
  
  That 2.5-second delay on the last slide
&lt;/h2&gt;

&lt;p&gt;Commit title: &lt;code&gt;Fix last slide dashboard prompt timing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem: on the share-card slide, tapping the screen opens a "Go to dashboard?" modal. But people flip through Code Report with a rhythm — tap, tap, tap — and that same rhythm triggers the modal the moment they land on the last slide. They never even see the share card.&lt;/p&gt;

&lt;p&gt;Most people would shrug at this. But once it happened to me, I couldn't unsee it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setDashboardPromptReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slideIndex&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;lastSlideIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setDashboardPromptReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lastSlideIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slideIndex&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you enter the last slide, &lt;code&gt;dashboardPromptReady&lt;/code&gt; stays false for 2.5 seconds. Tap all you want — the modal won't open. I even changed the cursor to &lt;code&gt;default&lt;/code&gt; during that window. The mouse cursor itself signals "not yet."&lt;/p&gt;

&lt;p&gt;Writing it, I asked myself: is this really needed? The user won't even notice.&lt;/p&gt;

&lt;p&gt;And that's &lt;strong&gt;exactly the point.&lt;/strong&gt; Same idea as locking input for a few frames right after a cutscene ends in games. You prevent the player's "skip button rhythm" from triggering something they didn't mean to. When it bites, it feels awful; when it's handled, nobody notices. Nobody noticing is the win.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why 20 themes?
&lt;/h2&gt;

&lt;p&gt;Memradar ships with 20 themes. Four backgrounds (Dark, AMOLED, Light, Warm) × five accents (Indigo, Violet, Teal, Rose, Amber).&lt;/p&gt;

&lt;p&gt;Why so many? Same reason as everything else — it's about feel.&lt;/p&gt;

&lt;p&gt;Flipping through Code Report is &lt;strong&gt;personal.&lt;/strong&gt; It's me looking at my own coding log. I don't want to use someone else's dark theme — I want to pick my own mood. Unlike Cursor's year-end review where the palette is fixed, if I'm the one building it, I should be able to choose.&lt;/p&gt;

&lt;p&gt;The four backgrounds are calculated, too. Dark as the default. AMOLED for a true black on OLED screens. Light for a bright café. Warm for evening. The right pick changes with the situation.&lt;/p&gt;

&lt;p&gt;Fonts are pinned to Noto Sans KR + Noto Serif KR. The UI shows a lot of Hangul, so the Korean has to look right first. I didn't pick an English-first font. I code mostly in Korean, my prompts are mostly Korean, and the Code Report that reads those has to look good in Korean.&lt;/p&gt;

&lt;p&gt;localStorage preserves the choice across visits. Obvious, but forgetting it is the kind of thing that screams amateur.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decisions packed into one heatmap
&lt;/h2&gt;

&lt;p&gt;A GitHub-style daily activity heatmap. Here are the calls inside that single widget.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;responsive cell size.&lt;/strong&gt; Cells auto-grow and shrink with container width. A &lt;code&gt;ResizeObserver&lt;/code&gt; watches the container; on change, cell size is recomputed and the grid rerenders. I started with fixed sizes, then watched the heatmap get clipped on a smaller laptop and rebuilt it.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;click-to-pin a date.&lt;/strong&gt; Clicking a cell shows that day's session summary in a side panel. Hover-only worked on desktop but died on mobile, and "pinning" a day on desktop lets you actually dig in.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;streak counter.&lt;/strong&gt; "How many days in a row." I debated where to place it, and landed on the heatmap's side panel. Not trying to gamify like Duolingo — just a passive "huh, 15 straight days this month" when your eyes already land on the heatmap.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;day-of-week pattern.&lt;/strong&gt; Which weekday I code the most, tucked small on the side. I thought about cutting it. Then I noticed I work weekends way more than I thought. That's the Code Report flavor — surfacing a pattern I didn't see.&lt;/p&gt;

&lt;p&gt;Four decisions inside one widget. Same story for the word cloud, the hourly chart, the token chart.&lt;/p&gt;

&lt;h2&gt;
  
  
  How many times I rewrote the DropZone wording
&lt;/h2&gt;

&lt;p&gt;The most obsessive stretch was the landing page DropZone. The commit log has four wording fixes for one component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Replace copy-paste wording with Ctrl+C/V shortcut
- Use Ctrl+C/V/Enter wording consistently in DropZone
- Allow .claude/.codex root folder drop and add install guide link
- Fix DropZone wording: shorten Ctrl+C/V label
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One at a time. First, "copy and paste" was the original wording — but it's long in both languages. Two shortcuts side by side make the action click in half a second.&lt;/p&gt;

&lt;p&gt;Second was consistency. "Ctrl+C/V" in some places, "copy/paste" left in others. Mixed vocabulary annoys people.&lt;/p&gt;

&lt;p&gt;Third, accept the &lt;code&gt;.claude&lt;/code&gt; folder itself. Originally you had to drop the inner &lt;code&gt;.claude/projects/&lt;/code&gt;. But users naturally drag &lt;code&gt;.claude&lt;/code&gt; from their home. So the drop handler digs one level deeper when it sees &lt;code&gt;.claude&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;droppedFolder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.claude&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projectsDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;findChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;droppedFolder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;projects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectsDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;scanDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectsDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fourth, wording again. The "Ctrl+C/V" label had a redundant prefix stuck in front, so I shortened it.&lt;/p&gt;

&lt;p&gt;Four passes on one component's copy. Over the top? Maybe. But the DropZone is the first screen a user sees. If they can't figure out &lt;strong&gt;what to do in five seconds&lt;/strong&gt;, the rest doesn't matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bilingual support turned out to be a big call
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;i18n (ko/en), theme presets, and hash routing&lt;/code&gt;. Three things landed in one commit.&lt;/p&gt;

&lt;p&gt;I added bilingual support partly because I publish this blog in both Korean and English. But there's a bigger reason. &lt;strong&gt;The copy in Code Report is emotional.&lt;/strong&gt; "You're a Night Owl." "You started 3,200 conversations this month." If those only exist in English, the joy gets cut in half for Korean readers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/i18n.tsx&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;translations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ko&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.nightSage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;새벽의 현자&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.speedRunner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;번개 해결사&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.nightSage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Night Sage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.speedRunner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lightning Fixer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Translating Night Sage as "새벽의 현자" (sage of the dawn, not just night) and Lightning Fixer as "번개 해결사" wasn't literal — I picked each Korean name so &lt;strong&gt;it lands at the same temperature&lt;/strong&gt; the English version does. Writing the eight personality names in both languages took hours.&lt;/p&gt;

&lt;p&gt;Hash routing shipped alongside for a concrete reason: sharing Code Report links means state has to live in the URL. &lt;code&gt;#wrapped/5&lt;/code&gt; puts the slide index right there. Refreshing keeps you on the same slide.&lt;/p&gt;

&lt;h2&gt;
  
  
  The moment I threw single-HTML away
&lt;/h2&gt;

&lt;p&gt;The biggest technical call was flipping the CLI from single-HTML to a local server.&lt;/p&gt;

&lt;p&gt;Originally the CLI parsed every JSONL, serialized the result to JSON, inlined it into a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag, and produced a single giant HTML file. No server, works offline, one file to open. Clean.&lt;/p&gt;

&lt;p&gt;Then my &lt;code&gt;.claude/projects/&lt;/code&gt; grew up. The HTML passed 18MB. The browser froze for 4-5 seconds just running &lt;code&gt;JSON.parse&lt;/code&gt;. Code Report was already dead before it started.&lt;/p&gt;

&lt;p&gt;So I flipped it. A local server on port 3939 (&lt;code&gt;http.createServer&lt;/code&gt;) plus &lt;code&gt;/api/sessions&lt;/code&gt; streaming. The browser pulls a 0.6MB app bundle first. Sessions arrive in batches of ten from the server. Session bodies load only on click.&lt;/p&gt;

&lt;p&gt;It's the same shift as whole-world loading vs level streaming in UE5. You used to load the entire map into RAM. Modern open worlds stream only chunks near the player. Disk holds everything; RAM holds only what's needed. Exactly that move.&lt;/p&gt;

&lt;p&gt;I kept single-HTML around behind a &lt;code&gt;--static&lt;/code&gt; flag. For a handful of sessions, single-HTML is still the simplest thing that works. Pick based on the situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The name Memradar — and the one line
&lt;/h2&gt;

&lt;p&gt;The first name was Promptale. Prompt plus tale. Emotional but doesn't tell you what the tool does.&lt;/p&gt;

&lt;p&gt;Memradar made the intent concrete. Mem (memory) plus Radar. A radar sweeping over my memory. It also ties into my blog (radarlog.kr), so the brand carries across. And inside lives Code Report as its own screen. The product name and the feature name each do their own job.&lt;/p&gt;

&lt;p&gt;To try it locally, it's one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx memradar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It auto-scans &lt;code&gt;~/.claude/projects/&lt;/code&gt; and &lt;code&gt;~/.codex/sessions/&lt;/code&gt;, opens the browser into the dashboard. From there, opening Code Report kicks off the full-screen retrospective. Everything stays local. Nothing gets sent anywhere.&lt;/p&gt;

&lt;p&gt;There's a web version too. At &lt;a href="https://memradar.vercel.app" rel="noopener noreferrer"&gt;memradar.vercel.app&lt;/a&gt; you can drag the &lt;code&gt;.claude&lt;/code&gt; folder straight in.&lt;/p&gt;

&lt;p&gt;The first time I looked at my own logs through this, what hit me was &lt;strong&gt;how much more I'd been talking to Claude than I realized.&lt;/strong&gt; And how focused I was late at night. Seeing it as numbers, it finally clicked: "so this is how I've been living."&lt;/p&gt;

&lt;p&gt;That's the point of Code Report. Take the conversations I left behind — and let me look back on them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"My logs were on my disk the whole time. I just wasn't looking."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>sideprojects</category>
      <category>devlog</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>내 AI 코딩 연말결산을 직접 만들었다 — Memradar Code Report</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Fri, 17 Apr 2026 07:54:21 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/nae-ai-koding-yeonmalgyeolsaneul-jigjeob-mandeuleossda-memradar-code-report-2nb1</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/nae-ai-koding-yeonmalgyeolsaneul-jigjeob-mandeuleossda-memradar-code-report-2nb1</guid>
      <description>&lt;p&gt;앱은 &lt;a href="https://memradar.vercel.app" rel="noopener noreferrer"&gt;memradar.vercel.app&lt;/a&gt;에서, 코드는 &lt;a href="https://github.com/on1659/memradar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;에 있다.&lt;br&gt;
더 많은 글은 &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;에서.&lt;/p&gt;



&lt;p&gt;매년 연말이 되면 Cursor가 "올해 너는 몇 시간 코딩했고, 어떤 언어를 얼마나 썼고" 하는 회고를 띄운다. GitHub도 Year in Review를 낸다. Discord도 프로필에 연간 통계가 뜬다.&lt;/p&gt;

&lt;p&gt;숫자는 내 것인데, 페이지를 넘기다 보면 "아 나 이랬구나" 하고 웃게 된다. 이게 연말결산의 힘이다. 정보 전달이 아니라 &lt;strong&gt;한 장면에 한 숫자씩 꺼내놓는 의식&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;나도 그게 필요했다. Claude Code와 Codex가 내 홈 디렉터리(&lt;code&gt;~/.claude/projects/&lt;/code&gt;, &lt;code&gt;~/.codex/sessions/&lt;/code&gt;)에 매일 JSONL 로그를 쌓는데, 정작 그 안을 들여다본 적이 없다. 내 대화가 내 디스크에 있는데, 내가 못 읽는다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memradar&lt;/strong&gt;는 그 JSONL을 회고로 바꿔주는 로컬 툴이다. &lt;code&gt;npx memradar&lt;/code&gt; 한 줄이면 브라우저가 뜨고, 대시보드와 함께 풀스크린 슬라이드 회고 — &lt;strong&gt;Code Report&lt;/strong&gt;가 같이 들어있다.&lt;/p&gt;

&lt;p&gt;이 글은 Memradar를 만들면서 집요하게 매달린 디테일에 대한 기록이다. 아이디어는 단순하지만, 사람이 "재밌다"고 느끼게 만드는 데는 결정 하나하나가 다 필요했다.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wrapped가 아니라 Code Report여야 했다
&lt;/h2&gt;

&lt;p&gt;처음 풀스크린 회고 기능을 만들면서 내부적으로 "Wrapped"라고 불렀다. 코드 폴더 이름도 &lt;code&gt;src/components/wrapped/&lt;/code&gt;로 시작했다. Spotify Wrapped가 레퍼런스였으니까 자연스럽게 그렇게 됐다.&lt;/p&gt;

&lt;p&gt;근데 제품 이름으로 Wrapped를 그대로 쓰면 문제가 있다. 남의 브랜드 용어를 빌려 쓰는 셈이다. 또 Wrapped라는 말은 "연말결산"이라는 범주로만 읽힌다.&lt;/p&gt;

&lt;p&gt;이름을 다시 잡으면서 &lt;code&gt;docs/UI-UX-PRINCIPLES.md&lt;/code&gt;에 이런 원칙을 못 박았다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;9. 대시보드와 Code Report는 같은 제품의 다른 무드다
- 대시보드는 정보 탐색, Code Report는 감정적 회고와 공유를 담당한다.
- Code Report는 독립 팔레트와 전용 타이포,
  풀스크린 내러티브를 사용한다.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;같은 데이터를 다루지만, &lt;strong&gt;대시보드는 "분석 툴"처럼 침착해야 하고 Code Report는 "회고 경험"처럼 감정선을 강화해도 된다&lt;/strong&gt;고 적었다. 두 화면이 무드에서 섞이지 않도록 팔레트와 타이포그래피를 분리했다.&lt;/p&gt;

&lt;p&gt;그래서 이름이 Code Report가 됐다. 코드(내 AI 코딩 로그)에 대한 리포트. 연말결산이라는 고정된 시점이 아니라 &lt;strong&gt;언제 열어도 회고가 되는 화면&lt;/strong&gt;이라는 걸 이름에 담고 싶었다. Wrapped는 1년에 한 번이지만, Code Report는 내가 필요할 때마다 열 수 있다.&lt;/p&gt;

&lt;p&gt;코드상의 폴더명(&lt;code&gt;wrapped/&lt;/code&gt;)은 그대로 뒀다. 내부 변수명까지 갈아엎는 건 리팩터링 리스크가 크고, 외부에 노출되는 제품 이름만 Code Report로 고정했다. 이 구분 자체가 "같은 기능의 안과 밖을 다르게 부를 수 있다"는 작은 교훈이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  왜 대시보드만으로는 부족했나
&lt;/h2&gt;

&lt;p&gt;당연히 대시보드부터 만들었다. 히트맵, 시간대별 차트, 워드클라우드, 세션 브라우저. 모든 지표가 한 화면에 다 있다.&lt;/p&gt;

&lt;p&gt;완성하고 내 로그를 띄워봤다. 숫자가 다 있었다. 근데 &lt;strong&gt;아무 감정도 안 들었다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이게 대시보드의 한계다. 정보는 많은데, 보는 사람은 "음 그렇구나" 하고 창을 닫는다. 같은 데이터로 Cursor 연말결산이 사람들을 웃게 만드는 건, &lt;strong&gt;한 화면에 한 숫자만&lt;/strong&gt; 올라와서다. 그 숫자를 둘러싼 공간이 다 비어있기 때문이다.&lt;/p&gt;

&lt;p&gt;Code Report의 구성 원칙을 "한 장면 한 메시지"로 잡았다. &lt;code&gt;docs/UI-UX-PRINCIPLES.md&lt;/code&gt;에 이렇게 적어뒀다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- 여기서는 "대시보드 규칙"보다 "한 장면 한 메시지"가 더 중요하다.
- 풀스크린, 강한 여백, 큰 타이포,
  전용 다크 스토리 팔레트를 사용한다.
- 마지막은 공유 가능 이미지로 닫는다.
  즉, 감정선의 끝이 곧 행동 유도여야 한다.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;슬라이드는 여덟 장이다. 인트로에 첫 세션 날짜, 다음은 총 프롬프트 수, 자주 쓴 모델, 코딩 시간대, 자주 부른 툴 순위, 성격 유형, 사용량, 마지막에 공유 카드.&lt;/p&gt;

&lt;p&gt;각 슬라이드엔 숫자 하나 또는 메시지 하나만 올라간다. "내가 Claude를 3,200번 불렀다"는 걸 대시보드 구석에서 숫자로 보는 것과, 빈 슬라이드에 3,200까지 카운트업으로 올라오는 걸 보는 건 완전히 다르다. 같은 데이터인데.&lt;/p&gt;

&lt;p&gt;이게 첫 번째 집착이었다. &lt;strong&gt;숫자를 어떻게 "느끼게" 만들까.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  성격 유형을 4개에서 8개로 갈아엎은 이유
&lt;/h2&gt;

&lt;p&gt;Code Report의 하이라이트는 성격 유형 슬라이드다. Architect, Speed Runner, Explorer, Night Sage. 네 개로 시작했다.&lt;/p&gt;

&lt;p&gt;근데 이틀 돌려보니 전부 &lt;strong&gt;"어 나 저거 아닌데"&lt;/strong&gt; 소리가 나왔다. MBTI가 재밌는 건 네 축이 각각 독립적으로 계산되기 때문이다. "I이면서 N이면서 F이면서 P"라서 INFP가 나온다. 축이 하나(4타입 중 하나)면 거칠 수밖에 없다.&lt;/p&gt;

&lt;p&gt;그래서 3축 시스템으로 다시 짰다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;style × scope × rhythm
 ↓       ↓        ↓
꼼꼼함   깊이     속도
  8 조합
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이렇게 조합하면 "심해 잠수부", "번개 해결사", "카오스 크리에이터" 같은 이름이 나온다. 각 축이 따로 계산되니까 결과가 더 개인적으로 느껴진다.&lt;/p&gt;

&lt;p&gt;이거 짜는 데 반나절 날렸다. 4타입이 틀린 게 아니라, &lt;strong&gt;결과를 읽는 순간의 느낌이 약했다.&lt;/strong&gt; 이게 Code Report에서 제일 중요한 지점이다. 숫자가 맞고 틀리고 전에, 읽는 사람이 "오 이거 나네" 하고 웃어야 한다.&lt;/p&gt;

&lt;p&gt;성격 계산 로직도 실제 데이터로 계속 튜닝했다. 내 로그에 돌려봤을 때 나한테 맞는 결과가 나오는지, 친구 로그에 돌렸을 때 친구한테 맞는 결과가 나오는지. 임계값 하나를 바꾸면 결과가 흔들린다. 이걸 수십 번 맞췄다.&lt;/p&gt;

&lt;h2&gt;
  
  
  마지막 슬라이드에 2.5초를 박은 이야기
&lt;/h2&gt;

&lt;p&gt;커밋 제목: &lt;code&gt;Fix last slide dashboard prompt timing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;무슨 문제였냐면, 공유 카드 슬라이드에서 화면을 탭하면 "대시보드로 넘어가시겠습니까?" 모달이 뜨게 해뒀다. 근데 Code Report를 쭉 넘기던 손가락 리듬으로 마지막 슬라이드에서도 무심코 탭해서, 공유 카드를 보기도 전에 모달이 떠버린다.&lt;/p&gt;

&lt;p&gt;대부분은 "괜찮지 뭐" 하고 넘어갈 디테일이다. 근데 한 번 걸리니까 계속 신경 쓰였다. 그래서 고쳤다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setDashboardPromptReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slideIndex&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;lastSlideIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setDashboardPromptReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lastSlideIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slideIndex&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;마지막 슬라이드에 들어가면 2.5초 동안 &lt;code&gt;dashboardPromptReady&lt;/code&gt;가 false다. 그동안 탭해도 모달은 안 뜬다. 심지어 커서도 &lt;code&gt;default&lt;/code&gt;로 바꿨다. "아직 누를 수 없다"는 걸 마우스 커서로도 알려준다.&lt;/p&gt;

&lt;p&gt;이거 쓰면서 스스로도 생각했다. 이게 필요한 최적화일까. 사용자는 눈치 못 챌 것 같은데.&lt;/p&gt;

&lt;p&gt;근데 &lt;strong&gt;필요한 건 맞다.&lt;/strong&gt; 게임에서 컷씬이 끝난 직후 입력을 몇 프레임 막는 거랑 똑같다. 플레이어가 "스킵 버튼 누르는 리듬"으로 다음 장면에서 뭔가를 잘못 누르는 걸 막는다. 이런 건 걸리면 기분이 나쁘고, 막아두면 아무도 모른다. 근데 모르는 게 맞다.&lt;/p&gt;

&lt;h2&gt;
  
  
  테마가 20개인 이유
&lt;/h2&gt;

&lt;p&gt;Memradar에는 테마가 20개 있다. 배경 4종(Dark, AMOLED, Light, Warm), 액센트 색 5종(Indigo, Violet, Teal, Rose, Amber). 4 × 5 = 20.&lt;/p&gt;

&lt;p&gt;왜 이렇게 많냐. 이것도 "느낌"의 문제다.&lt;/p&gt;

&lt;p&gt;Code Report를 넘기는 경험은 &lt;strong&gt;사적이다.&lt;/strong&gt; 내 코딩 로그를 내가 보는 거다. 남이 만든 다크 테마를 그냥 쓰는 게 아니라, 내 분위기를 내가 고르고 싶다. Cursor 연말결산이 보라색 하나로 고정되어 있는 것과 다르게, 내가 만드는 건 내가 고를 수 있어야 한다.&lt;/p&gt;

&lt;p&gt;배경 네 개로 나눈 것도 계산된 거다. Dark는 기본, AMOLED는 OLED 화면용 진짜 검정, Light는 밝은 카페용, Warm은 저녁 무드. 상황이 다르면 고르는 게 다르다.&lt;/p&gt;

&lt;p&gt;폰트도 Noto Sans KR + Noto Serif KR로 고정했다. 한글이 엄청 많이 들어가기 때문에, 한글이 예쁘게 나오는 게 첫째다. 영어 폰트 안 썼다. 내가 주로 한국어로 코딩해서 프롬프트도 한국어 비중이 높고, 그걸 읽는 Code Report도 한국어가 예뻐야 한다.&lt;/p&gt;

&lt;p&gt;localStorage에 저장해서 다음번에도 고른 테마가 유지된다. 이건 당연한데, 당연한 걸 빼먹으면 바로 티난다.&lt;/p&gt;

&lt;h2&gt;
  
  
  히트맵 한 개에 들어간 결정들
&lt;/h2&gt;

&lt;p&gt;GitHub 스타일 일별 활동 히트맵. 이 위젯 하나에 들어간 결정이 이 정도다.&lt;/p&gt;

&lt;p&gt;첫째, &lt;strong&gt;반응형 셀 크기.&lt;/strong&gt; 창 너비에 따라 셀이 자동으로 커지고 작아진다. &lt;code&gt;ResizeObserver&lt;/code&gt;로 컨테이너 크기를 추적하다가, 셀 크기를 다시 계산해서 리렌더한다. 처음엔 고정 크기로 뒀는데, 화면 작은 노트북에서 히트맵이 잘려서 다시 짰다.&lt;/p&gt;

&lt;p&gt;둘째, &lt;strong&gt;클릭해서 날짜 선택.&lt;/strong&gt; 셀을 클릭하면 그날 세션 요약이 사이드에 뜬다. 처음엔 hover만 있었는데, hover는 모바일에서 안 되고, 클릭해서 "고정"할 방법이 있으면 더 자세히 볼 수 있다.&lt;/p&gt;

&lt;p&gt;셋째, &lt;strong&gt;streak 카운터.&lt;/strong&gt; "연속 며칠 코딩했는지." 이걸 어디에 넣을까 고민하다가 히트맵 옆 사이드바에 박았다. Duolingo처럼 게임화하려는 게 아니라, 히트맵 보면서 자연스럽게 "아 나 이번 달 15일 연속이네" 하고 알게 되는 정도.&lt;/p&gt;

&lt;p&gt;넷째, &lt;strong&gt;요일 패턴.&lt;/strong&gt; 월화수목금토일 중 어느 요일에 가장 많이 코딩했는지 사이드에 작게. 이건 넣을까 말까 고민했는데, 내가 주말에 생각보다 많이 코딩한다는 걸 이걸 보고 알았다. 이런 게 Code Report의 맛이다. 몰랐던 내 패턴이 보이는 거.&lt;/p&gt;

&lt;p&gt;위젯 하나에 결정이 네 개. 히트맵뿐 아니라 워드클라우드, 시간대별 차트, 토큰 차트 다 이렇게 만들어졌다.&lt;/p&gt;

&lt;h2&gt;
  
  
  DropZone wording을 몇 번 바꿨는지
&lt;/h2&gt;

&lt;p&gt;가장 집요했던 건 랜딩 페이지 DropZone이다. 커밋 로그에 DropZone wording 수정만 네 번 있다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Replace copy-paste wording with Ctrl+C/V shortcut
- Use Ctrl+C/V/Enter wording consistently in DropZone
- Allow .claude/.codex root folder drop and add install guide link
- Fix DropZone wording: shorten Ctrl+C/V label
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;하나씩 뜯어보면 이렇다. 처음엔 "복사해서 붙여넣기"였다. 그러다가 Ctrl+C / Ctrl+V로 바꿨다. 왜냐면 한국어로 "복사해서 붙여넣기"는 길고, 영어로 "copy and paste"도 장황하다. 숏컷 두 개 나란히 보여주면 0.5초 만에 "아 저거"가 꽂힌다.&lt;/p&gt;

&lt;p&gt;두 번째 변경은 "일관성"이었다. 어떤 곳엔 "Ctrl+C/V" 있는데 다른 곳엔 "복사/붙여넣기"가 남아있었다. 용어가 섞이면 불편하다.&lt;/p&gt;

&lt;p&gt;세 번째, &lt;code&gt;.claude&lt;/code&gt; 폴더 자체 드롭 허용. 원래는 &lt;code&gt;.claude/projects/&lt;/code&gt; 안쪽을 드롭해야 파싱됐다. 근데 사용자 입장에선 &lt;code&gt;.claude&lt;/code&gt;를 홈에서 드래그하는 게 자연스럽다. 그래서 드롭 핸들러가 &lt;code&gt;.claude&lt;/code&gt; 안의 &lt;code&gt;projects&lt;/code&gt; 자식을 자동으로 찾아 들어가도록 고쳤다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;droppedFolder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.claude&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projectsDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;findChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;droppedFolder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;projects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectsDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;scanDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectsDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;네 번째는 다시 wording. "Ctrl+C/V" 레이블이 너무 길어서 앞에 붙어있던 중복 prefix를 뺐다.&lt;/p&gt;

&lt;p&gt;같은 컴포넌트에서 표현 하나 가지고 네 번 고쳤다. 과하다 싶지만, DropZone은 사용자가 제일 먼저 보는 화면이다. 여기서 &lt;strong&gt;5초 안에 뭘 해야 하는지&lt;/strong&gt;가 안 꽂히면, 나머지가 아무리 예뻐도 소용없다.&lt;/p&gt;

&lt;h2&gt;
  
  
  한영 동시 지원이 생각보다 큰 결정이었다
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;i18n (ko/en), theme presets, and hash routing&lt;/code&gt;. 한 커밋에 세 가지가 같이 들어갔다.&lt;/p&gt;

&lt;p&gt;한영 동시 지원을 넣은 건 블로그를 한영 동시 발행하는 나 자신을 위해서다. 근데 더 큰 이유가 있다. &lt;strong&gt;Code Report에 들어가는 문구는 감정적이다.&lt;/strong&gt; "너는 Night Owl이야", "이번 달에만 3,200번 대화했어" 같은 문장들. 이게 영어로만 있으면, 한국어 유저는 "재미"가 반감된다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/i18n.tsx&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;translations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ko&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.nightSage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;새벽의 현자&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.speedRunner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;번개 해결사&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.nightSage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Night Sage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;personality.speedRunner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lightning Fixer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Night Sage를 "밤의 현자"가 아니라 "새벽의 현자"로 번역한 것도, "Lightning Fixer"를 "번개 해결사"로 맞춘 것도, 그냥 직역이 아니라 &lt;strong&gt;한국어로 읽었을 때 같은 온도&lt;/strong&gt;가 되도록 골랐다. 성격 유형 여덟 개 이름을 한영 각각 다시 쓰는 데 몇 시간 걸렸다.&lt;/p&gt;

&lt;p&gt;해시 라우팅을 같이 넣은 이유는, Code Report 링크를 공유할 수 있게 만들려면 URL에 상태가 담겨야 하기 때문이다. &lt;code&gt;#wrapped/5&lt;/code&gt; 같은 식으로 슬라이드 번호가 URL에 들어간다. 새로고침해도 돌아올 수 있다.&lt;/p&gt;

&lt;h2&gt;
  
  
  단일 HTML을 버린 순간
&lt;/h2&gt;

&lt;p&gt;기술적인 결정 중에 제일 컸던 건 CLI 구조를 단일 HTML에서 로컬 서버로 바꾼 거다.&lt;/p&gt;

&lt;p&gt;원래는 CLI가 JSONL을 다 파싱해서, JSON으로 직렬화하고, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 태그에 박아서 거대한 단일 HTML 파일을 만들었다. 오프라인에서도 돌고 서버도 필요 없고, 깔끔했다.&lt;/p&gt;

&lt;p&gt;근데 내 &lt;code&gt;.claude/projects/&lt;/code&gt;가 커지면서 그 HTML이 18MB를 넘겼다. 브라우저가 JSON.parse 하는 동안 4~5초 멈춘다. Code Report 시작하기도 전에 끊긴다.&lt;/p&gt;

&lt;p&gt;그래서 로컬 서버(http.createServer로 3939 포트) + &lt;code&gt;/api/sessions&lt;/code&gt; 스트리밍으로 뒤집었다. 브라우저는 0.6MB짜리 앱 번들만 먼저 받고, 세션은 10개씩 서버에서 당겨온다. 세션 본문은 클릭했을 때만.&lt;/p&gt;

&lt;p&gt;이건 UE5에서 맵 전체 로딩 vs 레벨 스트리밍이랑 똑같다. 예전엔 월드 전체를 RAM에 올렸다. 지금 오픈월드는 플레이어 주변만 스트리밍으로 로드한다. 디스크엔 다 있는데, 메모리엔 필요한 만큼만. 정확히 그 이동이다.&lt;/p&gt;

&lt;p&gt;단일 HTML 모드는 &lt;code&gt;--static&lt;/code&gt; 플래그로 살려뒀다. 세션이 몇 개 없을 땐 여전히 단일 HTML이 제일 간단하다. 상황에 따라 고를 수 있게.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memradar라는 이름, 그리고 한 줄
&lt;/h2&gt;

&lt;p&gt;처음 이름은 Promptale이었다. 프롬프트 + 이야기. 감성적이긴 한데 뭐 하는 툴인지 안 읽힌다.&lt;/p&gt;

&lt;p&gt;Memradar로 바꾸고 나니 의미가 명확해졌다. Mem(memory) + Radar. 내 기억(로그)을 레이더로 훑는다. 내 블로그(radarlog.kr)와도 엮여서 브랜드가 이어진다. 그리고 그 안에 Code Report라는 화면이 들어있다. 제품명과 기능명이 각자 자기 역할을 한다.&lt;/p&gt;

&lt;p&gt;로컬에서 돌려보고 싶으면 한 줄이면 된다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;npx memradar
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;자동으로 &lt;code&gt;~/.claude/projects/&lt;/code&gt;랑 &lt;code&gt;~/.codex/sessions/&lt;/code&gt;를 스캔하고, 브라우저에서 대시보드를 띄워준다. 거기서 Code Report를 열면 풀스크린 회고가 시작된다. 데이터는 전부 로컬에서만 처리된다. 서버에 뭐 안 보낸다.&lt;/p&gt;

&lt;p&gt;웹 버전도 있다. &lt;a href="https://memradar.vercel.app" rel="noopener noreferrer"&gt;memradar.vercel.app&lt;/a&gt;에서 &lt;code&gt;.claude&lt;/code&gt; 폴더를 직접 드래그해도 된다.&lt;/p&gt;

&lt;p&gt;내 로그를 이걸로 처음 봤을 때 들었던 생각은, &lt;strong&gt;Claude한테 생각보다 훨씬 많이 말했다&lt;/strong&gt;는 거였다. 그리고 새벽에 훨씬 집중했다는 것도. 숫자로 보고 나서야 "아 내가 이렇게 살고 있구나"가 와닿았다.&lt;/p&gt;

&lt;p&gt;이게 Code Report의 목적이다. 내가 남긴 대화를, 내가 회고할 수 있게.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"내 로그는 내 디스크에 있었다. 내가 안 봤을 뿐이다."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>ux</category>
    </item>
    <item>
      <title>Happy — The Open-Source App That Puts Claude Code in Your Pocket</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Wed, 15 Apr 2026 11:02:45 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/happy-the-open-source-app-that-puts-claude-code-in-your-pocket-7i2</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/happy-the-open-source-app-that-puts-claude-code-in-your-pocket-7i2</guid>
      <description>&lt;p&gt;Code on &lt;a href="https://github.com/slopus/happy" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Live app at &lt;a href="https://happy.engineering" rel="noopener noreferrer"&gt;happy.engineering&lt;/a&gt;.&lt;br&gt;
More posts at &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;I kicked off a refactoring job with Claude Code and went to grab lunch. Came back 20 minutes later. The terminal was sitting on a permission prompt. It had been doing nothing the entire time, just waiting for me to hit "yes."&lt;/p&gt;

&lt;p&gt;If you use Claude Code, you've been there.&lt;/p&gt;

&lt;p&gt;Happy solves this head-on. It's an open-source CLI wrapper that lets you control Claude Code from your phone. Over 17,000 GitHub stars, MIT licensed. But the first question everyone asks is the same one I had.&lt;/p&gt;

&lt;p&gt;"Isn't this just Claude Cowork Dispatch?"&lt;/p&gt;

&lt;p&gt;Short answer: completely different tools.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dispatch vs Dispatch vs Happy
&lt;/h2&gt;

&lt;p&gt;The word "Dispatch" shows up in at least three different contexts, and it's confusing. Let me untangle it.&lt;/p&gt;

&lt;p&gt;First, there's &lt;strong&gt;Claude Cowork Dispatch&lt;/strong&gt; — Anthropic's official feature announced in March 2026. You scan a QR code on your desktop, and your phone becomes a remote control for an AI agent. It connects with 38+ apps and is built for non-coding tasks: documents, emails, productivity tools. If you don't write code, this is your tool.&lt;/p&gt;

&lt;p&gt;Then there's &lt;strong&gt;bassimeledath/dispatch&lt;/strong&gt; — an open-source Claude Code skill. Type &lt;code&gt;/dispatch&lt;/code&gt; and your main session becomes an orchestrator. Actual work fans out to background workers, each with a fresh context window. It's about making context windows 10x more efficient. Nothing to do with mobile.&lt;/p&gt;

&lt;p&gt;And then there's &lt;strong&gt;Happy&lt;/strong&gt;. It wraps Claude Code's CLI and lets you remote-control the terminal session itself from a mobile app or web browser.&lt;/p&gt;

&lt;p&gt;Think of it this way. Cowork Dispatch is hiring an assistant. bassimeledath/dispatch is a team lead distributing tasks. Happy is putting your terminal in your pocket.&lt;/p&gt;

&lt;p&gt;Zero overlap.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Happy Actually Does
&lt;/h2&gt;

&lt;p&gt;Installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; happy-coder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Now type &lt;code&gt;happy&lt;/code&gt; instead of &lt;code&gt;claude&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Before&lt;/span&gt;
claude

&lt;span class="c"&gt;# After&lt;/span&gt;
happy

&lt;span class="c"&gt;# Works with Codex too&lt;/span&gt;
happy codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy wraps the Claude Code process. Claude Code still runs locally — nothing changes there. But Happy encrypts the session's I/O and relays it through a server to your phone.&lt;/p&gt;

&lt;p&gt;The architecture is three pieces. A CLI program on your machine starts and monitors Claude Code. A relay server passes encrypted blobs between devices. A mobile app decrypts and displays everything. The server only moves encrypted data around — it literally cannot read your code.&lt;/p&gt;

&lt;p&gt;The encryption is solid. X25519 keypairs, ECDH key exchange, AES-256-GCM message encryption, ephemeral session keys for forward secrecy. If you're working with company code, this matters. Your code never exists in plaintext on anyone else's infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Voice Coding — Skeptical Until I Wasn't
&lt;/h2&gt;

&lt;p&gt;"Code with your voice" sounds like a gimmick. I thought so too. Dictating &lt;code&gt;for (int i = 0; i &amp;lt; n; i++)&lt;/code&gt; into a microphone is obviously terrible.&lt;/p&gt;

&lt;p&gt;But that's not what Happy's voice agent does.&lt;/p&gt;

&lt;p&gt;It does exactly one thing: translates your rambling into structured requests that Claude Code can understand. You're not dictating code. You're saying things like "refactor the auth module to separate concerns" while walking your dog.&lt;/p&gt;

&lt;p&gt;The docs make a good point. Sitting at your desk at 100% efficiency for zero hours beats walking around at 50% efficiency for three hours — wait, no. It's the other way around. 50% of three otherwise-wasted hours is infinitely more than 0% of them.&lt;/p&gt;

&lt;p&gt;The voice agent prompts are customizable inside the app. No forking, no rebuilding. You can tune how it interprets your speech directly. That's practical.&lt;/p&gt;

&lt;p&gt;For someone like me who runs UE5 builds that take ages, this means I can voice-control a Claude Code agent on a side project while waiting for shaders to compile. Build wait time just disappears.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallel Sessions and Why They Matter
&lt;/h2&gt;

&lt;p&gt;Happy can run multiple Claude Code instances simultaneously. Frontend refactoring in one session, API test generation in another, infra work in a third. Switch between them on your phone.&lt;/p&gt;

&lt;p&gt;Why this matters: Claude Code Max gives you unlimited tokens, but context contamination is real. Running five different tasks in one session means by task three, Claude is losing track of task one. Separate sessions keep each task in a clean context.&lt;/p&gt;

&lt;p&gt;The bassimeledath/dispatch skill focuses on using context windows efficiently within a single session. Happy's multi-session approach physically isolates sessions so they don't interfere. Different strategy, complementary goals.&lt;/p&gt;

&lt;p&gt;In practice, it looks like this. Session A runs a component refactoring. Session B generates missing tests. Both show up on your phone. A permission request comes in on Session A — you approve it while sipping coffee. Session B finishes — you review the output. Neither session knows the other exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Happy Won Over the Alternatives
&lt;/h2&gt;

&lt;p&gt;Happy wasn't the first attempt at mobile Claude Code. CodeRemote, YoloCode, Omnara, Claudia, Conductor, Tonkotsu — they all tried. One user on X posted they'd tried every single one and Happy beat them all.&lt;/p&gt;

&lt;p&gt;Three reasons, I think.&lt;/p&gt;

&lt;p&gt;Open source means transparency. You can audit every line. No telemetry, no tracking. When you're piping company code through a tool, this is decisive. A closed-source app asking for terminal access to your codebase is a non-starter for most teams.&lt;/p&gt;

&lt;p&gt;Self-hosting is straightforward. One Docker Compose file gives you PostgreSQL + Redis + Happy Server in about three minutes. Run it behind your company firewall and the relay server never touches the public internet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;happy-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;happy-server:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DATABASE_URL=postgresql://postgres:postgres@postgres:5432/happy-server&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_URL=redis://redis:6379&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SEED=your-secure-seed&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it's free. This alone beats everything else. When a free open-source tool is better than paid alternatives, the market corrects fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Still Missing
&lt;/h2&gt;

&lt;p&gt;Being honest: Happy isn't perfect.&lt;/p&gt;

&lt;p&gt;Cowork Dispatch integrates natively with 38+ apps. Happy is purely CLI terminal remote control. Sending Slack messages or editing Google Docs isn't what Happy does. That's Cowork Dispatch's territory.&lt;/p&gt;

&lt;p&gt;The last official release (v1.4.0) was September 2025. The npm package rename and monorepo consolidation happened after that, but without formal release tags. Development continues on main, which is great for velocity but can be shaky for stability.&lt;/p&gt;

&lt;p&gt;And there are edge cases. GitHub issues mention stdin-related crashes in background mode. The project is active — 1,500+ commits, 44 contributors — but it's community-driven, not backed by a company.&lt;/p&gt;

&lt;h2&gt;
  
  
  So What Should You Actually Use
&lt;/h2&gt;

&lt;p&gt;Here's the decision tree.&lt;/p&gt;

&lt;p&gt;You don't write code and want AI to automate documents, emails, and productivity tools → &lt;strong&gt;Claude Cowork Dispatch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You want to maximize context efficiency within a single Claude Code session with parallel background workers → &lt;strong&gt;bassimeledath/dispatch skill&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You want to control your Claude Code terminal from anywhere with your phone → &lt;strong&gt;Happy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These three aren't competing. They're different layers. You could even combine them: use Happy to access Claude Code from your phone, then run /dispatch inside that session to fan out work to background agents.&lt;/p&gt;

&lt;p&gt;The real bottleneck in the AI coding agent era isn't model performance. It's whether you can control an already-running agent when you're not at your desk. Happy solves that with one CLI wrapper.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We didn't need a better model. We needed a better remote."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>opensource</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Claude Code를 폰에 들고 다니게 해주는 오픈소스, Happy</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Wed, 15 Apr 2026 11:02:44 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/claude-codereul-pone-deulgo-danige-haejuneun-opeunsoseu-happy-2i5n</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/claude-codereul-pone-deulgo-danige-haejuneun-opeunsoseu-happy-2i5n</guid>
      <description>&lt;p&gt;코드는 &lt;a href="https://github.com/slopus/happy" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;에, 앱은 &lt;a href="https://happy.engineering" rel="noopener noreferrer"&gt;happy.engineering&lt;/a&gt;에서 볼 수 있다.&lt;br&gt;
더 많은 글은 &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;에서.&lt;/p&gt;



&lt;p&gt;Claude Code로 리팩토링을 돌려놓고 밥 먹으러 나갔다. 20분 뒤 폰을 보니 아무 알림도 없다. 돌아와서 터미널을 열었더니 permission 요청에서 멈춰 있었다. 20분 동안 아무것도 안 하고 기다리고 있었던 거다.&lt;/p&gt;

&lt;p&gt;이 상황, Claude Code 쓰는 사람이면 다 겪어봤을 거다.&lt;/p&gt;

&lt;p&gt;Happy는 이 문제를 정면으로 해결한다. Claude Code를 폰에서 제어할 수 있게 해주는 오픈소스 CLI 래퍼다. GitHub 스타 17,000개 넘고, MIT 라이선스. 근데 처음 봤을 때 드는 의문이 있다.&lt;/p&gt;

&lt;p&gt;"이거 Claude Cowork Dispatch 아니야?"&lt;/p&gt;

&lt;p&gt;결론부터 말하면, 전혀 다른 물건이다.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dispatch는 뭐고 Happy는 뭔데
&lt;/h2&gt;

&lt;p&gt;"Dispatch"라는 이름이 붙은 게 최소 세 가지다. 먼저 정리하고 가자.&lt;/p&gt;

&lt;p&gt;첫 번째는 &lt;strong&gt;Claude Cowork Dispatch&lt;/strong&gt;. Anthropic이 2026년 3월에 공개한 공식 기능이다. 데스크톱에서 QR 코드를 스캔하면 폰에서 AI 에이전트를 제어할 수 있다. 38개 이상의 앱과 연동되고, 파일 검색이나 요약 같은 비코딩 작업에 최적화되어 있다. 코드를 쓰는 게 아니라 문서, 이메일, 생산성 도구를 다루는 사람들을 위한 물건이다.&lt;/p&gt;

&lt;p&gt;두 번째는 &lt;strong&gt;bassimeledath/dispatch&lt;/strong&gt;. Claude Code의 스킬로 동작하는 오픈소스 프로젝트다. &lt;code&gt;/dispatch&lt;/code&gt;를 치면 메인 세션이 오케스트레이터가 되고, 실제 작업은 백그라운드 워커들이 각자 독립된 컨텍스트 윈도우에서 병렬로 실행한다. 컨텍스트 윈도우를 10배 효율적으로 쓰는 게 핵심이다. 모바일 제어와는 관계 없다.&lt;/p&gt;

&lt;p&gt;세 번째가 &lt;strong&gt;Happy&lt;/strong&gt;. Claude Code의 CLI를 래핑해서 모바일/웹에서 터미널 세션 자체를 원격 제어하는 도구다.&lt;/p&gt;

&lt;p&gt;비유하자면 이렇다. Cowork Dispatch는 비서한테 일을 시키는 거다. bassimeledath/dispatch는 팀장이 팀원들한테 업무를 나누는 거다. Happy는 내가 쓰던 터미널을 주머니에 넣고 돌아다니는 거다.&lt;/p&gt;

&lt;p&gt;겹치는 영역이 전혀 없다.&lt;/p&gt;
&lt;h2&gt;
  
  
  그래서 Happy가 뭘 하는 건데
&lt;/h2&gt;

&lt;p&gt;설치부터 보자.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; happy-coder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이게 끝이다. 이제부터 &lt;code&gt;claude&lt;/code&gt; 대신 &lt;code&gt;happy&lt;/code&gt;를 치면 된다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 기존&lt;/span&gt;
claude

&lt;span class="c"&gt;# Happy&lt;/span&gt;
happy

&lt;span class="c"&gt;# Codex도 된다&lt;/span&gt;
happy codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy는 Claude Code 프로세스를 감싸는 래퍼다. 로컬에서 Claude Code가 돌아가는 건 똑같다. 다만 그 세션의 입출력을 암호화해서 릴레이 서버로 보내고, 폰 앱에서 받아 보여준다.&lt;/p&gt;

&lt;p&gt;아키텍처가 세 조각이다. CLI 프로그램이 로컬에서 Claude Code를 시작하고 모니터링한다. 릴레이 서버가 암호화된 블롭을 양쪽으로 전달한다. 모바일 앱이 그걸 복호화해서 보여준다. 서버는 E2E 암호화된 데이터를 중계만 하기 때문에 서버 쪽에서는 코드를 읽을 수 없다.&lt;/p&gt;

&lt;p&gt;X25519 키페어로 ECDH 키 교환을 하고, AES-256-GCM으로 메시지를 암호화한다. 세션별 임시 키로 전방 비밀성까지 보장한다. 회사 코드를 다루는 사람 입장에서 이 부분이 중요하다. 내 코드가 어딘가에 평문으로 저장되는 일은 없다.&lt;/p&gt;

&lt;h2&gt;
  
  
  보이스 코딩이 진짜 쓸만한가
&lt;/h2&gt;

&lt;p&gt;처음에 "음성으로 코딩"이라는 말을 듣고 솔직히 회의적이었다. 음성 인식이 아무리 좋아져도, 코드를 말로 짜는 건 비효율적이니까.&lt;/p&gt;

&lt;p&gt;근데 Happy의 보이스 코딩은 그런 게 아니다.&lt;/p&gt;

&lt;p&gt;voice agent가 하는 일은 딱 하나다. 내가 중얼거리는 말을 Claude Code가 이해할 수 있는 구조화된 요청으로 변환한다. 코드를 말로 짜는 게 아니라, "auth 모듈의 리팩토링 방향을 잡아줘"를 걸으면서 말하는 거다.&lt;/p&gt;

&lt;p&gt;공식 문서에서 재밌는 관점을 하나 꺼냈다. 키보드 앞에 앉아서 100% 효율로 일하는 것과, 산책하면서 50% 효율로 일하는 것을 비교하면, 후자의 "3시간 × 50%"가 전자의 "0시간 × 100%"보다 낫다는 거다. 어차피 쉬는 시간에 아무것도 안 하고 있었을 테니.&lt;/p&gt;

&lt;p&gt;프롬프트도 앱 안에서 커스터마이징 가능하다. 포크해서 리빌드할 필요 없다. voice agent의 행동 방식을 직접 조절할 수 있다. 이건 실용적이다.&lt;/p&gt;

&lt;p&gt;나 같은 경우를 생각해보면, UE5 빌드를 돌려놓고 기다리는 시간에 사이드프로젝트의 Claude Code 에이전트를 음성으로 제어할 수 있다. 빌드 대기 시간이 그냥 사라지는 거다.&lt;/p&gt;

&lt;h2&gt;
  
  
  멀티 세션 병렬이 의미 있는 이유
&lt;/h2&gt;

&lt;p&gt;Happy는 여러 Claude Code 인스턴스를 동시에 돌릴 수 있다. 프론트엔드, 백엔드, 인프라 작업을 각각 별도 세션으로 띄우고, 폰에서 세션 간 전환하면서 모니터링한다.&lt;/p&gt;

&lt;p&gt;이게 왜 중요하냐면, Claude Code Max 구독은 토큰 무제한이지만 동시 실행 세션 수에는 제한이 있다. 여러 작업을 한 세션에서 순차적으로 돌리면 컨텍스트가 오염된다. 세션을 분리하면 각 작업이 깨끗한 컨텍스트에서 독립적으로 돌아간다.&lt;/p&gt;

&lt;p&gt;앞서 언급한 bassimeledath/dispatch가 "컨텍스트 윈도우를 효율적으로 쓰는 것"에 집중한다면, Happy의 멀티 세션은 "물리적으로 세션을 분리해서 서로 간섭 없이 돌리는 것"에 집중한다. 방향이 다르다.&lt;/p&gt;

&lt;p&gt;실전에서 보면 이런 식이다. 세션 A에서는 프론트엔드 컴포넌트 리팩토링이 돌아간다. 세션 B에서는 API 엔드포인트 테스트 생성이 돌아간다. 폰에서 두 세션 다 보면서, 권한 요청이 오면 바로 승인한다. 커피 마시면서.&lt;/p&gt;

&lt;h2&gt;
  
  
  기존에 뭐가 있었고 왜 Happy가 이겼나
&lt;/h2&gt;

&lt;p&gt;모바일에서 Claude Code를 쓰려는 시도가 Happy만 있었던 건 아니다. CodeRemote, YoloCode, Omnara, Claudia, Conductor, Tonkotsu 같은 프로젝트들이 있었다. X에서 한 사용자가 "다 써봤는데 Happy가 이겼다"고 올린 글이 있다.&lt;/p&gt;

&lt;p&gt;왜 이겼을까. 추측해보면 세 가지다.&lt;/p&gt;

&lt;p&gt;오픈소스라서 투명하다. 내 코드가 어디로 가는지 직접 확인할 수 있다. 텔레메트리도 트래킹도 없다. 보안이 중요한 회사 코드를 다루는 개발자한테 이건 결정적이다. 클로즈드 소스 앱에 회사 코드를 흘려보내는 건 아무리 편해도 쓰기 어렵다.&lt;/p&gt;

&lt;p&gt;셀프호스팅이 가능하다. Docker Compose 파일 하나로 PostgreSQL + Redis + Happy Server를 3분 만에 띄울 수 있다. 회사 방화벽 안에서 돌리면 릴레이 서버조차 외부에 노출되지 않는다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.yml&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;happy-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;happy-server:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DATABASE_URL=postgresql://postgres:postgres@postgres:5432/happy-server&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_URL=redis://redis:6379&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SEED=your-secure-seed&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;그리고 무료다. 이건 사실 다른 걸 다 이기는 이유다. 같은 기능을 하는 유료 앱이 있는데 무료 오픈소스가 더 잘 만들어져 있으면, 결과는 뻔하다.&lt;/p&gt;

&lt;h2&gt;
  
  
  근데 아직 부족한 것도 있다
&lt;/h2&gt;

&lt;p&gt;솔직히 써야 할 것 같다. Happy가 만능은 아니다.&lt;/p&gt;

&lt;p&gt;Claude Cowork Dispatch가 38개 이상의 앱과 네이티브로 연동되는 것에 비하면, Happy는 순수하게 CLI 터미널의 원격 제어만 한다. Slack에 메시지 보내거나 Google Docs를 편집하는 건 Happy의 영역이 아니다. 그건 Cowork Dispatch의 영역이다.&lt;/p&gt;

&lt;p&gt;릴리즈 노트를 보면 v1.4.0이 마지막 공식 릴리즈고 2025년 9월이다. npm 패키지명이 &lt;code&gt;happy-coder&lt;/code&gt;에서 &lt;code&gt;happy&lt;/code&gt;로 바뀌고 모노레포로 통합된 건 그 이후인데, 정식 릴리즈 태깅 없이 main 브랜치에서 계속 개발이 진행되는 패턴이다. 안정성 측면에서는 좀 불안할 수 있다.&lt;/p&gt;

&lt;p&gt;그리고 Cowork Dispatch의 성공률이 복잡한 작업에서 50% 정도라는 외부 테스트 결과가 있었는데, Happy도 비슷한 엣지 케이스가 있을 수 있다. stdin 관련 이슈로 백그라운드 모드에서 크래시가 나는 경우가 GitHub 이슈에 보고되어 있다.&lt;/p&gt;

&lt;h2&gt;
  
  
  결국 뭘 써야 하나
&lt;/h2&gt;

&lt;p&gt;정리하면 이렇다.&lt;/p&gt;

&lt;p&gt;코드를 안 쓰고 문서/이메일/생산성 도구를 AI로 자동화하고 싶다면 → &lt;strong&gt;Claude Cowork Dispatch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;하나의 Claude Code 세션에서 컨텍스트를 효율적으로 쓰면서 병렬 작업을 하고 싶다면 → &lt;strong&gt;bassimeledath/dispatch&lt;/strong&gt; 스킬.&lt;/p&gt;

&lt;p&gt;Claude Code 터미널 자체를 어디서든 제어하고 싶다면 → &lt;strong&gt;Happy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;이 셋은 경쟁 관계가 아니라 레이어가 다르다. 같이 쓸 수도 있다. Happy로 모바일에서 Claude Code 세션에 접속해서, 그 안에서 /dispatch 스킬을 실행하는 것도 가능하다.&lt;/p&gt;

&lt;p&gt;AI 코딩 에이전트 시대에 진짜 병목은 모델 성능이 아니다. 이미 돌아가고 있는 에이전트를 내가 자리에 없을 때도 제어할 수 있느냐, 그게 병목이다. Happy는 그 병목을 CLI 래퍼 하나로 풀었다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"더 좋은 모델이 아니라 더 나은 리모컨이 필요했다."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>To Teach AI How to Remember, First Teach It How to Forget 2/2</title>
      <dc:creator>김이더</dc:creator>
      <pubDate>Tue, 14 Apr 2026 08:05:32 +0000</pubDate>
      <link>https://dev.to/_53fb7c03dd741a6124e4e/to-teach-ai-how-to-remember-first-teach-it-how-to-forget-22-1ejf</link>
      <guid>https://dev.to/_53fb7c03dd741a6124e4e/to-teach-ai-how-to-remember-first-teach-it-how-to-forget-22-1ejf</guid>
      <description>&lt;p&gt;Code on &lt;a href="https://github.com/zhongwanjun/MemoryBank-SiliconFriend" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Paper on &lt;a href="https://arxiv.org/abs/2305.10250" rel="noopener noreferrer"&gt;arXiv&lt;/a&gt;.&lt;br&gt;
More posts at &lt;a href="https://radarlog.kr" rel="noopener noreferrer"&gt;radarlog.kr&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;Part 1 covered MemoryBank's architecture and how to use it. This part cracks open the engine. One formula. &lt;code&gt;R = e^(−t/S)&lt;/code&gt;. How it works, what happens when S changes, where to set the threshold — all in numbers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Breaking Down the Formula
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R = e^(−t/S)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Three variables. R is memory retention (between 0 and 1), t is time elapsed since learning, S is memory strength. e is Euler's number, approximately 2.71828.&lt;/p&gt;

&lt;p&gt;This is an exponential decay model. Same structure as the formula for radioactive decay in physics. Values drop dramatically at first, then taper off gradually.&lt;/p&gt;

&lt;p&gt;If you're a game developer, this pattern is everywhere. Alpha decay on particle effects, sound fade-outs, damage-over-time tick reduction. All exponential decay. The forgetting curve is the same math. Just applied to memories instead of damage.&lt;/p&gt;

&lt;p&gt;Here's the key insight. What really matters in this formula is the &lt;strong&gt;t/S ratio&lt;/strong&gt;. Not the individual values of t and S, but how they relate. When t/S equals 1, R is about 0.368 (36.8%). At t/S = 2, R drops to about 0.135 (13.5%). At t/S = 3, it's roughly 0.050 (5.0%). Each unit increase in the ratio cuts retention by roughly 1/e (about 36.8%).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;

&lt;span class="c1"&gt;# Retention by t/S ratio
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t/S = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → R = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# t/S = 0.0 → R = 1.0000 (100.0%)
# t/S = 0.5 → R = 0.6065 (60.7%)
# t/S = 1.0 → R = 0.3679 (36.8%)
# t/S = 2.0 → R = 0.1353 (13.5%)
# t/S = 3.0 → R = 0.0498 (5.0%)
# t/S = 5.0 → R = 0.0067 (0.7%)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implication is clear. A larger S means the t/S ratio stays small for longer, so R stays high. S &lt;strong&gt;flattens the curve&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens When S Increases
&lt;/h2&gt;

&lt;p&gt;In MemoryBank, S is an integer. First mention: 1. One recall: 2. Another recall: 3. Simple. Let's see exactly what this simple change does to the curve.&lt;/p&gt;

&lt;p&gt;Using days as the time unit for t. What's the retention of an S=1 memory after one day?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Retention by S value and elapsed days
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- S = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t_days&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t_days&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  t=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_days&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;d → R = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;S=1:  Day 0 100% → Day 1 36.8% → Day 2 13.5% → Day 3 5.0% → Day 7 0.1%
S=2:  Day 0 100% → Day 1 60.7% → Day 2 36.8% → Day 3 22.3% → Day 7 3.0%
S=3:  Day 0 100% → Day 1 71.7% → Day 2 51.3% → Day 3 36.8% → Day 7 9.7%
S=5:  Day 0 100% → Day 1 81.9% → Day 2 67.0% → Day 3 54.9% → Day 7 24.7%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An S=1 memory crashes to 36.8% after one day. After a week, 0.1%. Effectively dead.&lt;/p&gt;

&lt;p&gt;At S=2, 60.7% survives after the same day. At S=5, 81.9% after a day. Even after a full week, 24.7% remains.&lt;/p&gt;

&lt;p&gt;Since S goes up by 1 with each recall, a memory recalled 3 times (S=4) retains 17.4% after a week. Recalled 5 times (S=6) retains 31.1% after a week. The curve visibly flattens.&lt;/p&gt;

&lt;p&gt;In game terms, think "buff duration increase from stacking." Apply the same buff multiple times, duration gets longer each time. More stacks, longer effect. MemoryBank's S works exactly like that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mathematical Impact of Resetting t
&lt;/h2&gt;

&lt;p&gt;The S increase matters, but &lt;strong&gt;resetting t to 0&lt;/strong&gt; actually creates the more dramatic effect.&lt;/p&gt;

&lt;p&gt;Picture this scenario. A memory sits at S=1, and 3 days have passed. R equals &lt;code&gt;e^(−3/1)&lt;/code&gt; = 0.050, or 5.0%. Nearly gone.&lt;/p&gt;

&lt;p&gt;At this moment, the memory gets recalled in conversation. MemoryBank bumps S to 2 and resets t to 0. Instantly, R becomes &lt;code&gt;e^(−0/2)&lt;/code&gt; = 1.000 — back to 100%.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before recall:  S=1, t=3 days → R = 5.0%  (nearly dead)
After recall:   S=2, t=0 days → R = 100%  (fully revived)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5% to 100%. That jump is everything.&lt;/p&gt;

&lt;p&gt;One more thing. The revived memory is &lt;strong&gt;stronger than before&lt;/strong&gt;. S went from 1 to 2, so the next time 3 days pass, R won't be 5.0% — it'll be 22.3%. In its first life, 3 days was almost fatal. In its second life, 3 days is perfectly survivable.&lt;/p&gt;

&lt;p&gt;Repeat this pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Recall simulation
# Memory recalled every 3 days
&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cycle&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 3 days pass
&lt;/span&gt;    &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;R_before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;# Recall occurs
&lt;/span&gt;    &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cycle &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cycle&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: Pre-recall R=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R_before&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R_before&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
          &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; → Post-recall S=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, R=100%&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Cycle 1: Pre-recall R=0.0498 (5.0%)  → Post-recall S=2, R=100%
# Cycle 2: Pre-recall R=0.2231 (22.3%) → Post-recall S=3, R=100%
# Cycle 3: Pre-recall R=0.3679 (36.8%) → Post-recall S=4, R=100%
# Cycle 4: Pre-recall R=0.4724 (47.2%) → Post-recall S=5, R=100%
# Cycle 5: Pre-recall R=0.5488 (54.9%) → Post-recall S=6, R=100%
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "pre-recall retention" for a memory recalled every 3 days climbs from 5.0% → 22.3% → 36.8% → 47.2% → 54.9%. Same 3-day gap, but accumulated recalls make the memory increasingly resilient.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;spacing effect&lt;/strong&gt; that Ebbinghaus discovered, naturally embedded in the formula. Repeated review flattens the forgetting curve — that principle, encoded in math.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Set the Threshold
&lt;/h2&gt;

&lt;p&gt;The MemoryBank paper doesn't specify an exact threshold number. But to implement this, you need to decide: "At what R do we delete a memory?"&lt;/p&gt;

&lt;p&gt;Reframe the question first. "How many days without recall should it take for a memory to be forgotten?"&lt;/p&gt;

&lt;p&gt;The baseline is an S=1 memory (never recalled). How long it survives depends on the threshold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Time to forget for S=1, by threshold
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="c1"&gt;# R = e^(-t/S) → t = -S * ln(R)
&lt;/span&gt;    &lt;span class="n"&gt;t_forget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Threshold &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → S=1 memory dies after &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_forget&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; days&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Threshold 0.5  → S=1 memory dies after 0.69 days (~17 hours)
# Threshold 0.3  → S=1 memory dies after 1.20 days (~29 hours)
# Threshold 0.1  → S=1 memory dies after 2.30 days
# Threshold 0.05 → S=1 memory dies after 3.00 days
# Threshold 0.01 → S=1 memory dies after 4.61 days
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Threshold 0.5 means memories vanish in 17 hours. Too aggressive. Yesterday's conversation is already gone today.&lt;/p&gt;

&lt;p&gt;Threshold 0.01 means 4.6 days of survival. Too loose. Meaningless chatter lingers for almost 5 days, wasting memory space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The practical sweet spot is 0.05 to 0.1.&lt;/strong&gt; S=1 memories naturally disappear within 2–3 days, while S=3+ memories (recalled twice or more) survive over a week.&lt;/p&gt;

&lt;p&gt;You can also work backwards. If "important memories must survive at least 7 days" is a requirement, you can reverse-engineer S and the threshold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# "What minimum S is needed to survive 7 days?"
&lt;/span&gt;&lt;span class="n"&gt;target_days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;

&lt;span class="c1"&gt;# R = e^(-t/S) ≥ threshold
# S ≥ -t / ln(threshold)
&lt;/span&gt;&lt;span class="n"&gt;S_min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;target_days&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;To have R ≥ 0.1 after 7 days, need S ≥ &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;S_min&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# To have R ≥ 0.1 after 7 days, need S ≥ 3.04
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;S needs to be at least 4 (recalled 3 times) to stay above the 0.1 threshold after 7 days. Tune these parameters to fit your service's characteristics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thinking in Half-Lives
&lt;/h2&gt;

&lt;p&gt;The most intuitive metric for exponential decay is the &lt;strong&gt;half-life&lt;/strong&gt; — how long until retention drops to 50%.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# R = e^(-t/S) = 0.5
# t_half = S * ln(2) ≈ S * 0.693
&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;t_half&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → half-life = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t_half&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; days&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# S= 1 → half-life = 0.69 days (~17 hours)
# S= 2 → half-life = 1.39 days (~33 hours)
# S= 3 → half-life = 2.08 days (~50 hours)
# S= 5 → half-life = 3.47 days
# S=10 → half-life = 6.93 days (~1 week)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Half-life is directly proportional to S. Double S, double the half-life. Linear relationship.&lt;/p&gt;

&lt;p&gt;A never-recalled memory (S=1) has a half-life of 17 hours. Half gone before the day is over. A twice-recalled memory (S=3) has a half-life of 2 days. Nine recalls (S=10) gets you nearly a week.&lt;/p&gt;

&lt;p&gt;These numbers make MemoryBank's design intent crystal clear. &lt;strong&gt;Topics that come up frequently are remembered longer. One-off mentions fade fast.&lt;/strong&gt; Same pattern as human memory.&lt;/p&gt;

&lt;p&gt;The game analogy here is aggro decay. When a player stops dealing damage to a boss, aggro decays over time. Keep hitting, and aggro stays high and builds. Damage dealt is "recall," aggro value is "retention." Same exponential dynamics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simulation: The Fate of 5 Memories Over 10 Days
&lt;/h2&gt;

&lt;p&gt;Let's run a real scenario. Five memories, different recall patterns, 10 days.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;

&lt;span class="n"&gt;THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;

&lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;job_change&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lunch_menu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UE5_bug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weekend_camp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;salary_talk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Recall schedule (by day)
&lt;/span&gt;&lt;span class="n"&gt;recall_schedule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;job_change&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;    &lt;span class="c1"&gt;# Frequent recalls
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lunch_menu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;[],&lt;/span&gt;               &lt;span class="c1"&gt;# Never recalled
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UE5_bug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;           &lt;span class="c1"&gt;# Occasional recalls
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weekend_camp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;              &lt;span class="c1"&gt;# Recalled once
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;salary_talk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# Very frequent recalls
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--- Day &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="n"&gt;last_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;born&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_event&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;recall_schedule&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recalls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALIVE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;THRESHOLD&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DEAD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: S=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, t=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;d, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
              &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;R=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%) [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key takeaways from the results.&lt;/p&gt;

&lt;p&gt;"lunch_menu" was never recalled. S=1, R hits 13.5% by Day 2 and 5.0% by Day 3. Dead at the 0.1 threshold on Day 3.&lt;/p&gt;

&lt;p&gt;"job_change" was recalled on Days 1, 3, 5, and 8. By Day 10, S=5, 2 days since last recall. R equals &lt;code&gt;e^(−2/5)&lt;/code&gt; = 67.0%. Still healthy.&lt;/p&gt;

&lt;p&gt;"salary_talk" was recalled almost daily starting Day 4. By Day 10, S=6, 1 day since last recall. R equals &lt;code&gt;e^(−1/6)&lt;/code&gt; = 84.6%. The strongest memory.&lt;/p&gt;

&lt;p&gt;"weekend_camp" was recalled exactly once on Day 3. S bumped to 2, but then 7 days of silence. By Day 10, R equals &lt;code&gt;e^(−7/2)&lt;/code&gt; = 3.0%. Dead.&lt;/p&gt;

&lt;p&gt;Same 10 days, completely different fates based on recall patterns. That's the core mechanism of MemoryBank at work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mathematical Limitations of the MemoryBank Model
&lt;/h2&gt;

&lt;p&gt;The formula is clean. The gaps with reality are equally clear.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linear S increase.&lt;/strong&gt; S goes up by exactly 1 per recall. But real human memory reinforcement is nonlinear. The first review has the biggest impact, and subsequent reviews show diminishing returns. Something like &lt;code&gt;S_new = S_old + 1/log(S_old + 1)&lt;/code&gt; would be more realistic than a flat &lt;code&gt;S_new = S_old + 1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No emotional weighting.&lt;/strong&gt; Ebbinghaus's original experiments used meaningless syllables — things like WID and ZOF. He himself acknowledged that meaningful information is forgotten roughly 10 times more slowly. MemoryBank initializes S at 1 for everything — career doubts and lunch choices alike. Emotional significance isn't factored in. An extension could use LLM-based sentiment analysis to assign differential S_init values (say, 1–3) based on emotional intensity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ambiguous time units.&lt;/strong&gt; The paper doesn't specify what unit t uses. Days? Hours? Minutes? Conversation sessions? The curve's shape changes entirely depending on the unit. This is the first parameter to lock down when deploying in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recall detection criteria.&lt;/strong&gt; "This memory was recalled during conversation" is determined by FAISS search results. Does appearing in top-k count as recall? Or does it need to actually influence the response? The answer changes how frequently S gets incremented. If memories that were retrieved but never used in the response still get their S bumped, memory strength gets overestimated.&lt;/p&gt;

&lt;p&gt;These limitations are also expansion directions. The authors stating this is "an exploratory and highly simplified model" means the formula is a &lt;strong&gt;starting point&lt;/strong&gt;, not the final answer. Layer emotional weighting, nonlinear S growth, and context-aware recall detection on top of the base formula, and you get a far more sophisticated memory system.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;R = e^(−t/S)&lt;/code&gt;. One formula explains the birth, reinforcement, and death of memories. Not a complex memory architecture — a 140-year-old psychological principle, transplanted onto LLMs. Simple but effective. And because it's simple, it's extensible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The simpler the formula, the stronger it is. Complexity is easy to implement. Simplicity is easy to extend."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>memorybank</category>
      <category>math</category>
    </item>
  </channel>
</rss>
