نصب نسخه مشخص SDK پایتون
نمونه با بسته a2ui-agent-sdk نسخه ۰٫۹٫۰ نوشته و بخش کامپایل آن با همین نسخه اجرا شده است. نسخه را در محیط مجازی جدا نصب کنید تا آزمایش، وابستگیهای برنامه اصلی را تغییر ندهد. در این نسخه، قرارداد قابلیتهای رندرر از مسیر نسخهدار وارد میشود؛ واردکردن نوع تجمیعی و رفتارکردن با آن مانند یک مدل پایدانتیک میتواند خطا بدهد. همچنین متن Express باید بین تگهای آغاز و پایان باشد؛ متن بدون این تگها ممکن است فقط متن عادی تلقی شود. این دو جزئیات دلیل خوبی برای اجرای مثال، بهجای اتکا به شباهت ظاهری کدها هستند.
python -m venv .venv
source .venv/bin/activate
python -m pip install a2ui-agent-sdk==0.9.0 a2ui-core==0.4.0
فرمان فعالسازی بالا برای محیطهای مبتنی بر شل یونیکس است؛ در ویندوز از فرمان فعالسازی مناسب همان محیط مجازی استفاده کنید. فایل زیر را با نام ui_demo.py ذخیره کنید. حالت پیشفرض هیچ سرویس پولی را فراخوانی نمیکند و فقط یک پاسخ ثابت را از SDK عبور میدهد. برای دریافت خروجی واقعی مدل، گزینه جداگانه لازم است. در زمان آمادهسازی این راهنما، آزمون SDK و پاسخ ساختگی انجام شد؛ کیفیت استنتاج واقعی مدل و اتصال یک رندرر کامل مرورگر جزو نتیجه ادعاشده این نمونه نیست.
نمونه کامل: کامپایل Express با کاتالوگ محدود
import argparse
import json
import os
import urllib.error
import urllib.request
from a2ui.processor import A2uiGenerator, CatalogConfig
from a2ui.processor.catalog_providers import InMemoryCatalogProvider
from a2ui.inference_formats import ExpressFormatFactory
from a2ui.core.schema.v0_9.client_capabilities import A2uiRendererCapabilities
CATALOG_ID = "https://example.org/catalog/read-only-demo"
catalog = {
"catalogId": CATALOG_ID,
"protocolVersion": "v0.9",
"components": {
"Text": {
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"],
"additionalProperties": False,
}
},
}
generator = A2uiGenerator(
[CatalogConfig(InMemoryCatalogProvider(catalog).load())],
inference_format_factory=ExpressFormatFactory(),
)
capabilities = A2uiRendererCapabilities.model_validate(
{"v0.9": {"supportedCatalogIds": [CATALOG_ID]}}
)
processor = generator.create_processor(capabilities)
def compile_reply(reply):
messages = [
message.model_dump(mode="json", by_alias=True, exclude_none=True)
for part in processor.parse_response(reply)
for message in getattr(part, "a2ui", [])
]
if len(messages) != 2:
raise ValueError("Expected one surface and one component update")
if "createSurface" not in messages[0] or "updateComponents" not in messages[1]:
raise ValueError("Unexpected message sequence")
if messages[0]["createSurface"]["surfaceId"] != "greeting":
raise ValueError("Unexpected surface")
update = messages[1]["updateComponents"]
components = update["components"]
if update["surfaceId"] != "greeting" or len(components) != 1:
raise ValueError("Unexpected component count")
item = components[0]
if item.get("id") != "root" or item.get("component") != "Text":
raise ValueError("Only root Text is permitted")
if not isinstance(item.get("text"), str) or len(item["text"]) > 160:
raise ValueError("Text is missing or too long")
return messages
def request_reply():
key = os.environ.get("PAASTA_API_KEY", "")
model = os.environ.get("PAASTA_MODEL", "")
if not key or not model:
raise ValueError("Set a scoped key and an available catalog model")
instructions = (
"Use surface greeting and exactly one root Text component. "
"Write a short greeting, at most 160 characters. No actions.\n"
+ processor.prompt_snippet
)
payload = {
"model": model,
"messages": [
{"role": "system", "content": instructions},
{"role": "user", "content": "Greet the reader in Persian."},
],
"max_tokens": 512,
}
request = urllib.request.Request(
"https://console.paasta.cloud/api/ai/v1/chat/completions",
data=json.dumps(payload).encode(),
headers={"Authorization": "Bearer " + key, "Content-Type": "application/json"},
)
try:
with urllib.request.urlopen(request, timeout=30) as response:
data = json.load(response)
except urllib.error.HTTPError as error:
raise RuntimeError("Model HTTP status " + str(error.code)) from None
choices = data.get("choices", [])
if not choices or not isinstance(choices[0].get("message", {}).get("content"), str):
raise ValueError("Missing model text")
return choices[0]["message"]["content"]
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--live", action="store_true")
args = parser.parse_args()
reply = request_reply() if args.live else (
'<a2ui>surface("greeting")\nroot=Text("Hello")</a2ui>'
)
print(json.dumps(compile_reply(reply), ensure_ascii=False, indent=2))
خروجی را چگونه بررسی کنیم؟
ابتدا python ui_demo.py را اجرا کنید. باید دو پیام ساختیافته، یکی برای ایجاد سطح و دیگری برای بهروزرسانی کامپوننت، دریافت شود. خروجی، تصویر یا صفحه نهایی نیست؛ دادهای است که یک رندرر سازگار میتواند مصرف کند. سپس بهصورت محلی تگها را حذف کنید، نام کامپوننت را عوض کنید یا متن بسیار بلند بگذارید و مطمئن شوید برنامه خروجی خارج از قرارداد را نمیپذیرد. اگر پاسخ نامعتبر آمد، آن را با استخراج دلخواه یک زیررشته «درست» نکنید؛ چنین ترمیمی میتواند خطای مدل یا تغییر نسخه قرارداد را پنهان کند.
اتصال اختیاری به API پاستا
برای حالت زنده، یک کلید محدود در پاستا بسازید و نام دقیق مدل فعال را در متغیر محیطی قرار دهید؛ سپس python ui_demo.py --live را اجرا کنید. این فرمان میتواند هزینه استنتاج داشته باشد. کاتالوگ API هوش مصنوعی پاستا و مستندات اتصال مرجع انتخاباند. در بررسی این راهنما Argon موجود بود، اما هر مدل متنی لزوماً خروجی Express معتبر و باکیفیت نمیسازد. آزمون باید جداگانه نرخ اعتبار ساختار و مفیدبودن متن را اندازه بگیرد؛ وجود پاسخ HTTP موفق برای هر دو معیار کافی نیست.
از پیام معتبر تا نمایش امن در مرورگر
رندرر باید نام Text را به کامپوننت ثابت برنامه نگاشت کند و متن را بهعنوان متن نمایش دهد، نه HTML قابل اجرا. قابلیت جدید را همزمان به کاتالوگ، رندرر و آزمون اضافه کنید. اگر بعداً Button دارید، شناسه رویداد باید از فهرست مجاز باشد و بکاند برای درخواست حاصل دوباره مجوز را کنترل کند. معتبر بودن پیام A2UI، مالکیت سفارش یا اجازه ویرایش را ثابت نمیکند. نمونه Text فقط برای یادگیری زنجیره است؛ پیش از افزودن فرم واقعی، رفتار صفحه در حالت بارگذاری، خطای مدل، پاسخ خالی و لغو درخواست را نیز طراحی کنید.
کاهش هزینه را با اندازهگیری اثبات کنید
ادعاهای سرعت معرفی گوگل به شرایط آزمایش خود آنها مربوط است؛ عددی از آن را نتیجه پاستا یا این نمونه ندانید. در آزمایش خودتان، زمان فراخوانی مدل، کامپایل، انتقال پیام و رندر را جدا ثبت کنید. اگر بیشتر زمان در شبکه یا واکشی داده صرف شود، کوتاهترشدن متن مدل همه تأخیر را حل نمیکند. ورودی یکسان و نسخه ثابت کاتالوگ را برای مقایسه نگه دارید و هزینه تلاشهای نامعتبر را نیز بشمارید. وقتی قالب صفحه از قبل روشن است، استفاده از یک قالب قطعی بدون مدل هم گزینهای معتبر است و باید در خط پایه مقایسه حضور داشته باشد.
داده تجاری و مدل تصمیمگیر را جدا نگه دارید
برای نمایش مانده اعتبار یا وضعیت سفارش، مدل نباید مقدار را حدس بزند. بکاند باید داده مجاز را بخواند و در قالب مورد تأیید قرار دهد؛ مدل فقط در محدوده تعریفشده تصمیم نمایشی بگیرد. در مسیر مبتنی بر Jev نیز انتخاب شناسه چیدمان جای بررسی مجوز یا دریافت عدد معتبر را نمیگیرد. ورودی مدل را به اطلاعات لازم محدود کنید و داده کاربران دیگر را برای بهترشدن ظاهر پاسخ وارد کانتکست نکنید. اگر داده آماده نیست، حالت خالی روشن و قابل فهم بهتر از پرکردن صفحه با اطلاعات ساختگی است؛ داده نمایشی باید به منبع قابل بررسی متصل بماند.
مسیر استقرار روی پاستا
رندرر وب و بکاند تولید پیام را میتوان در سرویسهای مستقل طراحی کرد. کلید API در بکاند باقی میماند و رابط کاربر فقط پیام معتبر یا شناسه درخواست را میگیرد. برای انتشار برنامه، هاست Next.js پاستا و پلتفرم ابری را براساس ساختار پروژه بررسی کنید. برای تاریخچه و وضعیت نیز دیتابیس مدیریتشده گزینهای برای طراحی است. هیچکدام جای احراز هویت برنامه را نمیگیرند. قبل از عمومیکردن مسیر، محدودیت اندازه ورودی، نرخ درخواست، زمان پاسخ و سقف هزینه هر کاربر را مشخص و آزمایش کنید.
نسخهبندی و بازگشت در زمان تغییر قرارداد
کاتالوگ بخشی از API داخلی رابط است. اگر نام یک کامپوننت یا ترتیب آرگومانهایش تغییر کند، پاسخ تولیدشده برای نسخه قبلی ممکن است دیگر قابل استفاده نباشد. شناسه و نسخه کاتالوگ را همراه درخواست نگه دارید و پیام قدیمی را بدون بررسی به رندرر جدید نفرستید. پیش از انتشار، چند پیام ثابت از نسخه قبلی و جدید را در آزمون قرار دهید. برای خطای سازگاری، رابط باید یک حالت خواندنی و روشن داشته باشد؛ اجرای HTML جایگزینِ تولیدشده توسط مدل، راه امنی برای دورزدن خطای قرارداد نیست. بازگشت نیز باید رندرر و کاتالوگ سازگار را با هم برگرداند، نه فقط نام مدل را عوض کند.
خوانایی فارسی و تجربه کاربر را مستقل آزمایش کنید
معتبر بودن پیام به معنی خوانا بودن صفحه نیست. متن فارسی، شناسه لاتین، عدد، نشانی و خطای طولانی را در موبایل باریک آزمایش کنید و جهت هرکدام را درست نگه دارید. پیام وضعیت باید بگوید درخواست در حال انجام است یا شکست خورده؛ باقیماندن یک اسکلت بارگذاری نباید تنها پاسخ صفحه به خطا باشد. برای اجزای تعاملی بعدی، برچسب دسترسپذیر، کارکرد صفحهکلید و حالت تمرکز لازم است. این ویژگیها باید در کامپوننتهای ثابت رندرر ساخته شوند تا هر بار به سلیقه مدل وابسته نباشند. کیفیت رابط از ترکیب قرارداد فنی و طراحی همین وضعیتهای واقعی به دست میآید.
چکلیست پذیرش یک رابط ایجنتمحور
پیش از انتشار، چهار دسته نمونه داشته باشید: پیام معتبر، خروجی ناقص، کامپوننت ممنوع و درخواست کاربر فاقد مجوز. برای هرکدام نتیجه مورد انتظار را از قبل بنویسید. سازگاری نسخه کاتالوگ و رندرر، خوانایی فارسی، جهت متنهای لاتین و کارکرد موبایل را نیز بررسی کنید. آزمایش امنیت را به SDK واگذار نکنید؛ SDK ساختار را میسنجد، اما برنامه درباره داده و عملیات تصمیم میگیرد. جمعبندی عملی این است که A2UI ابزار تعریف قرارداد رابط است. ارزش آن وقتی ظاهر میشود که نمونه محدود، مدل موجود، داده معتبر و مجوز سمت سرور کنار هم قرار بگیرند.
نظرات کاربران (۰)
هنوز نظری ثبت نشده است. اولین نفر باشید.