본문으로 건너뛰기
0%

온체인 AI 에이전트 아키텍처: 다섯 가지 빌드 패턴

Uttam Singh headshot

작성자 Uttam Singh

2026년 9월 2일에 게시됨7분 읽기

온체인 AI 에이전트 아키텍처 가이드 커버 이미지

온체인 상태를 읽고 쓰는 AI 에이전트는 데모 단계를 지나 프로덕션 단계로 넘어갔습니다. 모델은 추론할 수 있고, 에이전트 지갑은 제한된 권한 하에 서명할 수 있으며, 인프라는 이벤트가 온체인에 기록된 지 몇 초 만에 에이전트로 전달할 수 있습니다. 문제가 생기는 지점은 여전히 아키텍처입니다. 에이전트가 구독할 수 있는 이벤트를 폴링하거나, 신뢰할 수 없는 입력을 읽는 프로세스와 같은 프로세스에서 서명 권한을 보유하거나, 실제 자금으로 메인넷에서 학습하는 경우가 그렇습니다.

온체인 에이전트는 하나의 루프입니다: 관찰(watch), 판단(decide), 실행(act). 프로덕션 에이전트는 이 루프를 다섯 가지 반복되는 형태로 구성하며, 각각에 대한 예제를 아래에서 다룹니다. 온체인 에이전트 구축 가이드에서는 이들 모두의 기반이 되는 프리미티브(지갑, 결제 레일, 데이터 피드)를 다루며, 이 페이지에서는 그 프리미티브들을 어떻게 배치하는지를 다룹니다.

Pattern
Trigger
The agent reads
The agent does
Reach for it when
Wallet watcher
A transfer hits a watched address
Webhook or WebSocket events
Wakes and evaluates
You track deposits, whales, or counterparties
Event-driven reactor
A contract emits an event
Filtered logs
Responds with a transaction
Protocol state changes drive your strategy
Portfolio rebalancer
Allocation drifts past a band
Balances and prices
Proposes a swap
You hold target weights and want them enforced
Detect-then-execute split
The detector emits a signal
Everything, while signing nothing
The executor verifies, then signs
Untrusted input meets real money
Pre-mainnet testing
Every new capability
Testnets and dry-runs
Promotes the agent in stages
Always, before the other four go live

실시간 지갑 감시 에이전트는 어떻게 구축하는가?

관심 있는 주소를 웹훅에 등록하고 체인이 알아서 알려오게 하십시오. 루프를 돌며 잔고를 폴링하면 연산 자원만 소모하고도 정작 그 순간을 놓칩니다. 푸시 파이프라인은 전송이 기록된 지 몇 초 만에 전달되며, 이것이 바로 워처(watcher)의 전체 역할입니다.

예를 들어 에이전트가 펀드의 거래상대방 지갑을 추적하고 큰 규모의 USDC 이동을 표시한다고 합시다. Alchemy에서는 단일 Address Activity 웹훅이 네이티브, ERC-20, ERC-721, ERC-1155 전송을 최대 100,000개 주소까지 커버하므로, 웹훅 하나로 거래상대방 목록 전체를 감시할 수 있습니다. 에이전트가 장기 실행 프로세스로 동작하고 공개 URL을 노출하고 싶지 않다면, WebSocket 구독이 프로세스 내에서 동일한 역할을 수행합니다. alchemy_minedTransactions으로 구독하면 이미 해당 주소로 필터링된 확정 트랜잭션을 받을 수 있으며, 로그를 파싱할 필요가 없습니다. Solana에서는 Yellowstone gRPC 스트리밍이 TB당 $75로 동일한 역할을 수행하며 끊김 없는 재연결을 제공합니다. 어떤 전송 방식이 맞는지 확신이 서지 않는다면, webhooks vs WebSockets vs gRPC 비교에서 자세한 기준을 다룹니다.

핸들러 자체는 거의 아무것도 하지 않아야 합니다. 전달이 Alchemy에서 온 것임을 확인하고, 중복을 제거하고, 이벤트를 에이전트의 판단(decide) 단계로 넘긴 뒤에야 확인 응답을 보내야 합니다:

typescript
Copied
import express from "express"; import { createHmac, timingSafeEqual } from "node:crypto"; const SIGNING_KEY = process.env.ALCHEMY_WEBHOOK_SIGNING_KEY!; // from the webhook's dashboard settings const USDC = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; // canonical USDC contract on Ethereum mainnet const seen = new Set<string>(); function remember(key: string) { seen.add(key); if (seen.size > 10_000) seen.delete(seen.values().next().value!); // bound the set; only recent deliveries repeat } function wake(signal: unknown) { // The agent's decide step starts here. Queue the signal; // don't run model reasoning inside the request handler. } const app = express(); app.use( express.json({ verify: (req, _res, buf) => { (req as { rawBody?: Buffer }).rawBody = buf; // keep the raw bytes for the HMAC check }, }) ); app.post("/hooks/address-activity", (req, res) => { const sig = Buffer.from(String(req.headers["x-alchemy-signature"] ?? ""), "hex"); const expected = createHmac("sha256", SIGNING_KEY) .update((req as { rawBody?: Buffer }).rawBody ?? Buffer.alloc(0)) .digest(); if (sig.length !== expected.length || !timingSafeEqual(sig, expected)) { return res.sendStatus(401); // not signed with our key; never process it } for (const transfer of req.body.event.activity) { const key = `${transfer.hash}:${transfer.log?.logIndex ?? "native"}`; // one tx can carry several transfers if (seen.has(key)) continue; // repeat delivery, already handled if (transfer.rawContract?.address?.toLowerCase() === USDC && transfer.value > 50_000) { wake({ kind: "large-transfer", ...transfer }); // if this throws, the key stays unmarked and the retry redelivers } remember(key); // mark handled only after the handoff succeeded } res.sendStatus(200); // ack only after queueing: a crash above gets retried, not lost }); app.listen(8080);

이 패턴을 프로덕션에서 안정적으로 유지하려면 세 가지 습관이 필요합니다. 전달을 신뢰하기 전에 HMAC 서명을 검증해야 합니다. 그렇지 않으면 엔드포인트 URL을 알게 된 누구든 가짜 전송을 POST로 보내 에이전트를 조종할 수 있습니다. 토큰은 심볼이 아니라 반드시 컨트랙트 주소로 매칭해야 합니다. 누구나 자신을 USDC라고 부르는 토큰을 배포해 감시 중인 주소로 보낼 수 있기 때문입니다. 그리고 전달은 최소 한 번(at-least-once) 방식이므로 중복 제거 기록은 선택 사항이 아닙니다. 인메모리 집합은 하나의 장기 실행 프로세스에서는 작동하지만, 재시작되거나 복제본을 실행하는 서비스는 Redis 키나 데이터베이스 행처럼 공유되고 지속되는 곳에 기록을 두어야 합니다. 트레이딩 에이전트에게 중복된 알림은 곧 중복된 트랜잭션이기 때문입니다. 기계적인 필터링은 핸들러에 두고 모델은 관여시키지 말아야 합니다. 전송 건당 LLM 호출 비용이 그 전송을 전달한 인프라 비용보다 더 들기 때문입니다.

AI 에이전트가 스마트 컨트랙트 이벤트를 모니터링하고 자동으로 반응하게 하려면 어떻게 해야 하는가?

컨트랙트의 로그를 구독하고, 중요한 이벤트 한두 개로 필터링한 뒤, 핸들러를 멱등(idempotent)하게 만드십시오. 컨트랙트 이벤트는 에이전트가 얻을 수 있는 가장 깔끔한 트리거입니다. 컨트랙트가 무슨 일이 어떤 순서로 일어났는지를 정확히 명시하기 때문입니다.

Alchemy에서는 이를 두 가지 인터페이스로 다룹니다. 커스텀 웹훅은 GraphQL 필터를 받으므로 컨트랙트 주소와 이벤트 토픽으로 매칭해 요청한 로그만 받을 수 있습니다. 이는 서버리스 반응기에 적합합니다. 장기 실행 에이전트라면 WebSocket 로그 구독으로 모든 것을 한 프로세스 안에서 유지할 수 있습니다. 다음은 Uniswap v3 풀을 감시하는 반응기 예시로, 단일 스왑이 가격을 움직이는 순간을 감지하는 데 트레이딩 에이전트가 사용하는 종류의 피드입니다:

typescript
Copied
import { createPublicClient, webSocket, parseAbiItem } from "viem"; import { mainnet } from "viem/chains"; function react(args: unknown) { // Decide step: is this swap big enough to act on? } const client = createPublicClient({ chain: mainnet, transport: webSocket("wss://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"), }); client.watchEvent({ address: "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640", // USDC/WETH 0.05% pool event: parseAbiItem( "event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)" ), onLogs: (logs) => { for (const log of logs) { if (log.removed) continue; // reorg removal notice; irreversible actions also need the confirmation-depth rule below react(log.args); } }, });

log.removed 체크는 보기보다 중요합니다. 체인은 재구성(reorganize)될 수 있으며, 에이전트가 이미 반응한 로그가 몇 블록 후 정규 체인에서 사라질 수 있습니다. 멱등 핸들러와 확인 깊이 규칙(비가역적 행동 전에 몇 블록을 기다리는 것)을 결합하는 것이 표준적인 방어책입니다. 반응기의 나머지 원칙은 워처와 동일합니다. 구독 필터가 저렴한 제거 작업을 수행하고, 모델은 그 필터를 통과한 이벤트만 보게 됩니다.

DeFi 포트폴리오 리밸런싱 에이전트를 구축하려면 무엇이 필요한가?

네 가지 요소입니다: 현재 잔고, 현재 가격, 드리프트 규칙, 스왑 경로. 에이전트는 앞의 두 가지를 읽고, 세 번째를 확인하며, 규칙이 발동될 때만 네 번째를 건드립니다.

WETH, USDC, WBTC를 50/30/20 비율로 보유하는 트레저리 에이전트를 예로 들어봅시다. 잔고는 Portfolio API에서 가져오는데, 이는 여러 네트워크에 걸친 지갑의 토큰을 체인별 호출을 여러 번 나누지 않고 한 번의 요청으로 반환합니다. 가치는 Prices API에서 가져옵니다. 드리프트 규칙은 단순 산술입니다. 일반적인 출발점은 각 목표 비중 주위로 5퍼센트포인트 대역을 두는 것입니다. 이는 타이머로 확인해야 하는데, 드리프트는 대체로 토큰이 움직여서가 아니라 가격이 움직여서 발생하며, 가격 변동은 반응할 온체인 이벤트를 만들어내지 않기 때문입니다. 워처(패턴 1)가 보고하는 전송은 입출금이 발생하는 순간을 포착하는 보조 트리거입니다.

typescript
Copied
const TARGET = { WETH: 0.5, USDC: 0.3, WBTC: 0.2 } as const; const BAND = 0.05; // rebalance when a weight drifts 5 points from target const WALLET = "0xYourTreasuryWallet"; // the wallet the agent manages const res = await fetch( `https://api.g.alchemy.com/data/v1/${process.env.ALCHEMY_API_KEY}/assets/tokens/by-address`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ addresses: [{ address: WALLET, networks: ["eth-mainnet"] }], }), } ); const { data } = await res.json(); // Price each balance with the Prices API, sum to a total, then: for (const [symbol, target] of Object.entries(TARGET)) { const drift = weightOf(symbol, data) - target; // weightOf: your portfolio math if (Math.abs(drift) > BAND) { propose({ symbol, drift }); // propose: log it and request approval; never swap directly } }

실행 측은 원시 개인 키를 보유해서는 안 됩니다. 범위가 제한된 에이전트 지갑을 사용하면 키는 커스터디 상태로 유지되고 세션은 부여받은 권한만 지니게 됩니다. ERC-20을 사용하려면 스왑 전에 라우터에 대한 허용량(allowance)이 필요합니다. 매번 정확한 금액만큼만 승인하면 트랜잭션 하나가 더 들지만, 공격자가 빼갈 수 있는 상시 허용량을 남기지 않습니다:

bash
Copied
# before each swap: let the router from your quote spend exactly this swap's WETH alchemy evm approve 0xRouterFromQuote --token-address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --amount 0.4 -n eth-mainnet # swap WETH into USDC (Ethereum mainnet contract addresses) alchemy evm swap execute \ --from 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ --to 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \ --amount 0.4 --slippage 0.5 -n eth-mainnet \ --signer session --json --no-interactive

이 루프의 형태를 주목하십시오. 에이전트는 제안하고, 다른 무언가가 승인합니다. 초기에는 그 무언가가 바로 당신입니다. 나중에는 규모, 슬리피지, 자산 허용 목록에 대한 정책 검사가 될 수 있습니다. DeFi AI 에이전트 개요에서는 이러한 분리가 프로덕션 DeFi 에이전트 전반에서 표준인 이유를 다루며, 가스 스폰서십은 당신이 통제하는 정책 하에 수수료를 대신 지불함으로써 마지막 운영상의 부담을 없애줍니다. 에이전트는 가스 잔고를 관리할 필요가 전혀 없게 됩니다.

감지-후-실행(detect-then-execute) 멀티 에이전트 시스템에 가장 적합한 아키텍처는 무엇인가?

에이전트를 작업량이 아니라 권한으로 분리하십시오. 탐지기(detector)는 모든 것을 읽지만 아무것도 서명할 수 없습니다. 실행기(executor)는 트랜잭션에 서명하지만 재검증하지 않은 것은 아무것도 믿지 않습니다.

애널리스트와 트레이더라고 생각하면 됩니다. 애널리스트는 하루 종일 시장을 지켜보며 누구와도 이야기할 수 있습니다. 트레이더는 애널리스트의 의견을 받아 검토하고, 계정에 접근할 수 있는 유일한 사람입니다.

이 패턴의 널리 알려진 틀은 일반적인 에이전트 도구에서 나온 것으로, 플래너 모델이 단계를 생성하고 실행기 에이전트가 도구를 실행하는 방식입니다. 그 틀은 오케스트레이션에 관한 것입니다. 온체인에서는 이 분리가 더 어려운 이유로 그 복잡성을 정당화합니다. 바로 커스터디입니다. 탐지기는 하루 종일 신뢰할 수 없는 입력을 소비합니다: 멤풀 노이즈, 서드파티 API, 이벤트 스트림, 때로는 소셜 피드까지. 이 중 어느 것이든 프롬프트 인젝션을 실어 나를 수 있습니다. 적대적 입력을 읽는 프로세스가 동시에 서명 권한을 쥔 프로세스라면, 오염된 메시지 하나가 서명된 트랜잭션이 될 수 있습니다. 이 둘을 분리하면, 탈취된 탐지기가 할 수 있는 최악의 일은 실행기가 버리는 나쁜 제안을 내놓는 것에 그칩니다.

탐지기는 패턴 1과 2로 구성되며, 폴링 루프가 아니라 푸시 인프라에 연결됩니다. 탐지기는 큐를 통해 신호를 내보내며, 그 큐는 감사 로그 역할도 겸합니다. 신호 계약(contract)은 작고 검증 가능하게 유지하십시오:

json
Copied
{ "kind": "arb-opportunity", "pair": "WETH/USDC", "evidence": { "txHash": "0x…", "block": 23411005 }, "proposal": { "action": "swap", "from": "WETH", "to": "USDC", "amount": "0.4" }, "observedAt": "2026-09-05T09:14:03Z", "expiresAt": "2026-09-05T09:14:33Z" }

실행기는 어떤 신호에도 행동하기 전에 세 가지 규칙을 적용합니다:

  • 증거를 온체인에서 재검증합니다. 탐지기의 요약을 신뢰하는 대신 참조된 트랜잭션을 직접 읽으십시오. 탐지기의 역할은 알아채는 것이었고, 증명하는 것은 실행기의 역할입니다.
  • 만료를 강제합니다. 낡은 기회에 대해 행동하는 것은 공격자가 루프에 없어도 감지-후-실행 시스템이 손실을 보는 흔한 원인입니다.
  • 지갑 계층에서 지출 한도를 둡니다. 신호당, 일별 예산은 범위가 제한된 세션에 존재하며, 행동이 이상해 보이는 순간 대시보드에서 즉시 취소할 수 있습니다.

도구 측면에서 실행기에게 필요한 것은 딱 두 가지입니다: 검증을 위한 RPC 연결과 서명 인터페이스입니다. 탐지기가 더 많은 자원을 필요로 하는 쪽이며, 이를 인덱싱된 데이터(Transfers API로 이력을, Portfolio API로 상태를 조회)와 결합하면 토큰 지출을 원시 체인 데이터 디코딩이 아니라 추론에 쓸 수 있습니다. 자율 에이전트를 위한 블록체인 API 비교에서는 그 선택의 인프라 측면을 다룹니다.

메인넷으로 넘어가기 전에 AI 에이전트의 트랜잭션을 안전하게 테스트하려면 어떻게 해야 하는가?

에이전트와 실제 자산 사이에 네 개의 관문을 두십시오: 모든 트랜잭션을 드라이런하고, 키가 지출할 수 있는 범위를 제한하고, 테스트넷에서 전체 루프를 리허설하고, 자금을 움직이는 모든 행동에 사람의 승인을 남겨두십시오.

  • 먼저 드라이런합니다. Alchemy CLI는 서명하거나 전파하지 않고도 모든 전송을 미리 보여줍니다(alchemy evm send 0xRecipient 0.4 --dry-run). 코드에서는 viem의 simulateContract이 실제 메인넷 상태에 대해 컨트랙트 호출을 제출 없이 검증하므로, 리허설이 오래된 픽스처가 아니라 실제 가격과 실제 풀 깊이를 사용합니다.
  • 키를 제한합니다. 범위가 제한된 세션 지갑은 설정한 일정에 따라 만료되며 승인된 작업만 할 수 있고, 가스 스폰서십 정책은 수수료 계층에서 허용 목록과 지출 한도를 추가합니다. 제한된 키는 최악의 버그를 계정 고갈에서 한정된 손실로 바꿔줍니다.
  • 테스트넷에서 리허설합니다. 동일한 코드를 Sepolia나 Base Sepolia 엔드포인트로 가리키고 테스트넷 파우셋으로 에이전트에 자금을 공급하십시오. 리허설과 프로덕션 사이에 코드가 바뀌면 이 실행은 무의미해지므로, 네트워크 이름만 설정에 두고 나머지는 아무것도 바꾸지 마십시오.
  • 자금 이동 행동을 게이트로 막습니다. 에이전트가 아직 신뢰를 쌓기 전에는, 모든 전송, 스왑, 승인이 명시적인 동의를 기다려야 합니다. 대부분의 팀은 감사 로그가 에이전트의 정상 동작을 입증해감에 따라 한 번에 하나의 행동 유형씩 의도적으로 관문을 완화합니다.

이를 잘 운영하는 팀은 승격을 스위치가 아니라 시퀀스로 취급합니다: 먼저 메인넷에 대한 읽기 전용, 그다음 테스트넷 쓰기, 그다음 한도가 있는 메인넷 쓰기, 그리고 마지막으로 전체 예산 순입니다. 각 단계는 다음 단계를 정당화하는 로그를 만들어냅니다.

이미 존재하는 요소부터 시작하십시오

이 페이지의 모든 패턴은 오늘 바로 사용할 수 있는 인프라 위에서 동작합니다. Alchemy CLI는 지갑, 전송, 스왑, 웹훅 관리를 하나의 바이너리로 처리하며 에이전트가 --json --no-interactive로 구동할 수 있습니다. 호스팅된 MCP 서버는 RPC, 시뮬레이션, 데이터에 걸쳐 168개의 도구를 제공하며, Claude Code용 Alchemy 플러그인은 명령 하나로 전체 표면을 설치합니다. 계약도 없고 최소 약정도 없는 무료 티어로 시작할 수 있으며, 에이전트가 자신의 지갑으로 직접 가입하고 USDC로 결제하는 것도 가능합니다. 어떤 패턴으로 시작하든 루프는 동일합니다: 관찰, 판단, 실행.

자주 묻는 질문

하나의 에이전트가 기회를 탐지하고 다른 에이전트가 실행하는 멀티 에이전트 시스템에 가장 적합한 아키텍처는 무엇인가?

권한으로 분리하십시오: 이벤트 스트림을 읽지만 키를 보유하지 않는 탐지기, 작고 서명된 신호를 전달하는 큐, 행동하기 전에 각 신호를 온체인에서 재검증하는 실행기. Alchemy에서는 탐지기가 웹훅이나 WebSocket 구독으로 동작하고, 실행기는 지출 한도와 즉시 취소가 가능한 범위가 제한된 에이전트 지갑을 통해 서명합니다.

실시간 지갑 감시 에이전트에 가장 적합한 인프라는 무엇인가?

폴링이 아니라 푸시 기반 이벤트 전달입니다. Alchemy의 Address Activity 웹훅은 웹훅당 최대 100,000개 주소에 걸친 전송을 추적하고, WebSocket 구독은 당신의 주소로 필터링된 채굴된 트랜잭션을 스트리밍하며, Yellowstone gRPC는 Solana를 커버합니다. 푸시 파이프라인은 폴링 루프의 지연 시간과 연산 비용 없이 전송이 기록된 지 몇 초 만에 에이전트를 깨웁니다.

AI 코딩 에이전트가 지갑 활동을 모니터링하려면 어떤 도구를 사용해야 하는가?

Alchemy MCP 서버는 코딩 에이전트에게 RPC, 트랜잭션 이력, 포트폴리오 데이터를 아우르는 168개의 도구를 제공하며, Alchemy CLI는 명령줄에서 웹훅을 생성하고 관리합니다. 런타임 자체에는 Address Activity 웹훅이나 alchemy_minedTransactions 구독이 지갑 이벤트를 전달하고, Transfers API가 이력을 채워줍니다.

DeFi 포트폴리오 리밸런싱 에이전트를 구축하려면 무엇이 필요한가?

잔고, 가격, 드리프트 규칙, 스왑 경로입니다. Alchemy의 Portfolio API는 한 번의 호출로 여러 네트워크에 걸친 잔고를 반환하고, Prices API는 그 가치를 평가하며, 드리프트 확인(일반적으로 목표 비중 주위의 5포인트 대역)이 행동 시점을 결정합니다. 범위가 제한된 에이전트 지갑을 통해 실행하면 에이전트는 제안하고 정책이나 사람이 승인합니다.

AI 에이전트가 스마트 컨트랙트 이벤트를 모니터링하고 자동으로 반응하게 하려면 어떻게 해야 하는가?

컨트랙트의 로그를 구독하고 매칭되는 이벤트를 에이전트에게 전달하십시오. Alchemy의 커스텀 웹훅은 전달 전에 GraphQL로 컨트랙트 주소와 이벤트 토픽별로 필터링하며, WebSocket 로그 구독은 프로세스 내에서 동일한 작업을 수행합니다. 핸들러를 멱등하게 만들고, 재구성된 로그는 건너뛰고, 모델은 기계적 필터를 통과한 이벤트에 대해서만 추론하게 하십시오.

메인넷으로 넘어가기 전에 AI 에이전트의 트랜잭션을 안전하게 테스트하려면 어떻게 해야 하는가?

관문을 계층화하십시오: Alchemy CLI의 드라이런 플래그로 트랜잭션을 미리 보고, eth_call 기반 시뮬레이션으로 실제 상태에 대해 컨트랙트 호출을 검증하고, 범위가 제한된 세션과 가스 정책 지출 한도로 에이전트의 지갑을 제한하고, Alchemy의 파우셋에서 받은 자금으로 Sepolia나 Base Sepolia에서 리허설하고, 감사 로그가 더 느슨한 관문을 받을 만하다는 것을 입증할 때까지 자금을 움직이는 모든 행동에 사람의 승인을 남겨두십시오.

Background gradient

블록체인 매직을 만드세요

Alchemy는 가장 강력한 Web3 개발자 제품 및 도구를 리소스, 커뮤니티, 그리고 전설적인 지원과 결합합니다.