Agent Loop
한번 묻고 끝나지 않는 일, 현업의 일은 보통 여러 단계이다. 행동 - 결과보고 - 다음행동 의 반복하는 구조가 Agent Loop.
one-shot 질문하나, 도구하나, 답하나 깔끔한 원샷은 복합적인 질문에서 한번에 끝나질못해 결과를 봐야 행동을 이어할 수가있다. Agent Loop는 단계적 추론 CoT, 도구호출의 Function Calling, 여러도구중 선택하는 Tool 시스템, 결정 - 실행 - 결과전달의 수동루프가 모여있는것을 while루프로 묶는것.
https://standout.tistory.com/1908
CoT란? Chain of Thought 프롬프트 방법 (" 단계적으로 생각하고 마지막에 최종 답을 제시해.")
Chain of Thought 생각의 사슬 CoTLM이 복잡한 문제를 해결할 때 단계적으로 추론하도록 유도하는 프롬프팅 기법" 단계적으로 생각하고 마지막에 최종 답을 제시해."https://standout.tistory.com/1875 프롬프트
standout.tistory.com
https://standout.tistory.com/1910
Function Calling이란? - 수동루프/자동실행 (feat.Docstring)
Function CallingFunction Calling은 LLM이 "이 함수를 호출하면 좋겠다"라고 판단하면 개발자가 만든 함수를 실행하는 기능 def get_weather(city): 함수를 개발했다면 사용자가 '서울날씨알려줘'라했을때 LLM이
standout.tistory.com
https://standout.tistory.com/1907
MCP란? Model Context Protocol: 사용자를 위한 서버가 아니라 AI를 위한 서버
MCP Model Context ProtocolLLM이 외부도구 Tool, 데이터 Data, 시스템 System 과 표준 방식으로 연결하기 위한 프로토콜.AI가 프로그램과 대화하기 위한 공통 언어. 기존의 서비스마다 연결 방식이 모두 달라
standout.tistory.com
https://standout.tistory.com/140
반복문 for와 while (feat. continue & break)
for문과 while모두 반복해서 돌리는 코드다. 그중 for문은 조건이 맞는것들만, while은 조건이 충족(참, true)일때 반복하는데 for문의 조건이 만약 비어있다면 사실 while(true)과 같다고 하겠다. for for(;;)
standout.tistory.com
사용자 요청
↓
Reasoning
(무엇을 해야 하지?)
↓
Tool 선택
↓
Function Calling
↓
결과 확인
↓
아직 해야 할 일이 있는가?
↓
Yes ───────────────┐
↓ │
다음 Tool 호출 │
↓ │
결과 확인───────────┘
↓
No
↓
최종 답변
while True:
# 1. LLM이 다음 행동 결정
action = llm(messages, tools)
# 2. 더 이상 Tool이 필요 없으면 종료
if action.type == "final_answer":
print(action.content)
break
# 3. Tool 실행
result = run_tool(action.name, action.arguments)
# 4. 결과를 LLM에게 전달
messages.append({
"role": "tool",
"content": result
})
ReAct 패턴
Reason, Act의 합성어, 모델이 Thought, Action, Obervation을 거치고 관찰결과를 다음입력으로 되돌려 반복한다.
While True는 무한루프의 위험이있고 토큰을 끝없이 태움으로 while True 대신 MAX_STEPS, max_step을 둔다 .
보통 5~10을 두나 작업의 성격에 맞게 정한다. 재고확인 같은 2~3 스탭에는 6정도가 넉넉하다.
추가로 모델이 진전없이 도구명 인자를 여러번 수행하지않도록 중복 호출을 감지한다.
MAX_STEPS = 6
messages = [{"role": "user", "content": user_question}]
# 중복 호출 감지용
visited = set()
for step in range(MAX_STEPS):
# 1. LLM이 다음 행동 결정
response = llm(messages, tools)
# 2. 최종 답변이면 종료
if response.type == "final_answer":
print(response.content)
break
# 3. 같은 Tool + 같은 인자 반복 호출 방지
tool_key = (
response.tool_name,
tuple(sorted(response.arguments.items()))
)
if tool_key in visited:
print("동일한 Tool을 반복 호출하여 종료합니다.")
break
visited.add(tool_key)
# 4. Tool 실행
result = run_tool(
response.tool_name,
response.arguments
)
# 5. Observation 추가
messages.append({
"role": "tool",
"content": result
})
else:
print("최대 반복 횟수를 초과했습니다.")
Trimming과 Conversation Summarization
ReAct루프는 매 스탭마다 관찰결과를 history에 덧붙임으로 메세지와 토큰이 게속 불어난다.
이는 비용, 지연이 됨으로 오래된 기록을 잘라내는 트리밍이 필요하다. 이때 첫 질문 즉 원래 목표는 반드시 보존해 모델이 목표를 잊지않도록 한다. 오래된 중간 기록은 대개 최종 판단에 덜 주요함으로 최근 몇개만 남기고 잘라낸다.
더 정교한 방법으로는 오래된 대화를 요약해서 압축하는 기법도 있다.
MAX_STEPS = 6
MAX_HISTORY = 10 # 최근 10개 메시지만 유지
messages = [
{"role": "user", "content": user_question}
]
for step in range(MAX_STEPS):
# LLM 호출
action = llm(messages)
# 최종 답변이면 종료
if action.type == "final_answer":
print(action.content)
break
# Tool 실행
result = run_tool(
action.tool_name,
action.arguments
)
# Observation 추가
messages.append({
"role": "tool",
"content": result
})
# History Trimming
if len(messages) > MAX_HISTORY:
messages = [messages[0]] + messages[-9:]
MAX_HISTORY = 10
if len(messages) > MAX_HISTORY:
# 오래된 대화
old_messages = messages[:-5]
# 최근 대화
recent_messages = messages[-5:]
# 오래된 내용을 LLM으로 요약
summary = llm(
"다음 대화를 핵심만 5줄 이내로 요약해줘.",
old_messages
)
# 요약 + 최근 대화만 유지
messages = [
{
"role": "system",
"content": f"대화 요약:\n{summary}"
}
] + recent_messages
'이론' 카테고리의 다른 글
| LangGraph와 StateGraph(State, Node, Edge) (0) | 2026.07.15 |
|---|---|
| Agent와 Workflow (0) | 2026.07.15 |
| Function Calling이란? - 수동루프/자동실행 (feat.Docstring) (0) | 2026.07.14 |
| Self-Consistency(자기 일관성)이란? (feat.Verify() 프롬프트 기법) (0) | 2026.07.14 |
| CoT란? Chain of Thought, Reasoning Prompt 프롬프트 방법 (" 단계적으로 생각하고 마지막에 최종 답을 제시해.") (0) | 2026.07.14 |