오늘도 공부
AI 에이전트는 “모델”이 아니라 “운영 시스템”이다 본문

Agent Harness, Loop Engineering, LLMOps, Eval, Tracing, RAG를 한 번에 이해하기
이 글은 업로드된 영어 자동 생성 자막을 바탕으로 핵심 내용을 한국어로 번역·재구성하고, 외부 공개용 브런치 글로 읽히도록 설명과 예제를 보강한 원고입니다. 원문은 AI 에이전트 시스템에서 자주 등장하는 Agent Harness, Loop Engineering, LLMOps, Eval, Tracing, RAG를 하나의 구조로 연결해 설명합니다.
1. 들어가며: 요즘 AI 에이전트 논의가 어려워 보이는 이유
요즘 AI 에이전트 이야기를 따라가다 보면 낯선 단어가 계속 등장합니다. Agent Harness, Loop Engineering, LLMOps, Eval, Tracing, RAG, Memory System 같은 표현입니다. 처음 들으면 각각 독립된 고급 기술처럼 보이지만, 실제로는 하나의 질문으로 모을 수 있습니다.
“거대한 언어 모델을 내가 원하는 방향으로 안정적으로 일하게 하려면 무엇이 필요한가?”
LLM은 매우 강력합니다. 방대한 지식과 언어 능력을 갖고 있고, 코드도 작성하며, 문서를 요약하고, 사람처럼 대화할 수 있습니다. 하지만 LLM 자체는 우리가 원하는 업무 환경, 회사의 규칙, 고객 데이터, 이전 대화, 업무 종료 기준, 실패했을 때의 복구 방식까지 자동으로 알지 못합니다.
그래서 AI 에이전트 시스템을 만들 때 중요한 것은 단순히 “어떤 모델을 쓸 것인가”가 아닙니다. 더 중요한 질문은 다음과 같습니다.
- 에이전트가 어떤 정보를 기억하게 할 것인가?
- 필요한 정보를 어디서 검색하게 할 것인가?
- 어떤 도구를 호출하게 할 것인가?
- 도구 호출을 몇 번까지 허용할 것인가?
- 언제 작업을 멈추고 사용자에게 답하게 할 것인가?
- 에이전트가 잘했는지, 못했는지 어떻게 평가할 것인가?
- 실패했다면 무엇을 고쳐야 하는가?
이 질문들을 시스템적으로 묶은 개념이 바로 Agent Harness입니다. 그리고 그 안에서 에이전트가 반복적으로 생각하고, 도구를 호출하고, 다시 판단하는 구조가 Loop Engineering입니다. 또한 이 전체 시스템을 관찰하고 평가하고 개선하는 운영 체계가 LLMOps입니다.
2. 핵심 요약: 영상 내용의 큰 흐름
원문 자막의 핵심 메시지는 단순합니다.
AI 에이전트는 LLM 하나로 완성되지 않는다. LLM을 원하는 방식으로 작동시키기 위한 기억, 도구, 반복 루프, 종료 조건, 관찰, 평가, 개선 시스템이 함께 있어야 한다.
이 구조를 단계별로 정리하면 다음과 같습니다.
- 사용자가 질문하거나 업무를 요청한다.
- 현재 대화, 시스템 프롬프트, 필요한 메모리들이 작업 메모리로 들어간다.
- LLM이 답변하거나, 필요한 경우 도구를 호출한다.
- 도구 호출 결과를 다시 보고 다음 행동을 결정한다.
- 작업이 충분히 완료되었다고 판단하면 루프를 종료한다.
- 최종 답변을 사용자에게 반환한다.
- 전체 실행 과정을 추적한다.
- 결과가 좋았는지 평가한다.
- 문제가 있으면 프롬프트, 모델 설정, 검색 방식, 도구, 루프 조건을 개선한다.
즉, AI 에이전트 개발은 단순히 “프롬프트 잘 쓰기”가 아닙니다. 점점 더 시스템 설계와 운영의 문제가 됩니다.
3. AI Agent Run: 에이전트 실행 1회란 무엇인가
가장 먼저 이해해야 할 단위는 Agent Run입니다. Agent Run은 사용자의 입력이 들어와서 에이전트의 응답이 나가기까지의 한 번의 실행을 의미합니다.
예를 들어 사용자가 이렇게 묻는다고 해보겠습니다.
“Sam Altman이 OpenAI에서 해임된 시점이 언제였지?”
이때 에이전트는 사용자의 질문, 현재 대화 기록, 시스템 프롬프트를 바탕으로 답변을 생성합니다. 단순한 챗봇이라면 이 정도로 끝날 수 있습니다. 그러나 실제 에이전트 시스템에서는 여기에 여러 종류의 기억과 도구가 붙습니다.
Agent Run을 단순화하면 다음과 같습니다.
사용자 입력
↓
현재 대화 기록 + 시스템 프롬프트 + 관련 메모리
↓
LLM 판단
↓
필요하면 도구 호출
↓
결과를 다시 판단
↓
최종 답변
여기서 중요한 점은 “한 번의 Agent Run 안에서도 LLM 호출과 도구 호출이 여러 번 일어날 수 있다”는 것입니다. 사용자가 보는 것은 하나의 답변이지만, 내부에서는 검색, 계산, 데이터베이스 조회, CRM 확인, 결제 정보 확인 같은 여러 단계가 숨어 있을 수 있습니다.
4. Working Memory: 현재 실행을 위한 작업 메모리
LLM에게 한 번에 전달되는 정보는 무한하지 않습니다. 모델에는 컨텍스트 윈도우가 있고, 그 안에 현재 질문, 최근 대화, 시스템 지시문, 관련 문서, 도구 결과 등이 들어갑니다. 이 묶음을 원문에서는 Working Memory 또는 Context RAM에 가깝게 설명합니다.
사람으로 비유하면 지금 책상 위에 올려놓고 보고 있는 자료입니다. 책장에 있는 모든 책을 동시에 펼쳐놓을 수는 없기 때문에, 지금 문제를 해결하는 데 필요한 자료만 꺼내 놓는 것입니다.
예를 들어 고객지원 AI 에이전트가 있다고 해보겠습니다. 사용자가 이렇게 묻습니다.
“지난달 환불 요청했는데 아직 처리됐나요?”
이 질문에 답하려면 단순한 언어 능력만으로는 부족합니다. 에이전트는 다음 정보를 작업 메모리에 넣어야 합니다.
- 현재 사용자의 고객 ID
- 최근 문의 내역
- 주문 번호
- 환불 요청 상태
- 회사의 환불 정책
- 결제 시스템에서 확인한 실제 환불 처리 여부
이런 정보가 들어와야 에이전트는 그럴듯한 답이 아니라 업무적으로 쓸 수 있는 답을 할 수 있습니다.
5. 세 가지 메모리: Procedural, Semantic, Episodic
원문은 AI 에이전트가 단기 대화만으로는 충분하지 않기 때문에 추가적인 메모리 시스템이 필요하다고 설명합니다. 특히 세 가지 메모리 구분이 중요합니다.
5-1. Procedural Memory: 어떻게 행동해야 하는가
Procedural Memory는 에이전트의 행동 방식과 절차를 담은 기억입니다. 쉽게 말하면 업무 매뉴얼입니다.
예를 들면 다음과 같은 내용입니다.
# 고객지원 에이전트 응대 규칙
1. 고객에게 먼저 공감 표현을 한다.
2. 주문번호가 없으면 주문번호를 요청한다.
3. 환불 가능 기간을 확인한다.
4. 정책상 환불이 불가능하면 대체 보상 옵션을 안내한다.
5. 결제 취소가 필요한 경우 Stripe Refund Tool을 호출한다.
6. 실제 환불 실행 전에는 사용자 확인을 받는다.
최근 AI 개발 생태계에서 말하는 “Skill”도 이 범주에 들어갈 수 있습니다. 특정 업무를 수행하기 위한 절차, 프롬프트, 체크리스트, 도구 사용 규칙이 하나의 파일이나 문서로 정리되고, 에이전트는 필요할 때 그 내용을 읽고 행동합니다.
5-2. Semantic Memory: 오래 유지되는 사실
Semantic Memory는 오래 유지되는 사실 정보입니다. 예를 들어 개인 비서 에이전트라면 다음과 같은 내용을 기억할 수 있습니다.
{
"user_name": "Sean",
"role": "early-stage startup founder",
"company_stage": "pre-seed",
"preferred_tone": "direct and strategic",
"current_goal": "compare startup journey with Sam Altman's early career"
}
이 정보는 현재 대화에만 존재하는 것이 아니라 여러 대화에 걸쳐 유지될 수 있습니다. 사용자가 매번 “나는 초기 스타트업 창업자이고, 이런 목표가 있어”라고 설명하지 않아도 에이전트가 개인화된 답변을 만들 수 있게 해줍니다.
회사 업무 에이전트라면 Semantic Memory에는 다음과 같은 내용이 들어갈 수 있습니다.
- 제품 가격 정책
- 환불 정책
- 배송 정책
- 조직도
- 브랜드 톤앤매너
- 고객 응대 기준
- 자주 발생하는 이슈와 해결 방법
5-3. Episodic Memory: 과거 사건과 대화 기록
Episodic Memory는 시간 순서가 있는 과거 사건의 기록입니다. 쉽게 말해 로그와 히스토리입니다.
예를 들어 고객지원 시스템에서는 다음처럼 저장될 수 있습니다.
[
{
"timestamp": "2026-06-01T10:22:00Z",
"customer_id": "cus_1029",
"event_type": "chat",
"summary": "고객이 제품 불량으로 환불을 요청함",
"status": "refund_requested"
},
{
"timestamp": "2026-06-03T14:12:00Z",
"customer_id": "cus_1029",
"event_type": "payment_check",
"summary": "환불 처리 여부를 결제 시스템에서 확인했으나 미처리 상태였음",
"status": "refund_pending"
}
]
Episodic Memory는 “지난번에 무슨 일이 있었는가?”를 찾는 데 유용합니다. 개인 비서라면 “내가 마지막으로 이직 준비를 한 게 언제였지?” 같은 질문에 답할 수 있습니다. 기업 에이전트라면 “최근 2개월 동안 같은 제품 품질 문제로 불만을 제기한 고객이 누구였지?” 같은 질문에 답할 수 있습니다.
6. Agent Harness: LLM이라는 말을 제어하는 장비
원문에서 가장 중요한 비유는 Harness입니다. Harness는 말을 탈 때 말의 움직임을 제어하기 위해 사용하는 장비입니다. LLM을 강력한 말이라고 보면, Agent Harness는 그 말을 원하는 방향으로 움직이게 하는 제어 장치입니다.
LLM은 강력하지만 확률적으로 다음 단어를 예측하는 시스템입니다. 따라서 아무 장치 없이 쓰면 방향이 흔들릴 수 있습니다. 어떤 때는 과도하게 추론하고, 어떤 때는 필요한 도구를 쓰지 않으며, 어떤 때는 멈춰야 할 시점에 멈추지 못합니다.
그래서 Harness는 다음 구성 요소를 포함합니다.
구성 요소역할
| System Prompt | 에이전트의 역할, 금지사항, 응답 방식 정의 |
| Procedural Memory | 업무 절차와 스킬 정의 |
| Semantic Memory | 오래 유지되는 사실 정보 저장 |
| Episodic Memory | 과거 대화와 사건 로그 저장 |
| Tool Registry | 사용할 수 있는 도구 목록과 호출 방식 정의 |
| Retrieval System | 필요한 기억과 문서를 검색 |
| Loop Controller | 반복 실행과 종료 조건 제어 |
| Guardrails | 위험 행동, 무한 루프, 권한 문제 방지 |
| Tracing | 실행 과정 기록 |
| Evaluation | 결과 품질 평가 |
| LLMOps | 관찰, 진단, 개선, 배포의 운영 체계 |
이 표를 보면 에이전트 개발이 왜 단순한 챗봇 제작과 다른지 알 수 있습니다. 챗봇은 보통 “입력 → 답변”에 가깝지만, 에이전트는 “입력 → 기억 검색 → 계획 → 도구 호출 → 결과 검토 → 반복 → 종료 → 평가 → 개선”으로 움직입니다.
7. Memory Update: 기억은 자동으로 생기지 않는다
중요한 지점이 하나 있습니다. 메모리는 그냥 생기지 않습니다. 기억하려면 저장해야 하고, 저장하려면 업데이트 시스템이 있어야 합니다.
예를 들어 고객지원 에이전트가 매일 수천 건의 대화를 처리한다고 해보겠습니다. 모든 대화를 그대로 장기 기억에 넣으면 비용도 커지고 검색 품질도 떨어질 수 있습니다. 그래서 보통은 다음과 같은 구조를 씁니다.
대화/이벤트 발생
↓
원본 로그 저장
↓
일정 기준마다 요약 또는 추출
↓
중요 사실만 Semantic Memory로 승격
↓
필요할 때 검색해서 Working Memory에 삽입
예를 들어 2,000건의 고객 대화마다 요약 에이전트를 실행해 다음과 같은 사실을 추출할 수 있습니다.
{
"product": "SmartBottle V2",
"issue": "뚜껑 센서 불량",
"frequency": "최근 2,000건 중 184건",
"customer_sentiment": "강한 불만 증가",
"recommended_action": "FAQ 업데이트, 교환 정책 강화, 생산 배치 확인"
}
이렇게 원본 대화 전체를 매번 검색하지 않고, 압축된 사실을 별도로 관리하면 에이전트가 더 빠르고 일관되게 답할 수 있습니다.
8. RAG: 필요한 기억을 검색해 답변에 붙이는 방식
RAG는 Retrieval-Augmented Generation의 약자입니다. 한국어로 옮기면 “검색 증강 생성” 정도입니다. 모델이 자체 지식만으로 답하는 것이 아니라, 외부 데이터베이스나 문서에서 관련 정보를 찾아 컨텍스트에 넣고 답하게 하는 방식입니다.
원문에서는 Semantic Memory와 Episodic Memory의 검색 방식이 다를 수 있다고 설명합니다.
8-1. Semantic Memory 검색
Semantic Memory는 정책, 제품 정보, 사용자 프로필처럼 비교적 안정적인 사실입니다. 이런 정보는 문서 검색이나 벡터 검색으로 찾기 좋습니다.
예시 질문:
“우리 회사의 환불 정책에 따르면 개봉한 제품도 환불 가능한가?”
검색 대상:
- 환불 정책 문서
- 고객지원 매뉴얼
- 예외 처리 규정
8-2. Episodic Memory 검색
Episodic Memory는 시간 순서가 있는 이벤트입니다. 이 경우 단순 벡터 검색만으로는 부족할 수 있습니다. SQL 조회와 의미 검색을 함께 써야 할 때가 많습니다.
예시 질문 1:
“이 고객과 최근 10번 나눈 대화를 보여줘.”
이 경우는 시간 기준 SQL 쿼리로 충분할 수 있습니다.
SELECT *
FROM customer_events
WHERE customer_id = 'cus_1029'
ORDER BY timestamp DESC
LIMIT 10;
예시 질문 2:
“최근 2개월 동안 제품 품질 불만을 말했는데 상담원이 해결하지 못한 대화를 찾아줘.”
이 경우는 시간 필터, 고객 불만 분류, 해결 여부, 의미 검색이 함께 필요합니다.
SELECT *
FROM customer_events
WHERE timestamp >= NOW() - INTERVAL '2 months'
AND status != 'resolved';
그다음 해당 결과에서 “품질 불만”, “고장”, “불량”, “환불 요청”과 의미적으로 가까운 대화를 벡터 검색으로 골라낼 수 있습니다.
요약하면 RAG는 단순히 “문서 검색”이 아닙니다. 에이전트가 지금 판단하는 데 필요한 정보를 외부 기억에서 가져오는 전체 메커니즘입니다.
9. Tool Calling: 에이전트가 실제 업무를 하게 하는 장치
AI 에이전트의 강력함은 답변만 하는 것이 아니라 실제 도구를 호출할 수 있다는 점에서 나옵니다. 예를 들어 다음과 같은 도구가 있을 수 있습니다.
- 캘린더 일정 생성 도구
- CRM 고객 정보 조회 도구
- Stripe 또는 Alipay 결제 조회 도구
- 환불 실행 도구
- 이메일 발송 도구
- 내부 데이터베이스 조회 도구
- 문서 검색 도구
- 코드 실행 도구
사용자가 이렇게 요청한다고 해보겠습니다.
“우리 제품에 불만을 제기한 고객들을 찾아보고, 환불이 안 된 사람들에게 후속 조치를 제안해줘.”
에이전트는 단순 답변으로 끝낼 수 없습니다. 내부적으로는 다음 단계를 거쳐야 합니다.
- CRM에서 최근 고객 불만 내역을 조회한다.
- 불만 유형을 분류한다.
- 환불 요청이 있었는지 확인한다.
- 결제 시스템에서 환불 처리 여부를 확인한다.
- 환불 미처리 고객을 추린다.
- 후속 이메일 초안을 작성한다.
- 실제 환불 실행이 필요한 경우 사용자 승인을 요청한다.
이 과정에서 에이전트는 여러 도구를 반복적으로 호출합니다. 바로 여기서 Loop Engineering이 중요해집니다.
10. Loop Engineering: 언제 반복하고 언제 멈출 것인가
Loop Engineering은 최근 AI 에이전트 논의에서 자주 등장하는 표현입니다. 원문에서는 Loop가 Harness의 일부라고 설명합니다. 이유는 간단합니다. 루프 역시 LLM을 원하는 방식으로 제어하기 위한 장치이기 때문입니다.
에이전트 루프는 대략 다음 구조입니다.
목표 확인
↓
다음 행동 결정
↓
도구 호출 또는 답변 생성
↓
결과 관찰
↓
목표 달성 여부 판단
↓
미완료면 반복
↓
완료면 종료
문제는 LLM에게 너무 많은 자유를 주면 루프가 길어지거나 멈추지 않을 수 있다는 점입니다. 반대로 너무 빨리 멈추면 업무가 미완성 상태로 끝납니다. 따라서 좋은 에이전트 시스템은 “충분히 완료됨”의 기준을 명확히 가져야 합니다.
10-1. 고객 환불 예제
사용자 요청:
“지난 2개월 동안 제품 불만을 제기한 고객을 찾아줘. 환불 요청이 있었는데 처리되지 않은 사람이 있으면 후속 조치를 제안해줘.”
에이전트 루프:
1단계: CRM에서 최근 2개월 불만 고객 조회
2단계: 불만 유형이 제품 품질인 고객 필터링
3단계: 환불 요청 여부 확인
4단계: 결제 시스템에서 환불 완료 여부 확인
5단계: 미처리 고객 목록 생성
6단계: 후속 조치 초안 작성
7단계: 실제 환불 실행 전 사용자 승인 요청
8단계: 최종 요약 답변
여기서 종료 조건은 다음처럼 정의할 수 있습니다.
{
"stop_when": [
"complaint_customers_identified",
"refund_status_checked",
"unresolved_cases_summarized",
"follow_up_actions_drafted",
"dangerous_actions_waiting_for_user_confirmation"
],
"max_tool_calls": 12,
"requires_user_confirmation_before": [
"issuing_refund",
"sending_email",
"changing_customer_status"
]
}
이렇게 종료 조건과 권한 조건을 명확히 정의해야 에이전트가 안전하게 움직입니다.
10-2. 코딩 에이전트 예제
코딩 에이전트를 사용할 때도 루프가 중요합니다. 예를 들어 코딩 에이전트가 파일을 수정하다가 권한 승인이 필요한 상황에서 멈췄다고 해보겠습니다. 사용자는 유튜브를 보다가 30분 뒤에 돌아왔고, 에이전트는 25분 전부터 권한 승인 창에서 멈춰 있었습니다. 이는 루프 설계가 부족한 사례입니다.
개선된 루프는 다음과 같습니다.
권한 요청 발생
↓
사용자 입력 필요 상태로 전환
↓
데스크톱 알림 발송
↓
사용자 승인 대기
↓
승인 후 작업 재개
여기서 중요한 것은 “에이전트가 멈춘 사실을 사용자에게 알려야 한다”는 점입니다. 루프는 단순 반복이 아니라 상태 관리입니다.
11. Guardrails: 에이전트에게 브레이크를 달아야 한다
Loop Engineering에서 Guardrails는 필수입니다. Guardrails는 에이전트가 위험하거나 비효율적인 행동을 하지 않도록 제한하는 규칙입니다.
예를 들어 다음과 같은 규칙이 필요합니다.
guardrails:
max_iterations: 8
max_tool_calls: 15
max_runtime_seconds: 60
require_confirmation:
- send_email
- issue_refund
- delete_record
- update_payment_status
stop_if:
- tool_returns_same_result_three_times
- missing_required_customer_id
- user_goal_is_ambiguous
- cost_estimate_exceeds_limit
Guardrails가 없으면 에이전트는 다음과 같은 문제를 일으킬 수 있습니다.
- 같은 도구를 반복 호출한다.
- 필요 없는 검색을 계속한다.
- 비용이 과도하게 발생한다.
- 사용자의 승인 없이 이메일을 보내거나 환불을 실행한다.
- 실패한 작업을 실패로 인정하지 않고 계속 시도한다.
따라서 에이전트 설계에서 “무엇을 할 수 있는가”만큼 중요한 질문은 “무엇을 하면 안 되는가”입니다.
12. LLMOps: 에이전트 시스템을 운영하는 방법
LLMOps는 Large Language Model Operations의 약자입니다. 전통적인 소프트웨어 운영에서 로그, 모니터링, 테스트, 배포, 장애 대응이 중요하듯이, LLM 기반 시스템에서도 운영 체계가 필요합니다.
원문에서는 LLMOps가 필요한 이유를 이렇게 설명합니다.
에이전트가 실제로 잘 작동하는지 알 수 없기 때문이다.
단순히 사용자가 답변을 받았다고 해서 좋은 실행이라고 볼 수 없습니다. 다음 질문을 봐야 합니다.
- 요청한 작업이 실제로 완료되었는가?
- 필요한 도구가 호출되었는가?
- 잘못된 도구를 호출하지 않았는가?
- 응답 시간이 너무 길지 않았는가?
- 토큰 비용이 과도하지 않았는가?
- 검색된 문서가 적절했는가?
- 최종 답변이 사실에 근거했는가?
- 위험한 행동 전에 사용자 확인을 받았는가?
이런 질문에 답하기 위해 필요한 것이 Tracing과 Eval입니다.
13. Tracing: 에이전트 실행을 나무처럼 기록하기
Tracing은 한 번의 Agent Run 안에서 무슨 일이 일어났는지 기록하는 것입니다. 원문에서는 이를 “tree of events”로 설명합니다.
예를 들어 사용자가 환불 상태를 물었을 때 내부 실행 기록은 다음과 같을 수 있습니다.
{
"run_id": "run_20260630_001",
"user_input": "지난달 환불 요청했는데 처리됐나요?",
"events": [
{
"type": "memory_retrieval",
"source": "episodic_memory",
"query": "user refund request last month",
"latency_ms": 120
},
{
"type": "tool_call",
"tool": "crm_lookup",
"args": {"customer_id": "cus_1029"},
"latency_ms": 340
},
{
"type": "tool_call",
"tool": "payment_refund_status",
"args": {"order_id": "ord_8891"},
"latency_ms": 520
},
{
"type": "llm_response",
"model": "agent-model",
"tokens_input": 3200,
"tokens_output": 420,
"latency_ms": 1800
}
],
"final_status": "completed"
}
Tracing을 하면 다음을 확인할 수 있습니다.
- 어떤 질문이 들어왔는가?
- 어떤 메모리를 검색했는가?
- 어떤 도구를 몇 번 호출했는가?
- 각 단계의 응답 시간은 얼마였는가?
- 토큰은 얼마나 사용했는가?
- 어느 단계에서 실패했는가?
대표적인 관찰 도구로는 LangFuse, LangSmith 같은 도구가 언급됩니다. 중요한 것은 특정 도구명이 아니라, 에이전트 실행을 추적 가능한 구조로 남겨야 한다는 원칙입니다.
14. Eval: 에이전트가 잘했는지 평가하기
Eval은 Evaluation의 줄임말입니다. 에이전트의 결과가 좋은지 평가하는 시스템입니다.
평가는 크게 두 방향으로 나눌 수 있습니다.
14-1. 품질 평가
품질 평가는 최종 답변이 사용자 요구를 만족했는지 보는 것입니다.
예시 평가 기준:
{
"criteria": {
"task_completion": "요청한 작업을 완료했는가?",
"groundedness": "답변이 검색된 근거에 기반하는가?",
"tool_correctness": "적절한 도구를 사용했는가?",
"safety": "위험 작업 전에 확인을 받았는가?",
"clarity": "사용자가 이해하기 쉽게 설명했는가?"
},
"score_scale": "1 to 5"
}
LLM을 평가자로 사용할 수도 있습니다. 예를 들어 평가용 프롬프트는 다음처럼 만들 수 있습니다.
너는 고객지원 AI 에이전트의 실행 결과를 평가하는 심사자다.
다음 사용자 요청, 도구 호출 기록, 최종 답변을 보고 1~5점으로 평가하라.
평가 항목:
1. 요청 완료 여부
2. 근거 기반성
3. 불필요한 도구 호출 여부
4. 정책 준수 여부
5. 사용자에게 필요한 다음 행동 제시 여부
각 항목에 점수와 짧은 이유를 작성하라.
14-2. 시스템 건강도 평가
시스템 건강도 평가는 성능과 비용을 보는 것입니다.
예시 지표:
지표의미
| Latency | 전체 응답 시간 |
| Tool Call Count | 도구 호출 횟수 |
| Token Usage | 입력·출력 토큰 사용량 |
| Retrieval Count | 검색 횟수 |
| Error Rate | 도구 실패율 |
| Loop Iterations | 반복 횟수 |
| User Confirmation Rate | 사용자 확인이 필요한 작업 비율 |
예를 들어 간단한 질문에 매번 거대한 메모리 검색을 수행한다면 응답이 느려지고 비용이 증가합니다. 이 경우 LLMOps 관점에서는 “모든 질문에 RAG를 쓰는 것이 맞는가?”를 다시 봐야 합니다.
15. Diagnosis: 문제가 생겼을 때 어디를 고칠 것인가
Tracing과 Eval을 하면 다음 단계는 Diagnosis입니다. 즉, 어디서 문제가 생겼는지 진단하는 것입니다.
예를 들어 일정 예약 에이전트가 있다고 해보겠습니다. 사용자가 “내일 오후 3시에 미팅 잡아줘”라고 했는데 미팅이 생성되지 않았습니다. 가능한 원인은 여러 가지입니다.
- 캘린더 도구가 호출되지 않았다.
- 도구는 호출됐지만 필요한 참석자 이메일이 없었다.
- 시간대 변환이 잘못됐다.
- 에이전트가 사용자 확인을 기다리다가 멈췄다.
- 시스템 프롬프트에서 일정 생성 권한이 제한돼 있었다.
- 도구 스키마가 변경되었는데 프롬프트가 업데이트되지 않았다.
이때 Tracing이 없다면 “왜 안 됐는지” 알기 어렵습니다. 하지만 실행 기록이 있으면 어떤 단계에서 실패했는지 확인할 수 있습니다.
문제 유형별 수정 방향은 다음과 같습니다.
문제수정 방향
| 도구를 호출하지 않음 | 시스템 프롬프트 또는 계획 프롬프트 수정 |
| 잘못된 도구 호출 | Tool description과 스키마 개선 |
| 검색 결과 부정확 | 임베딩, chunking, reranking, 필터 개선 |
| 응답 지연 | 불필요한 검색 제거, 캐싱, 모델 변경 |
| 토큰 비용 과다 | 메모리 요약, 컨텍스트 축소, 저렴한 모델 분기 |
| 루프 미종료 | max iterations, stop condition 추가 |
| 위험 작업 자동 실행 | confirmation guardrail 추가 |
16. LLMOps Loop: 개선은 다시 에이전트로 돌아간다
LLMOps의 핵심은 관찰에서 끝나지 않는다는 점입니다. 평가와 진단 결과는 다시 에이전트 시스템으로 들어가야 합니다.
Agent Run 실행
↓
Trace 수집
↓
Eval 평가
↓
Diagnosis 진단
↓
Prompt / Model / Retrieval / Tool / Loop 수정
↓
새 버전 배포
↓
다시 Agent Run 실행
이 구조가 반복되면 에이전트는 점점 더 나은 시스템이 됩니다. 여기서 중요한 것은 “모델이 스스로 좋아진다”는 뜻이 아닙니다. 운영자가 관찰 가능한 데이터를 바탕으로 시스템 구성 요소를 개선한다는 뜻입니다.
개선 대상은 다음과 같습니다.
- System Prompt
- Tool Description
- Retrieval Query
- Memory Update Rule
- Summarizer Agent
- Model Selection
- Temperature 등 모델 파라미터
- Loop Stop Condition
- Guardrails
- Eval Rubric
즉, AI 에이전트의 품질은 모델 하나가 아니라 전체 운영 루프의 품질에 의해 결정됩니다.
17. 간단한 구현 예제: 고객지원 에이전트 아키텍처
아래는 실제 구현을 상상할 수 있는 단순한 의사코드입니다.
class CustomerSupportAgent:
def run(self, user_input, user_id):
trace = Trace(run_id=create_run_id())
# 1. 현재 사용자와 관련된 메모리 검색
semantic_context = retrieve_semantic_memory(user_input)
episodic_context = retrieve_recent_customer_events(user_id, user_input)
trace.add("memory_retrieval", {
"semantic_count": len(semantic_context),
"episodic_count": len(episodic_context)
})
# 2. 작업 메모리 구성
working_memory = build_context(
system_prompt=CUSTOMER_SUPPORT_SYSTEM_PROMPT,
user_input=user_input,
semantic_context=semantic_context,
episodic_context=episodic_context,
tools=TOOL_DESCRIPTIONS
)
# 3. 루프 실행
for step in range(MAX_ITERATIONS):
action = llm_decide_next_action(working_memory)
trace.add("llm_decision", action)
if action.type == "final_answer":
trace.add("final_answer", action.content)
return action.content
if action.type == "tool_call":
if requires_confirmation(action.tool):
return ask_user_confirmation(action)
result = call_tool(action.tool, action.args)
trace.add("tool_call", {
"tool": action.tool,
"args": action.args,
"result_summary": summarize(result)
})
working_memory.add_tool_result(result)
# 4. 루프 초과 시 안전 종료
trace.add("stopped", "max_iterations_exceeded")
return "작업을 계속 진행하려면 추가 확인이 필요합니다. 지금까지 확인한 내용을 요약해드리겠습니다."
이 코드는 단순하지만 Agent Harness의 핵심을 거의 모두 담고 있습니다.
- 메모리 검색
- 작업 메모리 구성
- LLM 판단
- 도구 호출
- 반복 루프
- 종료 조건
- 사용자 확인
- 실행 추적
실제 제품에서는 여기에 권한 관리, 비용 제한, 모델 라우팅, 오류 복구, 평가 시스템, 대시보드가 붙습니다.
18. 스타트업이나 개인 개발자가 바로 적용할 수 있는 최소 구조
처음부터 거대한 에이전트 플랫폼을 만들 필요는 없습니다. 작은 서비스라면 다음 정도로 시작할 수 있습니다.
18-1. 최소 구성
Frontend
↓
API Server
↓
Agent Runner
↓
LLM Provider
↓
Postgres / Supabase
↓
Vector Store
↓
Tracing Table
↓
Eval Script
18-2. 데이터베이스 테이블 예시
CREATE TABLE agent_runs (
id UUID PRIMARY KEY,
user_id TEXT,
input TEXT,
output TEXT,
status TEXT,
latency_ms INTEGER,
token_input INTEGER,
token_output INTEGER,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE agent_events (
id UUID PRIMARY KEY,
run_id UUID REFERENCES agent_runs(id),
event_type TEXT,
payload JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE memories (
id UUID PRIMARY KEY,
user_id TEXT,
memory_type TEXT,
content TEXT,
embedding VECTOR,
importance INTEGER,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
18-3. 운영 대시보드에서 봐야 할 항목
- 최근 실행 실패율
- 평균 응답 시간
- 평균 도구 호출 수
- 평균 토큰 비용
- 가장 많이 실패한 도구
- 검색 결과가 없었던 질문
- 사용자 확인이 필요한 작업 비율
- Eval 점수 하락 케이스
이 정도만 있어도 “에이전트가 왜 이상하게 답했는지”를 감으로 추측하는 단계에서 벗어날 수 있습니다.
19. RAG와 Memory를 구분해서 설계해야 하는 이유
많은 사람이 RAG와 Memory를 같은 것으로 생각하지만, 둘은 다릅니다.
RAG는 필요한 정보를 검색해서 답변에 넣는 기술적 방식입니다. Memory는 무엇을 기억할지, 얼마나 오래 기억할지, 어떤 구조로 기억할지에 대한 제품·시스템 설계입니다.
예를 들어 회사 정책 문서를 검색하는 것은 RAG입니다. 그러나 “이 고객은 지난 세 번 모두 배송 지연에 불만을 제기했다”를 장기적으로 관리하는 것은 Memory 설계입니다. 둘은 연결되지만 같은 개념은 아닙니다.
정리하면 다음과 같습니다.
구분RAGMemory
| 핵심 질문 | 무엇을 검색할 것인가 | 무엇을 기억할 것인가 |
| 대상 | 문서, 지식베이스, 로그 | 사용자, 사건, 절차, 사실 |
| 방식 | 벡터 검색, 키워드 검색, rerank | 저장, 요약, 승격, 삭제, 갱신 |
| 목적 | 답변 근거 제공 | 에이전트의 지속성 확보 |
좋은 에이전트 시스템은 RAG만 붙인다고 완성되지 않습니다. 어떤 정보를 Semantic Memory로 유지할지, 어떤 이벤트를 Episodic Memory로 남길지, 어떤 절차를 Procedural Memory로 관리할지까지 설계해야 합니다.
20. 브런치 독자를 위한 비유: AI 에이전트는 신입 직원과 비슷하다
AI 에이전트를 신입 직원에 비유하면 이해하기 쉽습니다.
LLM은 똑똑한 신입 직원입니다. 지식도 많고 문서도 잘 씁니다. 하지만 회사의 실제 업무 방식은 모릅니다. 고객 데이터도 모릅니다. 결제 시스템에 접근하는 법도 모릅니다. 어떤 경우에 팀장 승인을 받아야 하는지도 모릅니다.
그래서 신입 직원에게 필요한 것은 다음과 같습니다.
- 업무 매뉴얼: Procedural Memory
- 회사와 제품에 대한 기본 지식: Semantic Memory
- 고객과 나눈 이전 대화 기록: Episodic Memory
- 사내 시스템 접근 권한: Tool Calling
- 업무 진행 체크리스트: Loop Engineering
- 위험 작업 승인 규칙: Guardrails
- 업무 일지: Tracing
- 성과 평가: Eval
- 교육과 개선 프로세스: LLMOps
결국 AI 에이전트를 만든다는 것은 똑똑한 신입 직원에게 업무 환경, 권한, 규칙, 평가 체계를 제공하는 일과 비슷합니다.
21. 실제 적용 예제 1: 한국어 교육 플랫폼 AI 튜터
한국어 학습자를 위한 AI 튜터를 만든다고 해보겠습니다. 단순 챗봇이라면 학습자가 질문할 때마다 답을 해줄 수 있습니다. 하지만 에이전트형 튜터라면 다음이 가능해야 합니다.
필요한 메모리
{
"semantic_memory": [
"학습자는 초급 2단계이다",
"현재 교재는 즐거운 한국어 초급2이다",
"학습자는 조사 은/는과 이/가를 자주 헷갈린다"
],
"episodic_memory": [
"2026-06-10: -아/어 보다 연습에서 오류 4회",
"2026-06-15: 음식점 주문 대화 연습 완료",
"2026-06-20: 과거형 활용에서 받침 있는 동사 오류 발생"
],
"procedural_memory": [
"초급자에게는 문법 용어를 최소화한다",
"예문은 짧고 생활 상황 중심으로 제시한다",
"정답을 바로 주기보다 한 번 더 시도하게 한다"
]
}
루프 설계
학습자 답변 입력
↓
오류 유형 분석
↓
이전 오류 기록 검색
↓
현재 수준에 맞는 힌트 제공
↓
학습자 재시도
↓
정답 여부 확인
↓
오류 기록 업데이트
↓
다음 연습 추천
종료 조건
- 학습자가 정답을 맞혔다.
- 학습자가 3회 이상 틀려서 설명 모드로 전환한다.
- 같은 오류가 반복되어 복습 과제로 저장한다.
- 수업 시간이 종료되었다.
이렇게 설계하면 AI 튜터는 단순 답변기가 아니라 학습 이력을 바탕으로 적응하는 교육 에이전트가 됩니다.
22. 실제 적용 예제 2: 블록체인 지갑 고객지원 에이전트
블록체인 지갑 앱의 고객지원 에이전트를 만든다고 해보겠습니다. 이 에이전트는 일반 상담보다 더 강한 Guardrails가 필요합니다. 지갑, 서명, 트랜잭션, 자산과 관련된 작업은 위험할 수 있기 때문입니다.
가능한 도구
- 지갑 연결 상태 조회
- 트랜잭션 해시 조회
- 토큰 잔액 조회
- 네트워크 상태 조회
- FAQ 검색
- 고객 티켓 생성
금지 또는 확인 필요 작업
never_do:
- ask_for_private_key
- ask_for_seed_phrase
- sign_transaction_without_user_action
- promise_recovery_of_lost_assets
require_confirmation:
- create_support_ticket
- send_transaction_guide
- change_security_setting
예시 응답 흐름
사용자:
“토큰을 보냈는데 지갑에 안 보여요.”
에이전트:
- 네트워크와 토큰 종류를 묻는다.
- 트랜잭션 해시가 있으면 조회한다.
- 컨트랙트 주소가 맞는지 확인한다.
- 지갑 UI에 토큰 추가가 필요한지 확인한다.
- 절대 개인키나 시드 문구를 요구하지 않는다.
- 해결되지 않으면 지원 티켓을 생성할지 사용자에게 확인한다.
이런 시스템은 단순 RAG보다 훨씬 더 정교한 Harness가 필요합니다.
23. 실제 적용 예제 3: 뉴스 자동화 에이전트
매일 블록체인 뉴스를 수집해 요약하고 숏츠 대본을 만드는 자동화 에이전트를 생각해볼 수 있습니다.
에이전트 루프
정해진 시간에 실행
↓
뉴스 소스 수집
↓
중복 기사 제거
↓
중요도 평가
↓
핵심 이슈 5개 선정
↓
각 이슈의 근거 링크 저장
↓
브리핑 글 작성
↓
숏츠 대본 생성
↓
썸네일 문구 생성
↓
사람 검수 대기
Eval 기준
- 최신성이 충분한가?
- 출처가 명확한가?
- 과장된 표현이 없는가?
- 투자 조언처럼 보이지 않는가?
- 숏츠 대본이 60초 안에 읽히는가?
- 제목이 자극적이지만 허위는 아닌가?
이 예제에서 중요한 것은 자동 발행보다 검수 가능한 자동화입니다. 에이전트가 많은 일을 처리하되, 민감한 최종 발행은 사람이 확인하도록 루프를 설계할 수 있습니다.
24. 이 영상의 핵심을 한 문장으로 요약하면
AI 에이전트의 본질은 LLM에게 일을 시키는 것이 아니라, LLM이 기억을 검색하고 도구를 사용하고 반복 작업을 수행하고 스스로 멈추며, 그 모든 실행을 추적·평가·개선할 수 있게 만드는 운영 구조를 설계하는 것이다.
이 관점에서 보면 Agent Harness, Loop Engineering, LLMOps, Eval, Tracing, RAG는 따로 떨어진 유행어가 아닙니다. 하나의 에이전트 시스템을 구성하는 서로 다른 층위입니다.
- Harness는 전체 제어 구조입니다.
- Memory는 에이전트가 참조할 맥락입니다.
- RAG는 필요한 정보를 검색하는 방식입니다.
- Tool Calling은 실제 업무 수행 능력입니다.
- Loop Engineering은 반복과 종료를 설계하는 방식입니다.
- Guardrails는 안전장치입니다.
- Tracing은 실행 기록입니다.
- Eval은 품질 평가입니다.
- LLMOps는 이 모든 것을 운영하고 개선하는 체계입니다.
25. 개발자를 위한 체크리스트
AI 에이전트를 만들기 전에 다음 질문에 답해보면 좋습니다.
목적 정의
- 이 에이전트는 답변만 하는가, 실제 업무도 수행하는가?
- 업무 완료의 기준은 무엇인가?
- 사용자의 확인이 필요한 행동은 무엇인가?
메모리 설계
- 어떤 정보를 장기 기억으로 저장할 것인가?
- 어떤 정보는 저장하면 안 되는가?
- 오래된 기억은 어떻게 갱신하거나 삭제할 것인가?
- 대화 로그를 언제 요약할 것인가?
검색 설계
- 어떤 질문에 RAG를 사용할 것인가?
- 어떤 질문은 모델 자체 지식으로 충분한가?
- 검색 결과가 너무 많을 때 어떻게 줄일 것인가?
- 시간 기준 검색과 의미 검색을 어떻게 결합할 것인가?
도구 설계
- 에이전트가 사용할 수 있는 도구는 무엇인가?
- 각 도구의 입력과 출력 스키마는 명확한가?
- 실패했을 때 재시도할 것인가, 사용자에게 물을 것인가?
- 비용이 큰 도구 호출은 제한되어 있는가?
루프 설계
- 최대 반복 횟수는 몇 번인가?
- 같은 결과가 반복되면 멈추는가?
- 사용자 입력이 필요한 상태를 감지하는가?
- 종료 조건이 명확한가?
평가 설계
- 좋은 답변의 기준은 무엇인가?
- 실패한 실행을 어떻게 수집할 것인가?
- Eval 점수는 어디에 저장할 것인가?
- 개선된 프롬프트를 어떻게 배포할 것인가?
26. 마무리: AI 에이전트 시대의 경쟁력은 운영 설계에 있다
LLM의 성능은 계속 좋아지고 있습니다. 하지만 실제 서비스에서 차이를 만드는 것은 모델 성능만이 아닙니다. 같은 모델을 쓰더라도 어떤 메모리를 붙이는지, 어떤 도구를 연결하는지, 어떤 루프를 설계하는지, 어떤 평가 체계를 운영하는지에 따라 결과는 크게 달라집니다.
앞으로의 AI 제품 개발은 “모델을 호출하는 앱”에서 “에이전트를 운영하는 시스템”으로 이동할 가능성이 큽니다. 이때 필요한 역량은 프롬프트 작성 능력뿐만 아니라 시스템 설계, 데이터 설계, 관찰 가능성, 평가 자동화, 안전장치 설계입니다.
AI 에이전트를 만들고 있다면 먼저 거창한 프레임워크부터 찾기보다 다음 질문에서 시작하는 것이 좋습니다.
“내 에이전트는 무엇을 기억해야 하고, 어떤 도구를 써야 하며, 언제 멈춰야 하고, 어떻게 평가받아야 하는가?”
이 질문에 답할 수 있다면 Agent Harness, Loop Engineering, LLMOps라는 용어도 더 이상 어렵게 느껴지지 않을 것입니다. 그것들은 결국 하나의 목표를 향하고 있습니다.
LLM을 예측 불가능한 답변 생성기가 아니라, 관찰 가능하고 개선 가능한 업무 시스템으로 만드는 것.
부록 A. 용어 사전
용어쉬운 설명
| Agent Run | 사용자 입력부터 최종 응답까지 한 번의 에이전트 실행 |
| Working Memory | 현재 실행에서 LLM에게 전달되는 임시 컨텍스트 |
| Procedural Memory | 에이전트가 어떻게 행동해야 하는지에 대한 절차 기억 |
| Semantic Memory | 오래 유지되는 사실 정보 |
| Episodic Memory | 시간 순서가 있는 과거 대화와 사건 기록 |
| Agent Harness | LLM을 원하는 방향으로 제어하기 위한 전체 시스템 장치 |
| RAG | 외부 정보를 검색해 답변 생성에 활용하는 방식 |
| Tool Calling | 에이전트가 외부 도구나 API를 호출하는 기능 |
| Loop Engineering | 에이전트가 반복적으로 판단하고 도구를 호출하며 종료하는 구조 설계 |
| Guardrails | 위험 행동, 무한 루프, 권한 문제를 막는 안전장치 |
| Tracing | 실행 과정 전체를 이벤트 단위로 기록하는 것 |
| Eval | 에이전트 결과를 평가하는 시스템 |
| LLMOps | LLM 기반 시스템을 관찰, 평가, 진단, 개선, 배포하는 운영 체계 |
'AI > 추천 오픈소스' 카테고리의 다른 글
| Flue : 하네스 AI 에이전트 (0) | 2026.06.30 |
|---|---|
| Ornith-1.0: 코딩 에이전트가 스스로 ‘일하는 방식’까지 학습하기 시작했다 (0) | 2026.06.27 |
| mattpocock/skills 에 대한 자세한 설명 (0) | 2026.06.25 |
| Loop 방식의 에이전트 (Loom) (0) | 2026.06.23 |
| AI 코딩 에이전트가 코드를 너무 많이 쓴다면: Ponytail (0) | 2026.06.19 |
