다중 단계 인터페이스

다중 단계 인터페이스 (Multistep Interfaces)

다중 단계 인터페이스(multistep interface)란 특정 작업을 완료하기 위해 여러 개의 독립적인 단계를 순서대로 실행해야 하는 사용자 인터페이스를 말합니다. AI SDK를 활용한 에이전트형 앱을 설계할 때 핵심이 되는 개념이며, 이를 이해하려면 툴 구성(Tool composition)애플리케이션 컨텍스트(Application context) 두 가지를 알아야 합니다.

툴 구성은 여러 을 결합해 새로운 툴을 만드는 과정입니다. 복잡한 작업을 더 작고 관리하기 쉬운 단계로 쪼갤 수 있게 해주는 강력한 개념입니다. 애플리케이션 컨텍스트는 특정 시점의 애플리케이션 상태를 말하며, 사용자의 입력, 언어 모델의 출력, 그 외 관련 정보를 포함합니다. 다중 단계 인터페이스를 설계할 때는 툴을 어떻게 조합해 일관된 사용자 경험을 만들지, 그리고 사용자가 인터페이스를 진행하면서 애플리케이션 컨텍스트가 어떻게 변하는지를 함께 고려해야 합니다.

출처: 공식문서

본문

애플리케이션 컨텍스트

애플리케이션 컨텍스트는 사용자와 언어 모델 사이의 대화 히스토리로 볼 수 있습니다. 컨텍스트가 풍부할수록 모델은 더 관련성 높은 응답을 생성할 정보를 갖게 됩니다.

다중 단계 인터페이스에서 애플리케이션 컨텍스트는 더 중요해집니다. 한 단계에서의 사용자 입력이 다음 단계의 모델 출력에 영향을 줄 수 있기 때문입니다.

예를 들어 사용자의 하루 식사 섭취를 추적하는 식사 기록 애플리케이션을 생각해 봅시다. 언어 모델에 다음 툴이 제공됩니다:

  • log_meal — 음식 이름, 수량, 섭취 시간을 인자로 받아 식사를 기록합니다.
  • delete_meal — 삭제할 식사 이름을 받습니다.

사용자가 식사를 기록하면 모델은 식사가 기록되었다는 응답을 생성합니다.

User: Log a chicken shawarma for lunch.
Tool: log_meal("chicken shawarma", "250g", "12:00 PM")
Model: Chicken shawarma has been logged for lunch.

이제 사용자가 식사를 삭제하려고 하면, 모델은 이전 단계를 참조해 삭제할 식사를 식별할 수 있어야 합니다.

User: Log a chicken shawarma for lunch.
Tool: log_meal("chicken shawarma", "250g", "12:00 PM")
Model: Chicken shawarma has been logged for lunch.
...
...
User: I skipped lunch today, can you update my log?
Tool: delete_meal("chicken shawarma")
Model: Chicken shawarma has been deleted from your log.

이 예시에서 애플리케이션 컨텍스트를 관리하는 것이 모델이 올바른 응답을 생성하는 데 중요합니다. delete_meal 툴의 인자를 생성하려면 모델이 이전 작업에 대한 정보를 갖고 있어야 합니다.

툴 구성

툴 구성은 여러 툴을 결합해 새로운 툴을 만드는 과정입니다. 각 툴의 입력·출력과 툴들이 서로 어떻게 상호작용하는지를 정의하는 일이 포함됩니다.

이 툴들이 어떻게 구성되어 다중 단계 인터페이스를 이루는지 설계하는 것은 애플리케이션의 사용자 경험과 모델이 올바른 출력을 생성하는 능력 모두에 결정적입니다.

예를 들어 항공편 예약을 도와주는 항공 예약 어시스턴트를 생각해 봅시다. 어시스턴트는 다음 툴을 가지도록 설계할 수 있습니다:

  • searchFlights — 사용자 쿼리를 기반으로 항공편을 검색합니다.
  • lookupFlight — 항공편 번호를 기반으로 특정 항공편의 세부 정보를 조회합니다.
  • bookFlight — 사용자 선택을 기반으로 항공편을 예약합니다.

마지막 툴 호출에서 bookFlight는 승객 정보를 입력 받지 못했습니다. 이는 유스케이스에 따라 다르지만, 사용자가 승객 정보를 제공하기 전에 예약을 진행할 수 없으므로 어시스턴트가 승객 정보를 요청하게 됩니다.

User: I want to book a flight from New York to London.
Tool: searchFlights("New York", "London")
Model: Here are the available flights from New York to London.
User: I want to book flight number BA123 on 12th December for myself and my wife.
Tool: bookFlight("BA123", "12th December")
Model: Your flight has been booked!

여기서 bookFlight는 애플리케이션 컨텍스트에 승객 정보가 아직 없기 때문에, 예약을 진행하기 전에 사용자에게 승객 정보를 요청합니다.

만약 사용자가 애플리케이션에 로그인한 상태라면, 승객 정보를 조회하는 별도의 툴을 bookFlight 호출 전에 호출하도록 설계할 수 있습니다. 이렇게 하면 모델이 승객 정보를 사용자에게 묻지 않고도 예약을 진행할 수 있습니다.

User: I want to book a flight from New York to London.
Tool: searchFlights("New York", "London")
Model: Here are the available flights from New York to London.
User: I want to book flight number BA123 on 12th December for myself and my wife.
Tool: lookupContacts() -> ["John Doe", "Jane Doe"]
Tool: bookFlight("BA123", "12th December", ["John Doe", "Jane Doe"])
Model: Your flight has been booked!

lookupContacts 툴은 bookFlight 툴 전에 호출되어 예약 시 승객 정보가 애플리케이션 컨텍스트에 존재하도록 보장합니다. 이렇게 하면 모델이 사용자에게 필요한 단계 수를 줄이고, 컨텍스트를 채우는 툴 호출 능력을 활용해 예약 과정을 완료할 수 있습니다.

이제 승객 이름을 인자로 받아 예약 정보를 보여주는 lookupBooking 툴을 추가해 봅시다. 이 툴은 기존 툴들과 구성되어 더 완전한 사용자 경험을 제공할 수 있습니다.

User: What's the status of my wife's upcoming flight?
Tool: lookupContacts() -> ["John Doe", "Jane Doe"]
Tool: lookupBooking("Jane Doe") -> "BA123 confirmed"
Tool: lookupFlight("BA123") -> "Flight BA123 is scheduled to depart on 12th December."
Model: Your wife's flight BA123 is confirmed and scheduled to depart on 12th December.

이 예시에서 lookupBooking 툴은 사용자의 아내가 탈 예정 항공편의 상태를 제공하는 데 쓰입니다. 이 툴을 기존 툴들과 구성함으로써 모델은 사용자가 추가 정보를 제공하지 않아도 예약 상태와 출발 날짜를 포함한 응답을 생성할 수 있게 됩니다.

결과적으로, 서로 구성 가능한 툴을 더 많이 설계할수록 애플리케이션은 더 복잡하고 강력해질 수 있습니다.

더 알아보기