LLM 평가 5주차. RAG / Safety / Agent 평가 완전 정리
Faithfulness, Answer Relevance, Context Precision / Recall, Hallucination, Grounding, Red Teaming, Harmfulness, Tool-use Evaluation, Task Success
1주차에서는 평가를 공부하기 전에 반드시 알아야 하는 평가의 기초 언어를 정리했습니다.
- Evaluation
- Metric
- Benchmark
- Dataset
- Leaderboard
- Offline Eval / Online Eval
- 정량 평가 / 정성 평가
- 절대 평가 / 상대 평가
- 지속적 평가
2주차에서는 그 위에 올라가는 전통적인 ML/NLP 평가 기초를 정리했습니다.
- Accuracy
- Precision
- Recall
- F1-score
- Confusion Matrix
- Exact Match
- Perplexity
- 분류 평가와 생성 평가의 차이
3주차에서는 LLM의 기초 체력을 보는 static benchmark를 정리했습니다.
- MMLU
- GSM8K
- HumanEval
- MBPP
- TruthfulQA
- Static benchmark의 의미와 한계
4주차에서는 생성 품질 평가를 정리했습니다.
- BLEU
- ROUGE
- METEOR
- BERTScore
- Reference-based / Reference-free
- LLM-as-a-Judge
- MT-Bench
- AlpacaEval
- Evaluator Bias
이제 5주차에서는 한 단계 더 실제 시스템에 가까운 평가로 들어갑니다.
이번 주차의 핵심은 단순합니다.
이제는 “모델 자체가 똑똑한가?”를 넘어서, “시스템이 제대로 동작하는가?”, “안전한가?”, “도구를 제대로 쓰는가?”를 평가해야 한다는 것입니다.
즉, 이번 주차에서는 다음을 다룹니다.
- RAG 시스템은 왜 따로 평가해야 하는가
- Faithfulness, Answer Relevance, Context Precision / Recall은 무엇을 보는가
- Hallucination과 Grounding은 왜 핵심 개념인가
- Safety 평가는 왜 일반 품질 평가와 별개인가
- Red Teaming은 무엇이며 왜 중요한가
- Harmfulness 평가는 무엇을 보는가
- Agent / Tool-use 평가는 왜 새로운 평가 축이 되었는가
- Tool-use Evaluation, Task Success는 어떻게 이해해야 하는가
이 글의 목표는 단순히 용어 설명이 아닙니다.
RAG, Safety, Agent가 각각 왜 “모델 평가”가 아니라 “시스템 평가”로 확장되는지 이해하는 것
이 글을 끝까지 이해하면, 앞으로 어떤 LLM 시스템을 볼 때
단순히 “점수가 높다”를 넘어
- 이 시스템은 근거 기반 답변을 잘하는가?
- 환각을 얼마나 줄였는가?
- 위험한 요청에 안전하게 대응하는가?
- 도구를 진짜로 제대로 사용했는가?
- 최종 과제를 성공적으로 끝냈는가?
를 훨씬 구조적으로 볼 수 있게 됩니다.
1. 왜 5주차가 중요한가?
LLM 평가를 처음 공부할 때는 보통 모델 자체를 평가하는 데 집중합니다.
예:
- 지식이 많은가?
- reasoning이 좋은가?
- 코드를 잘 짜는가?
- 답변이 자연스러운가?
그런데 실제 서비스로 가면 문제가 훨씬 복잡해집니다.
예를 들어:
- 검색 문서를 붙였는데 답변이 문서를 안 따를 수 있음
- 답변은 유창한데 문서에 없는 내용을 꾸며낼 수 있음
- 안전장치가 있는데도 유해 요청을 뚫릴 수 있음
- 에이전트가 도구를 썼지만 결과는 틀릴 수 있음
- 중간 과정은 그럴듯했는데 최종 과제는 실패할 수 있음
즉, 실제 시스템에서는
모델 하나의 지능보다
전체 파이프라인이 제대로 작동하는가가 더 중요해집니다.
그래서 5주차에서는
모델 평가를 넘어서 시스템 수준 평가(system-level evaluation) 로 넘어갑니다.
2. 왜 RAG는 따로 평가해야 할까?
2-1. 일반 LLM과 RAG의 차이
일반 LLM은 보통:
- 질문을 받고
- 내부 파라미터에 저장된 지식으로 답합니다
반면 RAG는:
- 질문을 받고
- 관련 문서를 검색하고
- 그 문서를 바탕으로 답을 생성합니다
즉, RAG는 단순 생성이 아니라
다음 두 단계가 결합된 시스템입니다.
- Retrieval(검색)
- Generation(생성)
2-2. 왜 일반 평가로 부족한가?
RAG 시스템이 실패하는 방식은 두 가지입니다.
1. 검색이 실패할 수 있음
- 관련 문서를 못 찾음
- 엉뚱한 문서를 가져옴
- 필요한 문서를 빠뜨림
2. 생성이 실패할 수 있음
- 문서는 잘 찾았는데 답변이 문서를 안 따름
- 문서에 없는 내용을 덧붙임
- 질문에 맞게 답을 재구성하지 못함
즉, RAG는 “최종 답변 하나”만 보고 평가하면
어디서 잘못됐는지 알기 어렵습니다.
그래서 RAG는 별도의 평가 관점이 필요합니다.
3. Faithfulness란 무엇인가?
3-1. 정의
Faithfulness(충실성) 는
답변이 검색된 문서의 내용에 실제로 근거하고 있는가를 보는 지표입니다.
쉽게 말하면:
“이 답변은 근거 문서 안에 있는 내용만 바탕으로 말하고 있는가?”
를 보는 것입니다.
3-2. 왜 중요한가?
RAG의 가장 큰 존재 이유 중 하나는
환각(hallucination)을 줄이고, 근거 기반 답변을 하게 만드는 것입니다.
그런데 문서를 검색해놓고도:
- 모델이 자기 멋대로 꾸며내거나
- 문서에 없는 내용을 섞거나
- 자신이 알고 있던 오래된 지식을 덧붙인다면
RAG를 쓴 의미가 줄어듭니다.
즉, Faithfulness는
RAG의 핵심 성공 조건을 보는 지표라고 할 수 있습니다.
3-3. Faithfulness가 높다는 뜻
- 문서 내용에 잘 근거함
- 환각이 적음
- 근거와 답변이 잘 연결됨
즉, “문서 기반 시스템답게 행동한다”는 뜻입니다.
3-4. 주의할 점
Faithfulness가 높다고 해서 항상 좋은 답변은 아닐 수 있습니다.
왜냐하면:
- 문서를 충실히 따랐지만 질문에 답을 제대로 안 했을 수도 있고
- 문서를 그냥 복붙했을 수도 있기 때문입니다
즉, Faithfulness는 중요하지만 그 자체로 충분하지는 않습니다.
4. Answer Relevance란 무엇인가?
4-1. 정의
Answer Relevance(답변 관련성) 은
답변이 사용자의 질문에 적절하게 대응하고 있는가를 보는 지표입니다.
즉, 질문은 이겁니다.
“이 답변은 정말 질문에 대한 답인가?”
4-2. 왜 중요한가?
RAG 시스템은 종종 이런 문제를 일으킬 수 있습니다.
- 문서는 잘 찾았는데 답변이 질문 핵심을 놓침
- 문서 내용을 장황하게 설명하지만 정작 질문에 대한 답은 안 함
- 관련 정보는 있지만 사용자의 의도에 맞게 정리하지 못함
즉, 문서 기반이라고 해서 자동으로 좋은 답변이 되는 것은 아닙니다.
그래서 Faithfulness와 별개로
질문 적합성을 따로 봐야 합니다.
4-3. Answer Relevance가 높다는 뜻
- 질문의 핵심을 잘 파악함
- 문서를 질문에 맞게 활용함
- 엉뚱한 정보로 새지 않음
즉, 단순 근거 충실성이 아니라
질문-답변 연결이 잘 되어 있다는 뜻입니다.
5. Context Precision이란 무엇인가?
5-1. 정의
Context Precision(맥락 정밀도) 는
검색된 문서들 중에서 실제로 질문에 도움이 되는 문서 비율이 얼마나 높은가를 보는 관점입니다.
쉽게 말하면:
“검색 결과가 얼마나 깔끔하게 relevant한 것들로 구성되어 있는가?”
를 보는 것입니다.
5-2. 왜 중요한가?
RAG는 문서를 많이 가져오는 것만으로는 충분하지 않습니다.
불필요한 문서가 너무 많으면:
- 생성 모델이 혼란스러워지고
- 핵심 근거가 묻히고
- 답변 품질이 떨어질 수 있습니다
즉, 검색은 “많이”보다
정확하게 필요한 것만 가져오는 것도 중요합니다.
5-3. Context Precision이 높다는 뜻
- irrelevant 문서가 적다
- 검색 결과의 품질이 깔끔하다
- 질문에 실제로 필요한 문서 위주다
즉, retrieval의 오탐(FP) 이 적은 감각과 연결됩니다.
6. Context Recall이란 무엇인가?
6-1. 정의
Context Recall(맥락 재현율) 은
질문에 필요한 관련 문서를 얼마나 놓치지 않고 가져왔는가를 보는 관점입니다.
즉, 질문은 이겁니다.
“정말 필요한 문서가 있었는데 검색이 놓친 건 없는가?”
6-2. 왜 중요한가?
Context Precision만 높고 Recall이 낮으면 이런 상황이 생길 수 있습니다.
- 검색 결과는 깔끔함
- 하지만 꼭 필요한 문서를 못 가져옴
- 그래서 답변이 핵심을 놓침
즉, 너무 엄격하게 검색하면 precision은 좋아질 수 있지만
필요한 정보까지 빠질 수 있습니다.
6-3. Context Recall이 높다는 뜻
- 필요한 근거를 잘 놓치지 않음
- 검색의 coverage가 좋음
- 질문에 필요한 문맥이 충분히 확보됨
즉, retrieval의 놓침(FN) 을 줄이는 감각과 연결됩니다.
7. Context Precision vs Context Recall 다시 정리
| Context Precision | 가져온 문서들이 얼마나 정확하게 relevant한가? | 불필요한 문서 줄이기 |
| Context Recall | 필요한 문서를 얼마나 빠뜨리지 않았는가? | 중요한 문서 놓치지 않기 |
즉:
- Precision은 “검색 결과가 깔끔한가”
- Recall은 “검색이 충분히 포괄적인가”
를 봅니다.
RAG에서는 이 둘의 균형이 매우 중요합니다.
8. Hallucination이란 무엇인가?
8-1. 정의
Hallucination(환각) 은
모델이 사실이 아니거나, 근거가 없거나, 주어진 문서에 없는 내용을 그럴듯하게 만들어내는 현상입니다.
즉:
- 말은 자연스럽다
- 문장도 유창하다
- 그런데 내용은 틀릴 수 있다
이게 환각입니다.
8-2. 왜 중요한가?
LLM의 가장 큰 위험 중 하나가 바로 환각입니다.
왜냐하면 사용자는:
- 유창한 답변을 신뢰하기 쉽고
- 틀린 정보도 맞다고 받아들일 수 있기 때문입니다
특히 RAG에서는:
- 문서가 있는데도 문서에 없는 내용을 꾸며내는가
를 꼭 봐야 합니다.
8-3. Hallucination과 Faithfulness의 관계
둘은 매우 가깝지만 완전히 같지는 않습니다.
- Faithfulness는 “문서에 근거했는가?”
- Hallucination은 “없는 내용을 꾸며냈는가?”
즉, Faithfulness가 낮으면 hallucination 가능성이 커질 수 있습니다.
하지만 hallucination은 더 넓은 개념으로,
일반 LLM에서도 중요한 문제입니다.
9. Grounding이란 무엇인가?
9-1. 정의
Grounding 은
모델의 답변이 외부 근거(문서, 데이터, 툴 결과, 검색 결과 등)에 제대로 연결되어 있는 상태를 뜻합니다.
쉽게 말하면:
“이 답변은 공중에 떠 있는 게 아니라, 실제 근거에 발을 딛고 있는가?”
를 보는 개념입니다.
9-2. 왜 중요한가?
Grounding은 환각 방지와 매우 깊게 연결됩니다.
예를 들어:
- 문서 기반 QA
- 검색 기반 챗봇
- 데이터베이스 조회 응답
- 툴 호출 기반 에이전트
이런 시스템에서는 답변이 반드시 외부 근거와 연결되어야 합니다.
즉, grounding은
“모델이 근거를 따르는 시스템처럼 행동하는가” 를 보는 관점입니다.
9-3. Faithfulness와 Grounding의 관계
- Faithfulness는 “답변이 근거 문서를 잘 따랐는가”
- Grounding은 “답변이 실제 근거 기반으로 형성되었는가”
즉, grounding이 더 넓은 상위 개념처럼 느껴질 수 있습니다.
10. Safety 평가는 왜 따로 봐야 할까?
이제 RAG에서 Safety로 넘어갑니다.
많은 초보자가 “좋은 답변이면 좋은 모델 아닌가?”라고 생각하기 쉽습니다.
하지만 실제 서비스에서는 그걸로 부족합니다.
왜냐하면 모델이:
- 유해한 요청에 답할 수 있고
- 편향된 답을 할 수 있고
- 위험한 조언을 할 수 있고
- 안전장치를 우회당할 수 있기 때문입니다
즉, Safety는 단순 품질이 아니라
별도의 평가 축입니다.
11. Harmfulness란 무엇인가?
11-1. 정의
Harmfulness(유해성) 은
모델의 출력이 사용자나 사회에 실질적으로 해로운 내용을 포함하는지를 보는 관점입니다.
예를 들어:
- 자해 유도
- 폭력 조장
- 불법 행위 도움
- 혐오 발화
- 위험한 의료 조언
- 허위 정보 확산
같은 것이 여기에 포함될 수 있습니다.
11-2. 왜 중요한가?
모델이 아무리 똑똑해도
위험한 요청에 너무 쉽게 응답하면 실제 서비스로 쓰기 어렵습니다.
즉, harmfulness 평가는
모델의 “유능함”과 별개로
배포 가능성을 결정하는 핵심 요소입니다.
12. Red Teaming이란 무엇인가?
12-1. 정의
Red Teaming 은
모델이 위험하거나 바람직하지 않은 답을 하도록
일부러 공격적이고 까다로운 질문을 던져 약점을 찾는 과정입니다.
즉:
- 안전장치를 우회하려는 시도
- 정책의 허점을 노리는 질문
- 경계 사례
- 복합적인 악성 프롬프트
를 통해 모델의 약점을 찾습니다.
12-2. 왜 중요한가?
일반 benchmark는 보통 “잘 푸는가”를 봅니다.
하지만 red teaming은 반대로:
“어디서 망가지는가?”
를 보는 평가입니다.
즉, 정답률을 보는 것이 아니라
취약점 탐지에 가까운 평가입니다.
12-3. 실제 의미
red teaming은 안전성 평가에서 매우 중요합니다.
왜냐하면 모델은 평범한 상황에선 괜찮아 보여도,
교묘한 입력을 받으면 갑자기 위험해질 수 있기 때문입니다.
즉, Red Teaming은
모델의 “최악의 상황 대응력”을 보는 과정이라고 할 수 있습니다.
13. Refusal Quality와 Over-refusal도 같이 알아야 한다
Safety 평가에서는 단순히 “거절했는가”만 보면 부족합니다.
왜냐하면:
- 거절해야 할 건 잘 거절해야 하고
- 괜찮은 요청은 과하게 막으면 안 되기 때문입니다
즉, 두 가지를 같이 봐야 합니다.
13-1. Refusal Quality
위험한 요청에 대해:
- 적절하게 거절했는가
- 안전한 방향으로 유도했는가
- 지나치게 공격적이거나 이상하지 않은가
를 보는 것입니다.
13-2. Over-refusal
사실은 답해도 되는 정상 요청인데
모델이 너무 과하게 거절하는 문제입니다.
예:
- 무해한 역사 질문
- 일반적인 건강 상식 질문
- 정상적인 코딩 질문
까지 다 막아버리면 사용자 경험이 크게 나빠집니다.
즉, Safety 평가는 항상
위험한 걸 잘 막는 것과
정상적인 걸 과하게 막지 않는 것
사이 균형 문제입니다.
14. Agent / Tool-use 평가는 왜 새로운 평가 축인가?
이제 마지막으로 Agent / Tool-use 평가를 보겠습니다.
기존 LLM은 보통 텍스트만 생성했습니다.
그런데 최근 모델은 점점 다음을 하게 됩니다.
- 검색 도구 호출
- 계산기 사용
- 코드 실행
- DB 조회
- API 호출
- 일정 등록
- 파일 분석
즉, 단순 답변 모델이 아니라
도구를 쓰고 행동하는 시스템이 되고 있습니다.
이때는 더 이상 “답변 문장 품질”만 평가해서는 부족합니다.
왜냐하면 중요한 것은:
- 도구를 올바르게 선택했는가
- 도구를 올바른 순서로 썼는가
- 필요한 입력을 정확히 만들었는가
- 도구 결과를 잘 해석했는가
- 최종 과제를 성공했는가
이기 때문입니다.
즉, Agent 평가는
생성 품질 평가를 넘어 행동 평가로 확장된 것입니다.
15. Tool-use Evaluation이란 무엇인가?
15-1. 정의
Tool-use Evaluation 은
모델이 외부 도구를 적절하게 선택하고, 올바르게 호출하고, 결과를 잘 활용하는가를 평가하는 것입니다.
즉, 질문은 다음과 같습니다.
- 이 상황에서 도구를 써야 한다는 걸 알았는가?
- 올바른 도구를 골랐는가?
- 입력 파라미터를 정확히 넣었는가?
- 도구 결과를 잘 읽었는가?
- 최종 응답에 올바르게 반영했는가?
15-2. 왜 중요한가?
Agent 시스템에서는
도구를 “썼다”보다
도구를 잘 썼다가 중요합니다.
예:
- 검색 도구를 써야 하는데 안 쓰면 문제
- 계산기를 써야 하는데 자기 머리로 틀리게 계산하면 문제
- 도구는 불렀는데 파라미터를 잘못 넣으면 문제
- 결과는 받았는데 잘못 해석하면 문제
즉, tool-use 평가는
Agent의 실제 실행 능력을 보는 핵심 축입니다.
16. Task Success란 무엇인가?
16-1. 정의
Task Success(과제 성공률) 은
모델이 최종적으로 사용자가 원하는 목표를 성공적으로 달성했는가를 보는 평가입니다.
즉, 중간 과정이 아니라
최종 결과 기준입니다.
16-2. 왜 중요한가?
Agent는 중간에 여러 단계를 거칩니다.
예:
- 질문 이해
- 계획 세우기
- 검색 도구 호출
- 계산 도구 호출
- 결과 종합
- 최종 답변
이 과정 중 일부는 잘했더라도
마지막 결과가 틀리면 과제는 실패입니다.
즉, Task Success는
전체 파이프라인의 실제 성공 여부를 보는 가장 직접적인 지표입니다.
16-3. Tool-use와 Task Success의 차이
둘은 비슷해 보이지만 다릅니다.
- Tool-use Evaluation → 도구 사용 과정이 올바른가
- Task Success → 최종 목표 달성에 성공했는가
예:
- 도구는 잘 썼지만 마지막 요약이 틀릴 수 있음
- 도구 사용은 다소 이상했지만 운 좋게 정답에 도달할 수도 있음
즉, 둘 다 봐야 합니다.
17. 5주차 전체 흐름 연결하기
이제 5주차 내용을 하나로 묶어보겠습니다.
LLM 시스템이 실제 서비스 단계로 가면, 더 이상 모델 자체의 지식이나 문장 품질만 평가해서는 충분하지 않습니다.
RAG 시스템에서는 검색과 생성이 결합되므로, 답변이 문서에 근거하는지를 보는 Faithfulness, 질문에 적절한지를 보는 Answer Relevance, 검색 결과의 품질을 보는 Context Precision / Recall 같은 지표가 필요합니다.
이 과정에서 Hallucination 과 Grounding 은 핵심 문제로 등장합니다.
한편 실제 서비스에서는 모델이 안전하게 동작해야 하므로, Harmfulness, Refusal Quality, Over-refusal, Red Teaming 같은 Safety 평가가 별도로 중요해집니다.
또 최근의 Agent 시스템에서는 모델이 단순히 답변만 하는 것이 아니라 도구를 사용해 과제를 수행하므로, Tool-use Evaluation 과 Task Success 같은 새로운 평가 축이 필요해졌습니다.
즉, 5주차의 핵심은 다음입니다.
LLM 평가는 이제 모델 자체를 넘어서, 검색·근거·안전성·행동까지 포함하는 시스템 수준 평가로 확장되고 있다.
18. 5주차 핵심 요약
RAG 평가
RAG는 retrieval과 generation이 결합된 시스템이기 때문에 별도의 평가가 필요합니다.
Faithfulness
답변이 검색된 문서 내용에 실제로 근거하고 있는가를 보는 지표입니다.
Answer Relevance
답변이 사용자의 질문에 적절하게 대응하는가를 보는 지표입니다.
Context Precision
검색된 문서들이 실제로 질문에 도움이 되는 문서 위주인가를 보는 관점입니다.
Context Recall
질문에 필요한 문서를 얼마나 빠뜨리지 않고 가져왔는가를 보는 관점입니다.
Hallucination
모델이 근거 없이 그럴듯한 거짓 내용을 만들어내는 현상입니다.
Grounding
답변이 외부 근거(문서, 데이터, 도구 결과 등)에 제대로 연결되어 있는 상태를 뜻합니다.
Harmfulness
모델 출력이 실제로 해로운 내용을 포함하는가를 보는 Safety 평가입니다.
Red Teaming
모델의 안전성 약점을 찾기 위해 일부러 공격적인 입력을 던지는 평가 방식입니다.
Refusal Quality / Over-refusal
위험한 요청은 잘 막되, 정상 요청을 과하게 막지 않는 균형을 보는 관점입니다.
Tool-use Evaluation
모델이 도구를 적절하게 선택하고 정확히 사용하는가를 평가합니다.
Task Success
최종적으로 사용자의 목표를 성공적으로 달성했는가를 평가합니다.
19. 이 글을 공부한 뒤 반드시 설명할 수 있어야 하는 문장
1
RAG는 검색과 생성이 결합된 시스템이기 때문에, 최종 답변만 보는 일반 생성 평가로는 충분하지 않다.
2
Faithfulness는 근거 충실성, Answer Relevance는 질문 적합성, Context Precision/Recall은 검색 품질을 보는 관점이다.
3
Hallucination은 근거 없는 그럴듯한 오답이고, Grounding은 답변이 실제 근거에 연결된 상태를 뜻한다.
4
Safety 평가는 일반 품질 평가와 별개로 중요하며, harmfulness와 red teaming은 핵심 축이다.
5
좋은 안전 시스템은 위험한 요청을 잘 막아야 하지만, 동시에 정상 요청을 과하게 거절하지도 않아야 한다.
6
Agent 평가는 단순 답변 품질을 넘어서, 도구 사용 과정과 최종 과제 성공 여부까지 평가해야 한다.
7
Tool-use Evaluation과 Task Success는 각각 과정과 결과를 보는 평가라고 이해할 수 있다.
20. 위 커리큘럼 내용이 5주차에 빠짐없이 들어갔는지 체크
앞서 추천한 5주차 커리큘럼은 다음이었습니다.
- RAG 평가
- faithfulness
- answer relevance
- context precision / recall
- hallucination
- grounding
- safety 평가
- red teaming
- harmfulness
- refusal quality / over-refusal
- agent 평가
- tool-use evaluation
- task success
이 글에 모두 포함되었는지 체크하면:
포함된 내용
- RAG 평가 설명 포함
- Faithfulness 설명 포함
- Answer Relevance 설명 포함
- Context Precision 설명 포함
- Context Recall 설명 포함
- Hallucination 설명 포함
- Grounding 설명 포함
- Safety 평가 설명 포함
- Harmfulness 설명 포함
- Red Teaming 설명 포함
- Refusal Quality / Over-refusal 설명 포함
- Agent 평가 설명 포함
- Tool-use Evaluation 설명 포함
- Task Success 설명 포함
즉, 5주차에 들어가야 할 핵심 내용은 빠짐없이 모두 포함되었습니다.
21. 마무리
5주차는 LLM 평가가 본격적으로 시스템 평가로 확장되는 단계입니다.
1~4주차가 모델의 기초 체력과 생성 품질을 보는 과정이었다면,
5주차는 이제 “이 시스템이 실제로 근거 기반으로 답하고, 안전하게 동작하며, 도구를 잘 써서 과제를 끝낼 수 있는가” 를 보는 단계입니다.
이 주차를 이해하면 앞으로:
- 왜 RAG는 별도 평가가 필요한지
- 왜 hallucination과 grounding이 핵심인지
- 왜 safety 평가는 일반 품질 평가와 다르게 설계해야 하는지
- 왜 agent는 답변 품질이 아니라 행동 성공까지 봐야 하는지
를 훨씬 더 구조적으로 이해할 수 있습니다.
즉, 5주차는
“LLM 평가가 모델 수준을 넘어서 시스템 수준으로 확장되는 흐름” 을 잡는 단계라고 보면 됩니다.
[Django 02] 데이터베이스 설계의 정석: 모델 정의와 PostgreSQL 연동
장고(Django)의 가장 강력한 무기는 **ORM(Object-Relational Mapping)**입니다. SQL을 직접 짜지 않아도 파이썬 코드로 복잡한 데이터베이스를 자유자재로 다룰 수 있습니다. 오늘은 로컬 환경에 PostgreSQL을 설정하고 모델을 설계하는 법을 배웁니다.
1. 왜 SQLite가 아니라 PostgreSQL인가?
Django 프로젝트를 생성하면 기본적으로 db.sqlite3가 설정되어 있습니다. 하지만 실무(AWS 배포 등)에서는 다음과 같은 이유로 PostgreSQL을 사용합니다.
- 동시성 처리: 여러 사용자가 동시에 데이터를 쓸 때 SQLite보다 훨씬 안정적입니다.
- 데이터 타입: JSONField 등 고급 데이터 타입을 지원하여 유연한 설계가 가능합니다.
- 운영 환경과의 일치: 로컬과 서버의 DB 환경을 일치시켜야 배포 시 발생하는 예상치 못한 오류를 막을 수 있습니다.
2. PostgreSQL 설치 및 데이터베이스 생성
먼저 PC에 PostgreSQL이 설치되어 있어야 합니다. (설치가 안 되어 있다면 공식 홈페이지나 Docker를 통해 설치하세요.)
- DB 접속: 터미널에서 psql -U postgres 입력 (또는 pgAdmin 사용)
- 프로젝트 전용 DB 생성:
-
SQL
CREATE DATABASE my_django_db; CREATE USER my_user WITH PASSWORD 'my_password'; ALTER ROLE my_user SET client_encoding TO 'utf8'; ALTER ROLE my_user SET default_transaction_isolation TO 'read committed'; ALTER ROLE my_user SET timezone TO 'Asia/Seoul'; GRANT ALL PRIVILEGES ON DATABASE my_django_db TO my_user;
3. Django-PostgreSQL 연동 설정
Django가 PostgreSQL과 대화할 수 있도록 드라이버를 설치하고 설정을 변경해야 합니다.
📦 필수 패키지 설치
pip install psycopg2-binary
⚙️ .env 파일 수정
보안을 위해 DB 접속 정보를 .env에 격리합니다.
DATABASE_URL=postgres://my_user:my_password@localhost:5432/my_django_db
🛠️ settings.py 수정
django-environ을 사용하여 DB 설정을 동적으로 불러옵니다.
# settings.py 상단에 이미 environ 설정이 되어 있다고 가정합니다.
DATABASES = {
'default': env.db(),
}
4. 모델(Model) 정의의 정석
이제 core/models.py에 데이터를 정의해 봅시다. 블로그 포스트를 관리하는 모델을 예시로 작성합니다.
from django.db import models
from django.conf import settings
class Post(models.Model):
# 1. 필드 정의
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts')
title = models.CharField(max_length=200, verbose_name="제목")
content = models.TextField(verbose_name="내용")
# 2. 메타 데이터 (생성일, 수정일) - 실무 필수 필드
created_at = models.DateTimeField(auto_auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# 3. 객체 표현 방식 정의
def __str__(self):
return self.title
class Meta:
verbose_name = "포스트"
verbose_name_plural = "포스트 목록"
ordering = ['-created_at'] # 최신순 정렬
💡 실무 팁: Meta 클래스와 str
- __str__: 관리자 페이지(Admin)에서 객체가 제목으로 표시되게 하여 가독성을 높입니다.
- ordering: DB에서 데이터를 가져올 때 기본 정렬 순서를 지정합니다.
5. Migration: 파이썬 코드를 DB 테이블로!
모델을 만들었으면 이를 실제 DB 테이블로 변환하는 과정을 거쳐야 합니다.
- 설계도 생성: python manage.py makemigrations
- core/migrations/ 폴더에 파이썬 파일이 생깁니다.
- DB 반영: python manage.py migrate
- 이 명령어를 실행하는 순간 PostgreSQL에 실제 테이블이 생성됩니다.
6. Admin 페이지에서 확인하기
작성한 모델이 잘 작동하는지 확인하기 위해 Django 관리자 도구에 등록합니다.
core/admin.py 수정:
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'created_at') # 목록에 보여줄 필드
search_fields = ('title', 'content') # 검색 기능 추가
이제 python manage.py createsuperuser로 관리자 계정을 만든 뒤, 127.0.0.1:8000/admin에서 데이터를 직접 넣어보세요.
✍️ 블로그 작성을 위한 마지막 조언
독자들에게 "ForeignKey의 on_delete 옵션"(사용자가 삭제될 때 글은 어떻게 될 것인가?)의 중요성을 설명해 주면 깊이 있는 포스팅이 됩니다. 또한, PostgreSQL 연동 시 자주 발생하는 psycopg2 설치 에러 해결법(컴파일러 문제 등)을 짧게 언급해 주면 매우 친절한 가이드가 됩니다.
ANKI MCP
🐞 에러 요약
1. ImportError: cannot import name 'ToolRequest'
- 원인: 최신 mcp 라이브러리에는 ToolRequest, ToolResponse가 없음.
- 해결: CallToolRequest, CallToolResult 등을 쓰거나, 아예 FastMCP 고수준 API 사용.
2. AttributeError: 'Server' object has no attribute 'tool'
- 원인: Server 클래스에는 .tool() 데코레이터가 없음.
- 해결: FastMCP 사용 (@app.tool(...)) 으로 전환.
3. TypeError: object _AsyncGeneratorContextManager can't be used in 'await' expression
- 원인: await stdio_server() 를 잘못 사용.
- 해결: async with stdio_server() as (read, write): 로 사용해야 함, 또는 FastMCP.run_stdio_async() 사용.
4. TypeError: Server.run() missing 2 required positional arguments
- 원인: Server.run() 은 read_stream, write_stream, initialization_options 필요.
- 해결: 직접 쓰지 않고 FastMCP의 .run_stdio_async() 사용.
5. AttributeError: 'FastMCP' object has no attribute 'create_initialization_options'
- 원인: 예전 예제 코드에서 쓰던 메서드, 현재 버전엔 없음.
- 해결: InitializationOptions(...) 직접 만들거나, 더 간단히 FastMCP.run_stdio_async() 사용.
6. ValidationError: InitializationOptions (server_name, server_version, capabilities required)
- 원인: InitializationOptions() 만들 때 필수 필드 미지정.
- 해결: server_name, server_version, capabilities 지정하거나 FastMCP.run_stdio_async()로 자동 처리.
7. ValidationError: upsert_noteArguments - payload Field required
- 원인: 서버 툴 함수가 payload: dict 하나만 받도록 정의돼 있었음.
- 해결:
- 방법 A: 클라이언트에서 {"payload": {...}} 형식으로 보내기
- 방법 B(採用): 서버 함수를 async def upsert_note(type: str, deck: str, ...) 처럼 개별 인자 받도록 변경.
8. ConnectionRefusedError: [Errno 111] Connection refused
- 원인: AnkiConnect 서버(127.0.0.1:8765)에 접근 불가.
- 상세: WSL2 리눅스 ↔ 윈도우 Anki 연결 문제. WSL에서 127.0.0.1은 리눅스 자기 자신이라 거부됨.
- 해결:
- 파이썬을 윈도우에서 실행,
🌐 RAG(Retrieval-Augmented Generation) 챗봇 기본 구조
1. 기본 개념
- LLM만 쓸 때 문제점
- LLM은 학습 당시까지의 데이터만 알고 있음. → 최신 정보 부족
- 내부 파라미터로 지식이 압축돼 있어서, 특정 도메인 문서를 그대로 알지 못함.
- 그래서 헛소리(환각, hallucination) 가능성 ↑.
- RAG의 핵심 아이디어
- **외부 지식베이스(Retriever)**에서 관련 문서를 찾아오고,
- 그 내용을 **LLM 프롬프트에 추가(Augmented)**해서 답변을 생성(Generation).
- 즉, “LLM + 검색기능”을 합쳐서 최신성과 정확성을 확보.
2. 흐름 구조 (단계별)
(1) User Query (사용자 질문 입력)
- 사용자가 질문을 던짐.
예: “SQLD 공부법 알려줘”
(2) Preprocessing (전처리 / Context Rewriting)
- 질문이 모호하거나 짧으면 → 활성 주제/라벨을 붙여서 명확히.
예: “이거 다시 설명해줘” → “SQLD 관련 이거 다시 설명해줘 [활성주제: …]”
(3) Retriever (문서 검색)
- 외부 지식 소스에서 관련 텍스트를 가져옴.
- 로컬 문서 (PDF, TXT → 벡터DB)
- 웹 검색 (Tavily, Bing 등)
- DB/사내 문서 (예: 위키)
흐름:
- 문서를 청킹(split) (200~1000 토큰 단위로 자르기).
- 각 청크에 대해 임베딩 벡터 생성.
- 사용자 질문도 임베딩 → 코사인 유사도로 가까운 청크 k개 검색.
(4) Prompt Construction (프롬프트 구성)
- LLM에게 보낼 최종 입력을 구성.
- 사용자 질문
- 검색된 관련 문서(context)
- 대화 히스토리 (필요시)
- 지시문 (Answer in Korean, Summarize, Quiz 등)
(5) LLM Generation (답변 생성)
- OpenAI 같은 LLM이 들어온 프롬프트를 보고 답을 생성.
- 모델은 검색된 문서를 참고하기 때문에, 환각이 줄고 도메인 특화 답변 가능.
(6) Postprocessing (출력 후처리)
- 답변 포맷 정리:
- 객관식 문제면 ① ② ③ ④ 라벨 정리
- Markdown 강제 개행 정리
- UI 표시 최적화
(7) Memory (대화 메모리)
- 사용자의 이전 질문/대답을 JSON 파일에 기록.
- 짧은 질문(“이거 뭐였지?”)을 해도 → 이전 맥락을 찾아 답 가능.
- 자동 주제 전환 감지(유사도 낮으면 새 세션으로).
3. 전체 그림 (한 문장 요약)
User 질문 → (전처리/맥락주입) → Retriever(문서/웹) → Prompt 조립(context+history+지시문) → LLM 답변 생성 → 후처리/메모리 기록
1. Attention Mechanism의 주요 목적은 무엇인가?
*2. Self-Attention의 특징이 아닌 것?
*3. Transformers 모델에서 사용되는 Attention 유형을 선택하시오?
*4. Transformers 모델에서 Positional Encoding의 역할에 대해서 설명한 것은?
*5. Transformers 모델의 장점이 아닌 것은?
*6. Multi-Head Attention에서 "Head"의 어떤 역할을 하는가?
*7. Transformers 모델에서 Feed-Forward Network의 역할은?
*8. BERT 모델의 특징이 아닌 것은?
*9. GPT 모델의 특징이 아닌 것은?
*10. Transformers 모델에서 Layer Normalization의 역할?
*11. Vision Transformer (ViT) 모델의 특징은 무엇인가?
*12 . PEFT의 주요 목적은 무엇인가?
*13. PEFT 방법이 아닌 것은 무엇인가?
*14. LoRA의 핵심 아이디어는 무엇인가?
*15. LangChain의 주요 목적은 무엇인가?
*16. LangChain에서 PromptTemplate의 역할은 무엇인가?
*17. LangChain에서 지원하는 벡터 저장소(Vector Store)가 아닌 것을 택하시오
*18. LangChain에서 Retriever의 역할에 대해서 알맞게 설명한 것은?
*19. RAG 모델이 일반적인 언어 모델에 비해 가지는 장점에 대해서 설명한 것은?
*20. RetrievalQA 체인과 ConversationalRetrievalChain 체인의 주요 차이점에 대해서 설명한 것은?
*
[Django 01] 2026년형 Django 개발 환경 구축 가이드
Django 개발의 시작은 단순히 설치하는 것이 아니라, 나중에 배포(Docker, AWS)할 때 문제가 없도록 깨끗한 환경을 만드는 것입니다. 2026년 표준에 맞춘 환경 구축법을 시작합니다.
1. Python 설치 및 버전 확인
Django는 파이썬 기반 프레임워크입니다. 최신 Django 5.x 버전은 파이썬 3.10 이상을 권장합니다.
- 설치 확인: 터미널(또는 CMD)에서 python --version 입력
- 권장 버전: Python 3.11 또는 3.12 (안정성과 속도가 검증된 버전)
2. 가상환경(venv) 설정: "왜 환경을 격리해야 할까?"
프로젝트마다 사용하는 라이브러리의 버전이 다를 수 있습니다. 가상환경을 쓰지 않으면 다른 프로젝트와 충돌이 발생해 배포 시 큰 문제가 생깁니다.
🏠 프로젝트 폴더 생성 및 이동
mkdir my-django-project
cd my-django-project
📦 가상환경 생성 및 활성화
# 가상환경 생성 (이름은 주로 .venv 또는 venv로 합니다)
python -m venv .venv
# 가상환경 활성화 (Windows)
.venv\Scripts\activate
# 가상환경 활성화 (Mac/Linux)
source .venv/bin/activate
Tip: 활성화되면 터미널 앞에 (.venv)라는 표시가 뜹니다.
3. Django 설치 및 프로젝트 시작
🚀 패키지 설치
2026년 현재 가장 많이 쓰이는 조합인 Django와 환경 변수 관리 도구를 함께 설치합니다.
pip install --upgrade pip
pip install django django-environ
🏗️ 프로젝트 및 앱 생성
실무에서는 프로젝트 루트에 관리를 위한 설정 파일들이 모이도록 아래와 같이 구성합니다.
# 현재 폴더(.)에 프로젝트 생성 (폴더가 중첩되는 것을 방지)
django-admin startproject config .
# 기능을 담당할 앱 생성 (예: core)
python manage.py startapp core
4. 실무형 필수 초기 설정 (Settings.py)
config/settings.py에서 가장 먼저 수정해야 할 핵심 설정들입니다.
① 시간대 및 언어 설정 (Localization)
한국 사용자를 위한 필수 설정입니다.
LANGUAGE_CODE = 'ko-hans' # 한국어 설정
TIME_ZONE = 'Asia/Seoul' # 한국 시간대
USE_I18N = True
USE_TZ = True # DB 저장 시 UTC 기준, 보여줄 때 로컬 기준
② 앱 등록
방금 만든 core 앱과 나중에 배포 시 필요한 앱들을 등록합니다.
INSTALLED_APPS = [
...
'core', # 내가 만든 앱 등록
]
③ 보안 설정 (django-environ 활용)
[중요] SECRET_KEY나 DB 비번을 소스코드에 그대로 두면 해킹의 위험이 있습니다. .env 파일을 활용하세요.
- 프로젝트 루트에 .env 파일 생성
- settings.py 수정:
import environ
import os
env = environ.Env(DEBUG=(bool, False))
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
5. 서버 실행 및 확인
모든 설정이 완료되었다면 서버를 띄워봅니다.
python manage.py migrate # 기본 DB 테이블 생성
python manage.py runserver
브라우저에서 http://127.0.0.1:8000/ 접속 시 로켓 아이콘이 뜨면 성공입니다!
6. Git 설정 (.gitignore)
가상환경 폴더나 .env 파일은 절대 GitHub에 올리면 안 됩니다.
- 프로젝트 루트에 .gitignore 파일 생성 후 아래 내용 추가:
.venv/
__pycache__/
*.pyc
.env
db.sqlite3
✍️ 블로그 작성을 위한 마지막 조언
이 포스팅을 마무리하며 독자들에게 "가상환경 활성화"를 잊지 말 것과 **".env 관리의 중요성"**을 강조해 주세요. 다음 글에서는 이 환경 위에서 실제 데이터 모델을 설계하는 법(2회차)을 배울 것이라고 예고하면 완벽합니다.
- 오토인코더
비지도학습 입력 데이터를 압축시킨 후 다시 원래의 입력으로 복원
1.인코더- 숨겨진표현, 잠재의식, 핵심적 특징
2디코더- 원래 데이터로 최대한 비슷하게 복원
입력풋 아웃풋이 동일한 구조
종류
잡음 제거
변이형
합성곱
활용분야
차원축소이상탐지이미지 생성이미지 노이즈 제거
kr발산 손실함수로 이용 (코스트펑션=로스펑션)분포가 완전히 동일할수록 0에 가까움-> 변이형 오토 인코더 강화학습에 활용
오토인코더 다음 모델 겐(GAN)
겐(GAN) 알고리즘 활용
주고받으면서 오류 수정
상수가 들어간 변수는 대문자 이용하는 규칙..
디퓨전 모델 노이즈를 없애는 방식
uv: 빠르고 가벼운 파이썬 환경/패키지 관리 툴
uv
📌 Django / Flask / FastAPI 비교 정리
| 성격 | 풀스택 프레임워크 (거대한 틀 제공) | 마이크로 프레임워크 (필요한 것만 붙임) | 비동기/최신형 마이크로 프레임워크 |
| 규모 | 대규모 프로젝트에 적합 | 소규모·중규모 서비스에 적합 | API 서버, ML 서비스, 스타트업 서비스에 적합 |
| 제공 기능 | ORM, 인증, 관리자(Admin), 템플릿 등 올인원 제공 | 기본 라우팅만 제공, ORM/DB/인증은 확장 | 타입 힌트 기반 자동 문서화, 빠른 API 구축 |
| 속도 | 상대적으로 무거움 | 가볍지만 동기식 | 매우 빠름 (비동기 지원, Starlette 기반) |
| 학습 곡선 | 높음 (많은 기능 → 공부할게 많음) | 낮음 (간단하게 시작 가능) | 중간 (파이썬 타입힌트+비동기 이해 필요) |
| 활용 예시 | 인스타그램, 유튜브 크론 기반 서비스 | 프로토타입, 간단한 웹 서비스 | API 서버, AI/ML 백엔드, 마이크로서비스 |
www.naver.com -> web server(아파치,엔진x)정적인것 -> <- web application server(톱캣)
model_serving.py
import json
from flask import Flask, request, Response
import torch
from torch.nn import functional as F
from transformers import BertTokenizer, BertForSequenceClassification
from transformers import pipeline
class BertModel:
device = "cuda" if torch.cuda.is_available() else "cpu"
@classmethod
def load_model(cls, weight_path):
model_url = "alsgyu/sentiment-analysis-fine-tuned-model"
cls.tokenizer = BertTokenizer.from_pretrained(
pretrained_model_name_or_path=model_url,
do_lower_case=False,
)
cls.model = BertForSequenceClassification.from_pretrained(
pretrained_model_name_or_path=model_url,
num_labels=3
).to(cls.device)
# # cls.model.load_state_dict(torch.load(weight_path, map_location=cls.device))
cls.model.eval()
@classmethod
def preprocessing(cls, data):
input_data = cls.tokenizer(
text=data,
padding="longest",
truncation=True,
return_tensors="pt"
).to(cls.device)
return input_data
@classmethod
@torch.no_grad()
def predict(cls, input):
input_data = cls.preprocessing(input)
outputs = cls.model(**input_data).logits
probs = F.softmax(outputs, dim=-1)
index = int(probs[0].argmax(axis=-1))
print(index)
if index == 0:
label = '부정'
elif index == 1 :
label = '중립'
else:
label = '긍정'
# label = "긍정" if index == 1 else "부정"
score = float(probs[0][index])
return {
"label": label,
"score": score
}
app = Flask(__name__)
@app.route("/predict", methods=["POST"])
def inference():
data = request.get_json()
text = data["text"]
try:
return Response(
response=json.dumps(BertModel.predict(text), ensure_ascii=False),
status=200,
mimetype="application/json",
)
except Exception as e:
return Response(
response=json.dumps({"error": str(e)}, ensure_ascii=False),
status=500,
mimetype="application/json",
)
if __name__ == "__main__":
BertModel.load_model(weight_path="./BertForSequenceClassification.pt")
app.run(host="0.0.0.0", port=8000)
1. torch 설정된 환경으로 변경
- conda env list
- conda activate torch
2. pip install flask
3. python model_serving.py
4. api 질의하기
import json
import requests
url = "http://127.0.0.1:8000/predict"
headers = {'content-type' : 'application/json'}
reponse = requests.post(url, headers=headers, data= json.dumps({'text' : '가산동고기무한 북촌삼대갈비 샐러드바 사이드도 너무 먹을게 없네요'}))
reponse.text
which python conda deactivate source ~/workspace/.venv/bin/activate VIRTUAL_ENV