Strona główna / Artykuły / Uwagi praktyczne: Integracja AI w praktyce – wyjście poza prosty wrapper API

Uwagi praktyczne: Integracja AI w praktyce – wyjście poza prosty wrapper API

Krok po kroku przewodnik po „Praktycznych notatkach: Integracja AI w praktyce – wyjście poza prosty wrapper API: umowy, sprawdzania oraz gotowe miejsca na kod dla zespołów wdrażających ten wzorzec”.

1351 słów

Poniższe notatki przedstawiają praktyczną ścieżkę postępowania w temacie „Integracja AI pragmatyczna: Wyjście poza wrapper API”. Nacisk kładziony jest na umowy, sprawdzania oraz miejsca zastępcze dla kodu, a nie na motywacyjne aspekty. Podczas przechodzenia przez etap przeglądu najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces.

Niepowodzenia integracji API w praktyce

Faza naprawiania błędów integracji API w rzeczywistym środowisku działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię do analizy. Zapisz jeden idealny zapis działania, jeden przypadek błędu oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy wprowadzanymi danymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Oddziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

import openai
# Replace with your actual API key or ensure it's set in an
environment variable
# openai.api_key = "YOUR_API_KEY"
model_name = "gpt-5.2" # Hardcoded model name
user_prompt = "Tell me a short, interesting fact about space."
# Simple string prompt
try:
 # Make a direct call to the Chat Completions API
 client = OpenAI(api_key="YOUR_API_KEY")
response = openai.ChatCompletion.create(
 model=model_name,
 messages=[
 {"role": "user", "content": user_prompt}
 ]
 )
 # Print the assistant's reply
 print(response.choices[0].message.content)
except openai.OpenAIError as e:
 # Catch specific OpenAI API errors
 print(f"An OpenAI API error occurred: {e}")
except Exception as e:
 # Catch any other unexpected errors
 print(f"An unexpected error occurred: {e}")

Budowanie solidnej warstwy integracji z AI

Faza budowy solidnej sztucznej inteligencji działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zanim rozszerzysz zakres, zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian. Zapisuj czasy wykonywania zadań oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się od wersji demonstracyjnej do środowisk współdzielonych. Rozdziel politykę dzielenia na fragmenty od polityki wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

Wdrażanie agentów AI opartych na zdarzeniach

Faza wdrażania agentów AI opartych na zdarzeniach funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości. Faza wdrażania agentów AI opartych na zdarzeniach funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sekwencję operacji.

import json
from typing import Dict, Any
def handle_new_ticket_webhook(event_payload: Dict[str, Any]) -> Dict[str, Any]:
 """
 Handles a 'new_ticket' webhook event by constructing a prompt and
 calling an LLM orchestrator.
 """
 event_type = event_payload.get("event_type")
 ticket_data = event_payload.get("data", {})
 if event_type != "new_ticket":
 # Ignore events that are not 'new_ticket'
 return {"status": "ignored", "message": "Not a new_ticket event"}
 ticket_id = ticket_data.get("ticket_id")
 subject = ticket_data.get("subject")
 description = ticket_data.get("description")
 requester_email = ticket_data.get("requester_email")
 if not all([ticket_id, subject, description, requester_email]):
 # Validate essential ticket data
 return {"status": "error", "message": "Missing essential ticket data"}
 # Construct a comprehensive prompt for the LLM based on the new ticket
 prompt = (
 f"A new support ticket (ID: {ticket_id}) has been created.
"
 f"Subject: {subject}
"
 f"Description: {description}
"
 f"Requester: {requester_email}
"
 "Please analyze this ticket. Use internal documentation to find relevant "
 "solutions or escalation paths, and if necessary, use communication tools "
 "to gather more information or update the requester."
 )
 try:
 # Call the orchestrator with the generated prompt
 # The orchestrator is expected to use an LLM with function-calling capabilities
 # to interact with various internal APIs (e.g., documentation search, email, chat).
 orchestrator_response = call_llm_orchestrator(prompt, ticket_id)
 return {"status": "success", "ticket_id": ticket_id, "orchestrator_output": orchestrator_response}
 except Exception as e:
 # Handle potential errors during the orchestrator call
 return {"status": "error", "ticket_id": ticket_id, "message": f"Orchestrator call failed: {e}"}
def call_llm_orchestrator(prompt: str, ticket_id: str) -> Dict[str, Any]:
 """
 Placeholder for the function that calls the LLM orchestrator.
 In a real scenario, this would interact with an LLM service.
 """
 # Simulate an orchestrator response
 # This might include actions taken, suggested next steps, or a summary.
 print(f"Calling LLM Orchestrator for Ticket ID: {ticket_id} with prompt:
{prompt[:100]}…")

 # Example of a function-calling interaction: LLM might decide to search docs
 # or draft an email.

 # Placeholder for actual LLM interaction and function calling logic
 # orchestrator_llm.invoke(prompt, tools=[search_docs, send_email, update_ticket_status])

 return {
 "action_suggested": "initial assessment complete",
 "next_steps": ["search internal knowledge base", "draft initial response"],
 "orchestrator_version": "v1.0"
 }
# Example usage (simulating a Flask/FastAPI request body)
if __name__ == "__main__":
 example_payload = {
 "event_type": "new_ticket",
 "data": {
 "ticket_id": "TKT-2023–001",
 "subject": "Email delivery issues for user X",
 "description": "User X reports not receiving emails since yesterday morning. Checked spam, nothing there.",
 "requester_email": "user.x@example.com",
 "priority": "high",
 "category": "Email Service"
 },
 "timestamp": "2023–10–27T10:00:00Z"
 }
 response = handle_new_ticket_webhook(example_payload)
 print("
Webhook Handler Response:")
 print(json.dumps(response, indent=2))
 # Example of a non-new_ticket event
 other_payload = {
 "event_type": "ticket_updated",
 "data": {"ticket_id": "TKT-2023–001", "status": "pending"},
 "timestamp": "2023–10–27T10:30:00Z"
 }
 response_other = handle_new_ticket_webhook(other_payload)
 print("
Webhook Handler Response for other event:")
 print(json.dumps(response_other, indent=2))

Optymalizacja systemów AI opartych na wielu modelach

W fazie optymalizacji systemów AI opartych na wielu modelach należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu systemu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć przypadkowe, częściowe ukończenie zadań. Przy następnym kroku, który polega na tworzeniu kodu lub wywoływaniu narzędzi, preferuj strukturyzowane wyniki z walidacją schematu zamiast tekstów w formie swobodnej.

Praktyczna droga naprzód

W fazie pragmatycznego rozwoju należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy odnotować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Należy podać fragmenty tekstu, które faktycznie stanowiły podstawę odpowiedzi. Bez tych odniesień operatorzy nie są w stanie odróżnić halucynacji od luki w indeksowaniu.

Lista kontrolna operacyjna

W fazie listy kontrolnej operacyjnej należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu.

Zdokumentuj razem ścieżkę prawidłowego działania oraz ścieżkę przywracania. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości nieudanych są częścią produktu, a nie czymś do dodania później.

Cytuj fragmenty, które faktycznie stanowią podstawę odpowiedzi. Bez cytatów operatorzy nie mogą odróżnić halucynacji od luki w indeksowaniu.

Napisz krótki przewodnik: jak rotować klucze, jak opróżnić kolejkę, jak cofnąć ostatnie zaimportowanie.

Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces.

Cytuj fragmenty, które faktycznie stanowią podstawę odpowiedzi. Bez cytatów operatorzy nie mogą odróżnić halucynacji od luki w indeksowaniu.

Zanim wdrożysz tę architekturę, zamroź wersje, utwórz dokładny zapis dla kluczowych etapów realizacji oraz potwierdź kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności użytkowników oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Wolimy nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwaga dotycząca 1eebfcb599d4: trzymaj klucze dostawcy poza repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj zapisy obok plików przygotowawczych do testów, aby późniejsze zmiany modeli pozostawały porównywalne.