본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 05. 14. 08:32

【제3회】Microsoft Agent Framework으로 배우는 AI 에이전트 설계 원칙: 자연어 파싱을 타입 계약으로 대체하기

요약

본 글은 AI 에이전트 설계 시, Agent의 출력을 구조화하여 후속 처리 단계에서 데이터 타입 안전성을 확보하는 방법을 다룹니다. 기존에는 자연어 파싱에 의존하여 인터페이스가 불안정했지만, Microsoft Agent Framework의 '구조화된 출력(Structured outputs)' 기능을 사용하면 Pydantic 모델을 통해 출력 타입을 명시적으로 선언할 수 있습니다. 이를 통해 LLM이 생성한 결과는 타입 검증이 완료된 안전한 객체로 취득되어, 견고하고 예측 가능한 시스템 설계를 가능하게 합니다.

핵심 포인트

  • AI 에이전트 설계 시, 후속 처리를 위해 구조화된 데이터 출력이 필수적이다.
  • 자연어 파싱에 의존하는 것은 인터페이스 계약(Interface Contract)의 부재로 인해 불안정한 안티 패턴이다.
  • Microsoft Agent Framework는 Pydantic 모델을 활용하여 '구조화된 출력(Structured outputs)' 기능을 제공한다.
  • 이 기능은 JSON Schema를 생성하고 LLM에게 전달하여, 출력을 타입 안전한 객체로 자동 파싱 및 검증한다.
  • 에이전트 설계 시 사전 조건(Precondition), 사후 조건(Postcondition), 불변 조건(Invariant)을 명확히 하는 '계약에 의한 설계' 원칙을 적용해야 한다.

서론

지난번에는 실행 모델의 선택에 대해 배웠습니다. 이번 주제는 Agent의 출력 형식 보장입니다.

Agent는 기본적으로 텍스트를 반환합니다. 하지만 후속 처리에서 예를 들어 점수로 비교·집계하고 싶은 경우 등, 구조를 가진 데이터로 받고 싶은 케이스가 있습니다.

그때 출력의 타입(Type)·구조·제약이 코드로 명시되어 있지 않으면, 파싱(Parsing)이나 가공 처리는 깨지기 쉬워집니다. 이는 **계약에 의한 설계 (Design by Contract)**가 다루는 문제입니다. 이 원칙을 에이전트에 적용하는 방법을 해설합니다.

잘못된 코드: 자연어를 문자열 조작으로 파싱하기

import asyncio
from agent_framework.openai import OpenAIChatClient
async def main():
...

"작동한다!"라고 생각하더라도, 이것은 시한폭탄입니다.

무엇이 잘못되었는가: 인터페이스 계약의 결여

**계약에 의한 설계 (Design by Contract)**에서는 컴포넌트 간의 인터페이스를 "받는 타입·반환하는 타입·지켜야 할 제약"으로 명시합니다. 이 코드에는 Agent와 후속 처리 사이에 그 계약이 존재하지 않습니다.

Agent Framework에서의 해결책: 구조화된 출력 (Structured outputs)

Microsoft Agent Framework의 **구조화된 출력 (Structured outputs)**을 사용하면, Pydantic 모델로 출력의 타입을 선언할 수 있습니다. Agent Framework가 JSON Schema를 생성하여 LLM에 전달하고, 반환된 JSON을 자동으로 파싱 및 타입 검증(Type validation)합니다. 얻은 결과는 타입 안전한(Type-safe) 객체로서 이용할 수 있습니다.

리팩터링 후의 코드

import asyncio
from typing import Annotated
from agent_framework.openai import OpenAIChatClient
...

무엇이 개선되었는가

관점❌️ 개선 전⭕️ 개선 후
출력 형식의 보장프롬프트 의존 (부탁)타입으로 선언 (보장)
...

구조화된 출력의 포인트

  • default_optionsresponse_format에 Pydantic 모델을 전달하기만 하면 된다
  • Field(ge=1, le=10) 등의 유효성 검사(Validation)도 LLM에 대한 지시로서 기능한다
  • result.value로 타입 안전한 객체를 취득하여, best.score와 같이 액세스할 수 있다
  • 타입 정의가 그대로 문서·사양이 된다

"계약에 의한 설계"를 에이전트에 적용하기

**계약에 의한 설계 (Design by Contract)**의 사고방식:

  • 사전 조건 (Precondition): Agent가 받는 입력의 타입·제약
  • 사후 조건 (Postcondition): Agent가 반환하는 출력의 타입·제약 (=response_format)
  • 불변 조건 (Invariant): Agent가 항상 지켜야 할 업무 규칙 (=instructions의 일부)

response_format을 정의하는 것은 "이 Agent는 이러한 구조의 데이터를 반환한다"라는 인터페이스 계약을 선언하는 것입니다.

요약

  • 자연어를 파싱하는 구현은 "깨지기 쉬운 인터페이스"의 안티 패턴(Anti-pattern)
  • Design by Contract를 적용함으로써 후속 처리와의 결합을 안전하게 유지할 수 있음
  • Agent Framework의 **구조화된 출력 (Structured outputs)**으로 출력 타입을 선언하면 파싱·유효성 검사가 자동화됨

다음 시간에는 "검증·승인 없이 외부로 출력하는" 문제와 FunctionMiddleware / HITL을 해설합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
1

댓글

0