OpenAi-dotnet을 기반으로합니다
RESTFUL API를 통해 Unity를 사용할 수있는 OpenAI 패키지. 독립적으로 개발 된 것은 공식 도서관이 아니며 OpenAI와 제휴하지 않습니다. OpenAI API 계정이 필요합니다.
모든 저작권, 상표, 로고 및 자산은 해당 소유자의 자산입니다.
Unity 2021.3 lts 이상이 필요합니다.
권장 설치 방법은 Unity Package Manager 및 OpenUPM입니다.
OpenUPMhttps://package.openupm.comcom.openaicom.utilities
My Registries 로 변경하십시오OpenAI 패키지를 추가하십시오https://github.com/RageAgainstThePixel/com.openai.unity.git#upm참고 :이 repo는 다른 저장소에 의존적입니다! 귀하는 직접 추가 할 책임이 있습니다.
새로운 API 문서를 확인하십시오!
https://rageagainstthepixel.github.io/openai-dotnet
우선 순위로 API 키를 제공하는 4 가지 방법이 있습니다.
경고
환경 변수를 사용하여 소스에 하드 코딩하는 대신 API 키를로드하는 것이 좋습니다. 이 방법을 제작에 사용하는 것이 아니라 사용자 자격 증명, 로컬 테스트 및 빠른 시작 시나리오를 수락하는 데만 사용하는 것이 좋습니다.
그림과 같이 API를 초기화 할 때 OpenAIAuthentication 을 사용합니다.
경고
환경 변수를 사용하여 소스에 하드 코딩하는 대신 API 키를로드하는 것이 좋습니다. 이 방법을 제작에 사용하는 것이 아니라 사용자 자격 증명, 로컬 테스트 및 빠른 시작 시나리오를 수락하는 데만 사용하는 것이 좋습니다.
var api = new OpenAIClient ( " sk-apiKey " ) ; 또는 수동으로 OpenAIAuthentication 객체를 만듭니다
var api = new OpenAIClient ( new OpenAIAuthentication ( " sk-apiKey " , " org-yourOrganizationId " , " proj_yourProjectId " ) ) ; 키를 Assets/Resources 폴더에있는 스크립트 가능한 객체에 직접 저장할 수 있습니다.
프로젝트 창의 컨텍스트 메뉴를 사용하여 새 OpenAIConfiguration 스크립트 가능한 객체를 만들어 새 것을 만들 수 있습니다.
경고
다른 사람들이 API 키를 볼 수 있으므로이 파일을 소스 제어로 확인하십시오. OpenAi-Dotnet-Proxy를 사용하고 선호하는 OAUTH 제공 업체를 사용하여 사용자를 인증하는 것이 좋습니다.

현재 디렉토리의 구성 파일, 기본적으로 .openai 에서 API 키를로드하려고 시도합니다.
구성 파일을 만들려면 .openai 라는 새 텍스트 파일을 작성하고 라인을 포함하십시오.
메모
조직 및 프로젝트 ID 항목은 선택 사항입니다.
{
"apiKey" : " sk-aaaabbbbbccccddddd " ,
"organizationId" : " org-yourOrganizationId " ,
"projectId" : " proj_yourProjectId "
}OPENAI_API_KEY=sk-aaaabbbbbccccddddd
OPENAI_ORGANIZATION_ID=org-yourOrganizationId
OPENAI_PROJECT_ID=proj_yourProjectId OpenAIAuthentication 에서 정적 메소드를 호출하여 알려진 경로로 구성 파일을 직접로드 할 수도 있습니다.
.openai 구성을로드합니다. var api = new OpenAIClient ( new OpenAIAuthentication ( ) . LoadFromDirectory ( " path/to/your/directory " ) ) ;.openai 로 명명 될 필요는 없습니다. var api = new OpenAIClient ( new OpenAIAuthentication ( ) . LoadFromPath ( " path/to/your/file.json " ) ) ; 시스템의 환경 변수를 사용하여 사용할 API 키 및 조직을 지정하십시오.
OPENAI_API_KEY 사용하십시오.OPENAI_ORGANIZATION_ID 사용하여 조직을 지정하십시오.OPENAI_PROJECT_ID 사용하여 프로젝트를 지정하십시오. var api = new OpenAIClient ( new OpenAIAuthentication ( ) . LoadFromEnvironment ( ) ) ;Microsoft의 Azure OpenAi 배포도 사용하도록 선택할 수도 있습니다.
View Code 버튼을 클릭하여 Azure Playground에서 필요한 정보를 찾을 수 있으며 다음과 같은 URL을 볼 수 있습니다.
https://{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}your-resource-name Azure Openai 리소스의 이름입니다.deployment-id 모델을 배포했을 때 선택한 배포 이름입니다.api-version 이 작업에 사용할 API 버전. 이는 YYYY-MM-DD 형식을 따릅니다. 배포를 사용하도록 클라이언트를 설정하려면 OpenAISettings 클라이언트 생성자로 전달해야합니다.
var auth = new OpenAIAuthentication ( " sk-apiKey " ) ;
var settings = new OpenAISettings ( resourceName : " your-resource-name " , deploymentId : " deployment-id " , apiVersion : " api-version " ) ;
var api = new OpenAIClient ( auth , settings ) ; 평소와 같이 MSAL을 인증하고 액세스 토큰을 얻은 다음 OpenAIAuthentication 만들 때 액세스 토큰을 사용하십시오. 그런 다음 OpenAISettings 만들 때 USEAZUREACTIVEDIVERORY를 TRUE로 설정하십시오.
튜토리얼 : 웹 API를 호출하는 데스크탑 앱 : 토큰 획득
// get your access token using any of the MSAL methods
var accessToken = result . AccessToken ;
var auth = new OpenAIAuthentication ( accessToken ) ;
var settings = new OpenAISettings ( resourceName : " your-resource " , deploymentId : " deployment-id " , apiVersion : " api-version " , useActiveDirectoryAuthentication : true ) ;
var api = new OpenAIClient ( auth , settings ) ;프론트 엔드 앱에서 직접 Openai-Dotnet 또는 Com.openai.unity 패키지를 사용하면 API 키 및 기타 민감한 정보가 노출 될 수 있습니다. 이 위험을 완화하려면 프론트 엔드 앱을 대신하여 OpenAI를 요청하는 중간 API를 설정하는 것이 좋습니다. 이 라이브러리는 프론트 엔드 및 중개 호스트 구성 모두에 활용하여 OpenAI API와의 안전한 통신을 보장 할 수 있습니다.
프론트 엔드 예에서는 선호하는 OAUTH 제공 업체를 사용하여 사용자를 안전하게 인증해야합니다. 사용자가 인증되면 Backend에서 API 키로 사용자 정의 인증 토큰을 교환하십시오.
다음 단계를 따르십시오.
OpenAIAuthentication 객체를 만들고 접두사 sess- 와 함께 사용자 정의 토큰을 통과하십시오.OpenAISettings 객체를 작성하고 중간 API가있는 도메인을 지정하십시오.auth 및 settings 객체를 OpenAIClient 생성자에게 전달하십시오.다음은 프론트 엔드를 설정하는 방법의 예입니다.
var authToken = await LoginAsync ( ) ;
var auth = new OpenAIAuthentication ( $" sess- { authToken } " ) ;
var settings = new OpenAISettings ( domain : " api.your-custom-domain.com " ) ;
var api = new OpenAIClient ( auth , settings ) ;이 설정을 통해 프론트 엔드 애플리케이션은 OpenAI-DotNet-Proxy를 사용하는 백엔드와 안전하게 통신 할 수 있으며, 이는 OpenAI API에 요청을 전달할 수 있습니다. 이를 통해 OpenAI API 키 및 기타 민감한 정보가 프로세스 전반에 걸쳐 안전하게 유지되도록합니다.
이 예에서는 새로운 ASP.NET Core 웹 앱에서 OpenAIProxy 설정하고 사용하는 방법을 보여줍니다. 프록시 서버는 OpenAI API에 대한 인증 및 전진 요청을 처리하여 API 키 및 기타 민감한 정보가 안전하게 유지되도록합니다.
Install-Package OpenAI-DotNet-Proxydotnet add package OpenAI-DotNet-Proxy<PackageReference Include="OpenAI-DotNet-Proxy" /> 편집AbstractAuthenticationFilter 에서 상속하는 새로운 클래스를 작성하고 ValidateAuthentication 방법을 무시하십시오. 이렇게하면 내부 서버에 대한 사용자 세션 토큰을 확인하는 데 사용할 IAuthenticationFilter 구현됩니다.Program.cs 에서 OpenAIProxy.CreateWebApplication 메소드를 호출하여 사용자 정의 AuthenticationFilter 유형 인수로 전달하여 새로운 프록시 웹 응용 프로그램을 만듭니다.OpenAIAuthentication 및 OpenAIClientSettings 만듭니다. public partial class Program
{
private class AuthenticationFilter : AbstractAuthenticationFilter
{
public override async Task ValidateAuthenticationAsync ( IHeaderDictionary request )
{
await Task . CompletedTask ; // remote resource call to verify token
// You will need to implement your own class to properly test
// custom issued tokens you've setup for your end users.
if ( ! request . Authorization . ToString ( ) . Contains ( TestUserToken ) )
{
throw new AuthenticationException ( " User is not authorized " ) ;
}
}
}
public static void Main ( string [ ] args )
{
var auth = OpenAIAuthentication . LoadFromEnv ( ) ;
var settings = new OpenAIClientSettings ( /* your custom settings if using Azure OpenAI */ ) ;
using var openAIClient = new OpenAIClient ( auth , settings ) ;
OpenAIProxy . CreateWebApplication < AuthenticationFilter > ( args , openAIClient ) . Run ( ) ;
}
}프록시 서버를 설정 한 후에는 최종 사용자가 OpenAI API 직접 대신 프록시 API에 인증 된 요청을 할 수 있습니다. 프록시 서버는 OpenAI API에 대한 인증 및 전진 요청을 처리하여 API 키 및 기타 민감한 정보가 안전하게 유지되도록합니다.
API에서 사용 가능한 다양한 모델을 나열하고 설명하십시오. 모델 문서를 참조하여 사용 가능한 모델과 그 모델의 차이점을 이해할 수 있습니다.
또한 점검 모델 엔드 포인트 호환성이 어떤 모델이 어떤 엔드 포인트에서 작동하는지 이해합니다.
이 라이브러리에서 사전 정의되지 않은 사용자 정의 모델을 지정하려면 다음과 같습니다.
var model = new Model ( " model-id " ) ; 모델 API는 OpenAIClient.ModelsEndpoint 를 통해 액세스됩니다
현재 사용 가능한 모델을 나열하고 소유자 및 가용성과 같은 각 모델에 대한 기본 정보를 제공합니다.
var api = new OpenAIClient ( ) ;
var models = await api . ModelsEndpoint . GetModelsAsync ( ) ;
foreach ( var model in models )
{
Debug . Log ( model . ToString ( ) ) ;
} 모델 인스턴스를 검색하여 소유자 및 권한과 같은 모델에 대한 기본 정보를 제공합니다.
var api = new OpenAIClient ( ) ;
var model = await api . ModelsEndpoint . GetModelDetailsAsync ( " gpt-4o " ) ;
Debug . Log ( model . ToString ( ) ) ; 미세 조정 모델을 삭제하십시오. 조직에서 소유자 역할이 있어야합니다.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . ModelsEndpoint . DeleteFineTuneModelAsync ( " your-fine-tuned-model " ) ;
Assert . IsTrue ( isDeleted ) ;경고
베타 기능. API 변경 사항이 적용됩니다.
실시간 API를 사용하면 저도의 다중 모달 대화 경험을 구축 할 수 있습니다. 현재 텍스트 및 오디오를 입력 및 출력 및 기능 호출로 지원합니다.
Assistants API는 OpenAIClient.RealtimeEndpoint 를 통해 액세스합니다
다음은 실시간 세션을 만들고 모델에서 메시지를 보내고받는 방법에 대한 간단한 예입니다.
var api = new OpenAIClient ( ) ;
var cancellationTokenSource = new CancellationTokenSource ( ) ;
var tools = new List < Tool >
{
Tool . FromFunc ( " goodbye " , ( ) =>
{
cancellationTokenSource . Cancel ( ) ;
return " Goodbye! " ;
} )
} ;
var options = new Options ( Model . GPT4oRealtime , tools : tools ) ;
using var session = await api . RealtimeEndpoint . CreateSessionAsync ( options ) ;
var responseTask = session . ReceiveUpdatesAsync < IServerEvent > ( ServerEvents , cancellationTokenSource . Token ) ;
await session . SendAsync ( new ConversationItemCreateRequest ( " Hello! " ) ) ;
await session . SendAsync ( new CreateResponseRequest ( ) ) ;
await session . SendAsync ( new InputAudioBufferAppendRequest ( new ReadOnlyMemory < byte > ( new byte [ 1024 * 4 ] ) ) , cancellationTokenSource . Token ) ;
await session . SendAsync ( new ConversationItemCreateRequest ( " GoodBye! " ) ) ;
await session . SendAsync ( new CreateResponseRequest ( ) ) ;
await responseTask ;
void ServerEvents ( IServerEvent @event )
{
switch ( @event )
{
case ResponseAudioTranscriptResponse transcriptResponse :
Debug . Log ( transcriptResponse . ToString ( ) ) ;
break ;
case ResponseFunctionCallArgumentsResponse functionCallResponse :
if ( functionCallResponse . IsDone )
{
ToolCall toolCall = functionCallResponse ;
toolCall . InvokeFunction ( ) ;
}
break ;
}
} 이 라이브러리는 나가는 클라이언트 전송 이벤트에 대한 IClientEvent 인터페이스를 구현합니다.
UpdateSessionRequest : 새 세션 옵션으로 세션을 업데이트하십시오.InputAudioBufferAppendRequest : 입력 오디오 버퍼에 오디오를 추가하십시오. (다른 클라이언트 이벤트와 달리 서버는이 이벤트에 대한 확인 응답을 보내지 않습니다).InputAudioBufferCommitRequest : 입력 오디오 버퍼를 커밋하십시오. (서버 VAD 모드에서 클라이언트 가이 이벤트를 보낼 필요가 없습니다).InputAudioBufferClearRequest : 입력 오디오 버퍼를 지우십시오.ConversationItemCreateRequest : 새 대화 항목을 만듭니다. 이것은 모델에 사용자 콘텐츠를 보내는 주요 방법입니다.ConversationItemTruncateRequest :이 이벤트를 보내서 이전 어시스턴트 메시지의 오디오를 잘라냅니다.ConversationItemDeleteRequest : 대화 항목을 삭제합니다. 이것은 대화 기록에서 메시지를 제거하려는 경우 유용합니다.CreateResponseRequest : 모델에서 응답을 만듭니다. 새 대화 항목을 만들거나 도구 통화를 호출 한 후이 이벤트를 보냅니다. 이렇게하면 응답을 생성하도록 모델이 트리거됩니다.ResponseCancelRequest 진행되지 않은 응답을 취소하기 위해이 이벤트를 세웁니다. 세션 객체에서 RealtimeSession.SendAsync 메소드를 호출하여 언제든지 클라이언트 이벤트를 서버로 보낼 수 있습니다. 보내기 통화는 해당 이벤트에 대한 서버의 적절한 응답을 가장 잘 나타내는 IServerEvent 핸들을 반환합니다. 더 세분화 된 방식으로 서버 응답을 처리하려는 경우 유용합니다.
이상적으로는 RealtimeSession.ReceiveUpdatesAsync 를 사용하여 모든 서버 응답을 처리 할 수 있습니다.
메모
서버는 InputAudioBufferAppendRequest 이벤트에 대한 확인 응답을 보내지 않습니다.
중요한
또한 응답을 생성하기 위해 모델을 트리거하려면 CreateResponseRequest 보내야합니다.
var serverEvent = await session . SendAsync ( new ConversationItemCreateRequest ( " Hello! " ) ) ;
Debug . Log ( serverEvent . ToJsonString ( ) ) ;
serverEvent = await session . SendAsync ( new CreateResponseRequest ( ) ) ;
Debug . Log ( serverEvent . ToJsonString ( ) ) ; 라이브러리는 들어오는 서버 전송 이벤트에 대한 IServerEvent 인터페이스를 구현합니다.
RealtimeEventError : 오류가 발생하면 반환되어 클라이언트 문제 또는 서버 문제가 될 수 있습니다.SessionResponse : session.created 모두 session.updated 대해 반환되었습니다.RealtimeConversationResponse : 새 대화 항목이 만들어지면 반환됩니다.ConversationItemCreatedResponse : 새 대화 항목이 만들어지면 반환됩니다.ConversationItemInputAudioTranscriptionResponse : 입력 오디오 전사가 완료되거나 실패했을 때 반환됩니다.ConversationItemTruncatedResponse : 대화 항목이 잘릴 때 반환됩니다.ConversationItemDeletedResponse : 대화 항목이 삭제되면 반환됩니다.InputAudioBufferCommittedResponse : 입력 오디오 버퍼가 클라이언트에 의해 또는 서버 VAD 모드에서 자동으로 커밋 될 때 반환됩니다.InputAudioBufferClearedResponse : 입력 오디오 버퍼가 지워지면 반환됩니다.InputAudioBufferStartedResponse : Server_VAD 모드에서 서버가 보낸 오디오 버퍼에서 음성이 감지되었음을 나타냅니다. 오디오가 버퍼에 추가 될 때마다 발생할 수 있습니다 (음성이 이미 감지되지 않는 한). 클라이언트는이 이벤트를 사용하여 오디오 재생을 방해하거나 사용자에게 시각적 피드백을 제공 할 수 있습니다.InputAudioBufferStoppedResponse : 서버가 오디오 버퍼에서 음성 끝을 감지 할 때 Server_vad 모드로 반환됩니다.RealtimeResponse : 응답이 만들어 지거나 완료되면 반환됩니다.ResponseOutputItemResponse : 응답 출력 항목이 추가되거나 완료되면 반환됩니다.ResponseContentPartResponse : 응답 내용 부분이 추가되거나 완료되면 반환됩니다.ResponseTextResponse : 응답 텍스트가 업데이트되거나 완료되면 반환됩니다.ResponseAudioTranscriptResponse : 응답 오디오 전 사원이 업데이트되거나 완료되면 반환됩니다.ResponseAudioResponse : 응답 오디오가 업데이트되거나 완료되면 반환됩니다.ResponseFunctionCallArgumentsResponse : 응답 함수 호출 인수가 업데이트되거나 완료되면 반환됩니다.RateLimitsResponse : 요금 제한이 업데이트되면 반환됩니다. 서버 이벤트를 받으려면 세션 객체에서 RealtimeSession.ReceiveUpdatesAsync 메소드를 호출해야합니다. 이 방법은 세션이 닫히거나 취소 토큰이 트리거 될 때 완료되는 Task 반환합니다. 이상적 으로이 방법은 한 번 호출되어 세션 기간 동안 실행되어야합니다.
메모
IServerEvent 대신 IRealtimeEvent 인터페이스를 사용하여 IClientEvent 콜백을 보낼 수도 있습니다.
await session . ReceiveUpdatesAsync < IServerEvent > ( ServerEvents , cancellationTokenSource . Token ) ;
void ServerEvents ( IServerEvent @event )
{
switch ( @event )
{
case RealtimeEventError error :
// raised anytime an error occurs
break ;
case SessionResponse sessionResponse :
// raised when a session is created or updated
break ;
case RealtimeConversationResponse conversationResponse :
// raised when a new conversation is created
break ;
case ConversationItemCreatedResponse conversationItemCreated :
// raised when a new conversation item is created
break ;
case ConversationItemInputAudioTranscriptionResponse conversationItemTranscription :
// raised when the input audio transcription is completed or failed
break ;
case ConversationItemTruncatedResponse conversationItemTruncated :
// raised when a conversation item is truncated
break ;
case ConversationItemDeletedResponse conversationItemDeleted :
// raised when a conversation item is deleted
break ;
case InputAudioBufferCommittedResponse committedResponse :
// raised when an input audio buffer is committed
break ;
case InputAudioBufferClearedResponse clearedResponse :
// raised when an input audio buffer is cleared
break ;
case InputAudioBufferStartedResponse startedResponse :
// raised when speech is detected in the audio buffer
break ;
case InputAudioBufferStoppedResponse stoppedResponse :
// raised when speech stops in the audio buffer
break ;
case RealtimeResponse realtimeResponse :
// raised when a response is created or done
break ;
case ResponseOutputItemResponse outputItemResponse :
// raised when a response output item is added or done
break ;
case ResponseContentPartResponse contentPartResponse :
// raised when a response content part is added or done
break ;
case ResponseTextResponse textResponse :
// raised when a response text is updated or done
break ;
case ResponseAudioTranscriptResponse transcriptResponse :
// raised when a response audio transcript is updated or done
break ;
case ResponseFunctionCallArgumentsResponse functionCallResponse :
// raised when a response function call arguments are updated or done
break ;
case RateLimitsResponse rateLimitsResponse :
// raised when rate limits are updated
break ;
}
}경고
베타 기능. API 변경 사항이 적용됩니다.
모델을 호출하고 도구를 사용하여 작업을 수행 할 수있는 비서를 구축하십시오.
어시스턴트 API는 OpenAIClient.AssistantsEndpoint 를 통해 액세스합니다
보조 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var assistantsList = await api . AssistantsEndpoint . ListAssistantsAsync ( ) ;
foreach ( var assistant in assistantsList . Items )
{
Debug . Log ( $" { assistant } -> { assistant . CreatedAt } " ) ;
} 모델과 지침으로 비서를 만듭니다.
var api = new OpenAIClient ( ) ;
var request = new CreateAssistantRequest ( Model . GPT4o ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( request ) ; 조수를 검색합니다.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . RetrieveAssistantAsync ( " assistant-id " ) ;
Debug . Log ( $" { assistant } -> { assistant . CreatedAt } " ) ; 조수를 수정합니다.
var api = new OpenAIClient ( ) ;
var createRequest = new CreateAssistantRequest ( Model . GPT4_Turbo ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( createRequest ) ;
var modifyRequest = new CreateAssistantRequest ( Model . GPT4o ) ;
var modifiedAssistant = await api . AssistantsEndpoint . ModifyAssistantAsync ( assistant . Id , modifyRequest ) ;
// OR AssistantExtension for easier use!
var modifiedAssistantEx = await assistant . ModifyAsync ( modifyRequest ) ; 조수를 삭제하십시오.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . AssistantsEndpoint . DeleteAssistantAsync ( " assistant-id " ) ;
// OR AssistantExtension for easier use!
var isDeleted = await assistant . DeleteAsync ( ) ;
Assert . IsTrue ( isDeleted ) ; 메모
Func<IServerSentEvent, Task> streamEventHandler 콜백을 스트리밍을 지원하는 기존 메소드로 전달하여 기존 스레드 호출에 어시스턴트 스트림 이벤트를 쉽게 추가 할 수 있습니다.
비서가 상호 작용할 수있는 스레드를 만듭니다.
스레드 API는 OpenAIClient.ThreadsEndpoint 를 통해 액세스됩니다
스레드를 만듭니다.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
Debug . Log ( $" Create thread { thread . Id } -> { thread . CreatedAt } " ) ; 스레드를 만들고 한 번의 요청으로 실행하십시오.
참조 : 스레드가 실행됩니다
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a personal math tutor. Answer questions briefly, in a sentence or less. " ,
model : Model . GPT4o ) ) ;
var messages = new List < Message > { " I need to solve the equation `3x + 11 = 14`. Can you help me? " } ;
var threadRequest = new CreateThreadRequest ( messages ) ;
var run = await assistant . CreateThreadAndRunAsync ( threadRequest ) ;
Debug . Log ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ; 스트리밍 이벤트에서 스레드를 만들고 한 번의 요청으로 실행하십시오.
var api = new OpenAIClient ( ) ;
var tools = new List < Tool >
{
Tool . GetOrCreateTool ( typeof ( WeatherService ) , nameof ( WeatherService . GetCurrentWeatherAsync ) )
} ;
var assistantRequest = new CreateAssistantRequest ( tools : tools , instructions : " You are a helpful weather assistant. Use the appropriate unit based on geographical location. " ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( assistantRequest ) ;
ThreadResponse thread = null ;
async Task StreamEventHandler ( IServerSentEvent streamEvent )
{
switch ( streamEvent )
{
case ThreadResponse threadResponse :
thread = threadResponse ;
break ;
case RunResponse runResponse :
if ( runResponse . Status == RunStatus . RequiresAction )
{
var toolOutputs = await assistant . GetToolOutputsAsync ( runResponse ) ;
foreach ( var toolOutput in toolOutputs )
{
Debug . Log ( $" Tool Output: { toolOutput } " ) ;
}
await runResponse . SubmitToolOutputsAsync ( toolOutputs , StreamEventHandler ) ;
}
break ;
default :
Debug . Log ( streamEvent . ToJsonString ( ) ) ;
break ;
}
}
var run = await assistant . CreateThreadAndRunAsync ( " I'm in Kuala-Lumpur, please tell me what's the temperature now? " , StreamEventHandler ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . Reverse ( ) )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
} 스레드를 검색합니다.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . RetrieveThreadAsync ( " thread-id " ) ;
// OR if you simply wish to get the latest state of a thread
thread = await thread . UpdateAsync ( ) ;
Debug . Log ( $" Retrieve thread { thread . Id } -> { thread . CreatedAt } " ) ; 스레드를 수정합니다.
참고 : 메타 데이터 만 수정할 수 있습니다.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var metadata = new Dictionary < string , string >
{
{ " key " , " custom thread metadata " }
}
thread = await api . ThreadsEndpoint . ModifyThreadAsync ( thread . Id , metadata ) ;
// OR use extension method for convenience!
thread = await thread . ModifyAsync ( metadata ) ;
Debug . Log ( $" Modify thread { thread . Id } -> { thread . Metadata [ " key " ] } " ) ; 스레드를 삭제하십시오.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . ThreadsEndpoint . DeleteThreadAsync ( " thread-id " ) ;
// OR use extension method for convenience!
var isDeleted = await thread . DeleteAsync ( ) ;
Assert . IsTrue ( isDeleted ) ; 스레드 내에서 메시지를 만듭니다.
주어진 스레드에 대한 메시지 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var messageList = await api . ThreadsEndpoint . ListMessagesAsync ( " thread-id " ) ;
// OR use extension method for convenience!
var messageList = await thread . ListMessagesAsync ( ) ;
foreach ( var message in messageList . Items )
{
Debug . Log ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ;
} 메시지를 만듭니다.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var request = new CreateMessageRequest ( " Hello world! " ) ;
var message = await api . ThreadsEndpoint . CreateMessageAsync ( thread . Id , request ) ;
// OR use extension method for convenience!
var message = await thread . CreateMessageAsync ( " Hello World! " ) ;
Debug . Log ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ; 메시지를 검색하십시오.
var api = new OpenAIClient ( ) ;
var message = await api . ThreadsEndpoint . RetrieveMessageAsync ( " thread-id " , " message-id " ) ;
// OR use extension methods for convenience!
var message = await thread . RetrieveMessageAsync ( " message-id " ) ;
var message = await message . UpdateAsync ( ) ;
Debug . Log ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ; 메시지를 수정하십시오.
참고 : 메시지 메타 데이터 만 수정할 수 있습니다.
var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , string >
{
{ " key " , " custom message metadata " }
} ;
var message = await api . ThreadsEndpoint . ModifyMessageAsync ( " thread-id " , " message-id " , metadata ) ;
// OR use extension method for convenience!
var message = await message . ModifyAsync ( metadata ) ;
Debug . Log ( $" Modify message metadata: { message . Id } -> { message . Metadata [ " key " ] } " ) ; 스레드에서 실행 실행을 나타냅니다.
스레드에 속하는 실행 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var runList = await api . ThreadsEndpoint . ListRunsAsync ( " thread-id " ) ;
// OR use extension method for convenience!
var runList = await thread . ListRunsAsync ( ) ;
foreach ( var run in runList . Items )
{
Debug . Log ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ;
} 달리기를 만듭니다.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a personal math tutor. Answer questions briefly, in a sentence or less. " ,
model : Model . GPT4o ) ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var message = await thread . CreateMessageAsync ( " I need to solve the equation `3x + 11 = 14`. Can you help me? " ) ;
var run = await thread . CreateRunAsync ( assistant ) ;
Debug . Log ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ; 실행을 만들고 이벤트를 스트리밍하십시오.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a personal math tutor. Answer questions briefly, in a sentence or less. Your responses should be formatted in JSON. " ,
model : Model . GPT4o ,
responseFormat : ChatResponseFormat . Json ) ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var message = await thread . CreateMessageAsync ( " I need to solve the equation `3x + 11 = 14`. Can you help me? " ) ;
var run = await thread . CreateRunAsync ( assistant , async streamEvent =>
{
Debug . Log ( streamEvent . ToJsonString ( ) ) ;
await Task . CompletedTask ;
} ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . Reverse ( ) )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
} 달리기를 검색합니다.
var api = new OpenAIClient ( ) ;
var run = await api . ThreadsEndpoint . RetrieveRunAsync ( " thread-id " , " run-id " ) ;
// OR use extension method for convenience!
var run = await thread . RetrieveRunAsync ( " run-id " ) ;
var run = await run . UpdateAsync ( ) ;
Debug . Log ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ; 실행을 수정합니다.
참고 : 메타 데이터 만 수정할 수 있습니다.
var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , string >
{
{ " key " , " custom run metadata " }
} ;
var run = await api . ThreadsEndpoint . ModifyRunAsync ( " thread-id " , " run-id " , metadata ) ;
// OR use extension method for convenience!
var run = await run . ModifyAsync ( metadata ) ;
Debug . Log ( $" Modify run { run . Id } -> { run . Metadata [ " key " ] } " ) ; 실행에 상태가있는 경우 : requires_action 및 required_action.type 가 submit_tool_outputs 입니다.이 엔드 포인트는 모두 완료되면 도구 호출에서 출력을 제출하는 데 사용될 수 있습니다. 모든 출력은 단일 요청으로 제출해야합니다.
메모
도구 출력 이벤트를 스트리밍하는 방법에 대한 스레드 생성 및 실행 스트리밍 예제를 참조하십시오.
var api = new OpenAIClient ( ) ;
var tools = new List < Tool >
{
// Use a predefined tool
Tool . Retrieval , Tool . CodeInterpreter ,
// Or create a tool from a type and the name of the method you want to use for function calling
Tool . GetOrCreateTool ( typeof ( WeatherService ) , nameof ( WeatherService . GetCurrentWeatherAsync ) ) ,
// Pass in an instance of an object to call a method on it
Tool . GetOrCreateTool ( api . ImagesEndPoint , nameof ( ImagesEndpoint . GenerateImageAsync ) ) ,
// Define func<,> callbacks
Tool . FromFunc ( " name_of_func " , ( ) => { /* callback function */ } ) ,
Tool . FromFunc < T1 , T2 , TResult > ( " func_with_multiple_params " , ( t1 , t2 ) => { /* logic that calculates return value */ return tResult ; } )
} ;
var assistantRequest = new CreateAssistantRequest ( tools : tools , instructions : " You are a helpful weather assistant. Use the appropriate unit based on geographical location. " ) ;
var testAssistant = await api . AssistantsEndpoint . CreateAssistantAsync ( assistantRequest ) ;
var run = await testAssistant . CreateThreadAndRunAsync ( " I'm in Kuala-Lumpur, please tell me what's the temperature now? " ) ;
// waiting while run is Queued and InProgress
run = await run . WaitForStatusChangeAsync ( ) ;
// Invoke all of the tool call functions and return the tool outputs.
var toolOutputs = await testAssistant . GetToolOutputsAsync ( run . RequiredAction . SubmitToolOutputs . ToolCalls ) ;
foreach ( var toolOutput in toolOutputs )
{
Debug . Log ( $" tool call output: { toolOutput . Output } " ) ;
}
// submit the tool outputs
run = await run . SubmitToolOutputsAsync ( toolOutputs ) ;
// waiting while run in Queued and InProgress
run = await run . WaitForStatusChangeAsync ( ) ;
var messages = await run . ListMessagesAsync ( ) ;
foreach ( var message in messages . Items . OrderBy ( response => response . CreatedAt ) )
{
Debug . Log ( $" { message . Role } : { message . PrintContent ( ) } " ) ;
} 구조화 된 출력은 JSON 모드의 진화입니다. 둘 다 유효한 JSON이 생성되지만 구조화 된 출력 만 스키마 준수를 보장합니다.
중요한
finish_reason 이 길이 인 경우 모델 리턴 메시지의 메시지에서 JSON은 부분적 일 수 있으며, 이는 생성이 max_tokens를 초과하거나 대화가 토큰 한계를 초과했음을 나타냅니다. 이를 막으려면 응답을 구문 분석하기 전에 finish_reason 확인하십시오.먼저 응답의 구조를 정의하십시오. 이들은 스키마로 사용됩니다. 이것들은 당신이 할인 할 객체이므로 표준 JSON 객체 모델을 사용해야합니다.
public class MathResponse
{
[ JsonProperty ( " steps " ) ]
public IReadOnlyList < MathStep > Steps { get ; private set ; }
[ JsonProperty ( " final_answer " ) ]
public string FinalAnswer { get ; private set ; }
}
public class MathStep
{
[ JsonProperty ( " explanation " ) ]
public string Explanation { get ; private set ; }
[ JsonProperty ( " output " ) ]
public string Output { get ; private set ; }
} 사용하려면 MathResponse 유형을 CreateAssistantAsync , CreateRunAsync 또는 CreateThreadAndRunAsync 에서 일반적인 제약으로 지정하십시오.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync < MathResponse > (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a helpful math tutor. Guide the user through the solution step by step. " ,
model : " gpt-4o-2024-08-06 " ) ) ;
ThreadResponse thread = null ;
try
{
async Task StreamEventHandler ( IServerSentEvent @event )
{
try
{
switch ( @event )
{
case MessageResponse message :
if ( message . Status != MessageStatus . Completed )
{
Debug . Log ( @event . ToJsonString ( ) ) ;
break ;
}
var mathResponse = message . FromSchema < MathResponse > ( ) ;
for ( var i = 0 ; i < mathResponse . Steps . Count ; i ++ )
{
var step = mathResponse . Steps [ i ] ;
Debug . Log ( $" Step { i } : { step . Explanation } " ) ;
Debug . Log ( $" Result: { step . Output } " ) ;
}
Debug . Log ( $" Final Answer: { mathResponse . FinalAnswer } " ) ;
break ;
default :
Debug . Log ( @event . ToJsonString ( ) ) ;
break ;
}
}
catch ( Exception e )
{
Debug . Log ( e ) ;
throw ;
}
await Task . CompletedTask ;
}
var run = await assistant . CreateThreadAndRunAsync ( " how can I solve 8x + 7 = -23 " , StreamEventHandler ) ;
thread = await run . GetThreadAsync ( ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
Debug . Log ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . OrderBy ( response => response . CreatedAt ) )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
}
}
finally
{
await assistant . DeleteAsync ( deleteToolResources : thread == null ) ;
if ( thread != null )
{
var isDeleted = await thread . DeleteAsync ( deleteToolResources : true ) ;
}
}JSON Schema JSON 문자열도 수동으로 만들 수 있지만 응답 데이터를 필수화 할 책임이 있습니다.
var api = new OpenAIClient ( ) ;
var mathSchema = new JsonSchema ( " math_response " , @"
{
""type"": ""object"",
""properties"": {
""steps"": {
""type"": ""array"",
""items"": {
""type"": ""object"",
""properties"": {
""explanation"": {
""type"": ""string""
},
""output"": {
""type"": ""string""
}
},
""required"": [
""explanation"",
""output""
],
""additionalProperties"": false
}
},
""final_answer"": {
""type"": ""string""
}
},
""required"": [
""steps"",
""final_answer""
],
""additionalProperties"": false
}" ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a helpful math tutor. Guide the user through the solution step by step. " ,
model : " gpt-4o-2024-08-06 " ,
jsonSchema : mathSchema ) ) ;
ThreadResponse thread = null ;
try
{
var run = await assistant . CreateThreadAndRunAsync ( " how can I solve 8x + 7 = -23 " ,
async @event =>
{
Debug . Log ( @event . ToJsonString ( ) ) ;
await Task . CompletedTask ;
} ) ;
thread = await run . GetThreadAsync ( ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
Debug . Log ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
}
}
finally
{
await assistant . DeleteAsync ( deleteToolResources : thread == null ) ;
if ( thread != null )
{
var isDeleted = await thread . DeleteAsync ( deleteToolResources : true ) ;
Assert . IsTrue ( isDeleted ) ;
}
} 실행에 속하는 실행 단계 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var runStepList = await api . ThreadsEndpoint . ListRunStepsAsync ( " thread-id " , " run-id " ) ;
// OR use extension method for convenience!
var runStepList = await run . ListRunStepsAsync ( ) ;
foreach ( var runStep in runStepList . Items )
{
Debug . Log ( $" [ { runStep . Id } ] { runStep . Status } { runStep . CreatedAt } -> { runStep . ExpiresAt } " ) ;
} 실행 단계를 검색합니다.
var api = new OpenAIClient ( ) ;
var runStep = await api . ThreadsEndpoint . RetrieveRunStepAsync ( " thread-id " , " run-id " , " step-id " ) ;
// OR use extension method for convenience!
var runStep = await run . RetrieveRunStepAsync ( " step-id " ) ;
var runStep = await runStep . UpdateAsync ( ) ;
Debug . Log ( $" [ { runStep . Id } ] { runStep . Status } { runStep . CreatedAt } -> { runStep . ExpiresAt } " ) ; in_progress 인 런을 취소합니다.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . ThreadsEndpoint . CancelRunAsync ( " thread-id " , " run-id " ) ;
// OR use extension method for convenience!
var isCancelled = await run . CancelAsync ( ) ;
Assert . IsTrue ( isCancelled ) ; 벡터 스토어는 file_search 도구에서 사용할 파일을 저장하는 데 사용됩니다.
Vector Stores API는 OpenAIClient.VectorStoresEndpoint 를 통해 액세스됩니다
벡터 상점 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var vectorStores = await api . VectorStoresEndpoint . ListVectorStoresAsync ( ) ;
foreach ( var vectorStore in vectorStores . Items )
{
Debug . Log ( vectorStore ) ;
} 벡터 스토어를 만듭니다.
var api = new OpenAIClient ( ) ;
var createVectorStoreRequest = new CreateVectorStoreRequest ( " test-vector-store " ) ;
var vectorStore = await api . VectorStoresEndpoint . CreateVectorStoreAsync ( createVectorStoreRequest ) ;
Debug . Log ( vectorStore ) ; 벡터 스토어를 검색합니다.
var api = new OpenAIClient ( ) ;
var vectorStore = await api . VectorStoresEndpoint . GetVectorStoreAsync ( " vector-store-id " ) ;
Debug . Log ( vectorStore ) ; 벡터 저장소를 수정합니다.
var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , object > { { " Test " , DateTime . UtcNow } } ;
var vectorStore = await api . VectorStoresEndpoint . ModifyVectorStoreAsync ( " vector-store-id " , metadata : metadata ) ;
Debug . Log ( vectorStore ) ; 벡터 저장소를 삭제하십시오.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreAsync ( " vector-store-id " ) ;
Assert . IsTrue ( isDeleted ) ; 벡터 스토어 파일은 벡터 스토어 내부의 파일을 나타냅니다.
벡터 저장 파일 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreFilesAsync ( " vector-store-id " ) ;
foreach ( var file in vectorStoreFiles . Items )
{
Debug . Log ( file ) ;
} 벡터 저장소에 파일을 첨부하여 벡터 저장 파일을 만듭니다.
var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . CreateVectorStoreFileAsync ( " vector-store-id " , " file-id " , new ChunkingStrategy ( ChunkingStrategyType . Static ) ) ;
Debug . Log ( file ) ; 벡터 스토어 파일을 검색합니다.
var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . GetVectorStoreFileAsync ( " vector-store-id " , " vector-store-file-id " ) ;
Debug . Log ( file ) ; 벡터 저장 파일을 삭제하십시오. 벡터 스토어에서 파일이 제거되지만 파일 자체는 삭제되지 않습니다. 파일을 삭제하려면 파일 삭제 엔드 포인트를 사용하십시오.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreFileAsync ( " vector-store-id " , vectorStoreFile ) ;
Assert . IsTrue ( isDeleted ) ; 벡터 스토어 파일은 벡터 스토어 내부의 파일을 나타냅니다.
벡터 스토어 파일 배치를 만듭니다.
var api = new OpenAIClient ( ) ;
var files = new List < string > { " file_id_1 " , " file_id_2 " } ;
var vectorStoreFileBatch = await api . VectorStoresEndpoint . CreateVectorStoreFileBatchAsync ( " vector-store-id " , files ) ;
Debug . Log ( vectorStoreFileBatch ) ; 벡터 스토어 파일 배치를 검색합니다.
var api = new OpenAIClient ( ) ;
var vectorStoreFileBatch = await api . VectorStoresEndpoint . GetVectorStoreFileBatchAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;
// you can also use convenience methods!
vectorStoreFileBatch = await vectorStoreFileBatch . UpdateAsync ( ) ;
vectorStoreFileBatch = await vectorStoreFileBatch . WaitForStatusChangeAsync ( ) ; 배치로 벡터 저장 파일 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreBatchFilesAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;
foreach ( var file in files . Items )
{
Debug . Log ( file ) ;
} 벡터 스토어 파일 배치를 취소하십시오. 이번 배치에서 가능한 빨리 파일 처리를 취소하려고 시도합니다.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . VectorStoresEndpoint . CancelVectorStoreFileBatchAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;채팅 대화가 주어지면 모델은 채팅 완료 응답을 반환합니다.
채팅 API는 OpenAIClient.ChatEndpoint 를 통해 액세스합니다
채팅 메시지에 대한 완료를 만듭니다
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , " Who won the world series in 2020? " ) ,
new Message ( Role . Assistant , " The Los Angeles Dodgers won the World Series in 2020. " ) ,
new Message ( Role . User , " Where was it played? " ) ,
} ;
var chatRequest = new ChatRequest ( messages , Model . GPT4o ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
var choice = response . FirstChoice ;
Debug . Log ( $" [ { choice . Index } ] { choice . Message . Role } : { choice . Message } | Finish Reason: { choice . FinishReason } " ) ; var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , " Who won the world series in 2020? " ) ,
new Message ( Role . Assistant , " The Los Angeles Dodgers won the World Series in 2020. " ) ,
new Message ( Role . User , " Where was it played? " ) ,
} ;
var chatRequest = new ChatRequest ( messages ) ;
var response = await api . ChatEndpoint . StreamCompletionAsync ( chatRequest , async partialResponse =>
{
Debug . Log ( partialResponse . FirstChoice . Delta . ToString ( ) ) ;
await Task . CompletedTask ;
} ) ;
var choice = response . FirstChoice ;
Debug . Log ( $" [ { choice . Index } ] { choice . Message . Role } : { choice . Message } | Finish Reason: { choice . FinishReason } " ) ; var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new ( Role . System , " You are a helpful weather assistant. Always prompt the user for their location. " ) ,
new Message ( Role . User , " What's the weather like today? " ) ,
} ;
foreach ( var message in messages )
{
Debug . Log ( $" { message . Role } : { message } " ) ;
}
// Define the tools that the assistant is able to use:
// 1. Get a list of all the static methods decorated with FunctionAttribute
var tools = Tool . GetAllAvailableTools ( includeDefaults : false , forceUpdate : true , clearCache : true ) ;
// 2. Define a custom list of tools:
var tools = new List < Tool >
{
Tool . GetOrCreateTool ( objectInstance , " TheNameOfTheMethodToCall " ) ,
Tool . FromFunc ( " a_custom_name_for_your_function " , ( ) => { /* Some logic to run */ } )
} ;
var chatRequest = new ChatRequest ( messages , tools : tools , toolChoice : " auto " ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
messages . Add ( response . FirstChoice . Message ) ;
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
var locationMessage = new Message ( Role . User , " I'm in Glasgow, Scotland " ) ;
messages . Add ( locationMessage ) ;
Debug . Log ( $" { locationMessage . Role } : { locationMessage . Content } " ) ;
chatRequest = new ChatRequest ( messages , tools : tools , toolChoice : " auto " ) ;
response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
messages . Add ( response . FirstChoice . Message ) ;
if ( response . FirstChoice . FinishReason == " stop " )
{
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
var unitMessage = new Message ( Role . User , " Fahrenheit " ) ;
messages . Add ( unitMessage ) ;
Debug . Log ( $" { unitMessage . Role } : { unitMessage . Content } " ) ;
chatRequest = new ChatRequest ( messages , tools : tools , toolChoice : " auto " ) ;
response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
}
// iterate over all tool calls and invoke them
foreach ( var toolCall in response . FirstChoice . Message . ToolCalls )
{
Debug . Log ( $" { response . FirstChoice . Message . Role } : { toolCall . Function . Name } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
Debug . Log ( $" { toolCall . Function . Arguments } " ) ;
// Invokes function to get a generic json result to return for tool call.
var functionResult = await toolCall . InvokeFunctionAsync ( ) ;
// If you know the return type and do additional processing you can use generic overload
var functionResult = await toolCall . InvokeFunctionAsync < string > ( ) ;
messages . Add ( new Message ( toolCall , functionResult ) ) ;
Debug . Log ( $" { Role . Tool } : { functionResult } " ) ;
}
// System: You are a helpful weather assistant.
// User: What's the weather like today?
// Assistant: Sure, may I know your current location? | Finish Reason: stop
// User: I'm in Glasgow, Scotland
// Assistant: GetCurrentWeather | Finish Reason: tool_calls
// {
// "location": "Glasgow, Scotland",
// "unit": "celsius"
// }
// Tool: The current weather in Glasgow, Scotland is 39°C. 경고
베타 기능. API 변경 사항이 적용됩니다.
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , new List < Content >
{
" What's in this image? " ,
new ImageUrl ( " https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg " , ImageDetail . Low )
} )
} ;
var chatRequest = new ChatRequest ( messages , model : Model . GPT4o ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice . Message . Content } | Finish Reason: { response . FirstChoice . FinishDetails } " ) ; Texture2D 를 통과 할 수도 있습니다!
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , new List < Content >
{
" What's in this image? " ,
texture
} )
} ;
var chatRequest = new ChatRequest ( messages , model : Model . GPT4o ) ;
var result = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
Debug . Log ( $" { result . FirstChoice . Message . Role } : { result . FirstChoice } | Finish Reason: { result . FirstChoice . FinishDetails } " ) ; var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , " Is a golden retriever a good family dog? " )
} ;
var chatRequest = new ChatRequest ( messages , Model . GPT4oAudio , audioConfig : Voice . Alloy ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishDetails } " ) ;
audioSource . PlayOneShot ( response . FirstChoice . Message . AudioOutput . AudioClip ) ; JSON 모드의 진화. 둘 다 유효한 JSON이 생성되지만 구조화 된 출력 만 스키마 준수를 보장합니다.
중요한
finish_reason 이 길이 인 경우 모델 리턴 메시지의 메시지에서 JSON은 부분적 일 수 있으며, 이는 생성이 max_tokens를 초과하거나 대화가 토큰 한계를 초과했음을 나타냅니다. 이를 막으려면 응답을 구문 분석하기 전에 finish_reason 확인하십시오.먼저 응답의 구조를 정의하십시오. 이들은 스키마로 사용됩니다. 이것들은 당신이 할인 할 객체이므로 표준 JSON 객체 모델을 사용해야합니다.
public class MathResponse
{
[ JsonProperty ( " steps " ) ]
public IReadOnlyList < MathStep > Steps { get ; private set ; }
[ JsonProperty ( " final_answer " ) ]
public string FinalAnswer { get ; private set ; }
}
public class MathStep
{
[ JsonProperty ( " explanation " ) ]
public string Explanation { get ; private set ; }
[ JsonProperty ( " output " ) ]
public string Output { get ; private set ; }
} 사용하려면 완료를 요청할 때 MathResponse 유형을 일반적인 제약으로 지정하십시오.
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new ( Role . System , " You are a helpful math tutor. Guide the user through the solution step by step. " ) ,
new ( Role . User , " how can I solve 8x + 7 = -23 " )
} ;
var chatRequest = new ChatRequest ( messages , model : " gpt-4o-2024-08-06 " ) ;
var ( mathResponse , chatResponse ) = await api . ChatEndpoint . GetCompletionAsync < MathResponse > ( chatRequest ) ;
for ( var i = 0 ; i < mathResponse . Steps . Count ; i ++ )
{
var step = mathResponse . Steps [ i ] ;
Debug . Log ( $" Step { i } : { step . Explanation } " ) ;
Debug . Log ( $" Result: { step . Output } " ) ;
}
Debug . Log ( $" Final Answer: { mathResponse . FinalAnswer } " ) ;
chatResponse . GetUsage ( ) ; 중요한
finish_reason 이 길이 인 경우 모델 리턴 메시지의 메시지에서 JSON은 부분적 일 수 있으며, 이는 생성이 max_tokens를 초과하거나 대화가 토큰 한계를 초과했음을 나타냅니다. 이를 막으려면 응답을 구문 분석하기 전에 finish_reason 확인하십시오. var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant designed to output JSON. " ) ,
new Message ( Role . User , " Who won the world series in 2020? " ) ,
} ;
var chatRequest = new ChatRequest ( messages , Model . GPT4o , responseFormat : ChatResponseFormat . Json ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
foreach ( var choice in response . Choices )
{
Debug . Log ( $" [ { choice . Index } ] { choice . Message . Role } : { choice } | Finish Reason: { choice . FinishReason } " ) ;
}
response . GetUsage ( ) ;오디오를 텍스트로 변환합니다.
오디오 API는 OpenAIClient.AudioEndpoint 를 통해 액세스됩니다
입력 텍스트에서 오디오를 생성합니다.
var api = new OpenAIClient ( ) ;
var request = new SpeechRequest ( " Hello world! " ) ;
var speechClip = await api . AudioEndpoint . GetSpeechAsync ( request ) ;
audioSource . PlayOneShot ( speechClip ) ;
Debug . Log ( speechClip ) ; 입력 텍스트에서 스트리밍 오디오를 생성합니다.
var api = new OpenAIClient ( ) ;
var request = new SpeechRequest ( " Hello world! " , responseFormat : SpeechResponseFormat . PCM ) ;
var speechClip = await api . AudioEndpoint . GetSpeechAsync ( request , partialClip =>
{
audioSource . PlayOneShot ( partialClip ) ;
} ) ;
Debug . Log ( speechClip ) ; 메모
OnAudioFilterRead 로 재생을 처리하는 방법에 대한 모범 사례에 대한 데모 장면을 확인하십시오.
오디오를 입력 언어로 전사합니다.
var api = new OpenAIClient ( ) ;
var request = new AudioTranscriptionRequest ( audioClip , language : " en " ) ;
var result = await api . AudioEndpoint . CreateTranscriptionAsync ( request ) ;
Debug . Log ( result ) ; verbose_json 사용하여 세부 정보를 얻으려면 타임 스탬프 세분화를 얻을 수도 있습니다.
var api = new OpenAIClient ( ) ;
using var request = new AudioTranscriptionRequest ( transcriptionAudio , responseFormat : AudioResponseFormat . Verbose_Json , timestampGranularity : TimestampGranularity . Word , temperature : 0.1f , language : " en " ) ;
var response = await api . AudioEndpoint . CreateTranscriptionTextAsync ( request ) ;
foreach ( var word in response . Words )
{
Debug . Log ( $" [ { word . Start } - { word . End } ] " { word . Word } " " ) ;
} 오디오를 영어로 변환합니다.
var api = new OpenAIClient ( ) ;
var request = new AudioTranslationRequest ( audioClip ) ;
var result = await api . AudioEndpoint . CreateTranslationAsync ( request ) ;
Debug . Log ( result ) ;프롬프트 및/또는 입력 이미지가 주어지면 모델은 새 이미지를 생성합니다.
이미지 API는 OpenAIClient.ImagesEndpoint 를 통해 액세스됩니다
프롬프트가 주어진 이미지를 만듭니다.
var api = new OpenAIClient ( ) ;
var request = new ImageGenerationRequest ( " A house riding a velociraptor " , Models . Model . DallE_3 ) ;
var imageResults = await api . ImagesEndPoint . GenerateImageAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
} 원본 이미지와 프롬프트가 주어지면 편집 또는 확장 된 이미지를 만듭니다.
var api = new OpenAIClient ( ) ;
var request = new ImageEditRequest ( Path . GetFullPath ( imageAssetPath ) , Path . GetFullPath ( maskAssetPath ) , " A sunlit indoor lounge area with a pool containing a flamingo " , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageEditAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
} 주어진 이미지의 변형을 만듭니다.
var api = new OpenAIClient ( ) ;
var request = new ImageVariationRequest ( imageTexture , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageVariationAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
}또는 엔드 포인트는 읽기/쓰기가 활성화되고 압축이 없음으로 직접 Texture2D를 취할 수 있습니다.
var api = new OpenAIClient ( ) ;
var request = new ImageVariationRequest ( imageTexture , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageVariationAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
}파일은 미세 조정과 같은 기능에서 사용할 수있는 문서를 업로드하는 데 사용됩니다.
파일 API는 OpenAIClient.FilesEndpoint 를 통해 액세스됩니다
사용자 조직에 속하는 파일 목록을 반환합니다.
var api = new OpenAIClient ( ) ;
var fileList = await api . FilesEndpoint . ListFilesAsync ( ) ;
foreach ( var file in fileList )
{
Debug . Log ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ;
} 다양한 엔드 포인트에서 사용할 수있는 파일을 업로드하십시오. 한 조직에서 업로드 한 모든 파일의 크기는 최대 100GB 일 수 있습니다.
개별 파일의 크기는 최대 512MB 일 수 있습니다. 지원되는 파일 유형에 대해 자세히 알아 보려면 어시스턴트 도구 안내서를 참조하십시오. 미세 조정 API는 .jsonl 파일 만 지원합니다.
var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . UploadFileAsync ( " path/to/your/file.jsonl " , FilePurpose . FineTune ) ;
Debug . Log ( file . Id ) ; 파일을 삭제하십시오.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . FilesEndpoint . DeleteFileAsync ( fileId ) ;
Assert . IsTrue ( isDeleted ) ; 특정 파일에 대한 정보를 반환합니다.
var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . GetFileInfoAsync ( fileId ) ;
Debug . Log ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ; 파일 내용을 지정된 디렉토리로 다운로드합니다.
var api = new OpenAIClient ( ) ;
var downloadedFilePath = await api . FilesEndpoint . DownloadFileAsync ( fileId ) ;
Debug . Log ( downloadedFilePath ) ;
Assert . IsTrue ( File . Exists ( downloadedFilePath ) ) ;미세 조정 작업을 관리하여 특정 교육 데이터에 모델을 조정하십시오.
관련 안내서 : 미세 조정 모델
파일 API는 OpenAIClient.FineTuningEndpoint 를 통해 액세스됩니다
주어진 데이터 세트에서 지정된 모델을 미세 조정하는 작업을 만듭니다.
응답에는 직무 상태와 미세 조정 된 모델의 이름을 포함한 queureed 작업의 세부 사항이 포함되어 있습니다.
var api = new OpenAIClient ( ) ;
var fileId = " file-abc123 " ;
var request = new CreateFineTuneRequest ( fileId ) ;
var job = await api . FineTuningEndpoint . CreateJobAsync ( Model . GPT3_5_Turbo , request ) ;
Debug . Log ( $" Started { job . Id } | Status: { job . Status } " ) ; 조직의 미세 조정 작업을 나열하십시오.
var api = new OpenAIClient ( ) ;
var jobList = await api . FineTuningEndpoint . ListJobsAsync ( ) ;
foreach ( var job in jobList . Items . OrderByDescending ( job => job . CreatedAt ) ) )
{
Debug . Log ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ;
} 미세 조정 작업에 대한 정보를 얻습니다.
var api = new OpenAIClient ( ) ;
var job = await api . FineTuningEndpoint . GetJobInfoAsync ( fineTuneJob ) ;
Debug . Log ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ; 즉시 미세 조정 작업을 취소하십시오.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . FineTuningEndpoint . CancelFineTuneJobAsync ( fineTuneJob ) ;
Assert . IsTrue ( isCancelled ) ; 미세 조정 작업에 대한 상태 업데이트를 받으십시오.
var api = new OpenAIClient ( ) ;
var eventList = await api . FineTuningEndpoint . ListJobEventsAsync ( fineTuneJob ) ;
Debug . Log ( $" { fineTuneJob . Id } -> status: { fineTuneJob . Status } | event count: { eventList . Events . Count } " ) ;
foreach ( var @event in eventList . Items . OrderByDescending ( @event => @event . CreatedAt ) )
{
Debug . Log ( $" { @event . CreatedAt } [ { @event . Level } ] { @event . Message } " ) ;
}비동기 처리에 대한 대량의 API 요청을 만듭니다. 배치 API는 24 시간 이내에 완료를 50% 할인으로 반환합니다.
배치 API는 OpenAIClient.BatchesEndpoint 를 통해 액세스됩니다
조직의 배치를 나열하십시오.
var api = new OpenAIClient ( ) ;
var batches = await api . BatchEndpoint . ListBatchesAsync ( ) ;
foreach ( var batch in listResponse . Items )
{
Debug . Log ( batch ) ;
} 업로드 된 요청 파일에서 배치를 생성하고 실행합니다.
var api = new OpenAIClient ( ) ;
var batchRequest = new CreateBatchRequest ( " file-id " , Endpoint . ChatCompletions ) ;
var batch = await api . BatchEndpoint . CreateBatchAsync ( batchRequest ) ; 배치를 검색합니다.
var api = new OpenAIClient ( ) ;
var batch = await api . BatchEndpoint . RetrieveBatchAsync ( " batch-id " ) ;
// you can also use convenience methods!
batch = await batch . UpdateAsync ( ) ;
batch = await batch . WaitForStatusChangeAsync ( ) ; 진행중인 배치를 취소합니다. 배치는 취소로 변경하기 전에 최대 10 분 동안 상태 취소되어 출력 파일에서 부분 결과 (있는 경우)가 제공됩니다.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . BatchEndpoint . CancelBatchAsync ( batch ) ;
Assert . IsTrue ( isCancelled ) ;기계 학습 모델 및 알고리즘으로 쉽게 소비 할 수있는 주어진 입력의 벡터 표현을 얻으십시오.
관련 안내서 : 임베딩
편집 API는 OpenAIClient.EmbeddingsEndpoint 를 통해 액세스됩니다
입력 텍스트를 나타내는 임베딩 벡터를 만듭니다.
var api = new OpenAIClient ( ) ;
var response = await api . EmbeddingsEndpoint . CreateEmbeddingAsync ( " The food was delicious and the waiter... " , Models . Embedding_Ada_002 ) ;
Debug . Log ( response ) ;입력 텍스트가 주어지면 모델이 OpenAI의 컨텐츠 정책을 위반하는 것으로 분류되는 경우 출력됩니다.
관련 안내서 : 중재
중재 API는 OpenAIClient.ModerationsEndpoint 를 통해 액세스 할 수 있습니다
텍스트가 OpenAI의 컨텐츠 정책을 위반하는지 분류합니다.
var api = new OpenAIClient ( ) ;
var isViolation = await api . ModerationsEndpoint . GetModerationAsync ( " I want to kill them. " ) ;
Assert . IsTrue ( isViolation ) ;또한 주어진 입력의 점수를 얻을 수도 있습니다.
var api = new OpenAIClient ( ) ;
var response = await api . ModerationsEndpoint . CreateModerationAsync ( new ModerationsRequest ( " I love you " ) ) ;
Assert . IsNotNull ( response ) ;
Debug . Log ( response . Results ? [ 0 ] ? . Scores ? . ToString ( ) ) ;