LLM 지형도 · 강의01 / 12

내가 만든 걸로 배우는 정석 · 실제 코드 + 시각화

너는 이미 다 만들었다.라벨이 없었을 뿐이지.

RAG·임베딩·에이전트·하네스·랭체인·MCP — 새로 배울 개념이 아니다. brain·ccapi·tube·ark·well-mcp에서 이미 만든 것들의 정식 이름이다. 슬라이드마다 네 진짜 repo 코드가 뜬다.

모델
하네스
RAG
MCP
멀티
프롬프트
eval
배포
너는 배우러 온 게 아니라 확인하러 온 거야. 여덟 층 중 일곱이 이미 네 코드에 있어 — MCP는 지난 일요일에 네가 직접 채웠지. 이번엔 말로만 안 하고 슬라이드마다 진짜 repo 코드를 띄운다.

01 임베딩 Embedding ✅ brain

글자를 "의미의 좌표"로

컴퓨터는 "우유 사기""장 보기"를 남남으로 본다. 임베딩은 글을 숫자 벡터로 바꾸되 뜻이 가까우면 좌표도 가깝게 찍는다. →

brainVoyage에 텍스트를 던지면 number[](의미의 좌표)가 돌아온다.

흩어진 단어 → 뜻끼리 군집 (임베딩)

apps/core/src/agent/embedding.tsreal repo
const res = await fetch(VOYAGE_API_URL, {
  method: "POST",
  headers: { Authorization: `Bearer ${key}` },
  body: JSON.stringify({ input: text, model: "voyage-3" }),
});
const data = await res.json();
return data.data[0].embedding;   // number[] — 의미의 좌표
임베딩은 글자를 좌표로 바꾸는 것. 뜻이 가까우면 좌표도 가깝게 찍혀서 단어들이 군집을 이뤄. 코드는 네 brain embedding.ts — Voyage에 텍스트 던지면 number[]가 돌아와.

02 벡터 검색 · pgvector Vector Search ✅ brain

가장 가까운 이웃 K개

질문도 좌표로 찍고 제일 가까운 K개를 꺼낸다. <=>가 두 벡터의 거리, ORDER BY로 가까운 순, LIMIT으로 top-k.

brain메사쿠어 얼굴엔진은 같은 걸 HNSW 1:N으로 매칭까지.

★ 질문 → 가장 가까운 top-3

embedding.ts · searchAll()real repo
SELECT text, (1 - (embedding <=> $1::vector)) AS score
FROM "SearchIndex"
WHERE embedding IS NOT NULL
ORDER BY embedding <=> $1::vector   -- 가까운 순
LIMIT $2;                           -- top-k
질문도 좌표로 찍고 제일 가까운 K개를 꺼내는 게 벡터 검색. 별에서 가장 가까운 세 점을 찾는 그림이 그거야. 코드의 물결표는 두 벡터 거리, ORDER BY로 가까운 순, LIMIT으로 top-k. brain의 실제 SQL이야.

03 RAG Retrieval-Augmented Generation ✅ 두 번

답하기 전에, 먼저 찾아서 쥐어준다

질문 searchAll sources 주입 답변+출처

검색(R)·보강(A)·생성(G) 세 단어가 그대로 이름. 소스 카드 = "지어낸 게 아니라 여기서 찾았다"는 영수증.

실전탄소회계·규제 대응의 제1원칙과 동일 — 근거(증빙) 없인 숫자도 없다. 소스 카드 = 감사 추적(audit trail).
http-handler.ts · enrichWithContext()real repo
const results = await searchAll(prompt, 12, undefined, userId);
for (const r of results) {
  sources.push({ type: r.entityType, id: r.entityId,
                 text: r.text, similarity: r.similarity });
}
// prompt + sources → LLM → 답변 + 소스 카드
brainsources가 UI에서 소스 카드로 렌더된다. 그게 RAG의 증거.
RAG는 검색·보강·생성 세 단계 이름. LLM은 네 데이터를 모르니 관련 조각만 찾아 쥐어주고 답하게 해. 코드의 searchAll이 12개 찾아 sources에 담고, 그게 프롬프트에 붙어 답변+소스 카드가 돼. 네가 두 번 만든 거야.

04 청킹 · 리랭킹 Chunking ✅ 설계에

RAG 품질은 여기서 갈린다

청킹이 크면 검색이 뭉개지고, 작으면 문맥이 끊긴다. 품질 레버: ① 청킹 ② 하이브리드 ③ 리랭킹 ④ 임베딩 교체.

REBUILDV0 청크를 "턴"(질문+답 한 쌍)으로. 해결이 같이 붙어야 소환되니까.
실전규제 문서도 같은 원리 — 조항 단위(요건+예외 한 덩어리)로 쪼개야 예외까지 같이 소환된다.

너무 큼 / 딱 좋음(턴) / 너무 잘음

개념
// ✗ 너무 큼:  [세션 전체] → 검색이 뭉개짐
// ✓ 딱 좋음:  [user질문 + assistant답] ← 턴 단위
// ✗ 너무 잘음: [문장 하나] → 맥락 끊김
청킹은 어떻게 쪼개 넣느냐. 크면 뭉개지고 작으면 끊겨. 가운데 턴 단위가 딱 좋아. 너는 V0에서 청크를 질문+답 턴으로 잡았어 — 정석대로.

05 에이전트 · 도구 호출 Agent & Tool use ✅ 엔진째

LLM이 스스로 도구를 부른다

기본 LLM은 말만 한다. 에이전트도구(파일·검색·DB)를 쥐어준 것 — "이건 검색이 필요하네" 판단하면 스스로 부르고 결과로 다음 행동을 정한다.

ccapi에이전트 엔진 그 자체. SDKSession을 직접 쥐고 HTTP API로 감쌌다.
apps/core/src/agent/worker.tsreal repo
import { unstable_v2_createSession }
  from "@anthropic-ai/claude-agent-sdk";

// 세션 = 도구를 쥔 에이전트
this.session = unstable_v2_createSession(sessionOptions);
// → LLM이 파일·검색·DB를 스스로 호출하며 여러 턴 진행
에이전트는 LLM에 손발(도구)을 달아준 것. 스스로 검색·파일·DB를 부르고 여러 턴을 이어가. 코드의 createSession이 그 에이전트 세션이야. 너는 ccapi로 엔진째 만들었어.

06 하네스 Harness ✅ 제일 잘함

에이전트를 "돌리는" 골격

에이전트가 똑똑해도 누군가는 실행·재시도·줄 세우기를 해야 한다. 그 실행 골격이 하네스(말에 씌우는 마구). 안 만든 건 eval 하네스 = ⑦빈칸.

ccapiccapi 자체가 에이전트 하네스. worker 풀 + 큐 + 세션 관리.
apps/core/src/agent/queue.tsreal repo
for (let i = 0; i < this.poolSize; i++) {
  const worker = new AgentWorker(`worker-${i}`);
  this.workers.push(worker);              // 워커 풀
}
const idle = this.workers.find(w => w.state === "ready");
if (idle) return this.runOnWorkerOnce(idle, request);
this.queue.push({ id: uuid(), request });  // 없으면 큐
하네스는 말에 씌우는 마구. LLM을 붙잡아 실행·재시도·큐잉하는 틀. 코드는 poolSize만큼 워커를 만들어 풀에 넣고, 노는 워커에 시키고 없으면 큐에 넣어. ccapi가 통째로 이거야. 안 만든 건 eval 하네스 하나.

07 멀티에이전트 Multi-agent ✅ 고급

역할로 나누고, 마지막에 게이트

하나에 다 시키면 품질이 들쭉날쭉. 멀티에이전트역할 분리 + 품질 게이트. "통과 못 하면 못 나간다."

면접"생성은 AI, 검증은 게이트" — 탄소 산정과 같은 철학(계산은 결정론, LLM은 추출까지).
planner
scriptwriter
visual-designer
media-curator
audio-engineer
compositor
quality-checker ← 6축 품질 게이트
tube/agents/real repo
agents/
  planner.md        scriptwriter.md    visual-designer.md
  media-curator.md  audio-engineer.md  compositor.md
  quality-checker.md   // ← 마지막 게이트
한 놈에 다 시키면 품질이 들쭉날쭉. 역할을 쪼개고 마지막에 게이트를 세우는 게 멀티에이전트. tube의 7에이전트 폴더가 그거고 quality-checker가 6축 게이트야. 면접에서 "생성은 AI, 검증은 게이트"가 답.

08 랭체인 LangChain

레고 블록 — 네가 안 쓴 이유

LangChain = 배관 키트. RAG를 한 줄로 조립. 네가 안 쓴 건 몰라서가 아니라 판단. 추상화가 두꺼워 프로덕션엔 걷어낸다는 정서가 흔하다.

면접"추상화가 두꺼워 뭐가 도는지 안 보여서 Agent SDK로 직접 짭니다." → 알고 안 골랐다.
랭체인 vs 너
// LangChain: 한 줄인데 안이 안 보임
qa = RetrievalQA.from_chain_type(llm, retriever)

// 너 (brain/ccapi): 직접 조립 — 다 보임
const results = await searchAll(prompt, 12);
this.session = unstable_v2_createSession(opts);
랭체인은 RAG를 한 줄로 조립하는 레고 블록. 근데 두꺼워서 안이 안 보여 프로덕션엔 걷어낸다는 정서가 흔해. 위 코드가 랭체인, 아래가 직접 조립한 너. "몰라서 안 썼다"가 아니라 "알고 안 골랐다"가 정답이야.

09 MCP Model Context Protocol ✅ well-mcp

외부 도구를 LLM에 꽂는 표준 — 만들었다

MCP = USB-C. 서버 하나면 Claude Code·Cursor·데스크톱 아무거나 꽂힌다. 빈칸이던 층을 일요일 하루에 채웠다 — 설계·배포·인증·E2E까지.

well-mcpmcp.leetei.com 라이브. Workers AI(bge-m3) + Vectorize + D1, GitHub OAuth. 검색 응답 150~400ms 실측.
꽂아 쓰기 ✅ Atlassian·Gmail·Chrome 직접 만들기 ✅ well (07-12)
well-mcp/src/index.tsreal repo
export class WellMCP extends McpAgent<Env, unknown, Props> {
  server = new McpServer({ name: "well", version: "0.1.0" });
  async init() {
    this.server.tool("well_search", "우물 의미 검색", ...,
      async ({ query, topK, type }) => {
        const hits = await search(this.env, query, topK ?? 5, type);
        // bge-m3 임베딩 → Vectorize top-k
    this.server.tool("well_write", "우물에 기억 저장", ...);
    // 읽고(search) 쓴다(write) = 양방향 우물, 규격대로
빈칸이던 MCP, 일요일 하루에 채웠어. CF Workers 원격 MCP 서버 — bge-m3 임베딩, Vectorize 검색, GitHub OAuth, mcp.leetei.com 라이브. well_search로 읽고 well_write로 쓰는 양방향 우물. 검색 150~400ms 실측. "씁니다"가 아니라 "만들어 배포했고 지금 라이브입니다"가 네 답이야.

10 정확 vs 의미 = 하이브리드 FTS & Vector ✅ 이미 함

벡터가 항상 답은 아니다

ark = FTS

일부러 임베딩 없이. 정확히 찾기엔 싸고 예측 가능.

brain = 벡터+키워드

의미 검색 + 정확 매칭을 합쳐서 반환.

brain은 이미 하이브리드다 — 정석이 최고로 치는 구조를 너는 이미 했다.

실전규제 검색이 정확히 이 문제 — "ISO 14064-1 6.4"는 정확 매칭(FTS), "냉매 누출은 어디 보고?"는 의미(벡터). 답은 하이브리드.
embedding.ts · searchAll() — 하이브리드real repo
// 1) 벡터: 의미 유사
ORDER BY embedding <=> $1::vector

// 2) 키워드: 정확 매칭
WHERE text ILIKE $1

// → 둘을 합쳐 반환 (이미 하이브리드!)
스펙트럼FTS → pgvector → 전용 벡터DB — 요구가 무거울수록 오른쪽. 고를 줄 아는 게 시니어.
검색이 다 벡터는 아니야. FTS는 단어 정확 매칭 — 빠르고 싸. 근데 네 brain 코드 봐. 벡터로 의미 검색하고 ILIKE로 키워드 검색해서 둘을 합쳐 반환해. 그게 하이브리드고 정석이 최고로 치는 거야. 너 이미 하고 있었어. ark는 일부러 FTS로만 갔고.

11 실전 대입 Applied · Carbon Accounting 면접 카드

이 지도를 탄소회계에 얹으면

배출량 = 활동자료 × 배출계수 (보험료 = 자격 × 요율과 같은 수학, 8년 정산해봤다). 숫자는 결정론 코드가 만들고, LLM은 문서↔숫자 번역만 — 그래야 검증기관 감사를 통과한다.

한 문장"생성은 AI, 계산은 코드, 검증은 게이트, 근거는 소스 카드." — "LLM을 어디까지 믿나" 질문의 준비된 답.
증빙 문서 추출 = LLM 산정 = 결정론 검증 = 게이트 리포트 = RAG
RAG"CBAM 대상 품목?" — 규제 문서 근거 질의. 조항 인용 = 감사 추적
하이브리드조항 번호는 FTS, 자연어 질문은 벡터 — 규제 검색의 정답 구조
게이트tube의 quality-checker 자리에 산정 검증 규칙이 들어간다
하네스ccapi의 워커 풀 자리에 월말 정산 배치가 들어간다
배출량 = 활동자료×배출계수 — 보험료 = 자격×요율과 같은 수학이고 너는 그걸 8년 정산했어. 숫자는 결정론 코드, LLM은 문서↔숫자 번역만(추출·근거 질의·초안). tube 게이트 자리에 산정 검증이, ccapi 워커 풀 자리에 월말 배치가 들어갈 뿐. "생성은 AI, 계산은 코드, 검증은 게이트, 근거는 소스 카드."

정리 Where you stand

8층 중 7층은 이미 네 것 — 빈칸은 발견하자마자 채웠다

남은 건 하나: eval 하네스. MCP는 발견 → 그 주에 배포 — 그 속도 자체가 증명이다.

✅ 07-12MCP 채움 — well-mcp 설계·배포·OAuth·E2E까지 하루. mcp.leetei.com 라이브.
nexteval 하네스 — 만들 게 돌기 시작하면. 마지막 빈칸.
면접지도는 말로, 증명은 라이브로 — exitx 데모 + well-mcp 실검색 + 실전 대입 한 장. 넌 7/8이고, 빈칸 채우는 속도가 상품이다.
여덟 층 중 일곱에 네 이름표가 붙었고 이번엔 코드로 증명됐어. MCP는 빈칸 발견 며칠 만에 직접 채웠지 — 그 속도가 상품이야. 남은 건 eval 하나. 면접에선 지도는 말로, 증명은 라이브로(exitx 데모 + well-mcp 실검색). 넌 이미 7대 8이다.
← → 방향키 · Space 다음 · S 대본