LLM 공부 01 | LLM은 검색기가 아니라 다음 토큰 생성기다
처음에는 LLM을 거대한 검색기처럼 생각했다.
질문을 던지면, 모델 안 어딘가에 있는 지식 저장소에서 관련 문서를 꺼내 읽고 답하는 줄 알았다. 하지만 기본 LLM은 내부 문서 검색기가 아니다. 학습 과정에서 만들어진 parameter를 사용해 입력 token의 문맥을 계산하고, 그다음에 올 token의 확률을 고른다.
RAG를 붙인 시스템은 외부 문서를 검색할 수 있다. 하지만 그 검색은 LLM 내부에서 일어나는 기본 동작이 아니라, 모델 바깥의 retrieval 계층이 context를 보강하는 방식이다.
5월에 prefill, decode, KV cache, MoE, batch, sequence length를 이어서 공부하면서 중심이 바뀌었다. 이제 내가 이해해야 하는 것은 "LLM이 지식을 어디에 저장하는가"만이 아니었다.
질문은 더 구체적으로 바뀌었다.
내가 입력한 문장은 모델 안에서 어떤 순서로 계산되고, 왜 긴 context와 high reasoning은 비싸지는가?
이 글은 그 질문의 시작점이다.
이번 재작성에서 앞 3편은 하나의 짧은 학습 경로로 잡는다.
1편: LLM은 무엇을 하는 시스템인가
2편: token은 어디서 비용이 되는가
3편: Transformer block 안에서는 무엇이 계산되는가
그래서 이 글은 모든 세부사항을 한 번에 설명하려는 글이 아니다. 먼저 전체 지도를 만든다. LLM이 검색기가 아니라 token 생성 시스템이라는 감각을 잡고, 다음 글들에서 tokenizer와 Transformer block으로 더 좁게 내려간다.
LLM은 답을 꺼내 읽는 검색기가 아니다. 입력 문장을 token으로 쪼개고, 그 token을 숫자 벡터로 바꾸고, Transformer block을 여러 층 통과시킨 뒤, 다음 token 하나를 고른다. 그리고 그 token을 다시 붙여 다음 token을 고른다.
이 반복이 우리가 보는 답변이다.
왜 지금 다시 LLM 내부를 공부해야 했나
AI Frontier EP 96에서 노정석 대표는 이제 training 이야기보다 inference 이야기가 훨씬 중요해졌다고 짚었다. Claude Code나 Codex로 실제 작업을 하면 긴 context를 넣고, reasoning token을 많이 쓰고, 코드와 대화가 계속 바뀌는 workload를 매일 만든다.
예전에는 "모델이 얼마나 큰가"가 더 크게 보였다. 몇 B parameter인지, 몇 T parameter인지, 어떤 모델이 더 똑똑한지에 시선이 갔다. 그런데 실제로 매일 돈과 속도를 만드는 것은 추론이다.
내가 천 줄짜리 코드를 붙여 넣고 "이거 봐줘"라고 하면, 모델은 바로 답을 쓰는 것이 아니다. 먼저 그 긴 입력을 읽어야 한다. 이 단계가 prefill이다. 그다음 답변 token을 하나씩 생성한다. 이 단계가 decode다.
이 둘은 비용 특성이 다르다.
긴 입력을 읽는 비용 = prefill, prompt length, KV cache 생성
긴 답변을 쓰는 비용 = decode step, output token, KV cache 재사용
긴 대화를 유지하는 비용 = sequence length, cache memory, scheduling
그래서 "왜 input token과 output token 가격이 다를까", "왜 cache 가격이 따로 있을까", "왜 context length가 커지면 티어가 바뀔까" 같은 질문이 생긴다.
이 질문은 단순한 가격표 해석이 아니다. LLM이 실제로 어떻게 계산되는지 모르면 답할 수 없다.
EP 94에서 나온 tokenizer 변화 체감도 같은 문제였다. vocabulary가 줄어든 것 같고, 같은 작업에 토큰이 더 많이 쓰이는 느낌이 있었다. 그때는 "토큰 단가가 오른 건가"로 느껴졌지만, 실제로는 tokenizer, embedding table, LM head, sequence length, KV cache 부담이 한 줄로 연결되어 있었다.
그래서 이 시리즈를 다시 쓴다.
이 시리즈는 LLM을 검색기처럼 보는 직관에서 벗어나 실제 계산 경로와 추론 인프라까지 내려간다.
검색하는 것이 아니라 다음 토큰을 만든다
가장 먼저 버려야 했던 오해는 이것이었다.
질문
-> 내부 Vector DB 검색
-> 관련 문서 읽기
-> 답변
실제 LLM 기본 동작은 이쪽에 가깝다.
질문
-> token IDs
-> embedding vectors
-> Transformer blocks
-> next-token logits
-> 다음 token 선택
-> 다시 입력 뒤에 붙임
물론 RAG를 붙인 시스템은 외부 문서를 검색한다. 회사 문서, 논문, 매뉴얼, 위키를 Vector DB나 graph index에 넣고, 질문이 들어오면 관련 근거를 찾아 LLM context에 넣을 수 있다. 그때 검색하는 것은 LLM 내부가 아니라 외부 retrieval 계층이다.
이 차이는 뒤에서 RAG/Vector DB/Graph RAG로 다시 자세히 다룬다. 지금은 하나만 잡으면 된다. 검색 시스템은 근거를 가져오고, LLM은 그 근거가 들어온 context를 읽고 다음 token을 생성한다.
모델 자체가 기본적으로 하는 일은 "문서 검색"이 아니라 "다음 token 예측"이다.
그래서 구조를 다시 정리하면 이렇게 된다.
parameter = 학습에서 얻은 패턴이 분산 저장된 숫자
RAG/Vector DB = 모델 바깥에서 근거 문서를 찾는 retrieval 계층
LLM 추론 = 현재 context를 읽고 다음 token을 이어 쓰는 계산 과정
중요한 차이가 있다. parameter 안에는 원본 문서가 그대로 들어 있지 않다. 수많은 학습 데이터에서 얻은 패턴이 숫자들에 분산되어 있다. 그래서 출처를 정확히 꺼내는 능력과 그럴듯하게 이어 쓰는 능력은 다르다.
이 차이가 hallucination과 RAG의 필요성을 만든다.
첫 번째 변환은 토큰이다
LLM은 글자를 그대로 계산하지 않는다. 먼저 문장을 token으로 쪼갠다.
예를 들어 사용자가 이렇게 입력했다고 하자.
LLM에서 sequence length가 뭐예요?
토크나이저는 이 문장을 모델 vocabulary에 있는 조각들로 나눈다. 어떤 조각은 단어일 수 있고, 어떤 조각은 subword일 수 있고, 어떤 조각은 기호일 수 있다.
토큰마다 ID가 있다.
"LLM" -> 12345
"sequence" -> 6789
" length" -> 2345
...
이 ID 자체에는 문맥이 없다. 그냥 사전 번호다. 그래서 다음 단계가 필요하다.
여기서 token은 사용자에게 바로 비용으로 보인다. 같은 문장을 더 잘게 쪼개면 sequence length가 길어진다. sequence length가 길어지면 더 많은 token을 prefill해야 하고, attention이 참고해야 할 위치도 늘어나고, KV cache도 커진다.
그래서 tokenizer는 단순한 전처리 도구가 아니다. 사용자 입장에서는 비용의 입구이고, 모델 입장에서는 embedding table과 LM head의 모양을 결정하는 경계다.
EP 94에서 Opus 4.7 tokenizer 변화가 화제가 된 이유도 여기에 있다. 그 논의는 공식 스펙 확정이라기보다 사용자 체감과 외부 분석에 가까웠다. 하지만 질문 자체는 중요했다.
vocabulary가 줄면?
-> embedding table과 LM head의 row 수는 줄 수 있다
-> 같은 텍스트가 더 많은 token으로 쪼개질 수 있다
-> sequence length와 decode 반복, KV cache 부담은 늘 수 있다
비용이 사라지는 것이 아니다. 한 축에서 다른 축으로 이동한다.
Embedding은 token ID를 계산 가능한 벡터로 바꾼다
token ID는 모델이 계산하기 쉬운 형태가 아니다. 모델은 숫자를 다루지만, token ID 숫자 하나를 그대로 크고 작음으로 해석하지 않는다.
12345번 token이 12346번 token보다 의미상 하나 더 큰 것이 아니다.
그래서 embedding table이 필요하다. embedding은 token ID를 벡터로 바꾼다.
token ID
-> embedding table lookup
-> [0.12, -0.08, 0.44, ...]
이 벡터가 모델 내부 계산의 출발점이다.
여기에 위치 정보도 더해진다. 같은 token이라도 문장 앞에 있는지 뒤에 있는지에 따라 역할이 달라지기 때문이다. 예전 Transformer 설명에서는 positional encoding을 입력 embedding에 더한다고 말하는 경우가 많고, 요즘 decoder-only LLM에서는 RoPE 같은 방식으로 attention 계산 안에서 위치 정보를 다루는 경우도 많다.
입문 단계에서는 이렇게 잡으면 된다.
token ID는 사전 번호다.
embedding은 그 번호를 모델 내부 좌표로 바꾸는 입력층이다.
위치 정보는 token 순서를 모델이 알 수 있게 해준다.
Transformer block은 token 벡터를 계속 갱신한다
embedding을 거친 token 벡터들은 Transformer block stack으로 들어간다.
여기서 "stack"이라는 말이 중요하다. 모델에는 Transformer block이 여러 층 쌓여 있다. 그 layer 수는 모델마다 정해져 있다. 요청이 들어올 때마다 layer 수가 바뀌는 것이 아니다.
한 block 안에는 대략 두 큰 계산이 있다.
self-attention
-> MLP / FFN
self-attention은 token들 사이의 관계를 섞는다.
예를 들어 "그것"이라는 token이 앞 문장의 "KV cache"를 가리키는지, "batch"를 가리키는지, "sequence length"를 가리키는지 문맥을 봐야 한다. attention은 각 token이 다른 token들을 얼마나 참고할지 계산한다.
MLP/FFN은 token 간 정보를 새로 섞는다기보다, attention을 통해 문맥이 반영된 각 token 벡터를 더 깊게 변환한다. 비유하면 attention은 "어떤 주변 정보를 가져올지"를 정하고, MLP는 "가져온 정보를 지금 token 표현 안에서 어떻게 가공할지"를 담당한다.
이 과정은 한 번만 일어나지 않는다.
embedding
-> block 1
-> block 2
-> block 3
-> ...
-> final hidden state
layer가 깊다는 것은 token 벡터가 여러 번 가공된다는 뜻이다. 하지만 이것을 곧바로 "생각을 더 깊게 한다"로 부르면 위험하다. layer 수는 모델 구조의 고정된 깊이다. 제품 설정의 high나 xhigh 같은 reasoning effort와 같은 말이 아니다.
LM head는 다음 token 후보를 점수로 바꾼다
마지막 Transformer block을 지나면 각 token 위치마다 hidden state가 생긴다.
이제 모델은 마지막 위치의 hidden state를 보고 다음에 올 token을 골라야 한다. 여기서 LM head가 나온다.
LM head는 마지막 hidden state를 vocabulary 전체에 대한 점수로 바꾼다.
hidden state
-> LM head
-> logits for every token in vocabulary
-> sampling / decoding strategy
-> selected next token
이때 나오는 것은 완성된 문장이 아니다. 다음 token 하나다.
그래서 자동회귀 생성, autoregressive generation이 필요하다.
Autoregressive는 방금 만든 token을 다시 붙이는 방식이다
LLM 답변은 한 번에 완성되지 않는다.
모델은 다음 token을 하나 고른다. 그 token을 지금까지의 문맥 뒤에 붙인다. 그리고 다시 다음 token을 고른다.
입력: "LLM은"
출력 token 1: " 다음"
새 문맥: "LLM은 다음"
출력 token 2: " token"
새 문맥: "LLM은 다음 token"
출력 token 3: "을"
이 반복이 decode다.
처음에는 이 반복을 "깊게 생각하는 과정"으로 착각했다. token을 하나 만들고 다시 넣고, 또 만들고 다시 넣으니, 많이 반복할수록 더 깊이 생각하는 것처럼 보였다.
그런데 이 반복은 기본 생성 방식이다. 긴 답변을 쓰려면 많이 반복해야 한다. 짧은 답변이면 적게 반복한다. 출력 길이와 추론 깊이는 같은 축이 아니다.
reasoning effort는 별도의 개념이다. 더 많은 중간 추론 token을 쓰거나, 더 많은 후보 검토와 검증을 하도록 예산을 주는 설정에 가깝다. Transformer layer 수가 늘어나는 것이 아니다.
Prefill은 입력을 한 번에 읽는 단계다
이제 추론 인프라에서 중요한 구분이 나온다.
prefill
decode
prefill은 입력 prompt 전체를 모델에 통과시키는 단계다. 사용자가 긴 코드, 긴 문서, 긴 대화 기록을 넣으면 그 전체가 prefill workload가 된다.
이 단계에서 모델은 prompt token들을 한 번에 처리하고, 각 layer마다 attention에 필요한 Key/Value를 만든다. 이것이 KV cache의 시작점이다.
정확히는 prefill이 첫 token을 "문장으로 생성"하는 단계라기보다, prompt 전체를 forward pass로 처리해서:
- 각 layer의 KV cache를 만들고
- 마지막 위치에서 첫 출력 token 후보 logits를 만든다
고 보는 편이 맞다.
그래서 입력이 길면 Time To First Token이 느려질 수 있다. 답변이 아직 나오기도 전에, 모델이 입력 전체를 읽고 KV cache를 만들어야 하기 때문이다.
EP 96에서 나온 천 줄 코드 예시는 이 감각을 잡기에 좋다. Claude Code에서 긴 파일이나 긴 repository context를 넣으면, 사용자는 "모델이 읽고 있다"고 느낀다. 내부적으로는 prompt token들이 Transformer block stack을 지나면서 각 layer의 K/V를 만들고 있다.
이 단계는 병렬화가 잘 되는 편이다. 입력 token 전체를 한 번에 처리할 수 있기 때문이다. 하지만 입력이 길수록 계산량과 메모리 사용량이 커진다.
특히 중요한 점은 prefill이 한 번만 하고 끝나는 단순한 텍스트 읽기가 아니라는 것이다. 모델의 모든 layer에서 token별 K/V가 만들어진다.
prompt token 수 x layer 수 x attention head 관련 차원
이 규모로 KV cache가 생긴다. 그래서 긴 context는 "그냥 많이 읽는 것"이 아니라 GPU memory를 실제로 잡아먹는 상태를 만든다.
Decode는 KV cache를 보면서 token을 하나씩 붙인다
decode는 prefill 이후에 이어진다.
새 token 하나가 선택되면, 모델은 그 token을 다시 Transformer block stack에 통과시킨다. 이때 과거 token 전체를 처음부터 다시 계산하면 너무 비싸다. 그래서 prefill 때 만들어 둔 KV cache를 쓴다.
Query는 지금 새 token에서 만들어진다. Key/Value는 과거 token의 것을 cache에서 가져오고, 새 token의 Key/Value만 추가한다.
기존 KV cache
+ 새 token의 K/V
-> 다음 token 계산
이것이 KV cache가 중요한 이유다.
KV cache는 모델 지식이 아니다. parameter도 아니다. 요청이 들어와 처리되는 동안 GPU memory에 생기는 동적 상태다. 요청이 끝나면 사라진다.
각 상태를 구분하면 이렇게 된다.
parameter = 학습이 끝난 뒤 모델에 남아 있는 고정 weight
activation = 지금 문제를 풀며 생긴 임시 계산
KV cache = 다음 문장을 쓰기 위해 책상 위에 남겨 둔 attention 메모
decode는 prefill보다 더 순차적이다. 다음 token을 만들려면 이전 token이 먼저 나와야 한다. 그래서 autoregressive generation은 latency에 민감하다.
한 사용자가 긴 답변을 생성하고 있으면 decode step이 계속 돈다. 여러 사용자가 동시에 답변을 생성하고 있으면 serving engine은 각 sequence의 다음 token 생성을 잘 섞어야 한다. 여기서 continuous batching 같은 기술이 중요해진다.
전통적인 batch는 요청을 모아서 한 번에 처리하고 끝내는 느낌이다. LLM serving에서는 요청마다 prompt 길이도 다르고 output 길이도 다르다. 어떤 요청은 짧게 끝나고, 어떤 요청은 reasoning token을 길게 쓴다.
그래서 현대 serving은 실행 중인 batch 안에서 끝난 sequence를 빼고, 새 sequence를 넣고, KV cache 위치를 관리한다. 이 과정은 단순 batch라기보다 scheduler 문제에 가깝다.
Batch와 sequence length는 비용 감각을 만든다
여기까지 이해하면 batch와 sequence length도 달라 보인다.
sequence length는 모델이 처리하는 token 줄의 길이다. 추론에서는 입력 prompt와 지금까지 생성된 token을 합친 현재 문맥 길이에 가깝다.
입력 prompt: 4,000 tokens
생성된 답변: 1,000 tokens
현재 문맥: 5,000 tokens
길어질수록 모델은 더 많은 context를 다룰 수 있다. 하지만 attention 비용과 KV cache memory가 커진다.
batch는 여러 sequence를 묶어 처리하는 단위다. 그런데 학습과 추론에서 의미가 다르다.
추론 batch는 여러 사용자 요청을 묶어 GPU를 효율적으로 쓰기 위한 scheduling 단위다. continuous batching은 실행 중인 batch에 새 요청을 계속 넣고, 끝난 요청은 빼면서 GPU가 쉬지 않게 한다.
학습 batch는 loss와 gradient를 계산하고 parameter를 업데이트하기 위한 데이터 묶음이다. LLM 학습에서는 단순 sample 수보다 token 수가 중요하다.
global batch tokens = global batch size x sequence length
그래서 batch와 sequence length는 "성능 옵션"이 아니라 비용 구조를 읽는 눈이다.
EP 96에서는 inference 비용을 compute time과 memory time의 조합으로 보는 관점이 나온다. 표현은 다를 수 있지만 핵심은 분명하다.
계산해야 하는 양
+ 메모리에서 불러오고 유지해야 하는 상태
-> token latency와 serving cost
LLM에서는 둘 다 중요하다.
Transformer block 안의 matrix multiplication은 GPU compute를 쓴다. 하지만 KV cache는 GPU memory를 잡아먹고, 긴 context에서는 attention이 참조해야 할 과거 token도 늘어난다. MoE나 multi-GPU sharding으로 가면 GPU 사이 통신도 비용이 된다.
그래서 "batch size를 키우면 항상 좋다"도 아니고, "context length가 길수록 무조건 좋다"도 아니다. 처리량, 지연시간, 메모리, 사용자 체감 속도 사이의 균형을 잡아야 한다.
학습에서는 이 감각이 또 달라진다.
학습 batch = gradient를 계산할 데이터 묶음
추론 batch = 동시에 serving할 sequence 묶음
학습 batch가 크면 gradient가 안정될 수 있고 GPU를 효율적으로 쓸 수 있다. 하지만 memory 한계가 있어 micro-batch와 gradient accumulation을 쓴다. 추론 batch는 GPU utilization과 throughput을 높이지만, 잘못 묶으면 latency가 늘어난다.
같은 batch라는 단어가 전혀 다른 목적을 가진다.
MoE와 GPU 이야기는 이 다음 단계다
여기까지는 하나의 모델이 하나의 큰 계산 그래프처럼 보인다.
하지만 프론티어 모델 크기로 가면 단순하지 않다. 모든 parameter가 한 GPU에 올라가지 않는다. layer, attention head, MLP, MoE expert, KV cache가 여러 GPU에 나뉠 수 있다.
MoE 모델에서는 MLP 자리에 router와 여러 expert MLP가 들어간다. 모든 expert를 매번 다 쓰는 것이 아니라, token별로 일부 expert를 고른다. 계산량은 줄일 수 있지만, expert가 다른 GPU나 다른 서버에 있으면 token dispatch/gather 통신이 생긴다.
이때 LLM serving은 신경망 문제가면서 동시에 분산컴퓨팅 문제가 된다.
어떤 가중치를 어느 GPU에 둘 것인가
KV cache를 어디에 둘 것인가
prefill과 decode를 같은 장치에서 할 것인가
batch를 어떻게 섞을 것인가
latency와 throughput 중 무엇을 우선할 것인가
이 질문들이 실제 토큰 가격과 응답 속도로 돌아온다.
EP96에서 Blackwell NVL72, HBM, GPU 간 통신 이야기가 나온 이유도 여기에 있다. 모델 아키텍처는 하드웨어와 분리되어 있지 않다. 큰 모델을 서비스하려면 weight를 여러 GPU에 쪼개 올려야 하고, KV cache를 어디에 둘지도 정해야 한다.
10T 같은 숫자를 들으면 처음에는 "엄청 큰 모델" 정도로 느껴진다. 그런데 serving 관점에서는 더 구체적으로 봐야 한다.
10T parameter
-> weight memory
-> precision에 따른 메모리 크기
-> 한 replica를 구성하는 GPU 수
-> replica를 여러 region에 복제하는 방식
-> 요청별 KV cache와 active user 수
프론티어 회사가 "수만 개의 다른 모델"을 운영한다기보다, 소수의 거대한 checkpoint를 여러 shard와 replica로 운영한다고 보는 편이 맞다. 한 요청은 보통 전 세계 여러 region의 weight를 동시에 섞어 쓰지 않는다. 특정 region이나 cluster의 완성된 model replica 하나로 라우팅된다.
이 관점이 생기면 LLM serving은 분산 시스템으로 보인다. compute, memory, network, scheduler, cache placement가 모두 중요해진다.
정리
이번 글의 핵심은 하나다.
LLM은 내부 검색기에서 답을 찾아 꺼내는 시스템이 아니다. 문장을 token으로 바꾸고, token을 embedding 벡터로 바꾸고, Transformer block stack을 통과시킨 뒤, LM head로 다음 token을 고른다. 그리고 그 token을 다시 붙여 다음 token을 만든다.
이 흐름 위에 prefill, decode, KV cache가 올라간다. 그다음에 batch, sequence length, MoE, GPU serving, token economics가 따라온다.
LLM을 이해하려면 이제 실제 실행 흐름을 봐야 한다.
그래야 tokenizer 변화가 왜 비용 체감으로 이어지는지, prefill과 decode가 왜 다른 workload인지, KV cache가 왜 메모리 병목이 되는지, batch와 sequence length가 왜 토큰 경제학의 중심인지 판단할 수 있다.
다음 글에서는 tokenizer와 embedding을 더 좁혀 본다. vocabulary, token ID, embedding table, LM head가 어떻게 이어지고, 왜 "같은 문장이 몇 token으로 쪼개지는가"가 실제 비용과 모델 구조의 경계가 되는지 정리한다.
이어 읽기
시리즈는 순서대로, 편집 추천은 맥락대로, 비슷한 주제는 태그 기준으로 정리합니다.
시리즈 전체
LLM 공부 시리즈1/9편- 1.LLM 공부 01 | LLM은 검색기가 아니라 다음 토큰 생성기다
- 2.LLM 공부 02 | 토큰이 비용을 만든다
- 3.LLM 공부 03 | Transformer 안에서 문맥이 섞이는 방식
- 4.LLM 공부 04 | Prefill과 Decode: LLM이 읽고 쓰는 두 단계
- 5.LLM 공부 05 | Batch와 Sequence Length가 속도와 비용을 정한다
- 6.LLM 공부 06 | MoE와 GPU 클러스터: 거대 모델은 어떻게 나뉘어 도는가
- 7.LLM 공부 07 | Reasoning Effort: 더 깊게 생각한다는 말의 실제 의미
- 8.LLM 공부 08 | 학습 Batch와 Distillation: 모델은 어떻게 바뀌는가
- 9.LLM 공부 09 | RAG와 Vector DB: LLM 밖에서 근거를 찾는 방식
비슷한 주제의 글
태그가 겹치는 글입니다. 시리즈와 편집 추천에 이미 나온 글은 제외합니다.
AI 웹개발 기초: 프론트엔드 1-1 | 프론트엔드는 왜 이렇게 복잡해졌을까
프론트엔드가 React나 Next.js 같은 기술명 묶음이 아니라, 웹 문서가 구조, 표현, 동작, 상태, API 통신, 성능, 배포 책임을 차례로 떠안으며 커진 문제 해결의 축적임을 설명하는 AI 웹개발 기초 시리즈 프론트엔드 1-1.
AI 웹개발 기초: 프론트엔드 1-2 | DOM은 화면이 아니라 브라우저의 작업 모델이다
HTML source가 곧 화면이 아니라 DOM, CSSOM, render tree, layout, paint, composite, accessibility tree를 거쳐 화면과 보조기술 의미로 바뀌며, DOM 조작이 reflow, XSS, event delegation, 성능 지표와 어떻게 연결되는지 설명하는 AI 웹개발 기초 시리즈 프론트엔드 1-2.
AI 웹개발 기초: 프론트엔드 1-3 | jQuery에서 React로 넘어간 진짜 이유
jQuery의 DOM 직접 조작과 AJAX가 해결한 문제를 인정하고, UI가 커지면서 React, Vue, Angular 같은 state/data 기반 component UI가 왜 필요해졌는지 설명하는 AI 웹개발 기초 시리즈 프론트엔드 1-3.