Lab 11: Wdrażanie agenta z kodu (Create/Update)
Opis
W tym laboratorium nauczymy się automatyzować tworzenie i aktualizację agentów używając Python SDK. Będziemy budować skrypt małymi kawałkami - każdy krok to kilka linijek kodu które dodasz, uruchomisz i zrozumiesz przed dodaniem kolejnego kawałka.
Co zbudujemy:
- Skrypt który ładuje instrukcje agenta z pliku Markdown
- Skrypt który ładuje OpenAPI spec z pliku JSON
- Pattern create-or-update - sprawdza czy agent istnieje i tworzy lub aktualizuje
- Referencjonowanie connection utworzonego w portalu
- Konfiguracja przez zmienne środowiskowe
Zalety tego podejścia:
- ✅ Infrastructure as Code - wersjonowanie agentów w git
- ✅ Powtarzalność - łatwo odtworzyć agenta w różnych środowiskach
- ✅ CI/CD ready - możliwość automatyzacji deploymentu
- ✅ Prawdziwy update - agent ID się nie zmienia
- ✅ Separacja concerns - instructions i spec w osobnych plikach
Przygotowanie
Krok 1: Wymagania
Virtual environment:
Użyj tego samego venv co w poprzednich labach. Jeśli masz aktywny venv - zostań w nim. Jeśli nie:
# Przejdź do katalogu roboczego z Lab 06
cd c:\workshop # lub twój katalog roboczy
# Aktywuj venv
source venv/bin/activate # Linux/Mac
# lub
venv\Scripts\activate.bat # Windows
Zainstaluj dodatkowy pakiet:
pip install python-dotenv
💡 Pakiety z Lab 06: Pakiety
azure-ai-projectsiazure-identityjuż masz zainstalowane z Lab 06, więc teraz tylko dodajemypython-dotenvdo obsługi plików.env.
Connection w portalu:
WAŻNE: Connection MUSI być utworzony ręcznie w portalu PRZED rozpoczęciem labu!
Jeśli masz już connection z Lab 04 (krs-apim-connection-<INICJAŁ>) - użyj go.
Jeśli nie, utwórz zgodnie z instrukcjami Lab 04:
- AI Portal (ai.azure.com) → Twój projekt → Management center → Connected resources → + New connection
- Custom keys
- Nazwa:
krs-apim-connection-<INICJAŁ> - Dodaj 2 klucze (oba z tym samym API subscription key)
Azure authentication:
Jeśli wykonałeś Lab 06: Python SDK Basics, masz już skonfigurowane uwierzytelnienie!
💡 Zobacz Lab 06: Szczegółowe instrukcje uwierzytelniania znajdziesz w Lab 06 → Krok 5: Konfiguracja uwierzytelniania. Nie musisz ponownie logować się jeśli już jesteś zalogowany (
az loginz Lab 01 nadal działa).
Krok 2: Przygotuj pliki konfiguracyjne
Otwórz Visual Studio Code przez wpisanie code . w katalogu gdzie masz venv
Utwórz plik .env:
Zawartość .env:
# Project Endpoint - z Portal → Overview
PROJECT_ENDPOINT="https://ai-xxx.services.ai.azure.com/api/projects/your-project"
# Model deployment - z Portal → Models + endpoints → Name
MODEL_DEPLOYMENT_NAME="gpt-4.1-mini"
# Connection name - z Portal → Management center → Connected resources
CONNECTION_NAME="krs-apim-connection-<INICJAŁ>"
Gdzie znaleźć te wartości:
| Zmienna | Lokalizacja w portalu |
|---|---|
PROJECT_ENDPOINT |
Overview → sekcja “Azure AI Foundry project endpoint” |
MODEL_DEPLOYMENT_NAME |
Models + endpoints → kolumna “Name” (nie “Model name”!) |
CONNECTION_NAME |
Management center → Connected resources → kolumna “Name” |
Tip: Nigdy nie commituj
.envdo git! Dodaj do.gitignore.
Krok 3: Przygotuj plik z instrukcjami agenta
Utwórz plik krs_agent_instructions.md:
Utwórz plik krs_agent_instructions.md
Zawartość krs_agent_instructions.md:
# KRS Agent Instructions
Jesteś asystentem pomagającym sprawdzać dane firm w Krajowym Rejestrze Sądowym.
## Twoje narzędzie
- **getKrsOdpisAktualny** - pobiera aktualny odpis z KRS
## Parametry
- **krs**: numer KRS (10 cyfr, np. 0000123456)
- **rejestr**: ZAWSZE używaj "P" (rejestr przedsiębiorców)
## Proces działania
Gdy użytkownik poda numer KRS:
1. Wywołaj getKrsOdpisAktualny z parametrem rejestr="P"
2. Przedstaw dane w czytelny sposób używając formatowania Markdown
3. Jeśli API zwróci 404 - powiedz że firma nie znaleziona
## ZASADY
- ZAWSZE używaj narzędzia - nie wymyślaj danych!
- Odpowiadaj TYLKO na pytania dotyczące danych z KRS
- Formatuj odpowiedzi używając Markdown (nagłówki, listy, pogrubienia)
Dlaczego osobny plik? Łatwiej edytować, wersjonować w git, reużywać w wielu skryptach.
Krok 4: Pobierz OpenAPI spec dla KRS API
Z Azure Portal (eksport z APIM):
- Portal Azure → API Management → APIs → KRS API
- Kliknij … (trzy kropki obok nazwy API)
- Export → OpenAPI v3 (JSON)
- Zapisz jako
krs-api.jsonw katalogu roboczym
Weryfikacja pliku:
type krs-api.json #CMD
Get-Content krs-api.json #PowerShell
Powinieneś zobaczyć JSON z:
"openapi": "3.0.1""title": "KRS API - Krajowy Rejestr Sądowy""paths": { ... }"operationId": "getKrsOdpisAktualny"
Ważne: Używaj formatu JSON, nie YAML!
Budowanie skryptu krok po kroku
Teraz zbudujemy skrypt małymi kawałkami. Każdy krok:
- Dodasz kod
- Uruchomisz skrypt
- Zobaczysz wynik
- Zrozumiesz co się stało
- Przejdziesz do kolejnego kroku
Krok 1: Utworzenie pliku i podstawowe importy
Utwórz plik create_agent.py w swoim katalogu roboczym (z aktywowanym venv!):
#!/usr/bin/env python3
"""
Lab 11: Create or Update Agent - Step by step
"""
import os
import json
from pathlib import Path
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from azure.ai.agents.models import (
OpenApiTool,
OpenApiConnectionAuthDetails,
OpenApiConnectionSecurityScheme
)
from dotenv import load_dotenv
print("✓ Importy załadowane")
Uruchom:
python create_agent.py
Oczekiwany wynik:
✓ Importy załadowane
Co się stało: Sprawdziliśmy że pakiety są zainstalowane poprawnie.
Krok 2: Załadowanie zmiennych środowiskowych
Dodaj do pliku create_agent.py (pod importami):
# Załaduj zmienne z .env
print("\n🔧 Ładowanie konfiguracji z .env...")
load_dotenv()
PROJECT_ENDPOINT = os.getenv("PROJECT_ENDPOINT")
MODEL_DEPLOYMENT_NAME = os.getenv("MODEL_DEPLOYMENT_NAME")
CONNECTION_NAME = os.getenv("CONNECTION_NAME")
print(f" PROJECT_ENDPOINT: {PROJECT_ENDPOINT}")
print(f" MODEL_DEPLOYMENT_NAME: {MODEL_DEPLOYMENT_NAME}")
print(f" CONNECTION_NAME: {CONNECTION_NAME}")
# Walidacja
if not PROJECT_ENDPOINT or not MODEL_DEPLOYMENT_NAME or not CONNECTION_NAME:
print("\n❌ BŁĄD: Brakuje zmiennych środowiskowych w .env!")
exit(1)
print("✓ Konfiguracja załadowana")
Uruchom:
python create_agent.py
Oczekiwany wynik:
✓ Importy załadowane
🔧 Ładowanie konfiguracji z .env...
PROJECT_ENDPOINT: https://ai-xxx.services.ai.azure.com/...
MODEL_DEPLOYMENT_NAME: gpt-4.1-mini
CONNECTION_NAME: krs-apim-connection-<INICJAŁ>
✓ Konfiguracja załadowana
Co się stało:
load_dotenv()załadował zmienne z pliku.envos.getenv()odczytał wartości zmiennych- Walidacja sprawdziła czy wszystkie wymagane zmienne są ustawione
- Jeśli brakuje którejkolwiek - skrypt kończy się błędem
Tip: Walidacja na początku = fail fast. Lepiej błąd na starcie niż w połowie wykonania.
Krok 3: Wczytanie instrukcji z pliku
Dodaj kolejny kawałek kodu:
# Wczytaj instrukcje agenta z pliku Markdown
print("\n📄 Wczytywanie instrukcji z pliku...")
instructions_file = Path("krs_agent_instructions.md")
if not instructions_file.exists():
print(f"❌ BŁĄD: Nie znaleziono pliku {instructions_file}")
exit(1)
with open(instructions_file, 'r', encoding='utf-8') as f:
instructions = f.read()
print(f"✓ Załadowano {len(instructions)} znaków z {instructions_file}")
Uruchom:
python create_agent.py
Oczekiwany wynik:
✓ Importy załadowane
🔧 Ładowanie konfiguracji z .env...
...
✓ Konfiguracja załadowana
📄 Wczytywanie instrukcji z pliku...
✓ Załadowano 1234 znaków z krs_agent_instructions.md
Co się stało:
Path("krs_agent_instructions.md")- obiekt reprezentujący ścieżkę do pliku.exists()- sprawdza czy plik istniejeopen(..., 'r', encoding='utf-8')- otwiera plik do odczytu z UTF-8.read()- wczytuje całą zawartość pliku do zmiennejinstructions
Dlaczego UTF-8? Polskie znaki (ą, ę, ł) wymagają UTF-8. Bez tego mogą się źle wyświetlać.
Krok 4: Wczytanie OpenAPI spec z JSON
Dodaj kolejny kawałek:
# Wczytaj OpenAPI spec z pliku JSON
print("\n📄 Wczytywanie OpenAPI spec z pliku...")
openapi_file = Path("krs-api.json")
if not openapi_file.exists():
print(f"❌ BŁĄD: Nie znaleziono pliku {openapi_file}")
exit(1)
with open(openapi_file, 'r', encoding='utf-8') as f:
openapi_spec = json.load(f)
print(f"✓ Załadowano OpenAPI spec")
print(f" API Title: {openapi_spec.get('info', {}).get('title')}")
print(f" API Version: {openapi_spec.get('info', {}).get('version')}")
# Policz operacje
operations = []
for path, methods in openapi_spec.get('paths', {}).items():
for method in ['get', 'post', 'put', 'delete', 'patch']:
if method in methods:
op_id = methods[method].get('operationId', 'unknown')
operations.append(op_id)
print(f" Operacja: {op_id}")
print(f"✓ Znaleziono {len(operations)} operacji")
Uruchom:
python create_agent.py
Oczekiwany wynik:
...
📄 Wczytywanie OpenAPI spec z pliku...
✓ Załadowano OpenAPI spec
API Title: KRS API - Krajowy Rejestr Sądowy
API Version: 1.0
Operacja: getKrsOdpisAktualny
✓ Znaleziono 1 operacji
Co się stało:
json.load(f)- parsuje JSON do słownika Python.get('info', {})- bezpieczny dostęp do kluczy (zwraca{}jeśli nie ma ‘info’)- Iteracja po
paths→methods- liczy dostępne operacje operationId- wymagane dla każdej operacji w OpenAPI
Tip:
operationIdjest używane przez agenta do wywołania funkcji. Musi być unikalne!
Krok 5: Utworzenie klienta Azure AI
Dodaj kolejny kawałek:
# Utwórz klienta Azure AI Project
print("\n🔧 Inicjalizacja klienta Azure AI...")
try:
credential = DefaultAzureCredential()
# (Opcjonalne) Jeżeli masz rozszyfrowywanie ruchu na proxy (SSL interception),
# możesz wyłączyć weryfikowanie certyfikatu:
# from azure.core.pipeline.transport import RequestsTransport
# transport = RequestsTransport(connection_verify=False)
project_client = AIProjectClient(
endpoint=PROJECT_ENDPOINT,
credential=credential
# transport=transport # Odkomentuj jeżeli używasz proxy
)
print("✓ Klient utworzony pomyślnie")
except Exception as e:
print(f"❌ BŁĄD: {e}")
print("\n💡 Upewnij się że jesteś zalogowany:")
print(" - Uruchom: az login")
print(" - Lub ustaw: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET")
exit(1)
Uruchom:
python create_agent.py
Oczekiwany wynik:
...
🔧 Inicjalizacja klienta Azure AI...
✓ Klient utworzony pomyślnie
Co się stało:
DefaultAzureCredential()- próbuje uwierzytelnienia w kolejności:- Zmienne środowiskowe (Service Principal)
- Managed Identity (jeśli na Azure VM)
- Azure CLI (
az login) - Interactive browser login
AIProjectClient- klient do komunikacji z Azure AI Foundry- Używa pierwszego credential który zadziała
Jeśli błąd uwierzytelnienia:
# Zaloguj się przez Azure CLI
az login
# Sprawdź
az account show
Krok 6: Utworzenie OpenAPI tool z connection
Dodaj kolejny kawałek:
# Utwórz OpenAPI tool z connection-based authentication
print(f"\n🔌 Tworzenie OpenAPI tool...")
print(f" Connection: {CONNECTION_NAME}")
try:
# Obiekt autentykacji
auth = OpenApiConnectionAuthDetails(
security_scheme=OpenApiConnectionSecurityScheme(
connection_id=CONNECTION_NAME
)
)
# Obiekt OpenAPI tool
openapi_tool = OpenApiTool(
name="krs_api",
spec=openapi_spec,
description="Retrieves company data from Polish National Court Register (KRS)",
auth=auth
)
print("✓ OpenAPI tool utworzony")
print(f" Nazwa: krs_api")
print(f" Auth: Connection ({CONNECTION_NAME})")
except Exception as e:
print(f"❌ BŁĄD: {e}")
print(f"\n💡 Sprawdź czy connection '{CONNECTION_NAME}' istnieje w portalu:")
print(" Portal → Management center → Connected resources")
exit(1)
Uruchom:
python create_agent.py
Oczekiwany wynik:
...
🔌 Tworzenie OpenAPI tool...
Connection: krs-apim-connection-<INICJAŁ>
✓ OpenAPI tool utworzony
Nazwa: krs_api
Auth: Connection (krs-apim-connection-<INICJAŁ>)
Co się stało:
OpenApiConnectionAuthDetails- typ autentykacji przez connectionconnection_id- nazwa connection z portalu (nie ID projektu!)OpenApiTool- opakowuje OpenAPI spec + authname- używane w wywołaniach agentaspec- słownik z OpenAPI (wczytany wcześniej)description- pomaga agentowi zdecydować kiedy użyć toolauth- obiekt z credentials
Ważne: Connection musi istnieć w portalu PRZED uruchomieniem skryptu!
Krok 7: Sprawdzenie czy agent już istnieje
Dodaj kolejny kawałek:
# Sprawdź czy agent już istnieje
print("\n🔍 Sprawdzanie czy agent istnieje...")
agent_name = "KRS-Agent-FromCode"
try:
agents_list = project_client.agents.list_agents()
agents = list(agents_list)
print(f"✓ Znaleziono {len(agents)} agentów w projekcie")
except Exception as e:
print(f"❌ BŁĄD przy listowaniu agentów: {e}")
exit(1)
# Szukaj agenta po nazwie
existing_agent = None
for agent in agents:
if agent.name == agent_name:
existing_agent = agent
print(f"✓ Agent '{agent_name}' istnieje (ID: {agent.id})")
break
if not existing_agent:
print(f" Agent '{agent_name}' nie istnieje - zostanie utworzony")
Uruchom:
python create_agent.py
Oczekiwany wynik (pierwszy raz - agent nie istnieje):
...
🔍 Sprawdzanie czy agent istnieje...
✓ Znaleziono 2 agentów w projekcie
Agent 'KRS-Agent-FromCode' nie istnieje - zostanie utworzony
Co się stało:
list_agents()- pobiera listę wszystkich agentów w projekcielist()- konwertuje iterator na listę (żeby móc iterować)- Pętla
for agent in agents- sprawdza każdego agenta - Porównanie
agent.name == agent_name- szuka po nazwie - Jeśli znajdzie - zapisuje do
existing_agent
Tip: Wyszukiwanie po nazwie, nie ID. Nazwa jest bardziej czytelna i stabilna.
Krok 8: Create lub Update agenta
Dodaj ostatni kawałek - serce skryptu:
# CREATE lub UPDATE agenta
print(f"\n🤖 {'Aktualizacja' if existing_agent else 'Tworzenie'} agenta...")
try:
if existing_agent:
# UPDATE - agent już istnieje
print(f" Istniejący agent ID: {existing_agent.id}")
print(f" Istniejący model: {existing_agent.model}")
final_agent = project_client.agents.update_agent(
agent_id=existing_agent.id,
model=MODEL_DEPLOYMENT_NAME,
name=agent_name,
instructions=instructions,
tools=openapi_tool.definitions
)
print("✅ Agent zaktualizowany!")
print(f" Agent ID: {final_agent.id} (ten sam)")
print(f" Nowy model: {final_agent.model}")
print(f" Instructions: zaktualizowane")
print(f" Tools: zaktualizowane")
else:
# CREATE - agent nie istnieje
final_agent = project_client.agents.create_agent(
model=MODEL_DEPLOYMENT_NAME,
name=agent_name,
instructions=instructions,
tools=openapi_tool.definitions
)
print("✅ Agent utworzony!")
print(f" Agent ID: {final_agent.id}")
print(f" Model: {final_agent.model}")
except Exception as e:
print(f"❌ BŁĄD: {e}")
exit(1)
Uruchom:
python create_agent.py
Oczekiwany wynik (pierwszy raz - CREATE):
...
🤖 Tworzenie agenta...
✅ Agent utworzony!
Agent ID: asst_abc123xyz456
Model: gpt-4.1-mini
Uruchom DRUGI raz (bez zmian):
python create_agent.py
Oczekiwany wynik (drugi raz - UPDATE):
...
🔍 Sprawdzanie czy agent istnieje...
✓ Znaleziono 3 agentów w projekcie
✓ Agent 'KRS-Agent-FromCode' istnieje (ID: asst_abc123xyz456)
🤖 Aktualizacja agenta...
Istniejący agent ID: asst_abc123xyz456
Istniejący model: gpt-4.1-mini
✅ Agent zaktualizowany!
Agent ID: asst_abc123xyz456 (ten sam)
Nowy model: gpt-4.1-mini
Instructions: zaktualizowane
Tools: zaktualizowane
Co się stało:
if existing_agent:- decyduje czy UPDATE czy CREATE- UPDATE path:
update_agent()- aktualizuje istniejącego agentaagent_id- ID agenta do aktualizacji- Wszystkie parametry (model, instructions, tools) - nowe wartości
- Agent ID się NIE zmienia - threads dalej działają!
- CREATE path:
create_agent()- tworzy nowego agenta- Nowy agent dostaje nowy ID
openapi_tool.definitions- liczba mnoga! (nie.definition)
Kluczowa różnica: UPDATE zachowuje Agent ID - wszystkie istniejące threads i runs dalej działają!
Krok 9: Podsumowanie i next steps
Dodaj na końcu pliku:
# Podsumowanie
print("\n" + "=" * 60)
print("✨ Gotowe!")
print("=" * 60)
print(f"\n📊 Szczegóły agenta:")
print(f" Nazwa: {final_agent.name}")
print(f" ID: {final_agent.id}")
print(f" Model: {final_agent.model}")
if existing_agent:
print(f"\n💡 Co się stało:")
print(f" ✅ Agent został ZAKTUALIZOWANY")
print(f" - Instructions z: {instructions_file}")
print(f" - OpenAPI spec z: {openapi_file}")
print(f" - Model: {MODEL_DEPLOYMENT_NAME}")
else:
print(f"\n💡 Co się stało:")
print(f" ✅ Agent został UTWORZONY")
print(f" - Instructions z: {instructions_file}")
print(f" - OpenAPI spec z: {openapi_file}")
print(f" - Model: {MODEL_DEPLOYMENT_NAME}")
print(f"\n🎯 Następne kroki:")
print(f" 1. Portal: https://ai.azure.com")
print(f" 2. Agents → My agents → {final_agent.name}")
print(f" 3. Test w Playground!")
print(f"\n Pytanie testowe: 'Sprawdź firmę KRS 0000028860'\n")
Uruchom pełny skrypt:
python create_agent.py
Pełny output:
✓ Importy załadowane
🔧 Ładowanie konfiguracji z .env...
PROJECT_ENDPOINT: https://ai-xxx.services.ai.azure.com/...
MODEL_DEPLOYMENT_NAME: gpt-4.1-mini
CONNECTION_NAME: krs-apim-connection-<INICJAŁ>
✓ Konfiguracja załadowana
📄 Wczytywanie instrukcji z pliku...
✓ Załadowano 1234 znaków z krs_agent_instructions.md
📄 Wczytywanie OpenAPI spec z pliku...
✓ Załadowano OpenAPI spec
API Title: KRS API - Krajowy Rejestr Sądowy
API Version: 1.0
Operacja: getKrsOdpisAktualny
✓ Znaleziono 1 operacji
🔧 Inicjalizacja klienta Azure AI...
✓ Klient utworzony pomyślnie
🔌 Tworzenie OpenAPI tool...
Connection: krs-apim-connection-<INICJAŁ>
✓ OpenAPI tool utworzony
Nazwa: krs_api
Auth: Connection (krs-apim-connection-<INICJAŁ>)
🔍 Sprawdzanie czy agent istnieje...
✓ Znaleziono 3 agentów w projekcie
✓ Agent 'KRS-Agent-FromCode' istnieje (ID: asst_abc123xyz456)
🤖 Aktualizacja agenta...
Istniejący agent ID: asst_abc123xyz456
Istniejący model: gpt-4.1-mini
✅ Agent zaktualizowany!
Agent ID: asst_abc123xyz456 (ten sam)
Nowy model: gpt-4.1-mini
Instructions: zaktualizowane
Tools: zaktualizowane
============================================================
✨ Gotowe!
============================================================
📊 Szczegóły agenta:
Nazwa: KRS-Agent-FromCode
ID: asst_abc123xyz456
Model: gpt-4.1-mini
💡 Co się stało:
✅ Agent został ZAKTUALIZOWANY
- Instructions z: krs_agent_instructions.md
- OpenAPI spec z: krs-api.json
- Model: gpt-4.1-mini
🎯 Następne kroki:
1. Portal: https://ai.azure.com
2. Agents → My agents → KRS-Agent-FromCode
3. Test w Playground!
Pytanie testowe: 'Sprawdź firmę KRS 0000028860'
Test agenta w portalu
Krok 1: Otwórz Portal
- Przejdź do Azure AI Foundry Portal
- Wybierz swój projekt
- Agents → My agents
- Znajdź KRS-Agent-FromCode
- Kliknij na niego
Krok 2: Sprawdź konfigurację
W prawym panelu sprawdź:
- Model:
gpt-4.1-mini - Instructions: Powinny być załadowane z
krs_agent_instructions.md - Actions: Powinien być
krs_api(OpenAPI tool)
Krok 3: Test w Playground
W Playground wpisz:
Sprawdź dane firmy o numerze KRS 0000028860
Oczekiwany wynik:
- Agent wywoła
getKrsOdpisAktualny - Parametry:
krs=0000028860,rejestr=P - Pobierze dane PKN ORLEN S.A.
- Wyświetli dane w formacie Markdown
Workflow: Edycja i aktualizacja
Scenariusz 1: Zmiana instrukcji agenta
-
Otwórz plik
krs_agent_instructions.mdi zmień jego instrukcję (Dodaj, usuń, zmień) -
Uruchom skrypt ```bash
1. Uruchom skrypt - automatyczny UPDATE
python create_agent.py
2. Agent zaktualizowany! Ten sam ID!
### Scenariusz 2: Zmiana modelu
1. Otwórz plik `.env` i zmień model na `gpt-4o`
2. Uruchom skrypt.
```bash
python create_agent.py
3. Sprawdź w portalu czy się zmienił
Scenariusz 3: Aktualizacja OpenAPI spec
-
Wyeksportuj nowy spec z APIM (Portal → APIM → Export → JSON)
-
Nadpisz nim plik
krs-api.json - Uruchom skrypt
python create_agent.py - Sprawdź w portalu czy agent używa nowego spec!
Kluczowe koncepty
Pattern Create-or-Update
if existing_agent:
# UPDATE - zachowuje Agent ID
agent = client.agents.update_agent(
agent_id=existing_agent.id,
...
)
else:
# CREATE - nowy Agent ID
agent = client.agents.create_agent(
...
)
Zalety:
- ✅ Idempotentność - wielokrotne uruchomienie = ten sam rezultat
- ✅ Stabilny Agent ID - threads dalej działają
- ✅ CI/CD ready - automatyczny deployment
- ✅ Rollback -
git checkout old-version+ uruchom skrypt
OpenAPI Tool z Connection
# 1. Connection auth object
auth = OpenApiConnectionAuthDetails(
security_scheme=OpenApiConnectionSecurityScheme(
connection_id="krs-apim-connection-<INICJAŁ>" # Nazwa z portalu
)
)
# 2. OpenAPI tool
tool = OpenApiTool(
name="krs_api", # Nazwa dla agenta
spec=openapi_spec, # Słownik z JSON
description="...", # Opis dla agenta
auth=auth # Connection z portalu
)
# 3. W create/update agenta
agent = client.agents.create_agent(
tools=tool.definitions # LICZBA MNOGA!
)
Connection musi:
- Być utworzony w portalu PRZED uruchomieniem
- Mieć dokładnie tę samą nazwę co
connection_id - Zawierać API keys (Ocp-Apim-Subscription-Key, subscription-key)
Infrastructure as Code
Project/
├── .env # Config (NIE commituj do git!)
├── .gitignore # Dodaj: .env
├── krs_agent_instructions.md # Instructions (GIT)
├── krs-api.json # OpenAPI spec (GIT)
└── create_agent.py # Skrypt (GIT)
Workflow:
# 1. Zmień plik
git diff krs_agent_instructions.md
# 2. Commit
git add krs_agent_instructions.md
git commit -m "Update KRS agent instructions"
# 3. Deploy
python create_agent.py
# 4. Verify w portalu
Troubleshooting
Problem 1: ModuleNotFoundError
Błąd:
ModuleNotFoundError: No module named 'azure.ai.projects'
Rozwiązanie:
# Sprawdź czy venv aktywowany
which python # powinno pokazać ścieżkę do venv
# Jeśli nie
source venv/bin/activate # Linux/Mac
venv\Scripts\activate.bat # Windows
# Zainstaluj pakiety
pip install azure-ai-projects azure-identity python-dotenv
Problem 2: Authentication failed
Błąd:
❌ BŁĄD: DefaultAzureCredential failed to retrieve a token
Rozwiązanie:
# Azure CLI
az login
az account show
# Service Principal
export AZURE_TENANT_ID="..."
export AZURE_CLIENT_ID="..."
export AZURE_CLIENT_SECRET="..."
Problem 3: Connection not found
Błąd:
❌ BŁĄD przy tworzeniu OpenAPI tool: Connection 'krs-apim-connection-<INICJAŁ>' not found
Rozwiązanie:
- Portal → Management center → Connected resources
- Sprawdź czy connection istnieje
- Sprawdź dokładną nazwę (case sensitive!)
- Jeśli nie ma - utwórz (Lab 04)
- Zaktualizuj
CONNECTION_NAMEw.env
Problem 4: File not found
Błąd:
❌ BŁĄD: Nie znaleziono pliku krs_agent_instructions.md
Rozwiązanie:
# Sprawdź gdzie jesteś
pwd
# Sprawdź co jest w katalogu
ls -la
# Plik musi być w tym samym katalogu co skrypt
# Lub podaj pełną ścieżkę w Path(...)
Problem 5: JSON decode error
Błąd:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1
Rozwiązanie:
# Sprawdź zawartość pliku
cat krs-api.json | head
# Upewnij się że to JSON, nie YAML
# Pierwszy znak powinien być {
# Wyeksportuj ponownie z APIM w formacie JSON
Problem 6: Model deployment not found
Błąd:
❌ BŁĄD: Model deployment 'gpt-4.1-mini' not found
Rozwiązanie:
- Portal → Models + endpoints
- Sprawdź kolumnę Name (nie “Model name”!)
- Skopiuj dokładną nazwę
- Wklej do
MODEL_DEPLOYMENT_NAMEw.env - Jeśli nie ma - wdróż model (Lab 03)
CI/CD Integration
GitHub Actions przykład
.github/workflows/deploy-agent.yml:
name: Deploy KRS Agent
on:
push:
branches: [main]
paths:
- 'krs_agent_instructions.md'
- 'krs-api.json'
- 'create_agent.py'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install azure-ai-projects azure-identity python-dotenv
- name: Deploy agent
env:
PROJECT_ENDPOINT: $
MODEL_DEPLOYMENT_NAME: $
CONNECTION_NAME: $
AZURE_TENANT_ID: $
AZURE_CLIENT_ID: $
AZURE_CLIENT_SECRET: $
run: |
python create_agent.py
Konfiguracja GitHub Secrets:
- Repo → Settings → Secrets and variables → Actions
- Dodaj secrets:
PROJECT_ENDPOINTMODEL_DEPLOYMENT_NAMECONNECTION_NAMEAZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET
Workflow:
# 1. Zmień instructions
git add krs_agent_instructions.md
git commit -m "Update instructions"
git push
# 2. GitHub Action automatycznie:
# - Pobiera kod
# - Instaluje dependencies
# - Uruchamia create_agent.py
# - Agent zaktualizowany!
Best Practices
1. Wersjonowanie
# Commituj konfigurację, NIE credentials
git add krs_agent_instructions.md
git add krs-api.json
git add create_agent.py
git add .env.example # Template bez wartości
# NIE commituj
# .env - zawiera credentials!
2. Separacja środowisk
# Różne .env dla środowisk
.env.dev
.env.staging
.env.prod
# W skrypcie
env_file = ".env.prod" if os.getenv("ENV") == "prod" else ".env.dev"
load_dotenv(env_file)
3. Testowanie
# Na końcu skryptu dodaj smoke test
print("\n🧪 Test agenta...")
thread = project_client.agents.threads.create()
message = project_client.agents.messages.create(
thread_id=thread.id,
role="user",
content="Test: sprawdź KRS 0000028860"
)
run = project_client.agents.runs.create(
thread_id=thread.id,
agent_id=final_agent.id
)
# Poll for completion...
# Verify response contains expected data
print("✅ Test passed!")
4. Dokumentacja w kodzie
# Dobre komentarze wyjaśniają DLACZEGO, nie CO
# DOBRZE:
# Używamy connection dla bezpieczeństwa - API key w portalu, nie w kodzie
auth = OpenApiConnectionAuthDetails(...)
# ŹLE:
# Tworzymy auth
auth = OpenApiConnectionAuthDetails(...)
Podsumowanie
W tym labie nauczyłeś się:
✅ Budować skrypt małymi kawałkami - każdy krok testowany osobno ✅ Pattern Create-or-Update - idempotentne deployementy ✅ Ładować config z plików - instructions (MD), OpenAPI spec (JSON) ✅ Używać update_agent() - zachowuje Agent ID ✅ Connection-based auth - bezpieczne credentials ✅ Infrastructure as Code - wszystko w git ✅ CI/CD ready - automatyczny deployment
Następne kroki:
- Dostosuj skrypt do swoich agentów
- Dodaj testy automatyczne
- Zintegruj z CI/CD
- Dodaj więcej agentów (multi-agent deployment)
Dokumentacja: