Интеграция OpenAI Agents SDK.
Пакета Agents SDK нет, и он вам не нужен. Декорируйте функцию с помощью @function_tool, вызывайте реальный клиент blockchain0x, и ваш агент сможет перемещать USDC на Base.
Специального пакета для OpenAI Agents SDK нет, и он вам не нужен. SDK превращает декорированную функцию в tool с помощью , поэтому вы оборачиваете реальный Python client в функцию и добавляете его в свой . Агент может отправлять USDC, закрывать invoices и читать wallets - для одиночных агентов, handoffs и underlying Responses API. Платежи завершаются в Base.
Самая чистая поверхность вызова инструментов, которую предоставляет OpenAI.
SDK OpenAI Agents (выпущен в 2025 году) - это рекомендуемый OpenAI способ создания агентов на основе API Responses. Он абстрагирует шаблонный код вокруг регистрации инструментов, циклов сообщений и передачи между агентами, и он производит чистый, типизированный код на Python. Если вы начинаете проект агента, ориентированный на OpenAI, сегодня и не имеете предпочтений по фрейму, это тот SDK, который мы рекомендуем.
Рецепт намеренно тонкий. send_usdc - это обычная функция, декорированная @function_tool; вы добавляете ее в список инструментов агента, и Runner подбирает ее. Никакой специальной конфигурации, никакой дополнительной обертки, никакого форка SDK. Когда SDK агентов поставляет новую функцию (мультимодальные входы, голосовые агенты), ваша функция продолжает работать, потому что она использует стандартный интерфейс вызова инструментов - ничего специфичного для версии в ней нет.
Установите Agents SDK и основной SDK. Два ключа.
Нет пакета blockchain0x Agents SDK для добавления. Вы устанавливаете OpenAI Agents SDK (пакет openai-agents, Python 3.10+) и реальный основной SDK blockchain0x, затем пишете функцию ниже. Это весь список зависимостей.
pip install openai-agents blockchain0xexport OPENAI_API_KEY=sk-... export BLOCKCHAIN0X_API_KEY=sk_test_... # sk_test_ = Base Sepolia, sk_live_ = Base mainnet
OPENAI_API_KEY - это ваш существующий ключ OpenAI (Agents SDK использует его для базового Responses API). BLOCKCHAIN0X_API_KEY - это ключ sk_test_ для testnet или sk_live_ для mainnet из вашего dashboard; client читает его из environment. Если ваш agent также получает деньги, обработчику webhook дополнительно нужен BLOCKCHAIN0X_WEBHOOK_SECRET.
A @function_tool, который умеет платить, передается Agent.
Ниже приведена вся интеграция. send_usdc вызывает реальный клиент blockchain0x; @function_tool превращает его в инструмент, а Runner организует вызов. SDK считывает подсказки типов и документацию, чтобы построить схему, поэтому держите их честными. Запустите его, и агент перемещает USDC на Base.
from agents import Agent, Runner, function_tool from blockchain0x import Client blockchain0x = Client() # reads BLOCKCHAIN0X_API_KEY from the environment @function_tool def send_usdc(agent_id: str, to: str, amount_wei: str) -> str: """Send a USDC payment from an agent wallet. amount_wei is USDC base units (6 decimals), so "10000" is 0.01 USDC. """ return str( blockchain0x.payments.create(body={"agentId": agent_id, "to": to, "amountWei": amount_wei}) ) agent = Agent( name="treasurer", instructions="You pay vendor invoices in USDC within owner-set limits.", tools=[send_usdc], model="gpt-4o", ) result = await Runner.run( agent, input="Pay 0.01 USDC from agent agt_123 to 0xVendor for the dataset.", ) print(result.final_output)
When the agent decides to pay, it calls send_usdc, the SDK submits the transfer, and you get a transaction hash back. amount_wei is base units, so 0.01 USDC is "10000". A sk_test_ key keeps it on Base Sepolia until you switch to sk_live_. Add more functions - read a wallet, settle an invoice - the same way; each is another @function_tool in the list.
Подтвердите входящие платежи с помощью подписанного webhook.
Если ваш агент также получает USDC, подтвердите это с помощью вебхука, а не опросом. Помощник проверки поставляется в Node SDK; в Python-сервисе вы проверяете вручную по документированному HMAC, что и делает помощник. Пример FastAPI ниже; тот же код работает в любом асинхронном Python-фреймворке.
import hmac, hashlib, os, time from fastapi import FastAPI, Request, HTTPException app = FastAPI() SECRET = os.environ["BLOCKCHAIN0X_WEBHOOK_SECRET"].encode() @app.post("/webhooks/payment") async def receive(request: Request): raw = await request.body() # RAW bytes - do not parse first sig = request.headers.get("X-Blockchain0x-Signature", "") ts = request.headers.get("X-Blockchain0x-Timestamp", "") parts = dict(p.split("=", 1) for p in sig.split(",") if "=" in p) t, v1 = parts.get("t", ts), parts.get("v1", sig) want = hmac.new(SECRET, t.encode() + b"." + raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(want, v1) or abs(time.time() - int(t)) > 300: raise HTTPException(status_code=401) if request.headers.get("X-Blockchain0x-Event-Type") == "payment.received": await trigger_followup() # USDC landed - run the next step return {"ok": True}
Алгоритм - HMAC-SHA256 над строкой t.rawBody, сравнение с постоянным временем и окно повторного воспроизведения 300 секунд. Читайте необработанное тело через await request.body(), никогда не request.json() повторно сериализованное, потому что это изменяет байты, которые охватывает подпись. Отправленные события - payment.received, payment.sent, wallet.deployed и webhook.test. Для тяжелой последующей работы добавьте задачу в очередь (Celery, arq) и сразу ответьте 200, а не блокируйте обработчик.
Клиент, который вы оборачиваете, открыт. Читайте его.
Нет starter package для Agents SDK, который можно было бы клонировать - рецепт выше и есть интеграция. SDK Blockchain0x открыты в GitHub; этот рецепт оборачивает Python SDK (blockchain0x-python), а полный набор методов приведен в docs. Используйте его как reference для body функций.
github.com/tosh-labs/blockchain0x-pythonПолный набор методов SDK и scopes описаны в the docs. Начните с ключа sk_test_ в Base Sepolia, затем переключитесь на sk_live_, когда функция начнет работать так, как вы ожидаете.
Пять вещей, на которые стоит обратить внимание при первой интеграции.
Эти данные поступают из нашего почтового ящика поддержки. Знание их заранее экономит по часу на каждом.
Пакета Agents SDK нет - вы оборачиваете SDK
Blockchain0x поставляет адаптеры для LangChain и CrewAI, а также сервер MCP; нет отдельного пакета OpenAI Agents SDK. Рецепт выше - это путь: декорируйте простую типизированную функцию с помощью @function_tool, вызовите реальный клиент blockchain0x внутри и добавьте его в Agent(tools=[...]). SDK читает сигнатуру и docstring, чтобы построить схему инструмента, поэтому держите docstring точным.
SDK агентов не является API помощников
SDK OpenAI Agents (пакет openai-agents, импортированный как agents) является другим продуктом по сравнению со старым API Assistants. Рецепт нацелен на SDK агентов: Агент + Runner + @function_tool через API Ответов. Если вы вызываете client.beta.assistants.create(...), вы находитесь на старой модели потоков/запусков, которую OpenAI сворачивает - перейдите на SDK агентов, и функция выше будет работать без изменений.
Суммы представлены в базовых единицах USDC, как строки
payments.create takes amountWei: a string of USDC base units, not a float. USDC has 6 decimals, so 0.01 USDC is "10000" and 5 USDC is "5000000". Type the function argument as str; a float will lose precision before it reaches the API. Keep it a string end to end.
send_payment может ответить 503 на раннем этапе
payments.create по умолчанию не повторяет и может вернуть 503, пока адаптер цепочки не подключен к вашей сети. Поймайте ошибку внутри вашей функции и верните четкое сообщение, на которое модель может реагировать, вместо того чтобы позволить Runner зациклиться. Автоматически созданный ключ идемпотентности означает, что ручная попытка не приведет к двойной оплате.
Только асинхронное время выполнения
SDK агентов в первую очередь асинхронный - await Runner.run(...). Вызов blockchain0x внутри вашего инструмента синхронный, что нормально для одного быстрого платежа, но блокирует цикл под нагрузкой. Если вы запускаете много параллельных агентов, оберните вызов SDK с помощью asyncio.to_thread. С точки зрения синхронного входа, используйте asyncio.run() на верхнем уровне.