Pular para o conteúdo principal

Desafio 13: Prompt Flow

Tempo Estimado

45-60 min | Custo: ~$1.00 (estimado) | Domínio: Soluções de IA Generativa (15-20%)

Habilidades do exame abordadas

  • Implementar uma solução com prompt flow
  • Criar e configurar tipos de fluxo (standard, chat, evaluation)
  • Definir nós e conexões de fluxo para orquestração

Visão Geral

Prompt flow é um framework de orquestração dentro do Azure AI Foundry que permite construir, testar e implantar workflows baseados em LLM como grafos acíclicos direcionados (DAGs). Cada fluxo consiste em nós que executam sequencialmente ou em paralelo—incluindo nós LLM (chamando Azure OpenAI), nós Python (lógica customizada) e nós Prompt (renderização de templates). Os fluxos são definidos em YAML e podem ser executados localmente durante o desenvolvimento ou implantados como endpoints gerenciados.

Existem três tipos de fluxo principais: Standard flows para pipelines LLM de propósito geral (processamento de dados, sumarização, extração), Chat flows otimizados para aplicações conversacionais com gerenciamento integrado de histórico de chat, e Evaluation flows que avaliam a qualidade de outros fluxos usando métricas como fundamentação, relevância e coerência. O padrão de evaluation flow é crítico para sistemas de IA em produção—ele permite medição sistemática de qualidade antes da implantação.

Variants permitem testes A/B de prompts dentro de um único fluxo. Você pode definir múltiplas variantes de prompt para um nó LLM e executá-las contra as mesmas entradas para comparar qualidade e custo. Connections vinculam fluxos a serviços externos (Azure OpenAI, AI Search) e são configuradas no nível do workspace, permitindo gerenciamento seguro de credenciais separado da lógica do fluxo.

Arquitetura

Prompt flow orquestra chamadas LLM, processamento Python e templates de prompt como nós conectados em um DAG, com conexões a serviços de IA externos.

Topologia do Desafio 13

Pré-requisitos

  • Projeto Azure AI Foundry (do Desafio 11)
  • Implantação Azure OpenAI (do Desafio 12)
  • Python 3.9+ com pacotes promptflow e promptflow-tools
  • Azure CLI com extensão ml

Implementação

Tarefa 1: Criar um Standard Prompt Flow

import os
from promptflow.client import PFClient
from promptflow.entities import Run

# Initialize the Prompt Flow client (local development)
pf = PFClient()

# Define flow YAML programmatically
flow_yaml = """
$schema: https://azuremlschemas.azureedge.net/promptflow/latest/Flow.schema.json
inputs:
topic:
type: string
default: "Azure AI Services"
outputs:
summary:
type: string
reference: ${summarize.output}
nodes:
- name: generate_content
type: llm
source:
type: code
path: generate_content.jinja2
inputs:
deployment_name: gpt-4o-standard
max_tokens: 500
temperature: 0.7
topic: ${inputs.topic}
connection: aoai-connection
api: chat
- name: summarize
type: python
source:
type: code
path: summarize.py
inputs:
content: ${generate_content.output}
"""

# Write flow definition
os.makedirs("my-standard-flow", exist_ok=True)
with open("my-standard-flow/flow.dag.yaml", "w") as f:
f.write(flow_yaml)

# Create the LLM node prompt template
prompt_template = """system:
You are a technical writer specializing in Azure cloud services.

user:
Write a detailed paragraph about: {{topic}}
"""
with open("my-standard-flow/generate_content.jinja2", "w") as f:
f.write(prompt_template)

# Create the Python processing node
python_node = """
def summarize(content: str) -> str:
\"\"\"Extract key points from generated content.\"\"\"
lines = content.strip().split(". ")
key_points = [line.strip() for line in lines[:3]]
summary = "Key points: " + "; ".join(key_points)
return summary
"""
with open("my-standard-flow/summarize.py", "w") as f:
f.write(python_node)

print("Flow created at: my-standard-flow/")
print("Files: flow.dag.yaml, generate_content.jinja2, summarize.py")

Tarefa 2: Adicionar um Evaluation Flow

import os
from promptflow.client import PFClient
from promptflow.entities import Run, AzureOpenAIConnection

pf = PFClient()

# Define evaluation flow
eval_flow_yaml = """
$schema: https://azuremlschemas.azureedge.net/promptflow/latest/Flow.schema.json
inputs:
question:
type: string
answer:
type: string
ground_truth:
type: string
outputs:
relevance_score:
type: string
reference: ${evaluate_relevance.output}
nodes:
- name: evaluate_relevance
type: llm
source:
type: code
path: evaluate_relevance.jinja2
inputs:
deployment_name: gpt-4o-standard
max_tokens: 50
temperature: 0.0
question: ${inputs.question}
answer: ${inputs.answer}
ground_truth: ${inputs.ground_truth}
connection: aoai-connection
api: chat
"""

os.makedirs("eval-flow", exist_ok=True)
with open("eval-flow/flow.dag.yaml", "w") as f:
f.write(eval_flow_yaml)

# Evaluation prompt template
eval_prompt = """system:
You are an AI quality evaluator. Score the answer's relevance to the question on a scale of 1-5.
Return ONLY a number.

user:
Question: {{question}}
Answer: {{answer}}
Ground Truth: {{ground_truth}}

Score (1-5):
"""
with open("eval-flow/evaluate_relevance.jinja2", "w") as f:
f.write(eval_prompt)

# Create test data for evaluation
import json
test_data = [
{
"question": "What is Azure AI Foundry?",
"answer": "Azure AI Foundry is a platform for building generative AI apps.",
"ground_truth": "Azure AI Foundry is a unified platform for building, testing, and deploying AI solutions with hub and project architecture."
},
{
"question": "What models does Azure OpenAI support?",
"answer": "Azure OpenAI supports GPT-4o, GPT-4o-mini, and other models.",
"ground_truth": "Azure OpenAI supports GPT-4o, GPT-4o-mini, GPT-4, DALL-E, Whisper, and text embedding models."
}
]
with open("eval-flow/test_data.jsonl", "w") as f:
for item in test_data:
f.write(json.dumps(item) + "\n")

# Run the evaluation
eval_run = pf.run(
flow="eval-flow",
data="eval-flow/test_data.jsonl",
name="eval-run-001"
)
print(f"Evaluation run: {eval_run.name}")
print(f"Status: {eval_run.status}")

# Get results
details = pf.get_details(eval_run)
print(f"\nResults:\n{details}")

Tarefa 3: Testar Fluxo com Variants

import os
from promptflow.client import PFClient

pf = PFClient()

# Create a flow with prompt variants for A/B testing
variant_flow_yaml = """
$schema: https://azuremlschemas.azureedge.net/promptflow/latest/Flow.schema.json
inputs:
topic:
type: string
default: "Azure Kubernetes Service"
outputs:
result:
type: string
reference: ${generate.output}
nodes:
- name: generate
type: llm
source:
type: code
path: generate.jinja2
inputs:
deployment_name: gpt-4o-standard
max_tokens: 300
temperature: 0.7
topic: ${inputs.topic}
connection: aoai-connection
api: chat
use_variants: true
"""

os.makedirs("variant-flow", exist_ok=True)
with open("variant-flow/flow.dag.yaml", "w") as f:
f.write(variant_flow_yaml)

# Variant 0: Concise style
variant_0 = """system:
You are a concise technical writer. Keep responses under 100 words.

user:
Explain: {{topic}}
"""
with open("variant-flow/generate.jinja2", "w") as f:
f.write(variant_0)

# Variant 1: Detailed style
variant_1 = """system:
You are a detailed technical writer. Provide comprehensive explanations with examples.

user:
Provide a detailed explanation of: {{topic}}
Include at least one practical example.
"""
with open("variant-flow/generate_variant_1.jinja2", "w") as f:
f.write(variant_1)

# Test with default variant
result_0 = pf.test(flow="variant-flow", inputs={"topic": "Azure Kubernetes Service"})
print(f"Variant 0 (Concise): {result_0['result'][:100]}...")

# Test with variant 1
result_1 = pf.test(
flow="variant-flow",
inputs={"topic": "Azure Kubernetes Service"},
node="generate",
variant="${generate.variant_1}"
)
print(f"\nVariant 1 (Detailed): {result_1['result'][:100]}...")

Tarefa 4: Implantar Fluxo em Endpoint Gerenciado

from azure.identity import DefaultAzureCredential
from azure.ai.ml import MLClient
from azure.ai.ml.entities import (
ManagedOnlineEndpoint,
ManagedOnlineDeployment,
Model,
Environment,
)

credential = DefaultAzureCredential()
ml_client = MLClient(
credential=credential,
subscription_id="YOUR_SUBSCRIPTION_ID",
resource_group_name="rg-ai102-challenge13",
workspace_name="proj-ai102-genai",
)

# Create managed online endpoint
endpoint = ManagedOnlineEndpoint(
name="pf-standard-flow-endpoint",
description="Prompt Flow standard flow endpoint",
auth_mode="key",
)
ml_client.online_endpoints.begin_create_or_update(endpoint).result()
print(f"Endpoint created: {endpoint.name}")

# Deploy the flow
deployment = ManagedOnlineDeployment(
name="default",
endpoint_name="pf-standard-flow-endpoint",
model=Model(path="my-standard-flow"),
instance_type="Standard_DS3_v2",
instance_count=1,
)
ml_client.online_deployments.begin_create_or_update(deployment).result()
print(f"Deployment created: {deployment.name}")

# Set traffic to 100%
endpoint.traffic = {"default": 100}
ml_client.online_endpoints.begin_create_or_update(endpoint).result()

# Test the deployed endpoint
import json
result = ml_client.online_endpoints.invoke(
endpoint_name="pf-standard-flow-endpoint",
request_file=json.dumps({"topic": "Azure AI Services"}),
)
print(f"Response: {result}")

Saída Esperada

Após completar todas as tarefas, você deve ter:

  1. Standard flow (my-standard-flow/) com:
    • flow.dag.yaml definindo a estrutura do DAG
    • Nó LLM usando o template generate_content.jinja2
    • Nó Python com a lógica summarize.py
  2. Evaluation flow (eval-flow/) que pontua relevância de 1-5
  3. Variant flow demonstrando teste A/B de estilos de prompt
  4. Endpoint implantado servindo o standard flow com autenticação por chave

Quebra & conserta

CenárioSintomaCausa RaizCorreção
Teste do fluxo falhaConnectionNotFound: aoai-connectionConexão não configurada localmenteExecute pf connection create --file connection.yaml ou defina variáveis de ambiente
Saída do nó vaziaNó downstream recebe NoneReferência ${node.output} incorretaVerifique se os nomes dos nós correspondem exatamente nas referências YAML
Avaliação pontua tudo como 1LLM retorna formato inesperadoPrompt não restritivo o suficienteAdicione "Return ONLY a number between 1 and 5" à mensagem de sistema
Implantação falhaModelNotFound durante implantaçãoCaminho do fluxo incorreto ou dependências faltandoGaranta que requirements.txt está no diretório do fluxo
Variant não encontradaErro VariantNotFoundNomenclatura do arquivo de variante não segue a convençãoUse o padrão de nomenclatura {node_name}_variant_{N}.jinja2

Verificação de Conhecimento

1. Quais são os três tipos de fluxo principais no Prompt Flow?

2. Como as variants permitem otimização de prompts no Prompt Flow?

3. Qual é a sintaxe correta para referenciar a saída de um nó no YAML do fluxo?

4. Qual é o propósito de uma connection no Prompt Flow?

5. Qual tipo de nó você usaria para implementar lógica customizada de transformação de dados em um fluxo?

Limpeza

# Delete endpoint (stops billing for compute)
az ml online-endpoint delete \
--name "pf-standard-flow-endpoint" \
--resource-group rg-ai102-challenge13 \
--workspace-name proj-ai102-genai --yes

az group delete --name rg-ai102-challenge13 --yes --no-wait

Saiba Mais