내가 만든 걸로 배우는 정석 · 실제 코드 + 시각화
RAG·임베딩·에이전트·하네스·랭체인·MCP — 새로 배울 개념이 아니다. brain·ccapi·tube·ark·well-mcp에서 이미 만든 것들의 정식 이름이다. 슬라이드마다 네 진짜 repo 코드가 뜬다.
01 임베딩 Embedding ✅ brain
컴퓨터는 "우유 사기"와 "장 보기"를 남남으로 본다. 임베딩은 글을 숫자 벡터로 바꾸되 뜻이 가까우면 좌표도 가깝게 찍는다. →
흩어진 단어 → 뜻끼리 군집 (임베딩)
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[] — 의미의 좌표
02 벡터 검색 · pgvector Vector Search ✅ brain
질문도 좌표로 찍고 제일 가까운 K개를 꺼낸다. <=>가 두 벡터의 거리, ORDER BY로 가까운 순, LIMIT으로 top-k.
★ 질문 → 가장 가까운 top-3
SELECT text, (1 - (embedding <=> $1::vector)) AS score FROM "SearchIndex" WHERE embedding IS NOT NULL ORDER BY embedding <=> $1::vector -- 가까운 순 LIMIT $2; -- top-k
03 RAG Retrieval-Augmented Generation ✅ 두 번
검색(R)·보강(A)·생성(G) 세 단어가 그대로 이름. 소스 카드 = "지어낸 게 아니라 여기서 찾았다"는 영수증.
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 → 답변 + 소스 카드
sources가 UI에서 소스 카드로 렌더된다. 그게 RAG의 증거.04 청킹 · 리랭킹 Chunking ✅ 설계에
청킹이 크면 검색이 뭉개지고, 작으면 문맥이 끊긴다. 품질 레버: ① 청킹 ② 하이브리드 ③ 리랭킹 ④ 임베딩 교체.
너무 큼 / 딱 좋음(턴) / 너무 잘음
// ✗ 너무 큼: [세션 전체] → 검색이 뭉개짐 // ✓ 딱 좋음: [user질문 + assistant답] ← 턴 단위 // ✗ 너무 잘음: [문장 하나] → 맥락 끊김
05 에이전트 · 도구 호출 Agent & Tool use ✅ 엔진째
기본 LLM은 말만 한다. 에이전트는 도구(파일·검색·DB)를 쥐어준 것 — "이건 검색이 필요하네" 판단하면 스스로 부르고 결과로 다음 행동을 정한다.
SDKSession을 직접 쥐고 HTTP API로 감쌌다.import { unstable_v2_createSession }
from "@anthropic-ai/claude-agent-sdk";
// 세션 = 도구를 쥔 에이전트
this.session = unstable_v2_createSession(sessionOptions);
// → LLM이 파일·검색·DB를 스스로 호출하며 여러 턴 진행
06 하네스 Harness ✅ 제일 잘함
에이전트가 똑똑해도 누군가는 실행·재시도·줄 세우기를 해야 한다. 그 실행 골격이 하네스(말에 씌우는 마구). 안 만든 건 eval 하네스 = ⑦빈칸.
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 }); // 없으면 큐
07 멀티에이전트 Multi-agent ✅ 고급
하나에 다 시키면 품질이 들쭉날쭉. 멀티에이전트는 역할 분리 + 품질 게이트. "통과 못 하면 못 나간다."
agents/ planner.md scriptwriter.md visual-designer.md media-curator.md audio-engineer.md compositor.md quality-checker.md // ← 마지막 게이트
08 랭체인 LangChain
LangChain = 배관 키트. RAG를 한 줄로 조립. 네가 안 쓴 건 몰라서가 아니라 판단. 추상화가 두꺼워 프로덕션엔 걷어낸다는 정서가 흔하다.
// LangChain: 한 줄인데 안이 안 보임 qa = RetrievalQA.from_chain_type(llm, retriever) // 너 (brain/ccapi): 직접 조립 — 다 보임 const results = await searchAll(prompt, 12); this.session = unstable_v2_createSession(opts);
09 MCP Model Context Protocol ✅ well-mcp
MCP = USB-C. 서버 하나면 Claude Code·Cursor·데스크톱 아무거나 꽂힌다. 빈칸이던 층을 일요일 하루에 채웠다 — 설계·배포·인증·E2E까지.
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) = 양방향 우물, 규격대로
10 정확 vs 의미 = 하이브리드 FTS & Vector ✅ 이미 함
일부러 임베딩 없이. 정확히 찾기엔 싸고 예측 가능.
의미 검색 + 정확 매칭을 합쳐서 반환.
brain은 이미 하이브리드다 — 정석이 최고로 치는 구조를 너는 이미 했다.
// 1) 벡터: 의미 유사 ORDER BY embedding <=> $1::vector // 2) 키워드: 정확 매칭 WHERE text ILIKE $1 // → 둘을 합쳐 반환 (이미 하이브리드!)
FTS → pgvector → 전용 벡터DB — 요구가 무거울수록 오른쪽. 고를 줄 아는 게 시니어.11 실전 대입 Applied · Carbon Accounting 면접 카드
배출량 = 활동자료 × 배출계수 (보험료 = 자격 × 요율과 같은 수학, 8년 정산해봤다). 숫자는 결정론 코드가 만들고, LLM은 문서↔숫자 번역만 — 그래야 검증기관 감사를 통과한다.
∑ 정리 Where you stand
남은 건 하나: eval 하네스. MCP는 발견 → 그 주에 배포 — 그 속도 자체가 증명이다.