25

Agent 실행 파이프라인 해부

Day 1: AI Agent 개념 & 제조 적용

학습 목표

Agent의 내부 실행 흐름을 단계별로 추적할 수 있다 OpenAI Function Calling의 메시지 프로토콜을 이해한다 Tool 호출 시 주고받는 데이터 구조를 파악한다

Agent 실행 파이프라인 해부

실습에서 만든 Agent가 내부적으로 어떻게 동작하는지 메시지 하나하나를 추적해보자.


질문: "CNC-003 상태 확인해줘"

Round 1: 사용자 질문 전달

// messages 배열 상태
[
  {
    "role": "system",
    "content": "당신은 제조 공장의 설비 관리 AI Agent..."
  },
  {
    "role": "user",
    "content": "CNC-003 상태 확인해줘"
  }
]

Round 2: LLM이 Tool 호출 결정

// LLM 응답
{
  "role": "assistant",
  "content": null,
  "tool_calls": [
    {
      "id": "call_abc123",
      "type": "function",
      "function": {
        "name": "get_equipment_status",
        "arguments": "{\"equipment_id\": \"CNC-003\"}"
      }
    }
  ]
}

주목할 점:

  • contentnull이다. 텍스트 응답 대신 Tool 호출을 선택했다.
  • argumentsJSON 문자열이다. json.loads()로 파싱 필요.
  • id는 이 호출의 고유 식별자. 결과를 돌려줄 때 매칭해야 한다.

Round 3: Tool 실행 결과 전달

// Tool 실행 후 결과를 messages에 추가
{
  "role": "tool",
  "tool_call_id": "call_abc123",
  "content": "설비 ID: CNC-003\n설비명: CNC 선반 #1\n상태: 경고\n가동률: 72.3%\n온도: 48.7°C\n진동: 1.2 mm/s\n마지막 점검: 2026-01-10\n활성 알람: W-1105: 진동 수치 상승"
}

주목할 점:

  • role"tool"이다 (user도 assistant도 아님).
  • tool_call_id로 어떤 호출의 결과인지 매칭한다.
  • content문자열이다. Tool 함수의 반환값.

Round 4: LLM이 최종 응답 생성

// 최종 LLM 응답
{
  "role": "assistant",
  "content": "CNC-003 (CNC 선반 #1) 현재 **경고** 상태입니다.\n\n주요 현황:\n- 가동률: 72.3% (정상 대비 낮음)\n- 진동: 1.2 mm/s (기준치 0.5 mm/s 초과)\n- 온도: 48.7°C\n- 활성 알람: W-1105 (진동 수치 상승)\n\n**권고사항:**\n1. 즉시 베어링 상태 점검\n2. 진동 센서 캘리브레이션 확인\n3. 마지막 점검(1/10)이 19일 전이므로 조기 점검 권장",
  "tool_calls": null
}

tool_callsnull이므로 루프 종료. 이 content가 사용자에게 전달되는 최종 응답이다.


전체 메시지 흐름 요약

messages 배열의 변화:

[system] -> [user]
  -> LLM 호출 (1차)
[system] -> [user] -> [assistant + tool_calls]
  -> Tool 실행
[system] -> [user] -> [assistant + tool_calls] -> [tool 결과]
  -> LLM 호출 (2차)
[system] -> [user] -> [assistant + tool_calls] -> [tool 결과] -> [assistant 최종응답]

복수 Tool 호출 케이스

질문: "CNC-001이랑 CNC-003 비교해줘"

LLM 응답:
  tool_calls: [
    { function: "get_equipment_status", args: { equipment_id: "CNC-001" } },
    { function: "get_equipment_status", args: { equipment_id: "CNC-003" } }
  ]

→ 두 Tool을 한 번에 호출 (병렬 실행 가능)
→ 두 결과를 모두 messages에 추가
→ LLM이 비교 분석 응답 생성

LLM은 필요하면 여러 Tool을 동시에 호출할 수 있다. 이것이 Agent가 단순 API 호출과 다른 점이다.


흔한 실수와 디버깅

실수증상해결
tool_call_id 미매칭"Invalid tool_call_id" 에러반드시 동일한 id 사용
arguments 파싱 실패JSON 에러json.loads() 사용
content가 None인데 접근AttributeErrortool_calls 먼저 확인
Tool 결과가 dictTypeError반드시 str로 반환
무한 루프Agent가 안 멈춤최대 반복 횟수 설정
AI로 학습하기 — 꿀팁
🤖Function Calling 메시지 흐름도 생성AI 학습 팁

OpenAI Function Calling의 메시지 프로토콜을 설비 데이터 조회 예시로 단계별 흐름도로 정리해두세요.

공장 설비의 진동 센서 데이터를 조회하는 get_sensor_data Tool을 예시로 사용해서, OpenAI Function Calling의 전체 메시지 흐름을 JSON 형식으로 보여줘. user 메시지 → assistant의 tool_calls → tool role의 결과 → 최종 assistant 응답까지 각 단계의 messages 배열을 실제 코드처럼 작성해줘.
이 팁이 도움이 됐나요?