Megosztás a következőn keresztül:


Azure OpenAI Assistants ügyfélkódtár JavaScripthez – 1.0.0-beta.5-verzió

A JavaScripthez készült Azure OpenAI Assistants ügyfélkódtár az OpenAI REST API-k adaptációja, amely idiomatikus felületet és gazdag integrációt biztosít az Azure SDK-ökoszisztéma többi részével. Csatlakozhat az Azure OpenAI-erőforrásokhoz vagy a nem Azure OpenAI-következtetési végponthoz, így nagyszerű választás akár nem Azure OpenAI-fejlesztéshez is.

Főbb hivatkozások:

Első lépések

Jelenleg támogatott környezetek

Előfeltételek

Ha Azure OpenAI-erőforrást szeretne használni, azure-előfizetéssel és Azure OpenAI-hozzáféréssel kell rendelkeznie. Így létrehozhat egy Azure OpenAI-erőforrást, és lekérheti a kapcsolati URL-címet és az API-kulcsokat is. További információ : Rövid útmutató: Szöveg létrehozása az Azure OpenAI szolgáltatással.

Ha az Azure OpenAI Assistants JS ügyfélkódtárat szeretné használni a nem Azure OpenAI-hoz való csatlakozáshoz, szüksége lesz egy API-kulcsra egy fejlesztői fiókból a címen https://platform.openai.com/.

Telepítse a(z) @azure/openai-assistants csomagot

Telepítse a JavaScripthez készült Azure OpenAI Assistants ügyfélkódtárat a következővel npm:

npm install @azure/openai-assistants

Hozzon létre és hitelesítsen egy AssistantsClient

Ha az ügyfelet az Azure OpenAI-val való használatra szeretné konfigurálni, adjon meg egy érvényes végponti URI-t egy Azure OpenAI-erőforrásnak, valamint egy megfelelő kulcs-hitelesítő adatot, jogkivonat-hitelesítő adatot vagy Azure-identitás hitelesítő adatait, amely jogosult az Azure OpenAI-erőforrás használatára. Ha ehelyett úgy szeretné konfigurálni az ügyfelet, hogy csatlakozzon az OpenAI szolgáltatásához, adjon meg egy API-kulcsot az OpenAI fejlesztői portáljáról.

API-kulcs használata az Azure-ból

Az Azure Portalon keresse meg az OpenAI-erőforrást, és kérjen le egy API-kulcsot, vagy használja az alábbi Azure CLI-kódrészletet :

Megjegyzés: Néha az API-kulcsot "előfizetői azonosítónak" vagy "előfizetési API-kulcsnak" is nevezik.

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

Fő fogalmak

Az asszisztensekkel használt fogalmakról és kapcsolatokról az OpenAI "Hogyan működnek az asszisztensek" dokumentációjában talál áttekintést. Ez az áttekintés szorosan követi az OpenAI áttekintő példáját , amely bemutatja az asszisztensek és szálak létrehozásának, futtatásának és használatának alapjait.

Az első lépésekhez hozzon létre egy :AssistantsClient

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

Az ügyféllel ezután létre lehet hozni egy segéd. A segéd egy olyan, az OpenAI-modellek célhoz készült felülete, amely meghívja az Eszközöket, miközben magas szintű utasításokat tesz lehetővé a segéd élettartama során.

A segéd létrehozására vonatkozó kód:

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" }]
});

Az asszisztens és a felhasználó közötti beszélgetési munkamenetet szálnak nevezzük. A szálak tárolják az üzeneteket, és automatikusan kezelik a csonkolást, hogy a tartalom illeszkedjen a modell környezetébe.

Szál létrehozása:

const assistantThread = await assistantsClient.createThread();

Az üzenet egy asszisztens vagy egy felhasználó által létrehozott üzenetet jelöl. Az üzenetek tartalmazhatnak szöveget, képeket és más fájlokat. Az üzenetek listaként vannak tárolva a szálon. A létrehozott szálon üzenetek hozhatók létre:

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

A futtatás egy asszisztens meghívását jelenti egy szálon. A Segéd a konfigurációját és a szál üzeneteit használja a feladatok végrehajtásához modellek és eszközök meghívásával. A Futtatás részeként a Segéd hozzáfűzi az üzeneteket a szálhoz. Ezután elindítható egy futtatás, amely kiértékeli a szálat egy segéd:

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

A futtatás elindítása után le kell kérdezni, amíg el nem éri a terminál állapotát:

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

Ha a futtatás sikeresen befejeződött, a futtatott szál üzeneteinek listázása mostantól a segéd által hozzáadott új információkat fogja tükrözni:

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);
    }
  }
}

Példakimenet ebből a sorozatból:

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?

Fájlok használata lekéréshez

A fájlokat feltöltheti, majd az asszisztensek vagy üzenetek hivatkozhatnak rá. Először használja az általánosított upload API-t "asszisztensek" céllal, hogy elérhetővé tegye a fájlazonosítót:

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 });

A feltöltés után a fájlazonosítót a létrehozáskor meg lehet adni egy segéd. Vegye figyelembe, hogy a fájlazonosítók csak akkor lesznek használatban, ha engedélyezve van egy megfelelő eszköz, például a Kódértelmező vagy a Lekérés.

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 ]
});

Ha engedélyezve van egy fájlazonosító-társítás és egy támogatott eszköz, a segéd ezután felhasználhatja a kapcsolódó adatokat a szálak futtatásakor.

Függvényeszközök és párhuzamos függvényhívás használata

Az OpenAI segéd eszközökre vonatkozó dokumentációjában leírtak szerint a hívó által definiált képességekre függvényként hivatkozó eszközök biztosíthatók egy segéd, hogy lehetővé tegyék a dinamikus feloldást és egyértelműsítést a futtatás során.

Az alábbiakban egy egyszerű segéd mutatunk be, amely a hívó által biztosított függvényekkel "tudja, hogyan kell":

  1. A felhasználó kedvenc városának lekérése
  2. Becenév lekérése egy adott városhoz
  3. Az aktuális időjárás lekérése, opcionálisan egy hőmérsékleti egységgel egy városban

Ehhez először definiálja a használni kívánt függvényeket – a tényleges implementációk itt csupán reprezentatív csonkok.

// 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"]
    }
  }
};

A megfelelő eszközökben definiált függvényekkel segéd hozhatók létre, amelyeken engedélyezve vannak ezek az eszközök:

  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]
});

Ha a segéd eszközöket hív meg, a hívó kódnak egyező ToolOutputSubmission példányokra kell feloldania ToolCall a példányokat. Az egyszerűség kedvéért itt talál egy egyszerű példát:

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;
};

A felhasználói bevitel (például " milyen az időjárás most a kedvenc városomban?" – kezeléséhez a befejezésre adott válasz lekérdezését ki kell egészíteni egy RunStatus ellenőrzéssel RequiresAction , vagy ebben az esetben a RequiredAction tulajdonság futás közbeni jelenlétével. Ezután a gyűjteményt ToolOutputSubmissions a metódussal kell elküldeni a SubmitRunToolOutputs futtatásnak, hogy a futtatás folytatódjon:

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")

Vegye figyelembe, hogy támogatott modellek használata esetén a segéd több függvény párhuzamos meghívását kérheti. A régebbi modellek egyszerre csak egy függvényt hívhatnak meg.

Az összes szükséges függvényhívás feloldása után a futtatás a szokásos módon folytatódik, és a szál befejezett üzenetei a megadott függvényeszköz kimenetével kiegészített modellkimenetet tartalmazzák.

Hibaelhárítás

Naplózás

A naplózás engedélyezése hasznos információkat deríthet fel a hibákról. A HTTP-kérések és -válaszok naplójának megtekintéséhez állítsa a környezeti változót értékre AZURE_LOG_LEVELinfo. A naplózás futásidőben is engedélyezhető a következő hívásával setLogLevel@azure/logger:

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

setLogLevel("info");

A naplók engedélyezésére vonatkozó részletesebb utasításokért tekintse meg a @azure/logger csomag dokumentációját.