Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide, AG-UI istemcilerinize ön uç işlev araçlarının nasıl ekleneceği gösterilir. Ön uç araçları, istemci tarafında yürütülen ve yapay zeka aracısının kullanıcının yerel ortamıyla etkileşim kurmasına, istemciye özgü verilere erişmesine veya kullanıcı arabirimi işlemleri gerçekleştirmesine olanak sağlayan işlevlerdir. Sunucu bu araçları ne zaman çağıracaklarını düzenler, ancak yürütme tamamen istemcide gerçekleşir.
Önkoşullar
Başlamadan önce Başlarken öğreticisini tamamladığınızdan ve aşağıdakilere sahip olduğunuzdan emin olun:
- .NET 8.0 veya üzeri
-
Microsoft.Agents.AI.AGUIpaket yüklendi -
Microsoft.Agents.AIpaket yüklendi - AG-UI istemci kurulumu hakkında temel bilgiler
Ön Uç Araçları nedir?
Ön uç araçları şunlara sahip işlev araçlarıdır:
- İstemcide tanımlanır ve kaydedilir
- İstemcinin ortamında yürüt (sunucuda değil)
- Yapay zeka aracısının istemciye özgü kaynaklarla etkileşim kurmasına izin verme
- Sonuçları aracının yanıtlara katabilmesi için sunucuya geri gönderin
- Kişiselleştirilmiş, bağlama duyarlı deneyimleri etkinleştirme
Yaygın kullanım örnekleri:
- Yerel algılayıcı verilerini okuma (GPS, sıcaklık vb.)
- İstemci tarafı depolamaya veya tercihlere erişme
- UI işlemlerini gerçekleştirme (temaları değiştirme, bildirimleri görüntüleme)
- Cihaza özgü özelliklerle (kamera, mikrofon) etkileşim kurma
İstemciye Frontend Araçları Kaydetme
"Başlarken kılavuzundaki en önemli fark, araçları istemci ajanına kaydetmektir." Değişiklikler şunlardır:
// Define a frontend function tool
[Description("Get the user's current location from GPS.")]
static string GetUserLocation()
{
// Access client-side GPS
return "Amsterdam, Netherlands (52.37°N, 4.90°E)";
}
// Create frontend tools
AITool[] frontendTools = [AIFunctionFactory.Create(GetUserLocation)];
// Pass tools when creating the agent
AIAgent agent = chatClient.AsAIAgent(
name: "agui-client",
description: "AG-UI Client Agent",
tools: frontendTools);
İstemci kodunuzun geri kalanı Başlarken öğreticisinde gösterildiği gibi kalır.
Araçlar Sunucuya Nasıl Gönderilir?
AsAIAgent() ile araçları kaydettiğinizde, AGUIChatClient otomatik olarak:
- Araç tanımlarını (adlar, açıklamalar, parametre şemaları) yakalar
- Her istekle birlikte araçları sunucu aracısına gönderir ve bunları ile eşler
ChatAgentRunOptions.ChatOptions.Tools
Sunucu istemci aracı bildirimlerini alır ve yapay zeka modeli bunları ne zaman çağıracaklarına karar verebilir.
Ara Yazılım ile Araçları İnceleme ve Değiştirme
Aracı işlem sürecini incelemek veya değiştirmek için araçlara erişim sağlamak da dahil olmak üzere, aracı ara katman yazılımını kullanabilirsiniz.
// Create agent with middleware that inspects tools
AIAgent inspectableAgent = baseAgent
.AsBuilder()
.Use(runFunc: null, runStreamingFunc: InspectToolsMiddleware)
.Build();
static async IAsyncEnumerable<AgentResponseUpdate> InspectToolsMiddleware(
IEnumerable<ChatMessage> messages,
AgentSession? session,
AgentRunOptions? options,
AIAgent innerAgent,
CancellationToken cancellationToken)
{
// Access the tools from ChatClientAgentRunOptions
if (options is ChatClientAgentRunOptions chatOptions)
{
IList<AITool>? tools = chatOptions.ChatOptions?.Tools;
if (tools != null)
{
Console.WriteLine($"Tools available for this run: {tools.Count}");
foreach (AITool tool in tools)
{
if (tool is AIFunction function)
{
Console.WriteLine($" - {function.Metadata.Name}: {function.Metadata.Description}");
}
}
}
}
await foreach (AgentResponseUpdate update in innerAgent.RunStreamingAsync(messages, session, options, cancellationToken))
{
yield return update;
}
}
Bu ara yazılım düzeni şunları yapmanızı sağlar:
- Yürütmeden önce araç tanımlarını doğrulama
Önemli Kavramlar
Ön uç araçlarına yönelik yeni kavramlar şunlardır:
-
İstemci tarafı kaydı: Araçlar önce
AIFunctionFactory.Create()kullanılarak istemci üzerinde kaydedilir ve ardındanAsAIAgent()'ye aktarılır. -
Otomatik yakalama: Araçlar otomatik olarak yakalanır ve
ChatAgentRunOptions.ChatOptions.Toolsaracılığıyla gönderilir.
Ön Uç Araçları Nasıl Çalışır?
Server-Side Süreci
Sunucu, ön uç araçlarının uygulama ayrıntılarını bilmiyor. Yalnızca şu bilgileri bilir:
- Araç adları ve açıklamaları (istemci kaydından)
- Parametre şemaları
- Aracın ne zaman çalıştırılması istenmelidir?
Yapay zeka aracısı bir ön uç aracısını çağırmaya karar verince:
- Sunucu, SSE aracılığıyla istemciye bir araç çağrısı isteği gönderir
- Sunucu istemcinin aracı yürütmesini ve sonuçları döndürmesini bekler
- Sunucu sonuçları aracının bağlamı içine ekler
- Ajan, araç sonuçlarıyla işlemeye devam ediyor
Müşteri Tarafı Akışı
İstemci ön yüz aracının çalıştırılmasını yönetir.
- Sunucudan, araç çağrısı isteğini gösteren
FunctionCallContentalır - Araç adını yerel olarak kaydedilmiş bir işlevle eşleştirir
- İstekten parametreleri seri durumdan kaldırır
- İşlevi yerel olarak yürütür
- Sonucu serileştirir
- Sunucuya geri gönderir
FunctionResultContent - Aracı yanıtları almaya devam ediyor
Arayüz Araçlarıyla Beklenen Sonuç
Aracı ön uç araçlarını çağırdığında araç çağrısını görürsünüz ve akış çıkışıyla sonuçlanır:
User (:q or quit to exit): Where am I located?
[Client Tool Call - Name: GetUserLocation]
[Client Tool Result: Amsterdam, Netherlands (52.37°N, 4.90°E)]
You are currently in Amsterdam, Netherlands, at coordinates 52.37°N, 4.90°E.
Ön Uç Araçları için Sunucu Kurulumu
Sunucunun ön uç araçlarını desteklemek için özel yapılandırmaya ihtiyacı yoktur. Başlarken kılavuzundan standart AG-UI sunucusunu kullanın, otomatik olarak:
- İstemci bağlantısı sırasında ön uç araç bildirimlerini alır
- Yapay zeka aracısının ihtiyaç duyduğunda araç yürütme isteğinde bulunur
- İstemciden sonuçları bekler
- Sonuçları aracının karar alma sürecine dahil eder
Sonraki Adımlar
Ön uç araçlarını anladığınıza göre şunları yapabilirsiniz:
- Arka Uç Araçları ile birleştirme: Hem ön uç hem de arka uç araçlarını birlikte kullanın
Ek Kaynaklar
Bu öğreticide, AG-UI istemcilerinize ön uç işlev araçlarının nasıl ekleneceği gösterilir. Ön uç araçları, istemci tarafında yürütülen ve yapay zeka aracısının kullanıcının yerel ortamıyla etkileşim kurmasına, istemciye özgü verilere erişmesine veya kullanıcı arabirimi işlemleri gerçekleştirmesine olanak sağlayan işlevlerdir.
Önkoşullar
Başlamadan önce Başlarken öğreticisini tamamladığınızdan ve aşağıdakilere sahip olduğunuzdan emin olun:
- Python 3.10 veya üzeri
-
httpxHTTP istemcisi işlevselliği için yüklendi - AG-UI istemci kurulumu hakkında temel bilgiler
- Azure OpenAI hizmeti yapılandırıldı
Ön Uç Araçları nedir?
Ön uç araçları şunlara sahip işlev araçlarıdır:
- İstemcide tanımlanır ve kaydedilir
- İstemcinin ortamında yürüt (sunucuda değil)
- Yapay zeka aracısının istemciye özgü kaynaklarla etkileşim kurmasına izin verme
- Sonuçları aracının yanıtlara katabilmesi için sunucuya geri gönderin
Yaygın kullanım örnekleri:
- Yerel algılayıcı verilerini okuma
- İstemci tarafı depolamaya veya tercihlere erişme
- Kullanıcı arabirimi işlemlerini gerçekleştirme
- Cihaza özgü özelliklerle etkileşim kurma
Ön Uç Araçları Oluşturma
Python'daki ön uç araçları arka uç araçlarına benzer şekilde tanımlanır ancak istemciye kaydedilir:
from typing import Annotated
from pydantic import BaseModel, Field
class SensorReading(BaseModel):
"""Sensor reading from client device."""
temperature: float
humidity: float
air_quality_index: int
def read_climate_sensors(
include_temperature: Annotated[bool, Field(description="Include temperature reading")] = True,
include_humidity: Annotated[bool, Field(description="Include humidity reading")] = True,
) -> SensorReading:
"""Read climate sensor data from the client device."""
# Simulate reading from local sensors
return SensorReading(
temperature=22.5 if include_temperature else 0.0,
humidity=45.0 if include_humidity else 0.0,
air_quality_index=75,
)
def change_background_color(color: Annotated[str, Field(description="Color name")] = "blue") -> str:
"""Change the console background color."""
# Simulate UI change
print(f"\n🎨 Background color changed to {color}")
return f"Background changed to {color}"
Ön Uç Araçları ile AG-UI İstemcisi Oluşturma
Ön uç araçlarıyla eksiksiz bir istemci uygulaması aşağıdadır:
"""AG-UI client with frontend tools."""
import asyncio
import json
import os
from typing import Annotated, AsyncIterator
import httpx
from pydantic import BaseModel, Field
class SensorReading(BaseModel):
"""Sensor reading from client device."""
temperature: float
humidity: float
air_quality_index: int
# Define frontend tools
def read_climate_sensors(
include_temperature: Annotated[bool, Field(description="Include temperature")] = True,
include_humidity: Annotated[bool, Field(description="Include humidity")] = True,
) -> SensorReading:
"""Read climate sensor data from the client device."""
return SensorReading(
temperature=22.5 if include_temperature else 0.0,
humidity=45.0 if include_humidity else 0.0,
air_quality_index=75,
)
def get_user_location() -> dict:
"""Get the user's current GPS location."""
# Simulate GPS reading
return {
"latitude": 52.3676,
"longitude": 4.9041,
"accuracy": 10.0,
"city": "Amsterdam",
}
# Tool registry maps tool names to functions
FRONTEND_TOOLS = {
"read_climate_sensors": read_climate_sensors,
"get_user_location": get_user_location,
}
class AGUIClientWithTools:
"""AG-UI client with frontend tool support."""
def __init__(self, server_url: str, tools: dict):
self.server_url = server_url
self.tools = tools
self.thread_id: str | None = None
async def send_message(self, message: str) -> AsyncIterator[dict]:
"""Send a message and handle streaming response with tool execution."""
# Prepare tool declarations for the server
tool_declarations = []
for name, func in self.tools.items():
tool_declarations.append({
"name": name,
"description": func.__doc__ or "",
# Add parameter schema from function signature
})
request_data = {
"messages": [
{"role": "system", "content": "You are a helpful assistant with access to client tools."},
{"role": "user", "content": message},
],
"tools": tool_declarations, # Send tool declarations to server
}
if self.thread_id:
request_data["thread_id"] = self.thread_id
async with httpx.AsyncClient(timeout=60.0) as client:
async with client.stream(
"POST",
self.server_url,
json=request_data,
headers={"Accept": "text/event-stream"},
) as response:
response.raise_for_status()
async for line in response.aiter_lines():
if line.startswith("data: "):
data = line[6:]
try:
event = json.loads(data)
# Handle tool call requests from server
if event.get("type") == "TOOL_CALL_REQUEST":
await self._handle_tool_call(event, client)
else:
yield event
# Capture thread_id
if event.get("type") == "RUN_STARTED" and not self.thread_id:
self.thread_id = event.get("threadId")
except json.JSONDecodeError:
continue
async def _handle_tool_call(self, event: dict, client: httpx.AsyncClient):
"""Execute frontend tool and send result back to server."""
tool_name = event.get("toolName")
tool_call_id = event.get("toolCallId")
arguments = event.get("arguments", {})
print(f"\n\033[95m[Client Tool Call: {tool_name}]\033[0m")
print(f" Arguments: {arguments}")
try:
# Execute the tool
tool_func = self.tools.get(tool_name)
if not tool_func:
raise ValueError(f"Unknown tool: {tool_name}")
result = tool_func(**arguments)
# Convert Pydantic models to dict
if hasattr(result, "model_dump"):
result = result.model_dump()
print(f"\033[94m[Client Tool Result: {result}]\033[0m")
# Send result back to server
await client.post(
f"{self.server_url}/tool_result",
json={
"tool_call_id": tool_call_id,
"result": result,
},
)
except Exception as e:
print(f"\033[91m[Tool Error: {e}]\033[0m")
# Send error back to server
await client.post(
f"{self.server_url}/tool_result",
json={
"tool_call_id": tool_call_id,
"error": str(e),
},
)
async def main():
"""Main client loop with frontend tools."""
server_url = os.environ.get("AGUI_SERVER_URL", "http://127.0.0.1:8888/")
print(f"Connecting to AG-UI server at: {server_url}\n")
client = AGUIClientWithTools(server_url, FRONTEND_TOOLS)
try:
while True:
message = input("\nUser (:q or quit to exit): ")
if not message.strip():
continue
if message.lower() in (":q", "quit"):
break
print()
async for event in client.send_message(message):
event_type = event.get("type", "")
if event_type == "RUN_STARTED":
print(f"\033[93m[Run Started]\033[0m")
elif event_type == "TEXT_MESSAGE_CONTENT":
print(f"\033[96m{event.get('delta', '')}\033[0m", end="", flush=True)
elif event_type == "RUN_FINISHED":
print(f"\n\033[92m[Run Finished]\033[0m")
elif event_type == "RUN_ERROR":
error_msg = event.get("message", "Unknown error")
print(f"\n\033[91m[Error: {error_msg}]\033[0m")
print()
except KeyboardInterrupt:
print("\n\nExiting...")
except Exception as e:
print(f"\n\033[91mError: {e}\033[0m")
if __name__ == "__main__":
asyncio.run(main())
Ön Uç Araçları Nasıl Çalışır?
Protokol Akışı
- İstemci Kaydı: İstemci sunucuya araç bildirimleri (adlar, açıklamalar, parametreler) gönderir
- Sunucu Düzenlemesi: Kullanıcı isteğine göre ön uç araçlarının ne zaman çağrıleceğine yapay zeka aracısı karar verir
-
Araç Çağrı İsteği: Sunucu SSE aracılığıyla istemciye
TOOL_CALL_REQUESTolay gönderir - İstemci Yürütmesi: İstemci aracı yerel olarak yürütür
- Sonuç Gönderimi: İstemci, POST isteği aracılığıyla sonucu sunucuya geri gönderir
- Aracı İşleme: Sunucu sonucu birleştirir ve yanıta devam eder
Önemli Olaylar
-
TOOL_CALL_REQUEST: Sunucu ön uç aracının yürütülmesini istemektedir -
TOOL_CALL_RESULT: İstemci yürütme sonucunu gönderir (HTTP POST aracılığıyla)
Beklenen Çıkış
User (:q or quit to exit): What's the temperature reading from my sensors?
[Run Started]
[Client Tool Call: read_climate_sensors]
Arguments: {'include_temperature': True, 'include_humidity': True}
[Client Tool Result: {'temperature': 22.5, 'humidity': 45.0, 'air_quality_index': 75}]
Based on your sensor readings, the current temperature is 22.5°C and the
humidity is at 45%. These are comfortable conditions!
[Run Finished]
Sunucu Kurulumu
Başlangıç kılavuzundaki standart AG-UI sunucusu, frontend araçlarını otomatik olarak destekler. Sunucu tarafında değişiklik gerekmez; araç düzenlemesini otomatik olarak işler.
En İyi Yöntemler
Security
def access_sensitive_data() -> str:
"""Access user's sensitive data."""
# Always check permissions first
if not has_permission():
return "Error: Permission denied"
try:
# Access data
return "Data retrieved"
except Exception as e:
# Don't expose internal errors
return "Unable to access data"
Hata İşleme
def read_file(path: str) -> str:
"""Read a local file."""
try:
with open(path, "r") as f:
return f.read()
except FileNotFoundError:
return f"Error: File not found: {path}"
except PermissionError:
return f"Error: Permission denied: {path}"
except Exception as e:
return f"Error reading file: {str(e)}"
Asenkron İşlemler
async def capture_photo() -> str:
"""Capture a photo from device camera."""
# Simulate camera access
await asyncio.sleep(1)
return "photo_12345.jpg"
Sorun giderme
Araçlar Çağrılmıyor
- Araç bildirimlerinin sunucuya gönderildiğinden emin olun
- Araç açıklamalarının amacı açıkça gösterdiğini doğrulama
- Araç kaydı için sunucu günlüklerini kontrol et
Yürütme Hataları
- Kapsamlı hata işleme ekleyin
- İşlemeden önce parametreleri doğrulama
- Kullanıcı dostu hata iletileri döndürme
- Hata ayıklama için hata kayıtları tutma
Tür Sorunları
- Karmaşık türler için Pydantic modellerini kullanma
- Serileştirmeden önce modelleri diktelere dönüştürme
- Tür dönüştürmelerini açıkça işleme
Sonraki Adımlar
- Arka Uç Aracı Görselleştirme: Sunucu taraflı araçlarla birleştirme