Ensuring AI Agent Reliability: From Hallucination Prevention to Exception Handling — A Practical Python Code Guide
In the previous episode, we looked at how AI agents are evolving beyond simple chatbots into “intelligent workflows” that carry out complex tasks. An agent’s potential is unlimited, but it is just as easy to hit the wall of reliability. You have probably all had the experience of something that looks perfect in theory but keeps producing off-the-wall results once you actually ship it.
AI agent reliability cannot be secured with a simple “write your prompts carefully” guideline. Like a car’s seatbelt or airbag, defensive mechanisms (guardrails) that are robustly designed at the code level are essential.
The goal of this article is to turn the abstract idea of “reliability” into concrete Python code blocks you can immediately test and apply in your development environment. Let’s move beyond theory and look at practical code that makes agents more resilient.
Implementing a Guardrail to Verify the Truthfulness of Search Results
The most common problem is hallucination. Even with RAG (retrieval-augmented generation), retrieved documents may not fit the context, or the LLM may misinterpret the retrieved information and draw the wrong conclusion.
Simply stuffing search results into a prompt and instructing “answer based on this” is equivalent to offloading verification onto the LLM. That is very dangerous.
💡 Key comparison: Prompt instructions vs. code-based validation
| Category | Simple prompt instruction (“Based on the retrieved information…”) | Code-based validation logic (Guardrail) |
|---|---|---|
| How it works | Relies on the LLM’s reasoning ability | Forced checks via developer-defined conditionals (if/else) |
| Reliability | Low (the LLM may violate the rules) | Very high (catches errors at compile time / runtime) |
| Best suited for | Draft generation, idea exploration | Finalizing answers, validating business logic |
In a real service, you absolutely need a layer that validates in code whether the retrieved information satisfies specific conditions. For example, if the rule is “you must only use data from 2023 onward,” you should filter in code instead of leaving it to the LLM.
The following is an example Guardrail function that takes search results (Context) and checks whether they satisfy a specific business rule (e.g., a date range).
from datetime import datetime
def validate_context_by_date(context_chunks: list[str], required_year: int) -> bool:
"""
검색된 문서 청크들이 필수 연도 조건을 만족하는지 검증하는 Guardrail 함수.
"""
print("--- [Guardrail] Context 데이터 검증 시작 ---")
valid_count = 0
for i, chunk in enumerate(context_chunks):
# 간단한 날짜 패턴 매칭을 가정합니다. 실제로는 정교한 NLP 파싱이 필요합니다.
if f"{required_year}" in chunk:
print(f"✅ 청크 {i+1}: {required_year}년 정보 발견. 유효함.")
valid_count += 1
else:
print(f"❌ 청크 {i+1}: {required_year}년 정보가 없어 필터링됨.")
# 최소한 2개 이상의 유효한 정보가 있어야 다음 단계로 진행한다고 가정
if valid_count >= 2:
print("✅ 검증 완료: 최소 요구 조건 충족. 에이전트 실행 허용.")
return True
else:
print("🛑 검증 실패: 필수 정보 부족. 사용자에게 재요청 필요.")
return False
# 사용 예시:
context_data = [
"2022년의 시장 동향은...",
"2023년 AI 기술 발전은 폭발적이었다.",
"2024년 전망은 밝다."
]
can_proceed = validate_context_by_date(context_data, required_year=2023)A State Management Pattern That Doesn’t Lose Conversation Context
When an agent goes through multi-step conversations, it can forget the context of the initial conversation, or the order of information the user wants can get tangled. This is a state-management problem.
Frameworks like LangChain provide a Memory component, but simply storing things in memory is not enough. As conversations get longer, the memory itself grows too large, increasing cost and diluting key information.
The solution is summary-based memory management. When conversation history reaches a certain length, you have the LLM produce a core summary of the entire conversation record and use that summary as the context for the next step. This is the most stable approach.
# 가상의 LangChain 구조를 가정합니다.
def summarize_and_manage_memory(chat_history: list[str], max_tokens: int) -> str:
"""대화 기록을 요약하여 다음 단계에 전달할 핵심 메모리를 생성합니다."""
# 1. 대화 기록을 요약하는 프롬프트를 구성합니다.
summary_prompt = f"다음 대화 기록을 바탕으로, 사용자가 가장 중요하게 생각하는 핵심 주제 3가지만 간결하게 요약해 주세요. (최대 {max_tokens} 토큰 분량)"
# 2. LLM 호출 (실제로는 LLM API 호출이 들어갑니다.)
# summary = llm_call(summary_prompt + "\n" + "\n".join(chat_history))
# 시뮬레이션된 결과
summary = "사용자는 A 기능의 가격 정책과 B 기능의 기술적 구현 가능성에 대해 주로 문의했습니다. 다음 단계에서는 이 두 가지에 대한 비교 분석이 필요합니다."
print(f"✅ 메모리 관리 성공: {summary}")
return summary
# 사용 예시
history = ["사용자: A 기능 가격은요?", "AI: 월 10만원입니다.", "사용자: B 기능은 언제쯤 가능할까요?"]
new_memory = summarize_and_manage_memory(history, 500)🚨 Exception Handling: Preparing for Failure Scenarios
The most important piece is exception handling. Every API call or external service integration can fail.
def execute_api_call_with_retry(endpoint: str, payload: dict, max_retries: int = 3):
"""API 호출을 시도하고, 실패 시 지수 백오프(Exponential Backoff)를 사용하여 재시도합니다."""
for attempt in range(max_retries):
try:
print(f"➡️ 시도 중: {endpoint} (시도 {attempt + 1}/{max_retries})")
# 실제 API 호출 로직 (requests.post(endpoint, json=payload))
# 시뮬레이션: 3번째 시도에서 성공한다고 가정
if attempt >= 2:
return {"status": "SUCCESS", "data": "데이터를 성공적으로 가져왔습니다."}
else:
raise ConnectionError("네트워크 연결 오류 발생")
except ConnectionError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # 1초, 2초, 4초...
print(f"⚠️ 실패: {e}. {wait_time}초 후 재시도합니다.")
import time; time.sleep(wait_time)
else:
print("❌ 모든 재시도 실패. 작업을 중단합니다.")
return {"status": "FAILED", "error": f"최종 실패: {e}"}
return {"status": "FAILED", "error": "알 수 없는 오류"}
# 실행 예시
result = execute_api_call_with_retry("/api/data", {"query": "latest"})
print(f"\n최종 결과: {result}")💡 Summary and Core Principles
- Guardrail: Do not blindly trust LLM output. Always force structured data with regular expressions or separate validation logic.
- State Management: To avoid losing conversation context, periodically summarize conversation history and keep only core memory.
- Resilience: You must implement retry logic and exponential backoff to prepare for network errors or API rate limits.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.