내가 만든 걸로 배우는 정석 · 실제 코드 + 시각화
RAG·임베딩·에이전트·하네스·랭체인·MCP — 새로 배울 개념이 아니다. brain·ccapi·tube·ark에서 이미 만든 것들의 정식 이름이다. 슬라이드마다 네 진짜 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 ◐ 쓰기✅ 만들기⬜
MCP = USB-C. 서버 하나면 Claude Code·Cursor·데스크톱 아무거나 꽂힌다. 양방향 — 읽고(Resources) 쓴다(Tools).
이미 꽂아 쓰는 MCP 서버 (클라이언트 ✅)
// Resources → LLM이 읽음 (내 우물 검색) // Tools → LLM이 씀 (내 우물에 저장) // = 오늘 그린 "양방향 우물"의 정식 규격
10 정확 vs 의미 = 하이브리드 FTS & Vector ✅ 이미 함
일부러 임베딩 없이. 정확히 찾기엔 싸고 예측 가능.
의미 검색 + 정확 매칭을 합쳐서 반환.
brain은 이미 하이브리드다 — 정석이 최고로 치는 구조를 너는 이미 했다.
// 1) 벡터: 의미 유사 ORDER BY embedding <=> $1::vector // 2) 키워드: 정확 매칭 WHERE text ILIKE $1 // → 둘을 합쳐 반환 (이미 하이브리드!)
FTS → pgvector → 전용 벡터DB — 요구가 무거울수록 오른쪽. 고를 줄 아는 게 시니어.∑ 정리 Where you stand
남은 건 둘: MCP 서버 만들기 와 eval 하네스.