Share via


JavaScript용 Azure OpenAI Assistants 클라이언트 라이브러리 - 버전 1.0.0-beta.5

JavaScript용 Azure OpenAI Assistants 클라이언트 라이브러리는 Idiomatic 인터페이스를 제공하고 나머지 Azure SDK 에코시스템과 풍부한 통합을 제공하는 OpenAI의 REST API를 적응한 것입니다. Azure OpenAI 리소스 또는 비 Azure OpenAI 유추 엔드포인트에 연결할 수 있으므로 비 Azure OpenAI 개발에도 적합합니다.

주요 링크:

시작

현재 지원되는 환경

사전 요구 사항

Azure OpenAI 리소스를 사용하려면 Azure 구독Azure OpenAI 액세스 권한이 있어야 합니다. 이렇게 하면 Azure OpenAI 리소스를 만들고 연결 URL과 API 키를 모두 가져올 수 있습니다. 자세한 내용은 빠른 시작: Azure OpenAI Service를 사용하여 텍스트 생성 시작을 참조하세요.

Azure OpenAI Assistants JS 클라이언트 라이브러리를 사용하여 비 Azure OpenAI에 연결하려면 의 개발자 계정 https://platform.openai.com/에서 API 키가 필요합니다.

@azure/openai-assistants 패키지를 설치합니다.

를 사용하여 JavaScript용 Azure OpenAI Assistants 클라이언트 라이브러리를 npm설치합니다.

npm install @azure/openai-assistants

AssistantsClient 만들기 및 인증

Azure OpenAI에서 사용할 클라이언트를 구성하려면 Azure OpenAI 리소스를 사용할 수 있는 권한이 부여된 해당 키 자격 증명, 토큰 자격 증명 또는 Azure ID 자격 증명과 함께 Azure OpenAI 리소스에 유효한 엔드포인트 URI를 제공합니다. 대신 OpenAI의 서비스에 연결하도록 클라이언트를 구성하려면 OpenAI의 개발자 포털에서 API 키를 제공합니다.

Azure에서 API 키 사용

Azure Portal을 사용하여 OpenAI 리소스로 이동하고 API 키를 검색하거나 아래 Azure CLI 코드 조각을 사용합니다.

참고: API 키를 "구독 키" 또는 "구독 API 키"라고도 합니다.

az cognitiveservices account keys list --resource-group <your-resource-group-name> --name <your-resource-name>

주요 개념

도우미와 함께 사용되는 개념 및 관계에 대한 개요는 OpenAI의 "도우미 작동 방식" 설명서를 참조하세요. 이 개요는 OpenAI의 개요 예제 에 따라 도우미 및 스레드를 만들고, 실행하고, 사용하는 기본 사항을 보여 줍니다.

시작하려면 을 만듭니다 AssistantsClient.

const assistantsClient = new AssistantsClient("<endpoint>", new AzureKeyCredential("<azure_api_key>"));

클라이언트를 사용하면 도우미 만들 수 있습니다. 도우미 도구는 도우미 수명 동안 개략적인 지침을 허용하면서 도구를 호출할 수 있는 OpenAI 모델에 대한 특별히 빌드된 인터페이스입니다.

도우미 만드는 코드:

const assistant = await assistantsClient.createAssistant({
  model: "gpt-4-1106-preview",
  name: "JS Math Tutor",
  instructions: "You are a personal math tutor. Write and run code to answer math questions.",
  tools: [{ type: "code_interpreter" }]
});

도우미와 사용자 간의 대화 세션을 스레드라고 합니다. 스레드는 메시지를 저장하고 콘텐츠를 모델의 컨텍스트에 맞게 잘림을 자동으로 처리합니다.

스레드를 만들려면 다음을 수행합니다.

const assistantThread = await assistantsClient.createThread();

메시지는 도우미 또는 사용자가 만든 메시지를 나타냅니다. 메시지에는 텍스트, 이미지 및 기타 파일이 포함될 수 있습니다. 메시지는 스레드의 목록으로 저장됩니다. 스레드를 만들면 메시지를 만들 수 있습니다.

const question = "I need to solve the equation '3x + 11 = 14'. Can you help me?";
const messageResponse = await assistantsClient.createMessage(assistantThread.id, "user", question);

실행은 스레드에서 도우미의 호출을 나타냅니다. 도우미는 구성 및 스레드의 메시지를 사용하여 모델 및 도구를 호출하여 작업을 수행합니다. 실행의 일부로 도우미는 스레드에 메시지를 추가합니다. 그런 다음 도우미 대해 스레드를 평가하는 실행을 시작할 수 있습니다.

let runResponse = await assistantsClient.createRun(assistantThread.id, {
   assistantId: assistant.id,
   instructions: "Please address the user as Jane Doe. The user has a premium account." 
});

실행이 시작되면 터미널 상태 도달할 때까지 폴링되어야 합니다.

do {
  await new Promise((resolve) => setTimeout(resolve, 800));
  runResponse = await assistantsClient.getRun(assistantThread.id, runResponse.id);
} while (runResponse.status === "queued" || runResponse.status === "in_progress")

실행이 성공적으로 완료되었다고 가정하면 실행된 스레드의 메시지를 나열하면 이제 도우미 추가된 새 정보가 반영됩니다.

const runMessages = await assistantsClient.listMessages(assistantThread.id);
for (const runMessageDatum of runMessages.data) {
  for (const item of runMessageDatum.content) {
    if (item.type === "text") {
      console.log(item.text.value);
    } else if (item.type === "image_file") {
      console.log(item.imageFile.fileId);
    }
  }
}

이 시퀀스의 출력 예제:

2023-11-14 20:21:23 -  assistant: The solution to the equation \(3x + 11 = 14\) is \(x = 1\).
2023-11-14 20:21:18 -       user: I need to solve the equation `3x + 11 = 14`. Can you help me?

검색을 위해 파일 작업

파일을 업로드한 다음 도우미 또는 메시지에서 참조할 수 있습니다. 먼저 'assistants'를 목적으로 일반화된 업로드 API를 사용하여 파일 ID를 사용할 수 있도록 합니다.

const filename = "<path_to_text_file>";
await fs.writeFile(filename, "The word 'apple' uses the code 442345, while the word 'banana' uses the code 673457.", "utf8");
const uint8array = await fs.readFile(filename);
const uploadAssistantFile = await assistantsClient.uploadFile(uint8array, "assistants", { filename });

업로드되면 파일 ID를 만들 때 도우미 제공할 수 있습니다. 파일 ID는 코드 인터프리터 또는 검색과 같은 적절한 도구를 사용하도록 설정한 경우에만 사용됩니다.

const fileAssistant = await assistantsClient.createAssistant({
  model: "gpt-4-1106-preview",
  name: "JS SDK Test Assistant - Retrieval",
  instructions: "You are a helpful assistant that can help fetch data from files you know about.",
  tools: [{ type: "retrieval" }],
  fileIds: [ uploadAssistantFile.id ]
});

파일 ID 연결 및 지원되는 도구를 사용하도록 설정하면 도우미 스레드를 실행할 때 연결된 데이터를 사용할 수 있습니다.

함수 도구 및 병렬 함수 호출 사용

도우미 도구에 대한 OpenAI 설명서에 설명된 대로 호출자 정의 기능을 함수로 참조하는 도구를 도우미 제공하여 실행 중에 동적으로 resolve 명확하게 할 수 있습니다.

여기서는 호출자가 제공하는 함수를 통해 "방법을 알고 있다"는 간단한 도우미 간략하게 설명합니다.

  1. 사용자가 가장 좋아하는 도시 가져오기
  2. 지정된 도시에 대한 애칭 가져오기
  3. 도시의 온도 단위를 사용하여 현재 날씨를 선택적으로 가져옵니다.

이렇게 하려면 먼저 사용할 함수를 정의합니다. 여기서 실제 구현은 단지 대표적인 스텁일 뿐입니다.

// Example of a function that defines no parameters
const getFavoriteCity = () => "Atlanta, GA";
const getUserFavoriteCityTool = { 
  type: "function",
  function: {
    name: "getUserFavoriteCity",
    description: "Gets the user's favorite city.",
    parameters: {
      type: "object",
      properties: {}
    }
  }
}; 

// Example of a function with a single required parameter
const getCityNickname = (city) => { 
  switch (city) { 
    case "Atlanta, GA": 
      return "The ATL"; 
    case "Seattle, WA": 
      return "The Emerald City"; 
    case "Los Angeles, CA":
      return "LA"; 
    default: 
      return "Unknown"; 
  }
};

const getCityNicknameTool = { 
  type: "function",
  function: {
    name: "getCityNickname",
    description: "Gets the nickname for a city, e.g. 'LA' for 'Los Angeles, CA'.",
    parameters: { 
      type: "object",
      properties: { 
        city: {
          type: "string",
          description: "The city and state, e.g. San Francisco, CA"
        } 
      }
    }
  }
};

// Example of a function with one required and one optional, enum parameter
const getWeatherAtLocation = (location, temperatureUnit = "f") => {
  switch (location) { 
    case "Atlanta, GA": 
      return temperatureUnit === "f" ? "84f" : "26c"; 
    case "Seattle, WA": 
      return temperatureUnit === "f" ? "70f" : "21c"; 
    case "Los Angeles, CA":
      return temperatureUnit === "f" ? "90f" : "28c"; 
    default: 
      return "Unknown"; 
  }
};

const getWeatherAtLocationTool = { 
  type: "function",
  function: {
    name: "getWeatherAtLocation",
    description: "Gets the current weather at a provided location.",
    parameters: { 
      type: "object",
      properties: { 
        location: {
          type: "string",
          description: "The city and state, e.g. San Francisco, CA"
        },
        temperatureUnit: {
          type: "string",
          enum: ["f", "c"],
        }
      },
      required: ["location"]
    }
  }
};

적절한 도구에 정의된 함수를 사용하면 이제 해당 도구를 사용하도록 설정된 도우미 만들 수 있습니다.

  const weatherAssistant = await assistantsClient.createAssistant({
  // note: parallel function calling is only supported with newer models like gpt-4-1106-preview
  model: "gpt-4-1106-preview",
  name: "JS SDK Test Assistant - Weather",
  instructions: `You are a weather bot. Use the provided functions to help answer questions.
    Customize your responses to the user's preferences as much as possible and use friendly
    nicknames for cities whenever possible.
  `,
  tools: [getUserFavoriteCityTool, getCityNicknameTool, getWeatherAtLocationTool]
});

도우미 도구를 호출하는 경우 호출 코드는 인스턴스를 일치하는 ToolOutputSubmission 인스턴스로 resolve ToolCall 합니다. 편의를 위해 기본 예제는 여기에서 추출됩니다.

const getResolvedToolOutput = (toolCall) => {
  const toolOutput = { toolCallId: toolCall.id };

  if (toolCall["function"]) {
    const functionCall = toolCall["function"];
    const functionName = functionCall.name;
    const functionArgs = JSON.parse(functionCall["arguments"] ?? {});

    switch (functionName) {
      case "getUserFavoriteCity":
        toolOutput.output = getFavoriteCity();
        break;
      case "getCityNickname":
        toolOutput.output = getCityNickname(functionArgs["city"]);
        break;
      case "getWeatherAtLocation":
        toolOutput.output = getWeatherAtLocation(functionArgs.location, functionArgs.temperatureUnit);
        break;
      default:
        toolOutput.output = `Unknown function: ${functionName}`;
        break;
    }
  }
  return toolOutput;
};

"내가 가장 좋아하는 도시에서 지금 날씨는 어때?"와 같은 사용자 입력을 처리하려면 완료에 대한 응답을 폴링하는 검사 RequiresAction 보완 RunStatus 해야 합니다. 이 경우 실행에 속성이 RequiredAction 존재합니다. 그런 다음, 실행을 계속할 수 있도록 의 ToolOutputSubmissions 컬렉션을 메서드를 SubmitRunToolOutputs 통해 실행에 제출해야 합니다.

const question = "What's the weather like right now in my favorite city?";
let runResponse = await assistantsClient.createThreadAndRun({ 
  assistantId: weatherAssistant.id, 
  thread: { messages: [{ role: "user", content: question }] },
  tools: [getUserFavoriteCityTool, getCityNicknameTool, getWeatherAtLocationTool]
});

do {
  await new Promise((resolve) => setTimeout(resolve, 500));
  runResponse = await assistantsClient.getRun(runResponse.threadId, runResponse.id);
  
  if (runResponse.status === "requires_action" && runResponse.requiredAction.type === "submit_tool_outputs") {
    const toolOutputs = [];

    for (const toolCall of runResponse.requiredAction.submitToolOutputs.toolCalls) {
      toolOutputs.push(getResolvedToolOutput(toolCall));
    }
    runResponse = await assistantsClient.submitToolOutputsToRun(runResponse.threadId, runResponse.id, toolOutputs);
  }
} while (runResponse.status === "queued" || runResponse.status === "in_progress")

지원되는 모델을 사용하는 경우 도우미 여러 함수를 병렬로 호출할 것을 요청할 수 있습니다. 이전 모델은 한 번에 하나의 함수만 호출할 수 있습니다.

필요한 모든 함수 호출이 해결되면 실행이 정상적으로 진행되며 스레드의 완료된 메시지에는 제공된 함수 도구 출력으로 보완된 모델 출력이 포함됩니다.

문제 해결

로깅

로깅을 사용하도록 설정하면 실패에 대한 유용한 정보를 파악하는 데 도움이 될 수 있습니다. HTTP 요청 및 응답 로그를 보려면 AZURE_LOG_LEVEL 환경 변수를 info로 설정합니다. 또는 @azure/logger에서 setLogLevel을 호출하여 런타임에 로깅을 사용하도록 설정할 수 있습니다.

const { setLogLevel } = require("@azure/logger");

setLogLevel("info");

로그를 사용하는 방법에 대한 자세한 내용은 @azure/logger package docs를 참조하세요.