Агентна търговия на GX10: ACP, UCP и безопасен чекаут
Какво са ACP и UCP, как изглежда безопасният чекаут, когато поръчката се води от AI агент, и как се прави магазин, в който агентът подготвя количката, но плаща само човек.
01Какво ще научиш
- Какво е „агентна търговия“ и къде е границата между това, което прави агентът, и това, което прави човекът.
- Какво са ACP и UCP, с какво си приличат и с какво се различават — и защо старото „едното е откриване, другото е плащане“ е грешно.
- Как е устроен блупринтът на NVIDIA, какво изисква и кое от него не се събира на една машина от класа GB10.
- Как да построиш учебен магазин, в който агентът не може сам да плати — ограничението е на сървъра, не в подканата към модела.
- Какво трябва да знае търговец за потребителските права, за означението „това е AI“ и за картовите данни.
02Преди да започнеш
- Python 3.10 или по-нов и основи на HTTP/JSON. За практическата част не е нужна видеокарта — върви и на обикновен компютър.
- Машина от класа NVIDIA GB10 с DGX OS е нужна само ако после пробваш локални модели. 128 GB памет е обща за процесора и видеокартата.
- Измислен магазин — работим само с примерни данни и цени в EUR. Не пускай урока срещу реален магазин и реални плащания.
03Стъпки
-
Какво е агентна търговия
Клиентът казва на асистент какво иска („подарък до 30 евро“), а асистентът търси, сравнява и подготвя поръчка. Протоколите определят как асистентът говори с магазина, за да не се чете екранът на всеки сайт поотделно. Правилото: търсенето и подготовката са работа за агента; плащането е решение на човека.
-
ACP и UCP: две спецификации
✅Поправка на често срещана грешкаИ двата протокола са за поръчка (checkout). Не е вярно, че ACP е „откриване“, а UCP — „транзакции“. Разликата е в обхвата и в това кой стои зад тях.ACP UCP Откъде идва Agentic Commerce Protocol — разработен от Stripe и OpenAI; отворен, Apache 2.0 Universal Commerce Protocol — разработен съвместно от Google, Shopify, Etsy, Wayfair, Target, Walmart и др.; отворен, Apache 2.0 Какво покрива Сесии за поръчка (checkout); търговецът остава продавач по закон (merchant of record) Каталог, количка, поръчка (checkout), свързване на профил (OAuth 2.0) и последваща поръчка Откриване на магазина — GET /.well-known/ucpТранспорт REST и MCP REST, MCP, A2A, вграден (Embedded) Плащане Делегиран платежен токен (при Stripe — Shared Payment Token) AP2 — мандати за плащане Статуси (по спецификацията) not_ready_for_payment→ready_for_payment→completed(иcanceled)incomplete→ready_for_complete→completed(иrequires_escalation,canceled)Версия на спецификацията (по блупринта и документацията) API версия 2026-01-16 протокол 2026-01-11 Спецификациите се менят — преди да строиш, прочети текущата. Данните в таблицата са сверени на 03.10.2026 с блупринта на NVIDIA и сайтовете на двата проекта.
-
Блупринтът на NVIDIA и какво не се събира на GB10
Retail Agentic Commerce (Apache-2.0) е еталонна реализация на двата протокола за магазин, който сам контролира поръчката. Съдържа API на магазина, заместител на платежна услуга, MCP сървър и четири агента — за промоции, следпродажбено обслужване, препоръки и търсене; данните са в SQLite и Milvus. За стартиране иска Python 3.12+, uv, Node 20.9+, pnpm и Docker 24+.
Режим Какво означава За GB10 По подразбиране Моделите се викат през публичните API на NVIDIA (нужен е API ключ). Не иска видеокарта. Данните от заявките напускат машината — важи GDPR; не го ползвай с реални клиентски данни без основание. Локални NIM контейнери Блупринтът изброява минимум 2 × A100 с 80 GB (препоръчва 2 × H100). 2 × 80 = 160 GB видеопамет — повече от 128 GB обща памет на GB10. GB10 не е в изброените. ⚠️ Не е сверено дали върви. Затова в този урок не пускаме блупринта, а учим принципите му с малък магазин, който върви навсякъде. Локален модел на GB10 за самия асистент виж в урок 04-217.
-
Учебен магазин: агентът не може сам да плати
Един файл, FastAPI. Два ключа: на агента (създава и променя количка) и на човека (само той може да завърши поръчка). Така правилото е в кода на сървъра и не зависи от това дали моделът „се държи прилично“. Сумата в одобрението трябва да съвпада със сумата на сесията — иначе цената би могла да се смени между „да“ и плащането. Повторна заявка със същия
Idempotency-Keyвръща същата поръчка, не втора. Сумите са цели числа в евроцента.python · shop.py# shop.py — учебен чекаут (опростен; НЕ е пълна реализация на ACP или UCP) import os, secrets, uuid from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel app = FastAPI() AGENT_KEY = os.environ["SHOP_AGENT_KEY"] HUMAN_KEY = os.environ["SHOP_HUMAN_KEY"] # измислен каталог; цените са в евроцента и включват ДДС CATALOG = { "mug-01": {"name": "Керамична чаша", "price": 1200}, "tea-02": {"name": "Чай, 50 г", "price": 650}, } SESSIONS, ORDERS = {}, {} # в паметта — само за урока class Item(BaseModel): id: str quantity: int = 1 class Cart(BaseModel): items: list[Item] class Approval(BaseModel): approved_by: str total: int class Complete(BaseModel): approval: Approval def role(authorization: str | None) -> str: key = (authorization or "").removeprefix("Bearer ") if secrets.compare_digest(key, HUMAN_KEY): return "human" if secrets.compare_digest(key, AGENT_KEY): return "agent" raise HTTPException(401, "невалиден ключ") def price(session): for it in session["items"]: if it["id"] not in CATALOG or not 1 <= it["quantity"] <= 20: raise HTTPException(422, "непознат артикул или недопустимо количество") subtotal = sum(CATALOG[i["id"]]["price"] * i["quantity"] for i in session["items"]) shipping = 0 if subtotal >= 3000 else 450 session["totals"] = {"items": subtotal, "shipping": shipping, "total": subtotal + shipping, "currency": "EUR"} session["status"] = "ready_for_payment" if session["items"] else "not_ready_for_payment" return session @app.post("/checkout_sessions") def create(cart: Cart, authorization: str | None = Header(None)): role(authorization) sid = uuid.uuid4().hex SESSIONS[sid] = price({"id": sid, "items": [i.model_dump() for i in cart.items]}) return SESSIONS[sid] @app.get("/checkout_sessions/{sid}") def read(sid: str, authorization: str | None = Header(None)): role(authorization) return SESSIONS[sid] @app.post("/checkout_sessions/{sid}") def update(sid: str, cart: Cart, authorization: str | None = Header(None)): role(authorization) s = SESSIONS[sid] if s["status"] in ("completed", "canceled"): raise HTTPException(409, "сесията е приключила") s["items"] = [i.model_dump() for i in cart.items] return price(s) @app.post("/checkout_sessions/{sid}/cancel") def cancel(sid: str, authorization: str | None = Header(None)): role(authorization) SESSIONS[sid]["status"] = "canceled" return SESSIONS[sid] @app.post("/checkout_sessions/{sid}/complete") def complete(sid: str, body: Complete, authorization: str | None = Header(None), idempotency_key: str = Header(...)): if role(authorization) != "human": raise HTTPException(403, "само човек може да завърши поръчка") if idempotency_key in ORDERS: # повторна заявка — същият отговор return ORDERS[idempotency_key] s = SESSIONS[sid] if s["status"] != "ready_for_payment": raise HTTPException(409, "сесията не е готова за плащане") if body.approval.total != s["totals"]["total"]: raise HTTPException(409, "одобрената сума не съвпада с сумата на сесията") s["status"] = "completed" # Тук реален магазин предава плащането на платежен доставчик с токен; картови данни не минават оттук. ORDERS[idempotency_key] = {"order_id": uuid.uuid4().hex, "session": sid, "approved_by": body.approval.approved_by, "totals": s["totals"]} return ORDERS[idempotency_key]Това е учебен код: данните са в паметта, обработката на грешките е частична, а плащането е заместено с бележка. Командите и кодът не са пускани от нас.
-
Пускане и проба
Ключовете се генерират на място и не се пишат в файлове или страници. Сървърът слуша само на
127.0.0.1.bashexport SHOP_AGENT_KEY=$(openssl rand -hex 24) export SHOP_HUMAN_KEY=$(openssl rand -hex 24) pip install fastapi uvicorn uvicorn shop:app --host 127.0.0.1 --port 8000В друг терминал, със същите променливи:
bash# 1. агентът подготвя количката curl -s -X POST http://127.0.0.1:8000/checkout_sessions \ -H "Authorization: Bearer $SHOP_AGENT_KEY" -H "Content-Type: application/json" \ -d '{"items":[{"id":"mug-01","quantity":2}]}' # в отговора: totals.total = 2850 (2400 + 450 доставка), status = ready_for_payment # 2. агентът се опитва сам да плати — очаквай 403 curl -s -X POST http://127.0.0.1:8000/checkout_sessions/<номер-на-сесията>/complete \ -H "Authorization: Bearer $SHOP_AGENT_KEY" -H "Idempotency-Key: demo-1" \ -H "Content-Type: application/json" \ -d '{"approval":{"approved_by":"operator","total":2850}}' # 3. човекът одобрява със своя ключ curl -s -X POST http://127.0.0.1:8000/checkout_sessions/<номер-на-сесията>/complete \ -H "Authorization: Bearer $SHOP_HUMAN_KEY" -H "Idempotency-Key: demo-1" \ -H "Content-Type: application/json" \ -d '{"approval":{"approved_by":"operator","total":2850}}' # 4. повторете стъпка 3 със същия Idempotency-Key — получавате същата поръчка, не втораОчакваш: подготвена сесия със сума 2850 евроцента,
403при опита на агента, одобрена поръчка при ключа на човека и същата поръчка при повторение. За да видиш проверката на сумата, направи нова сесия и прати друга сума в одобрението — получаваш409. -
Правилата за търговеца: потребители, AI, плащания
⚖️Потребителски права — по Комисията за защита на потребителитеНа страницата на КЗП за онлайн търговците пише, че онлайн търговецът публикува данните си (име, ЕИК, адрес, телефон, имейл), основните характеристики на стоката, крайната цена с ДДС и всички такси, условията за плащане и доставка и условията за отказ от договор от разстояние. Напомня още: законова гаранция 2 години за стоките; връщане на сумите в срок от 14 дни след уведомлението за отказ, включително разходите за доставка; при намаление — то трае от 1 ден до 1 месец, а „предишната цена“ е най-ниската от поне 30-те дни преди намалението; никаква подвеждаща информация или реклама. Законите са на страницата на КЗП „Закони и регламенти“. Номера на членове не даваме — не сме ги сверявали; питай юрист.🤖Кажи на клиента, че говори с AIЧл. 50, пар. 1 от Регламент (ЕС) 2024/1689 (AI Act) изисква системите, които общуват пряко с хора, да са така проектирани, че хората да бъдат уведомени, че говорят със система с изкуствен интелект — освен ако това е очевидно. Информацията се дава ясно, най-късно при първото взаимодействие (чл. 50, пар. 5; виж и страницата на AI Act Service Desk за чл. 50). Проверено на 03.10.2026 по графика на прилагането в AI Act Service Desk и съобщението на ЕК „AI Omnibus enters into force“: Регламент (ЕС) 2026/1744 („Digital Omnibus“ за AI) е в сила от 27.07.2026 и не отлага чл. 50 — правилата за прозрачност се прилагат от 2.08.2026. Виж и консолидирания текст в EUR-Lex. Практика: съобщение „Асистентът е AI“ в началото на разговора, винаги достъпен път към човек.✅Картови данни и човешко одобрениеКартови данни не влизат в подканата към модела, не се записват в дневници и не минават през кода на агента — плащането се предава на платежен доставчик с токен. Преди плащане клиентът вижда и одобрява какво купува, на каква цена и с какви условия за отказ; одобрението се записва. -
Какво още да направиш
- Поставяй ограничения: най-много артикули, най-голяма сума за поръчка, списък на разрешените артикули.
- Сумите идват винаги от сървъра, никога от текста на модела.
- Записвай кой, кога и какво е одобрил; пази записите според срока, който си определил (виж урок 04-202 за дневник само за добавяне).
- Имай ясен път за връщане и жалби — потребителските срокове по-горе са задължителни за търговеца.
- Когато стигнеш до реален протокол, започни от текущата спецификация на ACP или UCP и от блупринта, не от този учебен код.
04Проверка
- Сървърът слуша на
127.0.0.1. - Ключът на агента получава
403при/complete. - Поръчка с различна одобрена сума се отказва (
409). - Повторен
Idempotency-Keyне създава втора поръчка. - Сумите са цели числа в евроцента; валутата е EUR.
- Клиентът е информиран, че говори с AI; виждат се данни на търговеца, крайна цена и условия за отказ.
- В подканите и дневниците няма картови данни.
Тест
1. Кое твърдение е вярно?
2. Защо в учебния магазин /complete приема само ключа на човека?
3. Защо сумата в одобрението се сверява със сумата на сесията?
4. Блупринтът по подразбиране вика публични API на NVIDIA. Какво следва за данните?
05Какво следва
06Източници
- NVIDIA: Retail Agentic Commerce (GitHub) — компоненти, изисквания, режими, лицензи.
- Agentic Commerce Protocol — спецификация и описание.
- Universal Commerce Protocol — спецификация и описание.
- КЗП: онлайн търговци · КЗП: закони и регламенти — задължения на онлайн търговеца.
- Регламент (ЕС) 2024/1689 (AI Act), официален текст · консолидиран текст · AI Act Service Desk: чл. 50 — прозрачност.
- FastAPI 🔒 локално — документация (кодът в урока не е пускан).