2026. 8. 15. 18:47ㆍPROJECT/Toy Project
[ContentOps Agent #1] 프로젝트 소개와 학습 목표
1. 시작하며
Playback Gate에서는 하나의 API에 많은 요청이 들어왔을 때 발생하는 Latency, Connection Pool, Cache, 동시성 문제를 다뤘다.
Live Event Stream에서는 Kafka를 이용해 많은 Event를 비동기로 처리하면서 Consumer Lag, Partition, Idempotency, Retry, Replay 같은 문제를 직접 확인했다.
이번에는 조금 다른 영역을 다뤄보려고 한다.
최근에는 LLM을 이용해서 사내 문서나 데이터를 검색하고, 자연어로 질문하면 필요한 정보를 찾아주는 서비스를 쉽게 볼 수 있다.
예를 들어 OTT 콘텐츠 운영자가 다음과 같이 질문한다고 가정해볼 수 있다.
"이번 달 공개 예정인 15세 이상 액션 콘텐츠를 찾아줘."
"콘텐츠 공개 정책에서 연령 등급 관련 규칙을 알려줘."
"이 콘텐츠가 왜 공개 불가 상태인지 운영 정책을 기준으로 설명해줘."
"최근 등록된 콘텐츠 중 메타데이터가 누락된 항목을 찾아줘."
단순한 ChatGPT 형태라면 LLM이 알고 있는 지식만으로 답변할 수도 있다.
하지만 실제 서비스에서 필요한 정보는 LLM이 학습한 일반적인 지식이 아니라 우리 서비스 내부에 있는 데이터와 문서다.
콘텐츠 Metadata
운영 정책
등급 정책
콘텐츠 등록 가이드
공개 일정
운영 FAQ
이 데이터를 LLM에게 어떻게 연결할 것인지가 중요해진다.
가장 먼저 떠오르는 방법이 RAG다.
사용자 질문
↓
관련 문서 검색
↓
검색 결과
↓
LLM
↓
답변
개념만 보면 단순하다.
하지만 실제로 구현하려고 하면 여러 문제가 생긴다.
문서를 어떻게 나눠야 할까?
Embedding은 어떻게 저장할까?
Vector Search만 사용하면 충분할까?
정확한 단어가 중요한 검색은 어떻게 할까?
검색 결과의 순서는 믿을 만할까?
관련 없는 문서를 LLM에게 주면 어떻게 될까?
LLM이 검색 결과에 없는 내용을 만들어내면 어떻게 할까?
질문에 따라 문서 검색과 DB 조회 중 무엇을 해야 할까?
RAG가 실제로 좋아졌다는 것을 어떻게 측정할까?
이번 프로젝트에서는 이런 문제를 직접 만들어보고 개선해보려고 한다.
프로젝트 이름은 ContentOps Agent로 정했다.
2. ContentOps Agent란?
ContentOps Agent는 OTT 콘텐츠 운영자가 자연어로 질문하면 내부 콘텐츠 정보와 운영 문서를 검색하고 필요한 정보를 조합해 답변하는 AI Agent다.
예를 들어 다음과 같은 콘텐츠가 있다고 가정한다.
Content
제목
장르
연령 등급
공개 상태
공개 예정일
서비스 지역
Metadata 상태
그리고 별도의 운영 문서가 존재한다.
콘텐츠 등록 정책
연령 등급 정책
공개 상태 변경 가이드
Metadata 작성 규칙
운영 FAQ
운영자가:
"8월에 공개 예정인 15세 이상 액션 콘텐츠를 알려줘."
라고 질문하면 구조는 다음과 같이 동작할 수 있다.
사용자 질문
↓
질문 분석
↓
콘텐츠 데이터 조회
↓
조건에 맞는 콘텐츠 검색
↓
결과 생성
반면:
"15세 콘텐츠의 공개 기준이 뭐야?"
라는 질문은 DB보다는 운영 문서를 찾는 것이 적절하다.
사용자 질문
↓
질문 분석
↓
운영 문서 검색
↓
관련 Chunk 검색
↓
LLM
↓
근거 기반 답변
또 다음처럼 두 종류의 정보가 모두 필요할 수도 있다.
"이 콘텐츠가 공개되지 않는 이유를 정책 기준으로 설명해줘."
사용자 질문
↓
콘텐츠 상태 조회
+
운영 정책 검색
↓
정보 조합
↓
LLM
↓
답변
즉 ContentOps Agent에서는 단순히 Vector DB에서 문서를 검색하는 것에서 끝내지 않고,
질문에 따라 어떤 정보를 찾아야 하는지 판단하고, 필요한 Tool을 사용해서 결과를 조합하는 과정
까지 다뤄보려고 한다.
3. 이번 프로젝트에서 중요한 것
이번 프로젝트의 목표는:
Spring AI 연결
↓
pgvector 연결
↓
LangGraph 연결
↓
"AI Agent 만들었다."
로 끝내는 것이 아니다.
Playback Gate와 Live Event Stream에서 사용했던 방식과 동일하게 진행한다.
기본 구조 구현
↓
Baseline 평가
↓
문제 확인
↓
원인 분석
↓
개선 후보 비교
↓
구조 변경
↓
동일 질문으로 재평가
다만 이번에는 이전 프로젝트와 측정 대상이 다르다.
Playback Gate에서는:
RPS
p95
p99
를 봤고,
Live Event Stream에서는:
Events/sec
Consumer Lag
Processing Latency
를 봤다면,
ContentOps Agent에서는 다음과 같은 값을 보게 된다.
정답 문서를 검색했는가?
관련 없는 문서를 가져오지는 않았는가?
검색 순위가 적절한가?
답변이 검색 근거와 일치하는가?
필요한 Tool을 제대로 선택했는가?
최종 답변의 품질이 실제로 좋아졌는가?
즉 이번 프로젝트의 핵심은 AI 기능도 측정하고 개선할 수 있는 대상으로 보는 것이다.
4. 가장 단순한 구조부터 시작한다
처음부터 복잡한 Agent를 만들지 않는다.
초기 구조는 최대한 단순하게 시작한다.
사용자 질문
↓
Embedding
↓
Vector Search
↓
관련 문서
↓
LLM
↓
답변
예를 들어 운영 정책 문서를 PostgreSQL + pgvector에 저장하고 질문과 유사한 문서를 검색한다.
이것을 첫 번째 Baseline으로 사용한다.
처음부터 다음 기능을 모두 넣지는 않는다.
Hybrid Search
RRF
Reranker
Query Rewrite
Multi Query
Agent
LangGraph
Tool Calling
Memory
복잡한 Prompt Engineering
먼저 단순한 Vector Search에서 어떤 문제가 생기는지 확인한다.
5. RAG의 검색 품질을 직접 확인한다
예를 들어 다음 문서가 있다고 가정한다.
문서 A
15세 이상 콘텐츠의 공개 정책
문서 B
콘텐츠 Metadata 작성 규칙
문서 C
청소년 보호 정책
문서 D
콘텐츠 공개 일정 관리 방법
사용자가:
"15세 콘텐츠 공개할 때 확인해야 하는 기준은?"
이라고 질문했을 때 Vector Search가:
1위 문서 B
2위 문서 D
3위 문서 A
를 반환한다면 검색 자체가 완전히 틀린 것은 아니지만 가장 중요한 문서가 뒤에 있다.
LLM은 결국 검색 결과를 기반으로 답하기 때문에:
검색 품질
↓
Context 품질
↓
답변 품질
로 연결된다.
따라서 이번 프로젝트에서는 LLM의 답변만 보는 것이 아니라 LLM 이전 단계의 Retrieval 자체를 별도로 평가한다.
6. 학습 목표
6.1 RAG의 기본 구조 이해
먼저 가장 기본적인 RAG Pipeline을 직접 만든다.
Document
↓
Chunking
↓
Embedding
↓
Vector DB
User Query
↓
Embedding
↓
Similarity Search
↓
Top K Documents
↓
LLM
↓
Answer
이를 통해 다음 개념을 실제 코드로 확인한다.
Document
Chunk
Embedding
Vector
Similarity
Top K
Context
Grounding
단순히 RAG Framework를 호출하는 것보다 각 단계가 최종 결과에 어떤 영향을 주는지를 이해하는 것이 목표다.
6.2 Chunking 전략 이해
하나의 긴 문서를 그대로 Embedding하는 대신 여러 Chunk로 나눠 저장한다.
예를 들어:
콘텐츠 운영 정책.md
↓
Chunk 1
콘텐츠 등록 정책
Chunk 2
연령 등급 정책
Chunk 3
공개 상태 정책
Chunk 4
삭제 정책
처럼 나눌 수 있다.
하지만 Chunk가 너무 크면 관련 없는 내용까지 같이 들어올 수 있다.
Chunk 너무 큼
↓
관련 정보
+
관련 없는 정보
+
관련 없는 정보
반대로 너무 작으면 문맥이 잘릴 수 있다.
Chunk 너무 작음
↓
필요한 문맥이 여러 Chunk로 분리
따라서 다음과 같은 조건을 비교해본다.
Chunk Size
Chunk Overlap
문서 구조 기반 Chunking
그리고 같은 평가 질문을 이용해 검색 품질이 실제로 달라지는지 확인한다.
6.3 Embedding과 Vector Search 이해
문서와 질문을 Embedding Vector로 변환하고 유사도를 이용해 검색한다.
"15세 콘텐츠 공개 기준"
↓
Embedding
↓
[0.13, -0.24, 0.87, ...]
문서 역시 Vector로 저장한다.
Query Vector
↓
Vector Similarity
↓
가장 가까운 Document
이번 프로젝트에서는 PostgreSQL의 pgvector를 이용해 Vector를 저장하고 검색한다.
이를 통해 Vector DB를 별도의 마법 같은 시스템으로 보는 것이 아니라:
PostgreSQL
+
Vector Column
+
Similarity Search
라는 구조로 직접 확인한다.
6.4 Vector Search의 한계 확인
Semantic Search가 항상 좋은 결과를 만드는 것은 아니다.
예를 들어 다음과 같은 질문에서는 정확한 Keyword가 중요할 수 있다.
"OPS-101 정책 알려줘."
"CONTENT_BLOCKED 상태 조건이 뭐야?"
"Metadata Error Code M-03 의미가 뭐야?"
Vector Search는 의미적으로 비슷한 문서를 찾는 데 강하지만 정확한 식별자나 용어 검색에서는 Keyword Search가 더 적합할 수도 있다.
따라서 먼저 Vector Search만 사용한다.
그리고 실제 평가 질문에서 검색 실패 사례를 확인한다.
그 이후에만 Keyword Search 결합을 검토한다.
6.5 Hybrid Search 이해
Vector Search와 Keyword Search가 서로 다른 장점을 가진다면 두 결과를 같이 사용할 수 있다.
Vector Search
+
Keyword Search
↓
결과 결합
예를 들어:
Vector Search
A
B
C
Keyword Search
D
A
E
두 결과를 조합해 더 좋은 검색 순위를 만들 수 있다.
이번 프로젝트에서는 필요성이 확인되면 Hybrid Search를 적용하고 Vector Search만 사용했을 때와 비교한다.
6.6 RRF 이해
서로 다른 검색 방식의 Score는 직접 비교하기 어려울 수 있다.
Vector Score
0.86
Keyword Score
12.4
이런 경우 단순히 Score를 더하기 어렵다.
RRF(Reciprocal Rank Fusion)를 이용하면 각각의 검색 결과에서 순위를 기준으로 결과를 합칠 수 있다.
Vector Rank
1. A
2. B
3. C
Keyword Rank
1. D
2. A
3. B
↓
RRF
1. A
2. B
3. D
...
Hybrid Search가 실제 Retrieval 품질을 개선하는지 측정하면서 RRF가 어떤 역할을 하는지 확인한다.
6.7 Reranking 이해
Retriever에서 Top K 문서를 찾았더라도 순서가 항상 최적이라는 보장은 없다.
Retriever
1. Document A
2. Document B
3. Document C
4. Document D
5. Document E
별도의 Reranker를 이용해 Query와 Document의 관련성을 다시 평가할 수 있다.
Retriever
↓
Top 10
↓
Reranker
↓
Top 3
↓
LLM
다만 Reranker를 처음부터 사용하지 않는다.
검색 결과에서 실제 Ranking 문제가 확인됐을 때 적용하고:
Before
↓
Reranking
↓
After
를 비교한다.
7. Retrieval 품질을 수치로 측정한다
이번 프로젝트에서 특히 중요하게 다뤄볼 부분이다.
RAG를 구현한 뒤:
"질문해보니까 잘 되는 것 같다."
정도로 판단하지 않는다.
먼저 평가용 Dataset을 만든다.
예:
질문정답 문서
| 15세 콘텐츠 공개 기준은? | age-rating-policy.md |
| CONTENT_BLOCKED 조건은? | content-status-policy.md |
| Metadata M-03 오류는? | metadata-guide.md |
그리고 검색 결과를 평가한다.
예를 들어:
Query
"15세 콘텐츠 공개 기준은?"
Expected Document
age-rating-policy.md
Retriever Top 3
1. content-guide.md
2. age-rating-policy.md
3. youth-policy.md
이 경우 정답 문서가 Top 3 안에는 들어왔다.
이런 방식으로 다음 지표를 확인한다.
Recall@K
MRR
Top-K Hit Rate
필요하다면 이후 Ranking 품질을 평가하는 다른 Metric도 추가한다.
중요한 것은:
Retriever가 좋아졌다는 말을 실제 평가 Dataset으로 설명할 수 있어야 한다.
는 것이다.
8. 답변 품질도 Retrieval과 분리해서 본다
정답 문서를 잘 찾았다고 해서 LLM이 반드시 좋은 답을 만드는 것은 아니다.
예를 들어 검색 결과에는:
15세 콘텐츠는 연령 등급 검수가 완료되어야 공개할 수 있다.
라고 되어 있는데 LLM이:
15세 콘텐츠는 보호자 인증도 필요합니다.
라고 답한다면 Retrieval은 성공했지만 Generation이 실패한 것이다.
따라서:
Retrieval 평가
+
Generation 평가
를 분리한다.
답변에서는 다음을 확인한다.
검색된 Context를 근거로 답했는가?
Context에 없는 사실을 추가하지 않았는가?
질문에 필요한 내용을 빠뜨리지 않았는가?
근거 문서를 확인할 수 있는가?
이를 통해 Hallucination과 Grounding 문제를 직접 확인한다.
9. Grounding과 Citation
운영자가 AI의 답변을 실제 업무에 사용하려면:
"AI가 그렇게 말했습니다."
만으로는 부족하다.
어떤 문서를 기준으로 답했는지 확인할 수 있어야 한다.
따라서 최종 응답에는 가능한 한 근거를 함께 제공한다.
예:
15세 콘텐츠는 연령 등급 검수가 완료된 이후 공개할 수 있습니다.
근거:
- 콘텐츠 연령 등급 정책 / 3.2 공개 조건
즉:
Answer
+
Source
구조를 만든다.
이를 통해 운영자가 답변을 다시 검증할 수 있도록 한다.
10. 단순 RAG에서 Agent로 확장한다
모든 질문이 문서 검색으로 해결되는 것은 아니다.
예를 들어:
"이번 달 공개 예정인 액션 콘텐츠 알려줘."
라는 질문은 운영 정책 문서를 검색할 문제가 아니다.
실제 콘텐츠 DB를 조회하는 것이 더 적절하다.
반면:
"콘텐츠 공개 승인 조건 알려줘."
는 문서를 검색해야 한다.
따라서 질문에 따라 사용하는 Tool이 달라진다.
사용자 질문
↓
질문 분석
↓
┌─────┴─────┐
↓ ↓
문서 검색 콘텐츠 DB 조회
↓ ↓
RAG SQL / API
└─────┬─────┘
↓
Answer
여기서부터 단순한 RAG를 넘어 Agent의 역할이 생긴다.
11. Tool Calling 이해
Agent에게 다음과 같은 Tool을 제공할 수 있다.
search_policy_documents
search_contents
get_content_detail
질문에 따라 Agent가 적절한 Tool을 선택한다.
예를 들어:
"15세 콘텐츠 공개 정책 알려줘"
↓
search_policy_documents
반면:
"8월 20일 공개 예정 콘텐츠 알려줘"
↓
search_contents
그리고:
"콘텐츠 100번이 공개되지 않는 이유를 알려줘"
↓
get_content_detail
+
search_policy_documents
처럼 여러 Tool이 필요한 질문도 존재할 수 있다.
Agent가 Tool을 많이 호출하는 것이 목표는 아니다.
어떤 정보가 필요한지 판단하고 필요한 Tool만 호출할 수 있는 구조를 만드는 것이 목적이다.
12. LangGraph와 Agent State 이해
Agent Workflow가 복잡해지기 시작하면 단순한 함수 호출만으로 전체 흐름을 관리하기 어려울 수 있다.
예를 들어:
질문
↓
질문 분석
↓
Tool 선택
↓
Tool 실행
↓
결과 충분?
├─ YES → 답변
│
└─ NO
↓
추가 Tool
↓
답변
이런 상태 기반 Workflow를 LangGraph를 이용해 구현해본다.
Agent State에는 예를 들어 다음 정보가 존재할 수 있다.
userQuery
selectedTools
retrievedDocuments
contentData
toolResults
finalAnswer
이를 통해 Agent가 현재 어느 단계에 있고 어떤 정보를 가지고 있는지 명시적으로 관리한다.
13. 처음부터 Multi-Agent로 만들지는 않는다
AI Agent 프로젝트라고 해서 처음부터:
Planner Agent
↓
Search Agent
↓
DB Agent
↓
Review Agent
↓
Answer Agent
처럼 여러 Agent를 만들지는 않는다.
처음에는 하나의 Agent와 몇 개의 Tool로 시작한다.
ContentOps Agent
├─ Policy Search Tool
├─ Content Search Tool
└─ Content Detail Tool
실제로 역할 분리가 필요해지는 문제가 확인됐을 때만 구조 확장을 검토한다.
이번 프로젝트에서도 복잡한 구조 자체를 성과로 만들지는 않는다.
14. Agent가 Tool을 제대로 선택하는지도 평가한다
RAG에서는 주로:
올바른 문서를 찾았는가?
를 평가했다면 Agent에서는 한 가지가 더 추가된다.
올바른 Tool을 선택했는가?
예를 들어 평가 Dataset을 다음처럼 만들 수 있다.
질문기대 Tool
| 15세 콘텐츠 공개 정책은? | Policy Search |
| 이번 달 공개 콘텐츠는? | Content Search |
| 콘텐츠 100 상태 확인 | Content Detail |
| 콘텐츠 100이 왜 공개 불가야? | Content Detail + Policy Search |
그리고 실제 Agent가 어떤 Tool을 호출했는지 기록한다.
이를 통해:
Tool Selection Accuracy
도 평가할 수 있다.
Agent가 그럴듯한 답변을 만들었다는 사실만으로 성공으로 판단하지 않는다.
15. Prompt도 실험 대상으로 본다
LLM 프로젝트에서는 Prompt 하나만 바꿔도 결과가 달라질 수 있다.
하지만 Prompt를 계속 감으로 수정하면:
이 Prompt가 더 좋아 보인다.
수준에서 끝날 수 있다.
따라서 Prompt 역시 코드와 동일하게 평가 Dataset을 기준으로 비교한다.
Prompt A
↓
Evaluation
Prompt B
↓
Evaluation
↓
결과 비교
Prompt가 길어진다고 반드시 좋아지는 것도 아니고, System Prompt에 규칙을 많이 넣는다고 Hallucination이 완전히 없어지는 것도 아니다.
실제 결과를 기준으로 판단한다.
16. AI 시스템의 Latency와 비용도 확인한다
이번 프로젝트의 핵심은 품질이지만 응답시간도 무시할 수 없다.
예를 들어:
Vector Search
100ms
Reranking
700ms
LLM
2,000ms
가 걸린다면 Reranker를 추가하면서 Retrieval 품질은 좋아졌지만 전체 응답시간은 증가한 것이다.
따라서 일부 실험에서는 다음도 함께 확인한다.
Retrieval Latency
Reranking Latency
LLM Latency
전체 End-to-End Latency
상용 LLM API를 사용한다면 Token 사용량과 비용도 기록할 수 있다.
단:
더 빠르다 = 더 좋다
로 판단하지 않는다.
이번 프로젝트에서는 품질과 비용, Latency 사이의 Trade-off를 함께 본다.
17. 평가가 이번 프로젝트의 핵심이다
ContentOps Agent에서 가장 중요하게 가져갈 원칙은 다음과 같다.
기능 구현
↓
몇 개 질문
↓
"잘 되네"
로 끝내지 않는다.
대신:
Evaluation Dataset 생성
↓
Baseline 실행
↓
Metric 기록
↓
실패 Case 분석
↓
개선
↓
동일 Dataset 재평가
방식으로 진행한다.
예를 들어:
Vector Search
Recall@5 = 측정값
↓
Hybrid Search
Recall@5 = 측정값
↓
Reranker
Recall@5 = 측정값
MRR = 측정값
처럼 실제 결과를 비교한다.
물론 어떤 기술을 적용했다고 항상 점수가 올라갈 것이라고 가정하지 않는다.
RRF를 적용했는데 결과가 같을 수도 있다.
Reranker를 추가했는데 품질 증가보다 Latency 증가가 더 클 수도 있다.
그 역시 정상적인 Experiment 결과로 남긴다.
18. 이전 프로젝트와 다른 점
세 프로젝트의 중심 문제를 비교하면 다음과 같다.
프로젝트핵심 문제
| Playback Gate | 많은 동기 요청을 빠르고 정확하게 처리 |
| Live Event Stream | 많은 Event를 안정적으로 비동기 처리 |
| ContentOps Agent | 내부 데이터에서 올바른 정보를 찾아 근거 있는 AI 답변 생성 |
측정하는 값도 달라진다.
Playback GateLive Event StreamContentOps Agent
| RPS | Events/sec | Recall@K |
| p95 / p99 | Consumer Lag | MRR |
| DB Query | Processing Latency | Retrieval Latency |
| Connection Pool | Retry / DLT | Tool Selection |
| Race Condition | Duplicate Event | Grounding |
| Lock | Idempotency | Hallucination |
| Cache | Partition | RRF / Reranking |
Playback Gate와 Live Event Stream에서는 시스템이 얼마나 많은 요청과 Event를 처리할 수 있는가가 중요했다면,
이번에는:
AI가 얼마나 정확한 정보를 찾아서 근거 있게 답할 수 있는가
가 중심이 된다.
19. 이번 프로젝트에서도 기술을 미리 정답으로 두지 않는다
Kafka는 Live Event Stream의 학습 대상이라 처음부터 사용하는 것이 맞았다.
이번 프로젝트에서는 RAG 자체가 학습 대상이기 때문에:
Embedding
Vector Search
pgvector
정도는 처음부터 사용한다.
하지만 다음 기능까지 처음부터 넣지는 않는다.
Hybrid Search
RRF
Reranker
Query Rewrite
Multi Query
Agent
LangGraph
여러 Agent
Memory
Schema가 복잡한 Tool Calling
예를 들어 Vector Search만으로 평가 결과가 충분히 좋다면 Hybrid Search가 반드시 필요한 것은 아니다.
RRF로 개선되지 않는다면 최종 구조에서 빠질 수도 있다.
Reranker의 비용과 Latency가 품질 개선보다 크다면 사용하지 않을 수도 있다.
이번에도:
기술 사용 여부가 아니라 문제를 실제로 해결했는지를 기준으로 판단한다.
20. 바이브 코딩 방식도 한 단계 수정한다
Live Event Stream까지 진행하면서 프로젝트 전체에 항상 적용되는 제약을 SKILL.md에 넣었는데, 실제로 사용해보니 이것은 Skill보다는 Rule의 성격에 더 가까웠다.
그래서 이번 프로젝트에서는 처음부터:
docs/
├── REQUIREMENTS.md
├── DESIGN.md
├── ROADMAP.md
├── TASKS.md
├── adr/
└── experiments/
.cursor/
└── rules/
└── content-ops-agent.mdc
구조로 시작해보려고 한다.
Project Rule에는 다음과 같은 내용을 둔다.
현재 Phase를 넘어가지 않는다.
평가 전에 최적화하지 않는다.
RAG 개선 기능을 미리 넣지 않는다.
실제 측정되지 않은 품질 개선을 주장하지 않는다.
중요한 Agent 구조 변경은 Human Gate를 거친다.
그리고 실제 개발 과정에서 반복되는 작업이 발견되면 그때 Skill로 분리한다.
예를 들어:
Retrieval Evaluation
실패 Case 분석
RAG Experiment 정리
같은 작업을 반복하게 된다면 해당 Workflow를 Skill 후보로 볼 수 있다.
21. Git과 README도 이전 회고를 반영한다
Live Event Stream에서 아쉬웠던 두 가지도 이번에는 처음부터 반영한다.
첫 번째는 Git이다.
문제를 재현했다면 해결하기 전에 해당 상태를 먼저 Commit한다.
Baseline
↓
Commit
문제 재현
↓
Commit
개선 적용
↓
Commit
예를 들어:
experiment: reproduce vector retrieval misses
↓
feat: add hybrid retrieval
처럼 검색 실패가 존재하는 상태와 해결 이후 상태를 분리한다.
두 번째는 README다.
이번에는 Phase 1 완료 조건부터 README에 최소한 다음 내용을 포함한다.
프로젝트 실행 방법
PostgreSQL / pgvector 실행 방법
문서 적재 방법
기본 질문 방법
테스트 실행 방법
프로젝트 마지막에 한꺼번에 README를 정리하는 방식을 반복하지 않는 것이 목표다.
22. 최종 목표
ContentOps Agent를 통해 단순히 RAG와 LangGraph를 사용해보는 것이 아니라,
내부 문서와 콘텐츠 데이터를 대상으로 Retrieval 실패와 Hallucination을 직접 확인하고, Chunking·Hybrid Search·RRF·Reranking 등의 방법을 비교한 뒤, Agent가 적절한 Tool을 선택해 근거 있는 답변을 생성하도록 만들고 그 결과를 평가 Dataset과 실제 Metric으로 설명할 수 있는 경험
을 만드는 것이 최종 목표다.
특히 마지막에는 다음 질문에 직접 답할 수 있도록 해보려고 한다.
Vector Search만 사용하면 어떤 질문에서 실패하는가?
Chunk 크기가 검색 품질에 실제로 어떤 영향을 주는가?
Keyword Search를 결합하면 어떤 Query가 좋아지는가?
RRF를 적용했을 때 Ranking이 실제로 좋아지는가?
Reranker의 품질 향상이 추가 Latency를 감수할 정도인가?
정답 문서를 찾았는데도 LLM이 틀릴 수 있는 이유는 무엇인가?
Hallucination과 Retrieval 실패를 어떻게 구분할 수 있는가?
질문에 따라 RAG와 DB 조회 중 적절한 Tool을 선택할 수 있는가?
Agent를 추가한 것이 단순 RAG보다 실제로 나은가?
최종 시스템이 좋아졌다는 것을 어떤 평가 결과로 설명할 수 있는가?
이번 프로젝트에서도 결국 기본 원칙은 같다.
Baseline
↓
평가
↓
실패 Case 확인
↓
원인 분석
↓
대안 비교
↓
Human Gate
↓
개선
↓
동일 Dataset 재평가
다음 글에서는 ContentOps Agent가 실제로 어떤 데이터를 가지고 어떤 질문을 처리해야 하는지 정리하기 위해 기능 요구사항과 비기능 요구사항을 정의해보려고 한다.
'PROJECT > Toy Project' 카테고리의 다른 글
| [ContentOps Agent #3] AI 프로젝트에서 Evaluation을 Harness로 사용하는 방법 (0) | 2026.08.15 |
|---|---|
| [ContentOps Agent #2] 요구사항 정의 (0) | 2026.08.15 |
| [Live Event Stream #4] 회고 (0) | 2026.08.15 |
| [Live Event Stream #3] 바이브 코딩 전략 (0) | 2026.08.15 |
| [Live Event Stream #2] 요구사항 정의 (0) | 2026.08.15 |