Vereisten
Bij het ontwerpen van AI-oplossingen voor ondernemingen is de grootste uitdaging niet het bouwen van één indrukwekkend model. Het is het samenvoegen van meerdere AI-services tot een betrouwbare, observeerbare productie-pijplijn die daadwerkelijk een bedrijfsprobleem oplost. Klanten hebben vaak krachtige componenten die in silo's werken—een spraak-naar-tekstservice hier, een groot taalmodel (LLM) daar—maar ze worstelen met het orkestreren hiervan tot een samenhangende workflow. Stel je een wereldwijd ondersteuningscentrum voor dat inkomende klantgesprekken moet verwerken, sentiment moet begrijpen, kritieke problemen moet identificeren en de belangrijkste bevindingen voor regionale teams moet vertalen. Dit is geen enkele API-oproep; het is een meerstaps intelligente pijplijn.
Dit artikel is een praktijkhandleiding voor het oplossen van precies dat probleem. Ik loods je door hoe ik de AIProjectClient uit de Azure AI SDK gebruik om een robuuste AI-pijplijn te bouwen die drie afzonderlijke tools integreert: spraak-naar-tekst, generatieve AI-gestuurde sentimentanalyse en vertaling. We definiëren de infrastructuur met Terraform, implementeren de logica in Python en bekijken hoe dit alles past binnen de governancestructuur van een Azure AI Hub en Project. Tot slot geef ik mijn mening over hoe Azure's agent-gebaseerde aanpak zich verhoudt tot wat ik heb gezien bij projecten die AWS Bedrock en Google's Vertex AI gebruiken.
Om deze pijplijn te bouwen en uit te voeren, heb je een omgeving nodig met de volgende componenten. Ik ga uit van een standaard enterprise-configuratie waarbij je de juiste machtigingen hebt om resources te maken en te beheren.
- Azure Abonnement: Een actief abonnement met machtigingen om resourcegroepen en AI-services te maken.
- Azure AI-resources:
- Een Azure AI Hub en een AI Project. We zullen de onderstaande services inrichten en deze verbinden met je project.
- Een Azure AI Services multi-service account (voor Speech en Translator).
- Een Azure OpenAI Service-resource met een geïmplementeerd model (ik gebruik
gpt-4o).
- Python 3.12+: Mijn standaard voor elk nieuw Python-project.
- Azure CLI: De nieuwste versie, geauthenticeerd bij je abonnement (
az login). - Terraform CLI: De nieuwste versie voor infrastructuurvoorziening.
- Python Libraries: Je hebt de Azure SDK's voor Python nodig. Je kunt deze installeren met
pip:
python3.12 -m pip install azure-ai-projects azure-identity openai azure-cognitiveservices-speech httpx numpy scipy
Architectuur: de agent als orkestrator
Effectieve AI-orkestratie begint met een solide architectonische basis. In Azure dient het AI Project, gehost binnen een AI Hub, als het centrale controlepaneel. Het is de 'source of truth' voor het beheer van de gehele levenscyclus van een AI-oplossing. De AIProjectClient is je programmatische sleutel tot dit controlepaneel, waarmee je de componenten van je pijplijn kunt definiëren, versioneren en beheren, die we structureren als een agent met een reeks tools.
In ons scenario is de agent een logisch construct, aangedreven door een LLM, dat een doel op hoog niveau begrijpt, specifieke tools aanroept om dit te bereiken en hun outputs aaneenschakelt. Zo werken onze componenten:
- Spraak-naar-tekst Tool: Neemt een audiopad, roept de Azure Speech Service aan en retourneert de getranscribeerde tekst.
- GenAI-analyse Tool: Het transcript wordt doorgegeven aan deze tool, die een Azure OpenAI-model gebruikt om genuanceerde analyse uit te voeren—het extraheren van het algehele sentiment, specifieke problemen en een samenvatting.
- Vertaal Tool: De resulterende analyse wordt vervolgens doorgegeven aan de Azure Translator Service om te worden gelokaliseerd voor een doeltaal.
De AIProjectClient stelt ons in staat om deze functies te registreren als aanroepbare tools die de agent kan gebruiken. Deze modulariteit is essentieel voor het bouwen van complexe, onderhoudbare AI-systemen.
Het AI Project als Controlepaneel
Bij het architecten van een systeem op Azure moeten we nu het AI Project binnen een AI Hub gebruiken als de definitieve 'source of truth' voor agent- en tooldefinities. Het centraliseert beheer, maakt versiebeheer mogelijk en biedt een uniforme API-interface voor CI/CD. Dit is veel beter dan het verspreiden van toollogica over afzonderlijke microservices, een patroon dat snel kan ontaarden in een beheer- en beveiligingsnachtmerrie.
Voordat we de tools bouwen, kijken we hoe we verbinding maken met het project. De AIProjectClient wordt geïnitialiseerd met het unieke eindpunt van het project en een geauthenticeerde credential.
# Conceptual example of client initialization
import os
from azure.ai.projects.aio import AIProjectClient
from azure.identity.aio import DefaultAzureCredential
async def initialize_ai_project_client():
# Your AI Project endpoint is found in the Azure AI Studio.
# It looks like: https://<your-hub-name>.<region>.inference.ai.azure.com/api/projects/<your-project-name>
project_endpoint = os.environ.get("AZURE_AI_PROJECT_ENDPOINT")
if not project_endpoint:
raise ValueError("AZURE_AI_PROJECT_ENDPOINT environment variable not set.")
# DefaultAzureCredential is my standard for authentication.
# It automatically uses environment variables, Managed Identity, or Azure CLI login.
credential = DefaultAzureCredential()
client = AIProjectClient(endpoint=project_endpoint, credential=credential)
print(f"AIProjectClient initialized for project at: {project_endpoint}")
return client, credential
Dit fragment toont de fundamentele stap. Het gebruik van DefaultAzureCredential biedt een veilig en flexibel authenticatiepatroon dat naadloos werkt tussen lokale ontwikkeling en cloudimplementaties zonder codewijzigingen.
Implementatiegids
Nu de praktische implementatie. We beginnen met het inrichten van onze Azure-resources met Terraform voordat we de AI-tools in Python definiëren en orkestreren.
1. Azure-resources inrichten met Terraform
Infrastructure as Code (IaC) is de enige manier om productiesystemen te bouwen. Ik gebruik Terraform om cloudresources declaratief te definiëren en te beheren. Dit voorkomt configuratieafwijkingen en maakt de hele omgeving reproduceerbaar.
Maak een bestand met de naam main.tf:
# main.tf - Provisioning AI Services for our pipeline
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
provider "azurerm" {
features {}
}
# Variables for naming and location
variable "resource_group_name" {
description = "Name of the resource group."
type = string
default = "rg-ai-pipeline-dev-euw"
}
variable "location" {
description = "Azure region for deployment."
type = string
default = "westeurope"
}
variable "base_name" {
description = "A unique base name for resources to avoid collisions."
type = string
default = "tcapipelineeuw"
}
# Create a resource group in our target region
resource "azurerm_resource_group" "main" {
name = var.resource_group_name
location = var.location
}
# Create an Azure AI Services account (for Speech and Translator)
resource "azurerm_cognitive_account" "ai_services" {
name = "ais-${var.base_name}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
kind = "CognitiveServices"
sku_name = "S0" # Standard tier
}
# Create an Azure OpenAI Service account
resource "azurerm_cognitive_account" "openai" {
name = "aoai-${var.base_name}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
kind = "OpenAI"
sku_name = "S0"
}
# Deploy a GPT-4o model to the Azure OpenAI account
resource "azurerm_cognitive_deployment" "openai_deployment" {
name = "gpt-4o"
cognitive_account_id = azurerm_cognitive_account.openai.id
model {
format = "OpenAI"
name = "gpt-4o"
version = "2024-05-13"
}
scale {
type = "Standard"
capacity = 10 # Throughput units (10 = 10k tokens/min)
}
# Note: Ensure your subscription has quota for this model in the target region.
}
# Outputs for our Python application
output "ai_services_endpoint" {
value = azurerm_cognitive_account.ai_services.endpoint
}
output "ai_services_region" {
value = azurerm_cognitive_account.ai_services.location
}
output "openai_endpoint" {
value = azurerm_cognitive_account.openai.endpoint
}
output "openai_deployment_name" {
value = azurerm_cognitive_deployment.openai_deployment.name
}
Om deze resources in te richten, voert u de standaard Terraform-commando's uit:
# Log into Azure first
az login
# Initialize Terraform
terraform init
# Plan and apply the changes
terraform plan
terraform apply --auto-approve
Na de toepassing zal Terraform de eindpunten en namen uitvoeren die je nodig hebt voor de omgevingsvariabelen van je applicatie.
2. Configureer uw Python-omgeving
Stel de volgende omgevingsvariabelen in je shell in, gebruikmakend van de outputs van Terraform en het eindpunt van je AI Project in Azure AI Studio.
# Get this from the 'Develop' section of your AI Project in Azure AI Studio
export AZURE_AI_PROJECT_ENDPOINT="https://<your-hub-name>.<region>.inference.ai.azure.com/api/projects/<your-project-name>"
# Use these if you're authenticating with a Service Principal
export AZURE_CLIENT_ID="<your-service-principal-client-id>"
export AZURE_CLIENT_SECRET="<your-service-principal-client-secret>"
export AZURE_TENANT_ID="<your-tenant-id>"
# From Terraform outputs
export AZURE_AI_SERVICES_ENDPOINT="https://ais-tcapipelineeuw.cognitiveservices.azure.com/"
export AZURE_AI_SERVICES_REGION="westeurope"
export AZURE_OPENAI_ENDPOINT="https://aoai-tcapipelineeuw.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o"
Vergeet niet de identiteit die je gebruikt (je gebruikersaccount of Service Principal) de rol 'Cognitive Services User' toe te kennen op de AI Services- en OpenAI-resources, en geschikte machtigingen (bijv. 'Contributor') op het AI Project zelf.
3. Definieer de pijplijn-tools
Nu creëren we de Python-functies die als tools voor onze agent zullen dienen. Ik plaats deze in een bestand met de naam ai_pipeline_tools.py. Alle functies zijn async om niet-blokkerende I/O te garanderen, wat cruciaal is voor schaalbare services.
# ai_pipeline_tools.py
import os
import json
import httpx
from typing import Dict, Any
import azure.cognitiveservices.speech as speechsdk
from openai import AsyncAzureOpenAI
from azure.identity.aio import DefaultAzureCredential
# --- Tool Implementations ---
async def speech_to_text(audio_file_path: str, credential: DefaultAzureCredential) -> str:
"""Transcribes an audio file to text using Azure Speech Service."""
speech_region = os.environ["AZURE_AI_SERVICES_REGION"]
# The Speech SDK needs an auth token. We'll get one using our async credential.
token = await credential.get_token("https://cognitiveservices.azure.com/.default")
speech_config = speechsdk.SpeechConfig(auth_token=token.token, region=speech_region)
audio_config = speechsdk.AudioConfig(filename=audio_file_path)
speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)
print(f"Performing speech-to-text on {audio_file_path}...")
result = await speech_recognizer.recognize_once_async()
if result.reason == speechsdk.ResultReason.RecognizedSpeech:
print(f"Recognized: {result.text}")
return result.text
elif result.reason == speechsdk.ResultReason.NoMatch:
print("No speech could be recognized.")
elif result.reason == speechsdk.ResultReason.Canceled:
cancellation = result.cancellation_details
print(f"Speech Recognition canceled: {cancellation.reason}")
if cancellation.reason == speechsdk.CancellationReason.Error:
print(f"Error details: {cancellation.error_details}")
raise RuntimeError(f"Speech recognition failed: {cancellation.error_details}")
return ""
async def genai_sentiment_analysis(text: str, credential: DefaultAzureCredential) -> Dict[str, Any]:
"""Analyzes text for sentiment and extracts key takeaways using Azure OpenAI."""
# This helper function provides a refreshed token to the OpenAI client.
async def token_provider():
token = await credential.get_token("https://cognitiveservices.azure.com/.default")
return token.token
client = AsyncAzureOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version="2024-05-01-preview",
azure_ad_token_provider=token_provider,
)
prompt = f"""Analyze the following customer call transcript. Identify the overall sentiment, any specific issues raised, and summarize the key takeaways. Your response MUST be a valid JSON object with three keys: 'overall_sentiment' (string: 'positive', 'neutral', or 'negative'), 'issues' (list of strings), and 'key_takeaways' (list of strings).
Transcript: """{text}"""
JSON Output:"""
print(f"Performing GenAI analysis on: {text[:60]}...")
response = await client.chat.completions.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
response_format={ "type": "json_object" },
messages=[
{"role": "system", "content": "You are an expert AI assistant for customer service analysis."},
{"role": "user", "content": prompt}
]
)
analysis_result = json.loads(response.choices[0].message.content)
print(f"GenAI Analysis: {analysis_result}")
await client.close()
return analysis_result
async def translate_text(text: str, credential: DefaultAzureCredential, target_language: str = "fr") -> str:
"""Translates text to a target language using Azure Translator Service."""
translator_endpoint = os.environ["AZURE_AI_SERVICES_ENDPOINT"]
token = await credential.get_token('https://cognitiveservices.azure.com/.default')
headers = {
'Authorization': f'Bearer {token.token}',
'Content-Type': 'application/json',
}
api_endpoint = f"{translator_endpoint.rstrip('/')}/translator/text/v3.0/translate"
params = {'api-version': '3.0', 'to': target_language}
body = [{'text': text}]
print(f"Translating text to '{target_language}': {text[:60]}...")
async with httpx.AsyncClient() as client:
response = await client.post(api_endpoint, params=params, headers=headers, json=body)
response.raise_for_status()
translation = response.json()
translated_text = translation[0]['translations'][0]['text']
print(f"Translated: {translated_text}")
return translated_text
4. Definieer en implementeer de agent
Met onze geïmplementeerde tools kunnen we nu een agent definiëren die weet hoe ze te gebruiken. We zullen de AIProjectClient gebruiken om de definitie van de agent te registreren, inclusief zijn instructies en het schema van de tools die het kan aanroepen. Maak een bestand deploy_agent.py:
# deploy_agent.py
import asyncio
import os
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition, FunctionTool
from azure.identity.aio import DefaultAzureCredential
async def main():
project_endpoint = os.environ["AZURE_AI_PROJECT_ENDPOINT"]
openai_deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"]
credential = DefaultAzureCredential()
async with AIProjectClient(endpoint=project_endpoint, credential=credential) as client:
agent_name = "call-analysis-pipeline-agent"
# Define the tools the agent can use based on their function signatures
speech_tool = FunctionTool(
name="speech_to_text_transcription",
description="Transcribes an audio file path into text.",
parameters={
"type": "object",
"properties": {"audio_file_path": {"type": "string"}},
"required": ["audio_file_path"]
}
)
sentiment_tool = FunctionTool(
name="genai_sentiment_analysis_tool",
description="Analyzes text for sentiment, issues, and key takeaways.",
parameters={
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"]
}
)
translation_tool = FunctionTool(
name="translate_text_tool",
description="Translates text to a specified target language.",
parameters={
"type": "object",
"properties": {
"text": {"type": "string"},
"target_language": {"type": "string", "default": "fr"}
},
"required": ["text"]
}
)
# Define the agent's instructions and link the tools
agent_definition = PromptAgentDefinition(
model=f"azure_openai:/{openai_deployment_name}",
instructions=(
"You are a call analysis assistant. Your job is to take an audio file path, "
"transcribe it, analyze the transcript for sentiment and issues, and finally "
"translate the analysis summary into a target language (defaulting to French)."
),
tools=[speech_tool, sentiment_tool, translation_tool]
)
print(f"Creating or updating agent '{agent_name}'...")
agent_version = await client.agents.create_version(
agent_name=agent_name,
definition=agent_definition
)
print(f"Agent deployment complete. Name: {agent_version.name}, Version: {agent_version.version}")
await credential.close()
if __name__ == "__main__":
asyncio.run(main())
Door dit script uit te voeren, wordt onze agent geregistreerd in het AI Project. De LLM van de agent weet nu welke tools het heeft en waarvoor ze dienen, klaar om ze te orkestreren op basis van een prompt.
5. Voer de pijplijn uit
Laten we tot slot de pijplijn uitvoeren. Het volgende script, run_pipeline.py, simuleert een gebruikersverzoek. Voor deze demonstratie zullen we de tool-oproepen handmatig orkestreren om de stapsgewijze logica te tonen. In een real-world applicatie zou je interacteren met het geïmplementeerde agent-eindpunt, en de agent zelf zou deze orkestratie intern beheren.
Agent-orkestratie versus directe oproepen
Het onderstaande script roept de toolfuncties handmatig aan voor de duidelijkheid. In een productiescenario zou je dit niet doen. In plaats daarvan zou je een prompt op hoog niveau (bijv. "Analyseer deze oproepaudio en vat samen in het Frans") naar het eindpunt van de geïmplementeerde agent sturen. De LLM van de agent zou dan autonoom besluiten om `speech_to_text`, vervolgens `genai_sentiment_analysis`, en daarna `translate_text` in de juiste volgorde aan te roepen. Dit is de kracht van het agentmodel – het ontkoppelt de orkestratielogica van je applicatiecode.
# run_pipeline.py
import asyncio
import os
import json
import numpy as np
import scipy.io.wavfile as wavfile
from azure.identity.aio import DefaultAzureCredential
# Import our tool implementations
from ai_pipeline_tools import speech_to_text, genai_sentiment_analysis, translate_text
def create_dummy_audio_file(filename="sample_call.wav"):
"""Creates a dummy WAV file. The content is just a sine wave."""
samplerate = 16000
duration = 3.0
frequency = 440.0
t = np.linspace(0., duration, int(samplerate * duration))
amplitude = np.iinfo(np.int16).max * 0.3
data = amplitude * np.sin(2. * np.pi * frequency * t)
wavfile.write(filename, samplerate, data.astype(np.int16))
print(f"Dummy audio file '{filename}' created for STT input.")
return filename
async def main():
credential = DefaultAzureCredential()
# --- Simulation Setup ---
# For this demo, we'll use a clear, known text as a fallback,
# since transcribing a dummy sine wave won't produce meaningful results.
audio_file = create_dummy_audio_file()
mock_transcript = "The customer reported a critical issue with the service stability. Performance has degraded significantly over the past hour."
print("\n--- Simulating Agent Pipeline Execution ---")
# Step 1: Speech-to-Text
print("\n[AGENT] Calling Speech-to-Text tool...")
transcribed_text = await speech_to_text(audio_file, credential)
if not transcribed_text:
print("STT returned no result on dummy audio, using mock transcript.")
transcribed_text = mock_transcript
# Step 2: GenAI Sentiment Analysis
print("\n[AGENT] Calling GenAI Analysis tool...")
analysis = await genai_sentiment_analysis(transcribed_text, credential)
summary_for_translation = f"Sentiment: {analysis.get('overall_sentiment')}. Issues: {analysis.get('issues')}. Takeaways: {analysis.get('key_takeaways')}."
# Step 3: Translation
print("\n[AGENT] Calling Translation tool...")
translated_summary = await translate_text(summary_for_translation, credential, target_language="fr")
print("\n--- Final Pipeline Output ---")
print(f"Original Transcript: {transcribed_text}")
print(f"Analysis (JSON): {json.dumps(analysis, indent=2)}")
print(f"Translated Summary (fr): {translated_summary}")
await credential.close()
if __name__ == "__main__":
asyncio.run(main())
Wanneer je dit uitvoert, zie je de volledige pijplijn in actie: de dummy-audio wordt gemaakt, de speech-service wordt aangeroepen (en faalt waarschijnlijk, wat de fallback activeert), de mock-tekst wordt geanalyseerd door de LLM, en de resulterende samenvatting wordt vertaald naar het Frans.
Vergelijking met AWS en GCP
Hoe verhoudt Azure's aanpak zich tot de andere grote clouds?
-
Azure AI Projects (Hub/Foundry): Azure's kracht is de nauwe integratie met enterprise governance en de Azure OpenAI-service. Het
AIProjectClienten het agentframework bieden een orchestrator-first model. Je definieert tools en geeft een LLM instructies. De agent redeneert vervolgens over hoe deze tools moeten worden gesequenceerd. Dit is extreem krachtig voor dynamische, conversationele en complexe workflows. De Hub/Project-structuur is gebouwd voor teamgebaseerde ontwikkeling met duidelijke grenzen. -
AWS Bedrock Agents: Dit is filosofisch gezien zeer vergelijkbaar met Azure's aanpak. Je creëert een agent, geeft deze toegang tot fundamentele modellen (zoals Anthropic's Claude of Amazon's Titan), en definieert acties die het kan uitvoeren, typisch door AWS Lambda-functies aan te roepen. Bedrock's belangrijkste waardepropositie is de keuze van onderliggende modellen en de naadloze integratie met het AWS serverloze ecosysteem. Net als Azure abstraheert de agent de orkestratielogica.
-
GCP Vertex AI: Voor gestructureerde, herhaalbare ML-workflows zijn Vertex AI Pipelines (gebaseerd op Kubeflow) de gouden standaard. Ze zijn uitstekend voor traditionele MLOps. Voor LLM-gestuurd toolgebruik heb je Vertex AI Extensions, die een LLM in staat stellen externe tools aan te roepen (zoals Cloud Functions of API's van derden). Je kunt deze combineren, maar de agentieve, redenerende orkestratie is minder een enkel, uniform product en meer een functionaliteit die je bouwt door de krachtige componenten van Vertex AI te combineren. Het biedt grote flexibiliteit, maar kan meer handmatige integratie vereisen dan de agentframeworks van Azure en AWS.
Kortom, alle drie brengen je erheen. Azure en AWS bieden een meer 'batteries-included' agentframework, terwijl GCP krachtige, combineerbare bouwstenen biedt.
Belangrijkste leerpunten
Het bouwen van een intelligente pijplijn gaat meer over orkestratie dan over een enkel AI-model. Azure's AIProjectClient biedt de programmatische interface voor een krachtig, agent-gebaseerd framework dat het creëren en beheren van deze complexe systemen vereenvoudigt.
Hier zijn mijn laatste aanbevelingen:
- Centraliseer met AI Projects: Gebruik Azure AI Projects als je controlepaneel. Het is gebouwd voor enterprise governance, beveiliging en MLOps.
- Omarm agents en tools: Definieer de mogelijkheden van je pijplijn als discrete, herbruikbare
FunctionTools en laat een agent ze orkestreren. Dit is flexibeler dan een hardgecodeerd, sequentieel proces. - Infrastructuur als Code: Richt je onderliggende cloudresources altijd in met Terraform. Het is de enige manier om overzicht te houden over omgevingen.
- Veilig authenticeren: Gebruik overal
DefaultAzureCredential. Het verwijdert referenties uit je code en past zich automatisch aan verschillende omgevingen aan.
Als volgende stap raad ik aan om te onderzoeken hoe je geheugen aan je agent kunt toevoegen met behulp van de MemoryStoresOperations in de SDK om meer stateful, conversationele ervaringen te creëren. De AI-ruimte beweegt ongelooflijk snel, dus controleer altijd de officiële Microsoft Learn-documentatie voor de nieuwste SDK-functies en best practices voor Azure AI Studio!