구조화된 출력은 NPC와 함께하는 게임플레이에 더 깊이 있는 차원을 제공합니다. 구조화된 출력은 NPC를 지원하는 LLM이 게임플레이 로직을 구동하기 위해 사용자 정의 LLM 인스턴스 구조체를 반환하는 메커니즘입니다.
즉, LLM 캐릭터는 객관식 문제에 대한 답을 제시하거나, 아이템 가격이 그만한 가치가 있는지 판단하는 등 더욱 깊이 있는 상호작용을 할 수 있습니다.
응답과 구조화된 출력은 모두 영어여야 합니다.
개요
이 섹션에서는 페르소나에 대한 단일 구조화된 출력을 사용하여 persona_npc_behavior를 커스터마이징합니다. interactions_response 구조체:
이 NPC가 플레이어와 상호작용한 횟수를 기록합니다.
페르소나가 플레이어와의 이번 상호작용에 대해 현재 느끼는 감정입니다.
플레이어와의 모든 상호작용에 대한 페르소나의 감정 기록 배열입니다.
구조화된 출력을 하려면 다음을 해야 합니다.
구조화된 출력을 정의하는 구조체를 생성합니다.
페르소나가 구조화된 출력 구조체를 채우는 방법에 대한 지침을 제공합니다.
구조화된 출력 수신 시 신호가 전달된 이벤트를 정의하고 구독합니다.
하나의 페르소나에 여러 개의 구조화된 출력을 동시에 구성할 수 있으며, 페르소나의 각 구조화된 출력 유형에 대해 서로 다른 구독을 지정할 수 있습니다.
지원되는 유형
구조화된 출력은 구조체 내 필드로 다음과 같은 Verse 유형을 지원합니다.
intfloatboolenummessage
메시지 표시하기
메시지 유형은 로그 또는 게임 내에서 출력될 때 숨김 처리되지만, 다음과 같이 메시지 유형을 표시하도록 설계된 장치를 사용하면 메시지 유형을 표시할 수 있습니다.
billboard_devicehud_message_devicepopup_dialog_device
전제조건
NPC 비헤이비어 스크립트에 구조화된 출력 추가하기
아래의 코드는 구조화된 출력을 사용하여 prompt_binding_definition 유형과 RegisterAction() 함수를 통해 플레이어 프롬프트에 기반한 새로운 응답 유형을 도입함으로써 여러 LLM의 기능을 확장합니다.
프롬프트 바인딩은 RegisterAction() 함수에 정의된 동작을 등록하기 위해 AI에 제공되는 구조체입니다. 이를 함께 사용하면 LLM이 플레이어의 프롬프트에 따라 특정 행동을 언제 해야 하는지, 왜 특정 행동을 사용해야 하는지를 알 수 있습니다.
아래는 persona_npc_behavior.verse 섹션에 확장된 persona_npc_behavior가 포함된 Verse 스크립트입니다. 이는 구조화된 출력을 포함하여 대화에 NPC 추가하기 문서의 코드를 확장한 것입니다.
기존 persona_npc_behavior에서 코드를 수정하려면 다음 단계를 따릅니다.
VS Code에서 Verse 프로젝트를 열어 두어야 합니다.
메뉴 바에서 Verse > VS Code에서 프로젝트 열기…(Open Project in VS Code…)를 선택합니다.
VS Code가 열리면 VS Code 탐색기(VS Code Explorer)에서
persona_npc_behavior.verse파일을 찾습니다.
아래
persona_npc_behavior.verse의 내용을 복사하여 프로젝트의 Verse 파일에 붙여넣습니다.UEFN 툴바 또는 VS Code 내에서 Verse 코드를 컴파일합니다.
Verse 스크립트에 대한 단계별 지침은 스크립트 변경 사항 설명의 단계를 따르세요. 이 섹션은 NPC 캐릭터에 페르소나 추가하기에서 스크립트 설명이 끝난 지점부터 이어서 설명합니다.
persona_npc_behavior.verse
using { /Fortnite.com/AI }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /UnrealEngine.com/Conversations }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Chat }
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
스크립트 변경 사항 설명
interactions_response로 명명된 구조체는 함수가 LLM에 전달하는 변수를 저장합니다. LLM은 변수를 사용하여 프롬프트를 평가하고 어떻게 응답할지 결정합니다.Verseinteractions_response := struct: @ai_description("Use the Number field to output the number of times you have spoken to this player.") Number:int @ai_description("Use the Feeling field to output how you are feeling about your current interaction with the player.") Feeling:message두 개의 서로 다른
@ai_descriptions는 LLM에게 변수가 무엇인지와 LLM이 응답을 생성할 때 해당 변수를 사용해야 하는 이유를 알립니다.Verse@ai_description("Use the Number field to output the number of times you have spoken to this player.") Number:int @ai_description("Use the Feeling field to output how you are feeling about your current interaction with the player.") Feeling:messageOnInteractionsResponse는 구조화된 출력을 사용하여 게임플레이 로직을 구동하는 함수입니다. AI 세션이interactions_response구조체와 일치하는 구조화된 출력을 생성할 때마다 실행되는 콜백입니다. 이는AddStructuredOutput()의RegisterAction에 의해 등록된 핸들러이며, 해당 응답 매개변수에는 모델이 입력한 데이터가 포함됩니다.VerseOnInteractionsResponse(Response:interactions_response):void = Logger.Print("Structured response received") Logger.Print("Number of Interactions: {Response.Number}") Logger.Print("Feeling: {Localize(Response.Feeling)}") # Drive gameplay logic hereAddStructuredOutput함수는 NPC의 구조화된 출력 액션을 AI 세션에 등록합니다. 이를 통해 모델이 상호작용 데이터를 다시 게임플레이로 보고할 수 있습니다. 이 코드는 두 가지 기능을 합니다. 먼저prompt_binding_definition을 생성합니다. 이는 액션에Name및Description을 부여하는 작은 디스크립터입니다(두 값 모두MakeMessage헬퍼 함수를 통해 래핑되어 문자열 리터럴이 메시지 값으로 변환됨). 설명 텍스트는 모델에게 언제 이 액션을 사용해야 하는지 알립니다. 여기서는 플레이어가 NPC에게 말을 걸 때마다입니다.그런 다음 바인딩, true,
interactions_response구조체 유형 및OnInteractionsResponse핸들러를 전달하여Session.RegisterAction을 호출합니다. 이는 세션이interactions_response와 같은 형태의 구조화된 출력을 내보낼 때 해당 데이터를OnInteractionsResponse로 라우팅해야 함을 알려줍니다.RegisterAction은 취소 가능한 객체를 반환하며, 이는option{}으로 래핑되어InteractionsResponseSubscription에 저장되므로OnEnd메서드에서 구독을 해제할 수 있습니다.VerseAddStructuredOutput():void = if: NPCEntity := GetEntity[] PersonaComponent := NPCEntity.GetComponent[persona_component] Session := PersonaComponent.GetAISession() then: # Create a prompt_binding so that we can use it on RegisterAction InteractionBinding:prompt_binding_definition = prompt_binding_definition: Name := MakeMessage("InteractionBinding") Description := MakeMessage("Signals whenever the player has spoken to you.")OnBegin은 구조화된 출력을 세션에 추가하고 플레이어를 대화 상대로 설정합니다. 플레이어가 중도 합류할 수 있는 게임의 경우PlayerAddedEvent에 추가하거나 플레이어가 트리거를 통해 NPC에 접근할 때 추가해야 합니다.VerseOnBegin<override>()<suspends>:void= AddStructuredOutput() AddPlayersAsConversationTarget()OnEnd에서는InteractionsResponseSubscription이 정리되어 모든 플레이어에게서 제거됩니다. 이 방식을 권장합니다.VerseOnEnd<override>():void= if (Subscription := InteractionsResponseSubscription?): Subscription.Cancel() for (Player : GetEntity[].GetPlayspaceForEntity[].GetPlayers()): RemovePlayerAsConversationTarget(Player)
구조화된 출력 테스트
이제 NPC가 구조화된 출력으로 구성되었습니다. 페르소나가 말할 때마다 interactions_response에 신호가 전달됩니다.
게임 내 프롬프트에 대한 응답과 반응이 더욱 흥미롭도록 LLM 캐릭터의 비헤이비어를 테스트해 보세요.