TRENDSHIFT #2 · 2026.05.27 · ESENGINE

DeepSeek-Reasonix — "켜둬도 돈이 안 새는"
DeepSeek 전용 터미널 코딩 에이전트

1.4k 스타 · MIT · TypeScript 단일 코드베이스. Claude Code · Cursor · Aider가 "어떤 모델이든 붙일 수 있는 범용 에이전트"를 지향할 때, Reasonix는 정반대로 갔다 — DeepSeek API의 "접두사 캐시(prefix-cache)"가 한 번이라도 깨지면 비용이 10배가 되는 구조에 맞춰, 시스템 전체를 "캐시가 깨지지 않는 방향"으로 설계한 철저히 편향된 에이전트다. 실 사용자 하루 데이터: 4.35억 입력 토큰 · 캐시 적중률 99.82% · 청구액 $1.38 (캐시 없으면 $61.06).

1프로젝트 한줄 요약

"이 레포가 정확히 뭘 하는가"부터 한 문장으로
ONE-LINER

DeepSeek API만 쓰는, 캐시-우선(cache-first) 루프로 설계된 터미널용 AI 코딩 에이전트 — npx reasonix code 한 줄로 실행되는 Claude Code의 "DeepSeek 전용" 사촌.

Anthropic API를 부르는 Claude Code, OpenAI 모델을 끼우는 Cursor, 아무 모델이나 붙일 수 있는 Aider와 다르게 — Reasonix는 의도적으로 DeepSeek 한 종류만 지원한다. 그 대가로 얻는 것은 "긴 작업을 켜둬도 청구서가 부담스럽지 않은" 비용 곡선이다.

패키지명은 npm reasonix, 별칭(bin)으로 dsnix도 등록되어 있다. Node 22+가 깔린 어디서든 npx reasonix code 한 줄로 떠서 동작한다. macOS · Linux · Windows(PowerShell·Git Bash·Windows Terminal) 모두 지원.

핵심 용어
접두사 캐시 (Prefix Cache)
LLM API에 같은 프롬프트의 맨 앞부분(접두사)을 반복해서 보내면, 서버가 그 부분을 캐싱해두고 "다시 계산할 필요 없음" 처리를 해주는 기능. DeepSeek은 캐시된 토큰을 원가의 약 10%로만 청구한다. 단, 바이트 단위로 정확히 같아야 작동 — 타임스탬프 한 글자만 바뀌어도 캐시가 깨진다.

2왜 주목받는가

트렌딩 #2의 배경과 경쟁 제품 대비 차별점

2026년 5월 현재 GitHub에는 "Claude Code 클론", "Cursor 대안", "Aider 포크"가 셀 수 없이 많다. 그 사이에서 Reasonix가 단숨에 TrendShift 상위권으로 올라온 이유는 명확하다 — 한 가지 모델 패밀리만 깊게 파고든 첫 에이전트이기 때문이다.

99.82%
실측 프롬프트 캐시 적중률
$1.38 vs $61
하루치 청구액 (캐시 켬 vs 끔)
v4-flash
기본 모델 — 프로 모델은 /model pro로 전환 (sticky)
~12×
v4-pro 대 v4-flash 비용 비율

차별점 1: 모델을 "선택지"가 아니라 "전제"로 본다

대부분의 에이전트 프레임워크는 모델을 추상화한다. --model 플래그를 받고, OpenAI든 Anthropic이든 OpenRouter든 다 끼울 수 있게 한다. 그 결과 모든 모델에 "최소공배수"로만 동작한다.

Reasonix는 정반대 — DeepSeek의 캐시 동작, R1 사고 토큰의 형태, 툴콜이 깨지는 패턴 모두를 시스템 설계의 전제(invariant)로 박아넣었다. README의 표현 그대로 "Cache stability isn't a feature you turn on; it's an invariant the loop is designed around."

비유로 이해하기

일반 에이전트는 "어떤 차에든 맞는 범용 타이어"를 만드는 회사. F1 코너에 들어가면 미끄러진다.

Reasonix는 "DeepSeek 전용 슬릭 타이어". 다른 트랙에선 못 쓰지만, DeepSeek 코너에선 다른 어떤 타이어보다 빠르고 마모(=비용)가 적다.

차별점 2: 비용을 "기능"이 아니라 "측정값"으로 다룬다

TUI 상단 바에 turn $0.003, session $0.12이 항상 떠 있다. 0.05달러 넘어가면 노랑, 0.20달러 넘어가면 빨강. "내가 지금 얼마짜리 답을 받고 있는지"가 매 턴 보인다. 비용 인지(price-aware) UX를 처음부터 박아둔 코딩 에이전트는 아직 드물다.

차별점 3: 오픈소스 + MIT

Claude Code는 클로즈드, Cursor도 클로즈드. Reasonix는 MIT 라이선스의 진짜 오픈소스다 — 포크해서 사내용으로 커스터마이즈하거나, 회사 내부 LLM 게이트웨이에 붙일 수 있다.

차별점 4: 터미널 우선, 그러나 대시보드도 있음

본체는 Ink(터미널에서 React를 쓰는 라이브러리) 기반 TUI지만, dashboard/ 디렉토리에 별도의 웹 대시보드도 들어있다. 세션 로그, 캐시 히트율, 비용 추이를 브라우저에서 볼 수 있다.

3기술 스택 전체 지도

레포 안에 무엇이 들어있는지, 한 페이지로

3.1 코어 — 모두 TypeScript

package.json을 열면 한눈에 보인다. 94.6%가 TypeScript, 나머지는 CSS(4.3%, 대시보드용) + 소량 기타. 즉, 백엔드(LLM 호출 루프) · 프론트(터미널 UI) · 빌드 스크립트가 모두 한 언어로 묶여 있다.

CORE DEPENDENCIES

의존성 — 일부러 적게, 일부러 표준적으로

라이브러리역할왜 이걸 골랐나
commanderCLI 인자 파싱Node 생태계 표준. 학습 곡선 거의 없음
ink 7.x터미널에 React를 렌더링App.tsx · LiveRows.tsx · StatsPanel.tsx 모두 React 컴포넌트
react 19.2Ink가 사용하는 렌더 엔진훅(hook) 기반 상태관리를 그대로 활용
undiciNode용 고성능 HTTP 클라이언트DeepSeek API SSE 스트림 처리
eventsource-parserSSE 청크 파싱스트리밍 토큰을 한 글자씩 받기
web-tree-sitter코드 파서의미 단위 검색(semantic_search) · 인덱싱
zod 4.x런타임 타입 검증모델이 뱉은 JSON이 스키마와 맞는지 검사
wsWebSocket대시보드와 양방향 통신
ignore · picomatch.gitignore 패턴 매칭파일 인덱싱 시 무시할 경로 처리
핵심 용어
SSE (Server-Sent Events)
서버가 한 번 연결되면 데이터를 토큰 한 조각씩 흘려보내는 표준. ChatGPT 답변이 한 글자씩 타이핑되듯 나타나는 그 효과의 정체. Reasonix는 undici로 SSE를 받고 eventsource-parser로 파싱한다.

3.2 프론트엔드 — 터미널 안의 React

일반 웹 React가 DOM에 그림을 그린다면, Ink는 터미널 출력에 그림을 그린다. <Box>, <Text> 같은 컴포넌트가 각각 줄·문자에 매핑된다. useState, useEffect 그대로 쓰면 된다.

cli/ui/ ├── App.tsx ← 루트 컴포넌트 (~1984 LOC) ├── LiveRows.tsx ← "AI가 도구 실행 중..." 스피너 줄 ├── EventLog.tsx ← 지나간 대화 렌더링 ├── StatsPanel.tsx ← 상단바: 캐시 히트율 + 비용 뱃지 ├── PromptInput.tsx ← 커서 인식 멀티라인 입력창 ├── PlanConfirm.tsx ← "이 계획 실행해도 됨?" 모달 ├── ShellConfirm.tsx ← "이 쉘 명령 진짜 실행?" 모달 ├── EditConfirm.tsx ← "이 코드 수정 적용?" 모달 └── markdown.tsx ← Ink-네이티브 마크다운 렌더러

3.3 대시보드 — 별도 빌드의 웹 앱

레포의 dashboard/ 폴더는 독립된 npm 워크스페이스다. npm run build:dashboard로 따로 빌드되고, 최종 결과물(dashboard/dist/)은 npm 패키지에 함께 들어간다. 대시보드는 Preact + HTM 기반 SPA로 구성되며, 세션 로그와 비용 추이를 WebSocket으로 실시간 표시한다.

3.4 인프라 — 패키징과 검증

도구역할
tsupTypeScript → 최종 번들. dist/cli/index.js 한 파일로 출력
biome린트 + 포맷터 (ESLint + Prettier 대체)
vitest유닛 테스트 + 커버리지
@stryker-mutator변이 테스트(Mutation Testing) — 테스트가 진짜 잘 짜여졌는지 검증
simple-git-hookspre-commit · pre-push 훅. 푸시 전에 verify 강제 실행
핵심 용어
변이 테스트 (Mutation Testing)
코드를 일부러 한 줄씩 망가뜨려보고(예: ><로 바꾸기) 테스트가 그 버그를 잡아내는지 확인한다. 잡아내면 통과, 못 잡으면 "테스트가 부실하다"는 신호. Stryker가 이 자동화를 해준다.

4아키텍처 심화 분석

"세 개의 기둥(Three Pillars)" — Reasonix가 다른 에이전트와 갈라지는 지점

공식 ARCHITECTURE.md는 시스템을 세 개의 기둥(pillar)으로 정리한다. 각 기둥은 "범용 에이전트 프레임워크라면 보지도 못할 문제"를 해결한다 — 왜냐하면 그것들은 DeepSeek이라는 특정 모델의 캐시 동작 위에서만 의미가 있는 문제들이기 때문이다.

기둥 1 — 캐시 우선 루프 (Cache-First Loop)

문제: DeepSeek은 캐시된 입력 토큰을 원가의 ~10%로 청구한다. 하지만 자동 prefix 캐시는 이전 요청의 바이트 접두사가 정확히 동일할 때만 발동한다. 대부분의 에이전트 루프는 매 턴 컨텍스트를 재정렬·재작성·타임스탬프 주입을 하기 때문에, 실측 캐시 적중률이 20%도 안 된다.

해법: 컨텍스트를 세 영역으로 엄격히 분리한다.

┌─────────────────────────────────────────┐ │ IMMUTABLE PREFIX │ ← 세션 동안 고정 │ system + tool_specs + few_shots │ 캐시 적중 후보 ├─────────────────────────────────────────┤ │ APPEND-ONLY LOG │ ← 단조 증가만 허용 │ [assistant₁][tool₁][assistant₂]... │ 이전 턴 접두사 보존 ├─────────────────────────────────────────┤ │ VOLATILE SCRATCH │ ← 매 턴 리셋 │ R1 사고 토큰, 임시 plan 상태 │ 업스트림에 안 보냄 └─────────────────────────────────────────┘
비유로 이해하기

일반 채팅 UX는 메신저 같다 — 답장하면 위로 스크롤하면서 메시지를 편집·재정렬할 수도 있다. 한 번 편집이 들어가면 그 위까지 전부 "이전과 다른" 메시지가 된다.

Reasonix의 로그는 회계 장부 같다 — 한 줄 쓰면 절대 지우지 않고, 늘 마지막에만 새 줄을 추가한다. 그래야 1번 줄부터 N-1번 줄까지가 항상 어제와 같은 모양이고, DeepSeek 서버가 "어 어제 본 거랑 같네, 캐시 쓰자"고 판단할 수 있다.

측정 지표: 매 턴마다 prompt_cache_hit_tokens / (hit + miss)가 계산되어 TUI 상단바에 표시된다. "이 디자인 선택이 정말 효과가 있는가"를 사용자가 매 호출마다 눈으로 본다.

기둥 2 — 툴콜 수리 (Tool-Call Repair)

문제: DeepSeek에서 실제로 자주 발생하는 실패 패턴들 —

FAILURE MODE 1
툴콜이 <think> 블록 안에 갇힘

모델이 "이제 read_file을 호출해야겠다" 하고 사고 영역에 JSON을 적었지만, 최종 메시지의 tool_calls 필드에는 빠뜨림. 일반 SDK는 그냥 "툴콜 없음"으로 처리하고 끝.

FAILURE MODE 2
파라미터 10개 넘으면 인자 누락

스키마가 깊거나 leaf 파라미터가 많으면(>10) 모델이 절반만 채우고 보내는 일이 잦다.

FAILURE MODE 3
동일 인자 반복 호출 (Call Storm)

같은 파일을 30번 연속으로 read_file 하려는 무한 루프성 폭주.

FAILURE MODE 4
JSON 중간에 max_tokens 도달 → 잘림

응답 길이 제한에 걸려 { "path": "src/foo. 같이 끊긴 토큰콜.

해법: 네 단계 파이프라인.

단계역할
flatten스키마가 >10 leaf params 또는 깊이 >2면 자동으로 dot-notation(user.address.city)으로 펴서 모델에 노출. dispatch()에서 다시 중첩 객체로 복원.
scavengeregex + JSON 파서로 reasoning_content를 뒤져 모델이 깜빡한 툴콜을 회수.
truncation닫히지 않은 중괄호를 감지해서 자동으로 닫거나, 이어쓰기 요청을 보낸다.
storm슬라이딩 윈도우 안에서 동일 (tool, args) 튜플 반복을 감지 → 호출 억제 + 반성(reflection) 턴 주입.

기둥 3 — 비용 통제 (Cost Control, v0.6)

문제: 프론티어 모델(v4-pro)을 기본으로 두고 툴 결과 전체를 컨텍스트에 누적하면, 활성 사용자 월 청구액이 $150~$250로 치솟는다. 대부분의 턴은 프론티어 추론이 필요 없고, 대부분의 세션은 한 번만 쓸 툴 결과를 계속 재전송하면서 돈을 태운다.

해법: 네 가지 보완 메커니즘.

4.1 Flash-first 기본값 (Tiered Defaults)

프리셋모델Effort비용비율
flashv4-flashmax
auto (기본)v4-flash → v4-pro (hard turn)max1–3×
prov4-promax~12×

"비싼 모델 + 깊은 추론"이 기본이 아니라 명시적 선택지다. 부가 호출(요약·서브에이전트·툴콜 수리)은 사용자의 프리셋과 무관하게 항상 flash + high로 하드코딩 — "툴 결과 산문 정리" 작업에 pro 요금을 낼 이유가 없다.

4.2 턴 종료 자동 압축 (Auto-compaction)

한 턴이 끝날 때, 로그 안의 모든 툴 결과 중 TURN_END_RESULT_CAP_TOKENS(3000)를 초과한 것은 그 토큰 수로 잘려 요약본으로 대체된다. "그 턴에 모델은 전체 텍스트를 봤다, 다음 턴부터는 압축본만 보고 필요하면 다시 읽으면 된다"는 합리적 트레이드오프.

4.3 모델 선택 (/model)

/model flash 또는 /model pro로 모델을 전환하면, 다음 변경까지 해당 모델이 유지된다 (sticky). /pro 단발 무장은 v0.50.0에서 제거되었으며 v0.51.0에는 존재하지 않는다.

4.4 모델 자기 보고 승급 (Model Self-report Escalation)

현재 턴이 프론티어 추론이 필요하다고 모델이 판단하면, 답변 첫 줄에 <<<NEEDS_PRO>>> 또는 <<<NEEDS_PRO: reason>>>를 출력한다. 시스템이 이를 감지해 그 턴을 v4-pro로 재실행하며, 화면에 노란색 경고 줄로 사용자에게 표시 — "조용히 비싼 모델 쓰는" 짓은 절대 안 한다.

설계 철학
"Every pro-tier model call is surfaced. Silent escalation was considered and rejected."

비용이 자동으로 올라가는 모든 사건은 반드시 사용자가 본다. 청구서를 열어보고 놀라는 일이 없도록 "조용한 자동 승급"은 검토 후 명시적으로 거부됨.

5디렉토리 구조 해부

레포 루트부터 src 내부까지 — 어디에 뭐가 있는가

5.1 레포 루트

DeepSeek-Reasonix/ ├── .github/ GitHub Actions (CI) ├── benchmarks/ τ-bench-lite + real-world cache 케이스 스터디 ├── dashboard/ 웹 대시보드 (별도 npm workspace) ├── data/ DeepSeek V3 토크나이저(.json.gz) 등 ├── desktop/ 데스크톱 앱 실험 코드 ├── docs/ ARCHITECTURE · CLI-REFERENCE · 자산 ├── examples/ "어떻게 쓰는지" 샘플 ├── scripts/ postinstall · 빌드 헬퍼 ├── src/ ★ 본체 소스 ★ ├── tests/ vitest 단위 테스트 ├── biome.json 린트/포맷 설정 ├── tsup.config.ts 번들 빌드 설정 ├── stryker.config.mjs 변이 테스트 설정 ├── vitest.config.ts 테스트 러너 설정 ├── package.json npm 메타정보 └── REASONIX.md 프로젝트 메모리 파일(에이전트가 읽는다)

5.2 src/ — 본체

src/ ├── client.ts DeepSeek API 클라이언트 (fetch + SSE) ├── loop.ts ★ 기둥 1+3 — CacheFirstLoop의 본체 ★ ├── repair/ ★ 기둥 2 — 툴콜 수리 파이프라인 ★ │ ├── scavenge.ts reasoning에서 빠진 툴콜 회수 │ ├── flatten.ts 깊은 스키마를 dot-notation으로 펴기 │ ├── truncation.ts 잘린 JSON 복구 │ └── storm.ts 동일 호출 폭주 차단 ├── prompt-fragments.ts 공용 프롬프트 조각 (포맷 규칙 등) ├── code/prompt.ts "reasonix code" 시스템 프롬프트 ├── tools/ │ ├── filesystem.ts read/list/search/edit/write │ ├── shell.ts run_command + run_background │ ├── jobs.ts 백그라운드 프로세스 레지스트리 │ ├── memory.ts remember/forget/list 메모리 │ ├── skills.ts SKILL.md 플레이북 실행 │ ├── subagent.ts spawn_subagent (flash+high 고정) │ ├── plan.ts submit_plan (리뷰 게이트) │ └── web.ts Mojeek 또는 SearXNG 웹검색 ├── mcp/ MCP 클라이언트 + 브리지 (stdio + SSE) ├── memory/ │ ├── runtime.ts ImmutablePrefix/AppendOnlyLog/VolatileScratch │ ├── project.ts REASONIX.md 로더 │ ├── user.ts ~/.reasonix/memory/ 저장소 │ └── session.ts JSONL 세션 영속화 ├── skills.ts 내장 explore + research 스킬 ├── telemetry/ │ ├── stats.ts 비용 + 캐시 히트 + SessionSummary │ └── usage.ts ~/.reasonix/usage.jsonl 합산 ├── tokenizer.ts DeepSeek V3 토크나이저 (포팅) └── cli/ ├── index.ts commander 엔트리 ├── resolve.ts config vs CLI 플래그 우선순위 ├── commands/ chat, code, run, stats, sessions, ... └── ui/ ★ Ink 기반 TUI ★

5.3 cli/ui/slash/ — 슬래시 커맨드

모든 /명령handlers/ 아래 주제별 파일로 쪼개져 있다 — 한 파일이 200줄을 넘지 않는다는 규칙이 있다. 새 슬래시 커맨드 추가 = 한 핸들러 파일 + 레지스트리 한 줄 수정.

cli/ui/slash/ ├── types.ts SlashContext, SlashResult, ... ├── commands.ts SLASH_COMMANDS 데이터 + 파서 + suggest ├── helpers.ts git, memory, token 포매터 ├── dispatch.ts 레지스트리 + handleSlash └── handlers/ ├── basic.ts /help, /clear, ... ├── mcp.ts /mcp add, /mcp list ├── memory.ts /remember, /forget ├── skill.ts /skill new, /skill list ├── admin.ts /search-engine, /preset ├── observability.ts /stats, /events ├── edits.ts /apply, /undo, /show ├── jobs.ts 백그라운드 작업 ├── sessions.ts 세션 전환 └── model.ts /model flash|pro 전환 핸들러

6학습 포인트 (기술별)

이 레포에서 무엇을 배울 수 있는가

6.1 LLM API와 프롬프트 캐시 다루기

CORE LESSON

"같은 바이트를 보내라"가 왜 어려운가

이론적으로는 "이전 프롬프트 앞부분을 그대로 다시 보내라" 한 줄이면 끝나는 일이지만, 실제로는 — 시스템 프롬프트에 현재 시각을 주입하던 코드, 도구 목록을 alphabetical 정렬로 정규화하던 코드, 매 턴 컨텍스트를 압축하던 코드가 전부 캐시를 깨는 범인이다.

배울 것: loop.tsmemory.ts를 읽으면서 "이 구현은 정확히 어떤 변화를 막고 있는가"를 추적해보면, "캐시 친화적 프롬프트 설계" 감이 잡힌다.

6.2 Ink — 터미널에서 React 쓰기

FRONTEND LESSON

웹 React를 안다면 Ink로 5분 만에 TUI를 만든다

<Box flexDirection="column">, <Text color="green"> — DOM 대신 ANSI 시퀀스로 출력되는 것 외에 React 그대로다. 훅·상태·이펙트가 전부 동작한다.

실습: App.tsxuseSubagent, useEditHistory 같은 커스텀 훅을 읽어보자. "터미널 위의 React"가 일반 SPA와 어떻게 다른지 감이 온다.

6.3 SEARCH/REPLACE 편집 패턴

EDIT LESSON

왜 "diff 적용"이 아니라 "검색 후 치환"인가

Reasonix의 edit_file은 모델에게 "이 문자열을 찾아서 이걸로 바꿔" 형식의 패치를 요구한다. 라인 번호 기반 diff는 모델이 자주 틀린다 — 한 줄 추가되면 모든 번호가 어긋난다. 문자열 매칭은 컨텍스트 자체가 정답을 강제한다.

매칭 실패는 FAILURE_ESCALATION_THRESHOLD 카운터를 올려 자동 승급의 신호로도 쓰인다 — 단일 메커니즘이 편집 + 비용 통제 두 곳에 동시에 기여하는 예쁜 설계.

6.4 MCP (Model Context Protocol) 클라이언트 구현

src/mcp/는 Anthropic이 표준화한 MCP의 클라이언트 측 구현이다. stdio · SSE · Streamable HTTP 세 가지 전송 방식을 모두 지원한다. MCP 서버를 직접 작성해본 적 있다면, 클라이언트 쪽 코드를 읽는 게 큰 학습이 된다.

6.5 tree-sitter로 의미 단위 코드 검색

reasonix index는 로컬 Ollama(또는 임의의 OpenAI 호환 임베딩 엔드포인트)로 코드를 청크 단위 임베딩해서 의미 검색을 만든다. tree-sitter는 단순 라인 분할이 아닌 구문 트리 기반으로 함수 · 클래스 단위로 자른다. 6개 언어(Go · Java · JS · Python · Rust · TypeScript) 문법을 함께 로드한다.

6.6 비용을 1급 지표로 다루는 UX

대부분의 코딩 도구는 비용을 결제 페이지에 숨긴다. Reasonix는 매 턴 헤더에 색깔 뱃지로 띄운다. "사용자에게 자기 행동의 가격을 즉시 보여주는" 설계 패턴은 LLM 시대의 UX 키워드 중 하나가 될 것이다.

7하드웨어/시스템 요구사항

로컬에서 돌리기 위한 최소 조건
주의
에어갭/완전 무료 환경은 명시적 비목표

"Reasonix는 유료 DeepSeek API 키가 반드시 필요하다. 완전 오프라인 또는 zero-cost 운용은 Aider + Ollama 또는 Continue를 보라."

8직접 해볼 수 있는 실습 과제

난이도별로 정리한 5개의 실습 — 위에서 아래로 갈수록 어려워진다

실습 1 (★) — 5분짜리: 일단 켜본다

SETUP

npx reasonix code 한 줄로 띄우기

Node 22+가 있는 머신에서 빈 폴더 하나 만들고 npx reasonix code 실행. 처음에는 DeepSeek API 키를 한 번 붙여넣으면 자동 저장. "Hello, 이 폴더 안에 hello.py 라는 파일에 print('hi')를 적어줘"부터 시작해보자.

관찰 포인트: 상단바의 cache: 0% → 80%+, 비용 뱃지의 변화. 같은 세션 안에서 두 번째 · 세 번째 요청을 보낼 때 캐시 적중률이 어떻게 올라가는지.

실습 2 (★★) — 30분짜리: /skill new로 첫 스킬 만들기

SKILLS

"내가 자주 시키는 작업"을 마크다운 한 장에 박제

/skill new commit-message을 치면 <project>/.reasonix/skills/commit-message.md가 생성된다. frontmatter에 description:을 적고, 본문에 "git diff를 보고 Conventional Commits 형식으로 메시지를 뽑는 절차"를 자연어로 적어보자.

관찰 포인트: runAs: subagent로 바꿨을 때 격리된 하위 루프가 어떻게 동작하는지. 메인 컨텍스트에 잡음이 안 묻는다는 것이 핵심.

실습 3 (★★★) — 1~2시간짜리: 캐시 적중률 측정 실험

BENCHMARK

"내가 일부러 캐시를 깨면 비용이 얼마나 늘어나나"

같은 작업을 두 세션으로 나눠 실행 — (A) 평범하게, (B) 매 턴 시스템 프롬프트에 --system "현재 시각: $(date)" 같은 동적 내용을 강제로 주입.

reasonix stats로 두 세션의 캐시 히트율과 누적 비용을 비교해보자. 같은 작업이 몇 배 더 비싸지는지 직접 측정.

실습 4 (★★★★) — 반나절: repair/ 파이프라인 코드 읽기

SOURCE DIVE

4단계 툴콜 수리가 실제 코드에선 어떻게 엮이나

src/repair/index.ts를 출발점으로 scavenge → flatten → truncation → storm 순서로 각 파일을 읽으면서, "이 단계가 발동하는 정확한 조건"을 주석에 적으며 따라가보자. 그리고 tests/repair/*.test.ts를 보면 각 케이스의 실제 입력/출력 예시가 있다.

심화: 새로운 실패 케이스를 하나 만들어 패치를 PR로 보내는 것까지 — good first issue 라벨에 어울리는 작업.

실습 5 (★★★★★) — 며칠: OpenAI 호환 backend 어댑터 작성

ADVANCED

"DeepSeek-only는 정말 본질인가" 직접 검증해보기

README는 "OpenAI 호환 shim이 --model 오버라이드로 동작은 한다, 테스트되진 않았다"고 한다. 이 한 줄을 실험해보자 — src/client.ts를 베이스로 Gemini나 GPT-5용 클라이언트 어댑터를 작성하고, 같은 워크로드를 돌렸을 때 캐시 동작이 어떻게 달라지는지 측정.

결과는 둘 중 하나: "다른 백엔드도 잘 동작 → Pillar 1의 캐시 가정은 사실상 일반화 가능했다" 또는 "역시 DeepSeek 외에서는 캐시 모델이 달라 손익이 안 맞는다 → 비목표가 정당화됨". 어느 쪽이든 LLM API 디자인에 대한 깊은 인사이트를 얻는다.

9관련 기술 심화 학습 로드맵

Reasonix를 깊게 이해하려고 잡았을 때, 4주 코스로 설계해본다면

1주차 — LLM 기본 + DeepSeek 가격 모델

OpenAI API의 chat completion 호출과 SSE 응답 구조, system/user/assistant/tool 메시지의 역할, tool_calls 필드의 형식. DeepSeek의 가격 페이지를 직접 읽고, "캐시 hit vs miss 단가"를 비교해보기. "왜 캐시가 본질인가"를 숫자로 납득해야 다음 주차가 의미 있다.

2주차 — 에이전트 루프의 기본 패턴

ReAct(Reasoning + Acting), 툴 호출 루프, 멈춤 조건(stop condition) 등 일반 에이전트 패턴. 그 다음 src/loop.ts를 열어 Reasonix는 어디가 일반적이고 어디가 다른가를 표로 정리해보자.

3주차 — 터미널 UI (Ink + React)

Ink 공식 튜토리얼로 간단한 TUI 한 개 만들기. 그 후 cli/ui/App.tsx의 훅(useEditHistory · useSubagent · useCompletionPickers)을 한 개씩 분리해 읽기. 1984 LOC의 거대한 컴포넌트가 어떻게 책임을 쪼개 관리하는지가 보인다.

4주차 — 프롬프트 캐시 + 비용 통제 실전

자신만의 작은 에이전트를 OpenAI 또는 Anthropic API로 작성하되, Pillar 1의 세 영역 분리(immutable prefix / append-only log / volatile scratch)를 그대로 모방해보자. 그리고 캐시 hit율을 측정해 본가(Reasonix)의 99.82%에 얼마나 근접할 수 있는지 도전.

10핵심 키워드 사전

레포 안에서 자주 마주치는 용어들
KEY TERM
Prefix Cache / KV Cache
LLM이 동일한 입력 접두사를 다시 받았을 때, 트랜스포머의 어텐션 키/값(KV) 텐서를 재계산하지 않고 캐시에서 가져오는 최적화. DeepSeek은 캐시 hit 토큰을 ~10% 가격으로 청구.
KEY TERM
Reasoning Content (사고 토큰)
R1 · V4-thinking 모델이 답을 내기 전에 출력하는 "내적 추론" 토큰. 응답의 reasoning_content 필드에 분리되어 들어온다. 공식적으로 "다음 턴에 다시 보내지 말 것" 권고.
KEY TERM
Tool Call (툴콜)
모델이 "지금 이 도구를 이런 인자로 실행해달라"고 요청하는 구조화된 JSON 메시지. Reasonix의 repair/ 모듈은 이 JSON이 깨졌을 때 자동 복구한다.
KEY TERM
MCP (Model Context Protocol)
Anthropic이 표준화한 "LLM이 외부 도구·서비스에 접근하는 통신 프로토콜". stdio · SSE · Streamable HTTP 전송을 정의. Reasonix는 클라이언트 측 구현을 제공.
KEY TERM
SEARCH/REPLACE Edit
"이 문자열을 찾아서 이걸로 바꿔" 형식의 패치. 라인 번호 기반 unified diff보다 모델 친화적이라 Aider · Cursor 등도 채택. 매칭 실패 시 "모델이 헤맨다"는 신호로도 쓰임.
KEY TERM
Append-only Log
데이터베이스의 WAL(Write-Ahead Log)이나 Kafka처럼 "한 번 쓰면 절대 수정·삭제 안 하고 끝에만 추가" 구조. Reasonix는 대화 로그를 이 방식으로 관리해 캐시 접두사 안정성을 보장.
KEY TERM
Ink
"React for the terminal". DOM 대신 ANSI 시퀀스에 렌더링한다. vadimdemedes/ink 라이브러리. Claude Code · GitHub Copilot CLI 등 다수의 AI CLI가 채택.
KEY TERM
tree-sitter
언어별 구문 트리(Syntax Tree)를 빠르게 만드는 파서 라이브러리. 함수 · 클래스 단위로 코드를 자르는 의미 검색(semantic search)에 쓰인다.
KEY TERM
Mutation Testing (변이 테스트)
코드의 일부를 자동으로 바꿔서(mutation) 그 변경을 테스트가 잡는지 검사. Reasonix는 Stryker로 수행. "테스트의 테스트".
KEY TERM
TUI (Text User Interface)
터미널 안에서 키보드와 색상·박스로 조작하는 GUI 같은 인터페이스. vim · htop · k9s · Claude Code · Reasonix가 모두 TUI 앱.

11참고 링크

한 발 더 깊게 들어가고 싶다면
TRY THIS NEXT

지금 당장 해볼 수 있는 3가지

  1. npx reasonix code 한 줄로 띄우고, 같은 폴더에서 5번 연속 질문을 던지며 상단바 캐시 적중률이 어떻게 올라가는지 눈으로 본다 — 1주차 학습의 90%가 이 한 번에 끝난다.
  2. ARCHITECTURE.md를 인쇄해서 빨간펜으로 "내가 만들고 있는 사이드 프로젝트에 적용할 수 있는 패턴 3가지"를 표시한다. Pillar 1의 세 영역 분리는 LLM이 아닌 시스템에서도 그대로 쓸 수 있는 패턴이다.
  3. src/repair/storm.ts만 읽고, "동일 호출 폭주 감지" 로직을 자기 언어(파이썬·고·러스트)로 재구현해본다. 50줄짜리 코드지만 슬라이딩 윈도우 · 인자 해시 · 반성 턴 주입까지 압축적으로 들어있다.

이 문서는 esengine/DeepSeek-Reasonix(v0.51.0, 1.4k ★, MIT)의 README · ARCHITECTURE.md · package.json을 기반으로 작성된 한국어 학습 자료입니다. 데이터는 2026-05-27 기준 TrendShift 일간 #2 순위 시점.

원문: github.com/esengine/DeepSeek-Reasonix · 라이선스: MIT