나는 축구 케이크를 구웠고, 그것이 AI 에이전트 구축에 대해 가르쳐 주었다
소개
저는 최근에 축구 케이크를 구웠고, 이를 통해 AI 에이전트가 레이어드 디저트처럼 작동한다는 것을 깨달았습니다. 여기서는 맛, 몰드, 아이싱이 에이전시 설계와 어떻게 매핑되는지 보여드립니다.
아래 코드 예시는 사용자의 목표를 실행 가능한 단계로 나누고, 사용자 정의 도구 또는 LLM 추론을 사용해 이를 실행하도록 설계되었습니다. LLM이 만든 계획 출력에서 번호가 매겨진 단계를 추출하기 위해 정규식을 사용하고, search 또는 compute와 같은 키워드와 일치시키면 해당 도구를 호출하고, 일치하지 않을 경우 LLM 추론으로 대체합니다.
맞춤형 케이크가 맛, 구조, 장식의 레이어를 갖듯, AI 에이전트도 자체 스택을 가지고 있습니다.
이 에이전트는 llama‑3 LLM 모델(Ollama를 통해)과 두 개의 간단한 사용자 정의 도구를 사용합니다:
search_tool()– 검색 엔진을 시뮬레이션하여 모의 결과를 반환합니다.compute_tool()– 계산 작업을 시뮬레이션하여 자리표시자 결과를 반환합니다.
기본 모델(“스폰지 레이어”)은 LLM을 통한 기본 추론을 담당합니다.
Ollama LLM 래퍼
import requests
import json
class OllamaLLM:
def __init__(self, model="llama3"):
self.model = model
def __call__(self, prompt: str) -> str:
"""Send a prompt to a local Ollama instance."""
resp = requests.post(
"http://localhost:11434/api/generate",
json={"model": self.model, "prompt": prompt, "stream": False}
)
text = json.loads(resp.text).get("response", "")
return text
기본 에이전트
class AgentCore:
def __init__(self, llm):
self.llm = llm
def reason(self, prompt):
return self.llm(prompt)
로컬 도구 (아이싱 및 장식)
def search_tool(query: str) -> dict:
return {
"tool": "search",
"query": query,
"results": [
{"title": "Top NFL QBs 2024", "eff": 98.1},
{"title": "Quarterback Rankings", "eff": 95.6},
],
}
def compute_tool(task: str) -> dict:
return {
"tool": "compute",
"task": task,
"result": 42, # placeholder result
}
단계‑파싱 정규식
import re
# Detect common LLM step styles:
# 1. Do X
# 1) Do X
# Step 1: Do X
# **Step 1:** Do X
# - Step 1: Do X
# ### Step 1
# Step One:
STEP_REGEX = re.compile(
r"(?:^|\s)(?:\*\*)?(?:Step\s*)?(\d+)[\.\):\- ]+(.*)", re.IGNORECASE
)
구조화된 에이전트 (프롬프트 로직 및 도구 실행)
class StructuredAgent(AgentCore):
def parse_steps(self, plan: str):
"""Extract step lines starting with numbers."""
lines = plan.split("\n")
steps = []
for line in lines:
match = STEP_REGEX.search(line.strip())
if match:
cleaned = match.group(2).strip()
steps.append(cleaned)
return steps
def execute_step(self, step: str):
step_lower = step.lower()
if "search" in step_lower:
return search_tool(step)
if "calculate" in step_lower or "compute" in step_lower:
return compute_tool(step)
# fallback: let the model reason
return self.reason(step)
def run(self, goal: str):
PLAN_PROMPT = f"""You are a task decomposition engine.
Your ONLY job is to break the user's goal into a small set of concrete, functional steps.
Your outputs MUST stay within the domain of the user’s goal.
If the goal references football, metrics, or sports, remain in that domain only.
RULES:
- Only return steps directly needed to complete the user’s goal.
- Do NOT invent topics, examples, reviews, or unrelated domains.
- Do NOT expand into full explanations.
- No marketing language.
- No creative writing.
- No assumptions beyond the user's exact goal.
- No extra commentary.
FORMAT:
1. <short step>
2. <short step>
3. <short step>
User goal: "{goal}"
"""
plan = self.llm(PLAN_PROMPT)
steps = self.parse_steps(plan)
outputs = []
for step in steps:
outputs.append({
"step": step,
"output": self.execute_step(step)
})
return outputs
사용자‑대면 에이전트 (포맷된 출력 레이어)
class FinalAgent(StructuredAgent):
def respond(self, goal: str):
results = self.run(goal)
formatted = "\n".join(
f"- **{r['step']}** → {r['output']}"
for r in results
)
return (
f"## Result for goal: *{goal}*\n\n"
f"{formatted}\n"
)
테스트 케이스
if __name__ == "__main__":
agent = FinalAgent(llm=OllamaLLM("llama3"))
tests = [
"Compare NFL quarterback efficiency metrics and summarize insights.",
"Search for top training drills for youth football players.",
"Compute a simple metric and explain how you'd structure the process.",
]
for i, t in enumerate(tests, 1):
print("=" * 70)
print(f"TEST {i}: {t}")
print(agent.respond(t))
print()
샘플 출력 (첫 번째 테스트)
======================================================================
Compare NFL quarterback efficiency metrics and summarize insights.
Gather data on NFL quarterback statistics → Here are some key statistics for NFL quarterbacks, gathered from various sources including Pro-Football-Reference.com, ESPN, and NFL.com:
...
Calculate averages and rankings for each quarterback → {'tool': 'compute', 'task': 'Calculate averages and rankings for each quarterback', 'result': 42}
코드를 작성하든 케이크를 굽든, 구조가 중요합니다. 레이어를 생각하세요. 그리고 AI 에이전트를 설명할 달콤한 비유가 필요하다면 케이크를 활용해 보세요. 개발자 영감을 받은 디저트 메타포가 있나요? 댓글에 남겨서 기술을 맛있게 만들어 봅시다.