개발 › AI·LLM
개발 › AI·LLM 카테고리의 글
- 주목이라는 연산 — 트랜스포머로
시리즈의 마지막 편입니다. 신경망 위에 마지막 블록, 어텐션을 올려 트랜스포머를 완성하고, 밑바닥 벡터에서 시작한 한 줄기를 여기서 닫습니다. 어텐션의 핵심은 놀랍도록 익숙합니다. 각 토큰이 다른 토큰들을 얼마나 참고할지를 1편의 내적으로 재고, 3편의 소프트맥스로 합이 1인 주목 분포를 만든 뒤, 그 분포로 값 벡터들을 가중합하는 것이죠. 쿼리·키·밸류를 세우고, 스케일드 닷프로덕트 어텐션 한 식을 유도하며, 왜 루트 d로 나누는지를 4편의 그래디언트 관점으로 설명합니다. 멀티헤드로 여러 관점을 병렬로 보는 이유, 잔차 연결과 층 정규화와 위치 인코딩이 붙은 트랜스포머 블록의 구조, 그리고 이 거대한 모델도 여전히 6편의 역전파와 4편의 경사하강과 3편의 크로스 엔트로피로 다음 토큰을 예측하며 배운다는 것을 봅니다. 이차 복잡도, 위치 인코딩의 한계, 어텐션이 이해가 아니라 통계적 패턴이라는 점을 정직하게 짚고, 일곱 편을 하나로 되짚으며 시리즈를 닫습니다. 'AI의 수학적 기초' 7편이자 마지막 편입니다.
- 비선형으로 — 신경망과 역전파
5편의 선형회귀는 직선(초평면)밖에 못 그렸습니다. 1편에서 예고한 문제, 선형변환을 아무리 합성해도 여전히 선형이라는 벽이 마침내 무대에 오릅니다. 이 편에서는 그 벽을 넘습니다. 먼저 선형 합성이 왜 표현력을 못 늘리는지를 행렬곱으로 증명하고, 그 사이에 비선형 활성화 함수를 끼우면 어떻게 휘어진 함수를 담게 되는지, 시그모이드·tanh·ReLU를 세웁니다. 층을 쌓은 다층 퍼셉트론과 만능근사정리를 짚은 뒤, 순전파로 입력에서 손실까지 계산하고, 이 편의 백미인 역전파를 4편의 연쇄법칙에서 직접 유도합니다. 출력의 오차 신호를 층층이 거슬러 곱해 모든 가중치의 그래디언트를 순전파 한 번의 비용으로 한꺼번에 얻는 그 메커니즘, 그리고 그것이 4편의 경사하강과 만나 완성되는 학습 루프까지요. 비볼록성과 국소최소, 그래디언트 소실·폭발, 만능근사가 학습 가능성을 뜻하지 않는다는 점, 블랙박스 문제를 정직하게 짚습니다. 'AI의 수학적 기초' 6편입니다.
- 가장 단순한 학습 — 선형회귀를 끝까지
1편부터 4편까지 벡터·거리·확률·경사하강을 따로따로 세웠습니다. 이 편에서 그 넷을 처음으로 하나의 완결된 학습에 합칩니다. 선형회귀입니다. 학습은 늘 세 박자예요. 모델을 놓고, 손실을 정의하고, 그 손실을 최소화한다. 선형회귀는 그 삼박자가 가장 투명하게 보이는 학습이죠. 데이터 행렬로 선형 모델을 놓고, 잔차의 제곱노름으로 손실을 정의한 뒤, 왜 하필 제곱오차인지를 3편의 가우시안 오차 가정과 최대가능도로 유도합니다. 그리고 그 손실을 최소화하는 두 길을 끝까지 갑니다. 미분해서 0으로 놓아 얻는 정확해(정규방정식)와, 그 해가 2편의 투영, 즉 정답 벡터를 특징들의 열공간에 내린 그림자라는 기하학적 의미, 그리고 4편의 경사하강으로 같은 답에 이르는 반복적 길입니다. MSE가 볼록이라 경사하강이 전역최소에 닿는다는 것, 두 길을 언제 어떻게 고르는지, 과적합과 릿지·라쏘 정규화가 2편의 L1·L2 단위원과 어떻게 이어지는지까지 봅니다. 선형 가정의 한계, 다중공선성, 이상치 취약성, 외삽 위험을 정직하게 짚습니다. 'AI의 수학적 기초' 5편입니다.
- 미분과 경사하강 — 기계가 '배우는' 방식
3편에서 학습의 목적을 얻었습니다. 손실을 최소로, 로그가능도를 최대로. 그런데 '최소로 만들라'는 목적과 '실제로 최소를 찾는' 방법은 다릅니다. 이 편에서는 그 방법, 기계가 배우는 메커니즘을 세웁니다. 미분을 순간 변화율이자 접선 기울기로 정의하고, 다변수로 확장해 그래디언트를 세운 뒤, 방향도함수가 그래디언트와의 내적이라는 사실과 2편의 코시-슈바르츠 부등식을 이어 왜 그래디언트가 가장 가파르게 증가하는 방향인지를 손으로 증명합니다. 그 반대로 한 걸음씩 내려가는 경사하강법과 학습률의 딜레마, 볼록성과 국소최소·안장점, 전체 데이터 대신 미니배치로 기울기를 근사하는 확률적 경사하강(SGD)이 왜 편향 없는 추정인지를 3편의 기댓값으로 잇고, 합성함수의 연쇄법칙이 어떻게 신경망의 역전파가 되는지까지 예고합니다. 미분 가능성 가정, 학습률 튜닝의 고통, 그래디언트 소실·폭발, 볼록성은 예외라는 점을 정직하게 짚습니다. 'AI의 수학적 기초' 4편입니다.
- 확률과 불확실성 — 분포·기댓값·베이즈
1·2편의 벡터가 '무엇을 아는가'의 언어였다면, 확률은 '무엇을 모르는가'의 언어입니다. AI는 세상을 확실히 아는 게 아니라 확률로 믿고, 데이터를 보며 그 믿음을 갱신하죠. 이 편에서는 그 언어를 밑바닥부터 세웁니다. 확률의 세 공리에서 출발해 확률변수와 분포(이산 pmf·연속 pdf, 베르누이·정규), 기댓값과 분산을 정의하고 분산이 왜 E[X제곱] 빼기 평균제곱인지 손으로 유도합니다. 결합·주변·조건부 확률과 독립을 세운 뒤, 조건부 확률에서 베이즈 정리를 직접 이끌어 내 학습을 '사전 믿음을 데이터로 갱신해 사후 믿음을 얻는 일'로 다시 봅니다. 그리고 가능도와 최대가능도추정(MLE), 로그가능도를 세워, 뒤 편에서 만날 손실함수와 크로스 엔트로피가 왜 여기서 태어나는지를 예고합니다. 빈도주의와 베이지안의 해석 논쟁, 독립 가정과 iid의 위험, 밀도는 확률이 아니라는 함정, 모델 확률이 실제 신뢰도와 다른 보정 문제까지 정직하게 짚습니다. 'AI의 수학적 기초' 3편입니다.
- 거리와 유사도 — 노름과 내적이 재는 것
1편에서 데이터를 벡터로 놓았습니다. 그런데 '두 점이 가깝다', '두 벡터가 닮았다'를 재는 자는 하나가 아닙니다. 이 편에서는 그 자들을 제대로 세웁니다. 노름의 여러 얼굴(L1 맨해튼, L2 유클리드, L-무한대 체비쇼프)과 각 노름의 단위원 모양이 왜 학습의 성격(특히 희소성)을 가르는지, 거리가 진짜 '자'가 되려면 만족해야 하는 거리 공리(비음수·대칭·삼각부등식)가 무엇인지, 그리고 코시-슈바르츠 부등식이 어떻게 코사인 유사도를 -1과 1 사이에 가두는지를 유도합니다. 내적이 만드는 기하로 더 들어가 투영을 정의하고, 단위 벡터에서 유클리드 거리의 제곱이 2(1-코사인)이 된다는 관계를 손으로 증명해 '방향'과 '위치'라는 두 유사도를 하나로 잇습니다. 스케일 문제와 표준화, 고차원에서 거리가 서로 비슷해지는 거리 집중 현상, 내적은 유사도지 거리가 아니라는 점까지 정직하게 짚습니다. 'AI의 수학적 기초' 2편입니다.
- 세상을 벡터로 놓다 — AI가 데이터를 보는 첫 언어
새 시리즈를 엽니다. '에이전트 직접 짜기'가 AI를 어떻게 만드는지의 실전이었다면, 이 시리즈는 AI가 왜 도는지를 수식으로 차근차근 쌓는 이론입니다. 코드가 아니라 수학으로 증명하며 가죠. 그 첫 질문은 이겁니다. AI는 세상을 대체 어떻게 표현하는가? 답은 벡터입니다. 집 한 채든 단어 하나든 이미지 한 장이든, AI는 그것을 실수의 나열, 즉 고차원 공간의 한 점으로 놓습니다. 이 편에서는 벡터가 무엇인지 두 관점으로 세우고, 데이터가 왜 벡터가 되는지, 선형결합·벡터공간·기저로 '표현'이 무엇인지, 내적이 어떻게 유사도의 언어가 되는지, 노름이 어떻게 거리를 재는지, 그리고 행렬이 어떻게 데이터이자 선형변환이 되는지를 유도합니다. 임베딩·신경망 한 층·어텐션이 모두 이 벡터·내적·행렬 위에 선다는 것까지 조망하고, 선형이라는 가정의 한계와 고차원의 저주, 벡터 표현이 곧 모델링 선택이라는 점을 정직하게 짚습니다. 선형대수·확률·미적분의 필요한 조각을 그때그때 처음부터 세우는 'AI의 수학적 기초' 1편입니다.
- 매번 다시 읽히지 않게 — 프롬프트 캐싱으로 재전송 비용 줄이기
3편에서 대화 크기는 요약으로 줄였지만, 매 스텝 다시 보내는 게 하나 더 있었습니다. 안 변하는 접두부 — 도구 선언과 시스템 프롬프트요. 이건 매 요청 재전송될 뿐 아니라 매번 다시 처리(입력 토큰 과금)됩니다. 도구 스키마 JSON은 꽤 크고, 스텝마다 똑같이 재과금되죠. 이번 편에 프롬프트 캐싱으로 이걸 줄입니다. cache_control breakpoint를 도구 선언에 직접 붙여, 접두부를 캐시에 올려두고 다음 요청부터 캐시에서 싸게 읽게 합니다. raw HTTP라 SDK가 감추던 cache_control을 손으로 드러내고, 응답 usage의 cache_read_input_tokens로 캐시가 진짜 히트했는지 증명합니다. 여기서 눈에 안 보이던 전제 하나가 버그로 드러납니다 — 캐시는 접두부가 바이트까지 같아야 히트하는데, Go의 map 순회는 순서가 랜덤이라 도구 선언이 매 요청 달라져 캐시가 절대 히트하지 못했습니다. 정렬로 순서를 고정해 고칩니다. 캐싱이 3편 요약·4편 메모리 주입과 맺는 긴장까지 정직하게 짚습니다. 'AI 에이전트 직접 짜기' 6편입니다.
- 무엇을 직접 짜고 무엇을 맡길까 — 손으로 짠 골격을 공식과 나란히
1편부터 4편까지 에이전트의 뼈대를 프레임워크 없이 손으로 짰습니다. while 루프, 도구와 예산, 컨텍스트 요약, 메모리까지요. 이제 반대 방향으로 봅니다. 원리를 아는 지금, Anthropic이 공식으로 내놓은 것들(SDK의 Tool Runner, Managed Agents, Claude Agent SDK)이 각각 무엇을 감춰 주는지, 그리고 무엇을 직접 소유하고 무엇을 맡기는 게 좋은지를 견줍니다. 시리즈 정신대로 이것도 코드로 증명합니다. 모델 호출을 LLM 인터페이스 하나로 숨겨, 우리가 짠 루프와 정책은 그대로 두고 트랜스포트만 공식 SDK로 갈아 끼울 수 있게 경계를 긋습니다. HTTP 서버 없는 순수 fake로 그 이음매가 진짜 갈린다는 걸 테스트로 보입니다. '직접 짜기'와 '맡기기'는 양자택일이 아니라, 어디에 선을 긋느냐의 문제입니다. 'AI 에이전트 직접 짜기' 5편입니다.
- 요약이 지운 것을 붙잡다 — 에이전트에게 메모리를 주기
3편에서 대화를 요약해 접었지만, 요약은 손실 압축이라 정말 잃으면 안 되는 사실(파일 경로, 확정된 결정)이 함께 날아갈 수 있었습니다. 이번 편에 그걸 붙잡습니다. 에이전트에게 대화 밖에 사는 key-value 메모리를 주고, memory_write·memory_read 도구로 스스로 적고 읽게 합니다. 대화가 접혀도 메모리는 남죠. 그리고 적어 둔 키 목록을 매 스텝 시스템 프롬프트에 주입해, 접힌 뒤에도 모델이 '내가 무엇을 적어 뒀는지' 알게 합니다. 여기서 2편의 병렬 실행과 교차하는 함정이 하나 — 메모리 도구가 병렬로 불리면 map 동시 쓰기로 죽으므로 mutex가 필수이고, go test -race로 증명합니다. 요약은 흐름을, 메모리는 사실을 맡는 역할 분담까지 정리합니다. 'AI 에이전트 직접 짜기' 4편입니다.
- 대화가 눈덩이처럼 불어난다 — 컨텍스트를 요약해 접기
에이전트 루프는 한 바퀴 돌 때마다 대화(messages)에 모델의 말과 도구 결과를 이어 붙입니다. 그런데 매 스텝 그 전체를 다시 API로 보내죠. 그래서 대화는 눈덩이처럼 불어나 토큰이 O(n²)으로 커지고, 비싸지고 느려지다 결국 컨텍스트 윈도우를 넘겨 터집니다. 이번 편에 이걸 능동적으로 다스립니다. 대화 길이를 어림하고, 예산을 넘으면 앞부분을 모델에게 요약시켜 한 줄로 접는 compaction을 Go로 직접 짭니다. Claude Code가 실제로 하는 그 메커니즘이죠. 함정은 tool_use와 tool_result 쌍을 쪼개면 API가 400을 낸다는 것 — 경계를 안전하게 미는 로직까지 테스트로 못 박습니다. 'AI 에이전트 직접 짜기' 3편입니다.
- 도구를 여럿 쥐여주고, 루프가 폭주하지 않게 — 예산과 병렬
1편에서 에이전트가 while 루프 하나임을 봤지만, 그 루프엔 구멍이 둘 있었습니다. 도구가 하나뿐이었고, 종료 조건이 "모델이 멈출 때"뿐이라 모델이 도구를 끝없이 부르면 루프가 안 끝나 비용 폭탄이 되죠. 이번 편에 둘을 메웁니다. 도구를 레지스트리에 여럿 등록해 모델이 알아서 고르게 하고, 한 응답의 여러 도구 호출을 고루틴으로 병렬 실행하며, MaxSteps 예산으로 무한 루프를 막습니다. go test -race로 병렬에 데이터 레이스가 없음까지 증명합니다. 'AI 에이전트 직접 짜기' 2편입니다.
- 에이전트는 결국 while 루프다 — 프레임워크 없이 직접 짜기
AI 에이전트가 요즘 화두지만, LangChain 같은 프레임워크가 그 실체를 두껍게 감싸고 있습니다. Flutter 시리즈에서 provider를 40줄로, flutter_bloc을 60줄로 직접 짜 봤듯, 에이전트도 프레임워크를 걷어내고 직접 짜 보면 정체가 드러납니다. 실은 while 루프 + 도구 호출 + JSON이죠. Go와 raw HTTP로 Claude Messages API 위에 tool-use 루프를 손으로 짜고, mock 서버로 API 키 없이 그 루프를 검증합니다. 새 'AI 에이전트 직접 짜기' 시리즈 1편입니다.