JavaScript용 Azure AI Projects 클라이언트 라이브러리 - 버전 1.0.0-beta.2
AI Projects 클라이언트 라이브러리(미리 보기)를 사용하여 다음을 수행합니다.
- Azure AI Foundry 프로젝트에서 연결을 열거하고 연결 속성을 가져옵니다. 예를 들어 Azure OpenAI 연결과 연결된 유추 엔드포인트 URL 및 자격 증명을 가져옵니다.
- Azure AI 에이전트 서비스사용하여 에이전트를 개발하여 OpenAI, Microsoft 및 기타 LLM 공급자의 광범위한 모델, 도구 및 기능 에코시스템을 활용합니다. Azure AI 에이전트 서비스를 사용하면 광범위한 생성 AI 사용 사례에 대한 에이전트를 빌드할 수 있습니다. 패키지는 현재 프라이빗 미리 보기로 제공됩니다.
- OpenTelemetry 추적사용하도록 설정합니다.
목차
-
시작
- 필수 구성 요소
- 패키지 설치
-
주요 개념
- 클라이언트 만들기 및 인증
-
예제
- 연결 열거
-
에이전트(미리 보기)
- 다음을 사용하여 에이전트 만듭니다.
- 다음으로 스레드 만들기
- 다음을 사용하여 메시지 만듭니다.
- 실행 실행, 스레드 만들기 및 실행 또는 스트림
- 메시지 검색
- 파일 검색
- 리소스 삭제하여
중단 - 추적
- 추적
- 문제 해결
- 기여
시작
전제 조건
- LTS 버전의 Node.js
- Azure 구독.
- Azure AI Foundry
프로젝트. - 프로젝트 연결 문자열입니다. Azure AI Foundry 프로젝트 개요 페이지의 "프로젝트 세부 정보"에서 찾을 수 있습니다. 아래에서는
AZURE_AI_PROJECTS_CONNECTION_STRING
환경 변수가 이 값을 보유하도록 정의되었다고 가정합니다. - 클라이언트를 인증하려면 Entra ID가 필요합니다. 애플리케이션에는 TokenCredential 인터페이스를 구현하는 개체가 필요합니다. 여기서 코드 샘플은 DefaultAzureCredential사용합니다. 이 작업을 수행하려면 다음이 필요합니다.
-
Contributor
역할입니다. 할당된 역할은 Azure Portal에서 Azure AI Project 리소스의 "액세스 제어(IAM)" 탭을 통해 수행할 수 있습니다. - Azure CLI 설치되어 있습니다.
-
az login
실행하여 Azure 계정에 로그인됩니다. - 여러 Azure 구독이 있는 경우 Azure AI Project 리소스를 포함하는 구독은 기본 구독이어야 합니다.
az account list --output table
실행하여 모든 구독을 나열하고 어떤 구독이 기본값인지 확인합니다.az account set --subscription "Your Subscription ID or Name"
실행하여 기본 구독을 변경합니다.
-
패키지 설치
npm install @azure/ai-projects
주요 개념
클라이언트 만들기 및 인증
fromConnectionString
클래스 팩터리 메서드는 클라이언트를 생성하는 데 사용됩니다. 클라이언트를 생성하려면 다음을 수행합니다.
import { AIProjectsClient } from "@azure/ai-projects";
import { DefaultAzureCredential } from "@azure/identity";
import "dotenv/config";
const connectionString = process.env["AZURE_AI_PROJECTS_CONNECTION_STRING"] || "<connectionString>";
const client = AIProjectsClient.fromConnectionString(
connectionString,
new DefaultAzureCredential(),
);
예제
연결 열거
Azure AI Foundry 프로젝트에는 "관리 센터"가 있습니다. 입력하면 프로젝트 아래에 "연결된 리소스"라는 탭이 표시됩니다. 클라이언트에서 .connections
작업을 사용하면 연결을 열거하고 연결 속성을 가져올 수 있습니다. 연결 속성에는 리소스 URL 및 인증 자격 증명이 포함됩니다.
다음은 연결 작업의 코드 예제입니다. 전체 샘플은 [패키지 샘플][샘플]의 "연결" 폴더에서 찾을 수 있습니다.
모든 연결의 속성 가져오기
Azure AI Foundry 프로젝트의 모든 연결 속성을 나열하려면 다음을 수행합니다.
const connections = await client.connections.listConnections();
for (const connection of connections) {
console.log(connection);
}
특정 형식의 모든 연결 속성 가져오기
특정 형식의 연결 속성을 나열하려면(여기 Azure OpenAI)
const connections = await client.connections.listConnections({ category: "AzureOpenAI" });
for (const connection of connections) {
console.log(connection);
}
연결 이름으로 연결의 속성을 가져옵니다.
connectionName
연결의 연결 속성을 얻으려면:
const connection = await client.connections.getConnection("connectionName");
console.log(connection);
인증 자격 증명을 사용하여 연결 속성을 얻으려면 다음을 수행합니다.
const connection = await client.connections.getConnectionWithSecrets("connectionName");
console.log(connection);
에이전트(미리 보기)
Azure AI Projects 클라이언트 라이브러리의 에이전트는 AI 프로젝트 내에서 다양한 상호 작용 및 작업을 용이하게 하도록 설계되었습니다. 특정 목표를 달성하기 위해 다양한 도구와 리소스를 활용하여 작업을 관리하고 실행하는 핵심 구성 요소 역할을 합니다. 다음 단계에서는 에이전트와 상호 작용하기 위한 일반적인 시퀀스를 간략하게 설명합니다. 추가 에이전트 샘플은 [패키지 샘플][샘플]의 "에이전트" 폴더를 참조하세요.
에이전트가 적극적으로 개발되고 있습니다. 프라이빗 미리 보기에 대한 등록 양식이 곧 제공될 예정입니다.
에이전트 만들기
에이전트를 만드는 방법의 예는 다음과 같습니다.
const agent = await client.agents.createAgent("gpt-4o", {
name: "my-agent",
instructions: "You are a helpful assistant",
});
에이전트가 리소스 또는 사용자 지정 함수에 액세스할 수 있도록 하려면 도구가 필요합니다.
tools
및 toolResources
인수를 통해 createAgent
도구를 전달할 수 있습니다.
ToolSet
사용하여 다음을 수행할 수 있습니다.
const toolSet = new ToolSet();
toolSet.addFileSearchTool([vectorStore.id]);
toolSet.addCodeInterpreterTool([codeInterpreterFile.id]);
// Create agent with tool set
const agent = await client.agents.createAgent("gpt-4o", {
name: "my-agent",
instructions: "You are a helpful agent",
tools: toolSet.toolDefinitions,
toolResources: toolSet.toolResources,
});
console.log(`Created agent, agent ID: ${agent.id}`);
파일 검색을 사용하여 에이전트 만들기
에이전트에서 파일 검색을 수행하려면 먼저 파일을 업로드하고, 벡터 저장소를 만들고, 파일을 벡터 저장소에 연결해야 합니다. 예제는 다음과 같습니다.
const localFileStream = fs.createReadStream("sample_file_for_upload.txt");
const file = await client.agents.uploadFile(localFileStream, "assistants", {
fileName: "sample_file_for_upload.txt",
});
console.log(`Uploaded file, ID: ${file.id}`);
const vectorStore = await client.agents.createVectorStore({
fileIds: [file.id],
name: "my_vector_store",
});
console.log(`Created vector store, ID: ${vectorStore.id}`);
const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
const agent = await client.agents.createAgent("gpt-4o", {
name: "SDK Test Agent - Retrieval",
instructions: "You are helpful agent that can help fetch data from files you know about.",
tools: [fileSearchTool.definition],
toolResources: fileSearchTool.resources,
});
console.log(`Created agent, agent ID : ${agent.id}`);
코드 인터프리터를 사용하여 에이전트 만들기
다음은 파일을 업로드하고 에이전트의 코드 인터프리터에 사용하는 예제입니다.
const fileStream = fs.createReadStream("nifty_500_quarterly_results.csv");
const fFile = await client.agents.uploadFile(fileStream, "assistants", {
fileName: "nifty_500_quarterly_results.csv",
});
console.log(`Uploaded local file, file ID : ${file.id}`);
const codeInterpreterTool = ToolUtility.createCodeInterpreterTool([file.id]);
// Notice that CodeInterpreter must be enabled in the agent creation, otherwise the agent will not be able to see the file attachment
const agent = await client.agents.createAgent("gpt-4o-mini", {
name: "my-agent",
instructions: "You are a helpful agent",
tools: [codeInterpreterTool.definition],
toolResources: codeInterpreterTool.resources,
});
console.log(`Created agent, agent ID: ${agent.id}`);
Bing Grounding을 사용하여 에이전트 만들기
에이전트가 Bing Search API를 통해 검색을 수행할 수 있도록 하려면 연결과 함께 ToolUtility.createConnectionTool()
사용합니다.
예제는 다음과 같습니다.
const bingGroundingConnectionId = "<bingGroundingConnectionId>";
const bingTool = ToolUtility.createConnectionTool(connectionToolType.BingGrounding, [
bingGroundingConnectionId,
]);
const agent = await client.agents.createAgent("gpt-4-0125-preview", {
name: "my-agent",
instructions: "You are a helpful agent",
tools: [bingTool.definition],
});
console.log(`Created agent, agent ID : ${agent.id}`);
Azure AI Search를 사용하여 에이전트 만들기
Azure AI Search는 고성능 애플리케이션을 위한 엔터프라이즈 검색 시스템입니다. Azure OpenAI Service 및 Azure Machine Learning과 통합되어 벡터 검색 및 전체 텍스트 검색과 같은 고급 검색 기술을 제공합니다. 기술 자료 인사이트, 정보 검색 및 자동화에 적합합니다.
Azure AI Search를 통합하는 예제는 다음과 같습니다.
const cognitiveServicesConnectionName = "<cognitiveServicesConnectionName>";
const cognitiveServicesConnection = await client.connections.getConnection(
cognitiveServicesConnectionName,
);
const azureAISearchTool = ToolUtility.createAzureAISearchTool(
cognitiveServicesConnection.id,
cognitiveServicesConnection.name,
);
// Create agent with the Azure AI search tool
const agent = await client.agents.createAgent("gpt-4-0125-preview", {
name: "my-agent",
instructions: "You are a helpful agent",
tools: [azureAISearchTool.definition],
toolResources: azureAISearchTool.resources,
});
console.log(`Created agent, agent ID : ${agent.id}`);
함수 호출을 사용하여 에이전트 만들기
콜백 함수를 함수 도구로 정의하여 에이전트를 향상시킬 수 있습니다.
tools
및 toolResources
조합을 통해 createAgent
제공할 수 있습니다. 함수 정의 및 설명만 구현 없이 createAgent
제공됩니다.
Run
또는 event handler of stream
함수 정의에 따라 requires_action
상태가 발생합니다. 코드는 이 상태를 처리하고 적절한 함수를 호출해야 합니다.
예제는 다음과 같습니다.
class FunctionToolExecutor {
private functionTools: { func: Function, definition: FunctionToolDefinition }[];
constructor() {
this.functionTools = [{
func: this.getUserFavoriteCity,
...ToolUtility.createFunctionTool({
name: "getUserFavoriteCity",
description: "Gets the user's favorite city.",
parameters: {}
})
}, {
func: this.getCityNickname,
...ToolUtility.createFunctionTool({
name: "getCityNickname",
description: "Gets the nickname of a city, e.g. 'LA' for 'Los Angeles, CA'.",
parameters: { type: "object", properties: { location: { type: "string", description: "The city and state, e.g. Seattle, Wa" } } }
})
}, {
func: this.getWeather,
...ToolUtility.createFunctionTool({
name: "getWeather",
description: "Gets the weather for a location.",
parameters: { type: "object", properties: { location: { type: "string", description: "The city and state, e.g. Seattle, Wa" }, unit: { type: "string", enum: ['c', 'f'] } } }
})
}];
}
private getUserFavoriteCity(): {} {
return { "location": "Seattle, WA" };
}
private getCityNickname(location: string): {} {
return { "nickname": "The Emerald City" };
}
private getWeather(location: string, unit: string): {} {
return { "weather": unit === "f" ? "72f" : "22c" };
}
public invokeTool(toolCall: RequiredToolCallOutput & FunctionToolDefinitionOutput): ToolOutput | undefined {
console.log(`Function tool call - ${toolCall.function.name}`);
const args = [];
if (toolCall.function.parameters) {
try {
const params = JSON.parse(toolCall.function.parameters);
for (const key in params) {
if (Object.prototype.hasOwnProperty.call(params, key)) {
args.push(params[key]);
}
}
} catch (error) {
console.error(`Failed to parse parameters: ${toolCall.function.parameters}`, error);
return undefined;
}
}
const result = this.functionTools.find((tool) => tool.definition.function.name === toolCall.function.name)?.func(...args);
return result ? {
toolCallId: toolCall.id,
output: JSON.stringify(result)
} : undefined;
}
public getFunctionDefinitions(): FunctionToolDefinition[] {
return this.functionTools.map(tool => {return tool.definition});
}
}
const functionToolExecutor = new FunctionToolExecutor();
const functionTools = functionToolExecutor.getFunctionDefinitions();
const agent = await client.agents.createAgent("gpt-4o",
{
name: "my-agent",
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: functionTools
});
console.log(`Created agent, agent ID: ${agent.id}`);
스레드 만들기
각 세션 또는 대화에 대해 스레드가 필요합니다. 예제는 다음과 같습니다.
const thread = await client.agents.createThread();
도구 리소스를 사용하여 스레드 만들기
일부 시나리오에서는 개별 스레드에 특정 리소스를 할당해야 할 수 있습니다. 이를 위해 createThread
toolResources
인수를 제공합니다. 다음 예제에서는 벡터 저장소를 만들고 파일을 업로드하고, tools
인수를 사용하여 에이전트에서 파일 검색을 사용하도록 설정한 다음, toolResources
인수를 사용하여 파일을 스레드와 연결합니다.
const localFileStream = fs.createReadStream("sample_file_for_upload.txt");
const file = await client.agents.uploadFile(localFileStream, "assistants", {
fileName: "sample_file_for_upload.txt",
});
console.log(`Uploaded file, ID: ${file.id}`);
const vectorStore = await client.agents.createVectorStore({
fileIds: [file.id],
name: "my_vector_store",
});
console.log(`Created vector store, ID: ${vectorStore.id}`);
const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
const agent = await client.agents.createAgent("gpt-4o", {
name: "SDK Test Agent - Retrieval",
instructions: "You are helpful agent that can help fetch data from files you know about.",
tools: [fileSearchTool.definition],
});
console.log(`Created agent, agent ID : ${agent.id}`);
// Create thread with file resources.
// If the agent has multiple threads, only this thread can search this file.
const thread = await client.agents.createThread({ toolResources: fileSearchTool.resources });
메시지 만들기
도우미가 처리할 메시지를 만들려면 user
role
전달하고 질문을 content
.
const message = await client.agents.createMessage(thread.id, {
role: "user",
content: "hello, world!",
});
파일 검색 첨부 파일을 사용하여 메시지 만들기
콘텐츠 검색을 위해 메시지에 파일을 첨부하려면 ToolUtility.createFileSearchTool()
및 attachments
인수를 사용합니다.
const fileSearchTool = ToolUtility.createFileSearchTool();
const message = await client.agents.createMessage(thread.id, {
role: "user",
content: "What feature does Smart Eyewear offer?",
attachments: {
fileId: file.id,
tools: [fileSearchTool.definition],
},
});
코드 인터프리터 첨부 파일을 사용하여 메시지 만들기
데이터 분석을 위해 메시지에 파일을 첨부하려면 ToolUtility.createCodeInterpreterTool()
및 attachment
인수를 사용합니다.
예제는 다음과 같습니다.
// notice that CodeInterpreter must be enabled in the agent creation,
// otherwise the agent will not be able to see the file attachment for code interpretation
const codeInterpreterTool = ToolUtility.createCodeInterpreterTool();
const agent = await client.agents.createAgent("gpt-4-1106-preview", {
name: "my-assistant",
instructions: "You are helpful assistant",
tools: [codeInterpreterTool.definition],
});
console.log(`Created agent, agent ID: ${agent.id}`);
const thread = client.agents.createThread();
console.log(`Created thread, thread ID: ${thread.id}`);
const message = await client.agents.createMessage(thread.id, {
role: "user",
content:
"Could you please create bar chart in TRANSPORTATION sector for the operating profit from the uploaded csv file and provide file to me?",
attachments: {
fileId: file.id,
tools: [codeInterpreterTool.definition],
},
});
console.log(`Created message, message ID: ${message.id}`);
실행, Run_and_Process 또는 스트림 만들기
다음은 실행이 완료될 때까지 createRun
폴링의 예입니다.
let run = await client.agents.createRun(thread.id, agent.id);
// Poll the run as long as run status is queued or in progress
while (
run.status === "queued" ||
run.status === "in_progress" ||
run.status === "requires_action"
) {
// Wait for a second
await new Promise((resolve) => setTimeout(resolve, 1000));
run = await client.agents.getRun(thread.id, run.id);
}
사용자를 대신하여 SDK 폴링하려면 createThreadAndRun
메서드를 사용합니다.
예제는 다음과 같습니다.
const run = await client.agents.createThreadAndRun(thread.id, agent.id);
스트리밍에서는 폴링도 고려할 필요가 없습니다.
예제는 다음과 같습니다.
const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();
이벤트 처리는 다음과 같이 수행할 수 있습니다.
for await (const eventMessage of streamEventMessages) {
switch (eventMessage.event) {
case RunStreamEvent.ThreadRunCreated:
console.log(`ThreadRun status: ${(eventMessage.data as ThreadRunOutput).status}`)
break;
case MessageStreamEvent.ThreadMessageDelta:
{
const messageDelta = eventMessage.data as MessageDeltaChunk;
messageDelta.delta.content.forEach((contentPart) => {
if (contentPart.type === "text") {
const textContent = contentPart as MessageDeltaTextContent
const textValue = textContent.text?.value || "No text"
console.log(`Text delta received:: ${textValue}`)
}
});
}
break;
case RunStreamEvent.ThreadRunCompleted:
console.log("Thread Run Completed");
break;
case ErrorEvent.Error:
console.log(`An error occurred. Data ${eventMessage.data}`);
break;
case DoneEvent.Done:
console.log("Stream completed.");
break;
}
}
메시지 검색
에이전트에서 메시지를 검색하려면 다음 예제를 사용합니다.
const messages = await client.agents.listMessages(thread.id);
// The messages are following in the reverse order,
// we will iterate them and output only text contents.
for (const dataPoint of messages.data.reverse()) {
const lastMessageContent: MessageContentOutput = dataPoint.content[dataPoint.content.length - 1];
console.log( lastMessageContent);
if (isOutputOfType<MessageTextContentOutput>(lastMessageContent, "text")) {
console.log(`${dataPoint.role}: ${(lastMessageContent as MessageTextContentOutput).text.value}`);
}
}
파일 검색
에이전트에서 업로드한 파일은 다시 검색할 수 없습니다. 사용 사례가 에이전트에서 업로드한 파일 콘텐츠에 액세스해야 하는 경우 애플리케이션에서 액세스할 수 있는 추가 복사본을 유지하는 것이 좋습니다. 그러나 에이전트에서 생성된 파일은 getFileContent
검색할 수 있습니다.
다음은 메시지에서 파일 ID를 검색하는 예제입니다.
const messages = await client.agents.listMessages(thread.id);
const imageFile = (messages.data[0].content[0] as MessageImageFileContentOutput).imageFile;
const imageFileName = (await client.agents.getFile(imageFile.fileId)).filename;
const fileContent = await (await client.agents.getFileContent(imageFile.fileId).asNodeStream()).body;
if (fileContent) {
const chunks: Buffer[] = [];
for await (const chunk of fileContent) {
chunks.push(Buffer.from(chunk));
}
const buffer = Buffer.concat(chunks);
fs.writeFileSync(imageFileName, buffer);
} else {
console.error("Failed to retrieve file content: fileContent is undefined");
}
console.log(`Saved image file to: ${imageFileName}`);
해체
작업을 완료한 후 리소스를 제거하려면 다음 함수를 사용합니다.
await client.agents.deleteVectorStore(vectorStore.id);
console.log(`Deleted vector store, vector store ID: ${vectorStore.id}`);
await client.agents.deleteFile(file.id);
console.log(`Deleted file, file ID: ${file.id}`);
client.agents.deleteAgent(agent.id);
console.log(`Deleted agent, agent ID: ${agent.id}`);
추적
Azure AI Foundry 프로젝트에 Application Insights Azure 리소스를 추가할 수 있습니다. 스튜디오에서 추적 탭을 참조하세요. 사용하도록 설정된 경우 Application Insights 연결 문자열을 가져와서 에이전트를 구성하고 Azure Monitor를 통해 전체 실행 경로를 관찰할 수 있습니다. 일반적으로 에이전트를 만들기 전에 추적을 시작할 수 있습니다.
설치
를 통해 OpenTelemetry 및 Azure SDK 추적 플러그 인을 설치해야 합니다.
npm install @opentelemetry/api \
@opentelemetry/instrumentation \
@opentelemetry/sdk-trace-node \
@azure/opentelemetry-instrumentation-azure-sdk \
@azure/monitor-opentelemetry-exporter
또한 관찰 가능성 백 엔드에 원격 분석을 보내려면 내보내기가 필요합니다. 추적을 콘솔에 인쇄하거나 Aspire 대시보드같은 로컬 뷰어를 사용할 수 있습니다.
Aspire 대시보드 또는 다른 OpenTelemetry 호환 백 엔드에 연결하려면 OTLP 내보내기를 설치합니다.
npm install @opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-metrics-otlp-proto
추적 예제
다음은 위의 createAgent
포함할 코드 샘플입니다.
import { trace } from "@opentelemetry/api";
import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter"
import {
ConsoleSpanExporter,
NodeTracerProvider,
SimpleSpanProcessor,
} from "@opentelemetry/sdk-trace-node";
const provider = new NodeTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.register();
const tracer = trace.getTracer("Agents Sample", "1.0.0");
const client = AIProjectsClient.fromConnectionString(
connectionString || "", new DefaultAzureCredential()
);
if (!appInsightsConnectionString) {
appInsightsConnectionString = await client.telemetry.getConnectionString();
}
if (appInsightsConnectionString) {
const exporter = new AzureMonitorTraceExporter({
connectionString: appInsightsConnectionString
});
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
}
await tracer.startActiveSpan("main", async (span) => {
client.telemetry.updateSettings({enableContentRecording: true})
// ...
문제 해결
예외
서비스 호출을 만드는 클라이언트 메서드는 서비스에서 성공하지 않은 HTTP 상태 코드 응답에 대한 RestError 발생합니다. 예외의 code
HTTP 응답 상태 코드를 유지합니다. 예외의 error.message
문제를 진단하는 데 도움이 될 수 있는 자세한 메시지가 포함되어 있습니다.
import { RestError } from "@azure/core-rest-pipeline"
// ...
try {
const result = await client.connections.listConnections();
} catch (e as RestError) {
console.log(`Status code: ${e.code}`);
console.log(e.message);
}
예를 들어 잘못된 자격 증명을 제공하는 경우:
Status code: 401 (Unauthorized)
Operation returned an invalid status 'Unauthorized'
문제 보고
클라이언트 라이브러리와 관련된 문제를 보고하거나 추가 기능을 요청하려면 여기에서
기여
이 프로젝트는 기여와 제안을 환영합니다. 대부분의 기여는 귀하가 귀하의 기여를 사용할 권리를 부여할 권리가 있음을 선언하는 CLA(기여자 사용권 계약)에 동의해야 합니다. 자세한 내용은 https://cla.microsoft.com방문하세요.
끌어오기 요청을 제출하면 CLA 봇은 CLA를 제공하고 PR을 적절하게 데코레이팅해야 하는지 여부를 자동으로 결정합니다(예: 레이블, 주석). 봇에서 제공하는 지침을 따르기만 하면 됩니다. CLA를 사용하여 모든 리포지토리에서 한 번만 이 작업을 수행해야 합니다.
이 프로젝트는 Microsoft 오픈 소스 행동 강령
Azure SDK for JavaScript