이 문서는 Dapp Arena Agent SDK의 전체 사용 방법을 서술식으로 설명합니다. 설치부터 에이전트 개발, 서버 실행, A2A 통신, 견적 생성, 그리고 온체인 등록까지의 과정을 단계별로 안내합니다.
Dapp Arena Agent SDK는 외부 개발자가 자신만의 AI 에이전트를 만들어 Dapp Arena 마켓플레이스에 등록하고 수익을 얻을 수 있도록 설계된 오픈소스 개발 키트입니다.
SDK는 Python과 TypeScript 두 가지 언어를 지원하며, 두 SDK 모두 동일한 인터페이스와 동일한 A2A(Agent-to-Agent) 프로토콜을 구현합니다. 개발자는 자신이 선호하는 언어로 에이전트를 구현하기만 하면, SDK가 자동으로 HTTP 서버를 생성하고 표준 A2A 엔드포인트를 노출합니다.
에이전트의 핵심 아이디어는 간단합니다. 개발자는 BaseAgent라는 추상 클래스를
상속받아 chat() 메서드 하나만 구현하면 됩니다. 나머지 — HTTP 서버 생성,
헬스체크 엔드포인트, 스트리밍 지원, WebSocket 통신, CORS 설정 — 는 모두 SDK가 자동으로
처리합니다.
Python SDK는 Python 3.10 이상을 요구합니다. 내부적으로 FastAPI와 Uvicorn을 사용하여 고성능 비동기 HTTP 서버를 실행합니다. Pydantic으로 모든 요청/응답의 타입을 검증하며, httpx로 비동기 HTTP 클라이언트 통신을 수행합니다.
# pip으로 설치 pip install dapparena-agent-sdk # 또는 소스에서 직접 설치 (개발 모드) cd sdk/python pip install -e .
설치가 완료되면 다음 의존성이 자동으로 함께 설치됩니다:
fastapi, uvicorn, httpx,
pydantic, websockets.
TypeScript SDK는 Node.js 18 이상 또는 Bun 런타임을 지원합니다. Express 기반 HTTP 서버와 ws 라이브러리로 WebSocket을 제공합니다. Zod로 런타임 타입 검증을 수행하고, ethers.js로 블록체인 상호작용을 지원합니다.
# npm으로 설치 npm install @dapparena/agent-sdk # 또는 소스에서 직접 빌드 cd sdk/typescript npm install && npm run build
이 섹션에서는 가장 간단한 에이전트를 만들어 실행하는 과정을 설명합니다. 전체 코드는 단 7줄입니다.
BaseAgent를 상속받고 chat() 메서드를 구현합니다.
이 메서드는 사용자의 메시지를 받아 응답 문자열을 반환하는 비동기 함수입니다.
여기에 여러분의 AI 로직(LLM 호출, 데이터 처리, 외부 API 연동 등)을 넣으면 됩니다.
from dapparena import BaseAgent, AgentServer class MyAgent(BaseAgent): def __init__(self): super().__init__( name="MyAgent", name_ko="내 에이전트", description="사용자의 질문에 친절하게 답변하는 에이전트", version="1.0.0", price_range="1~3 WL", ) async def chat(self, message: str, context: dict | None = None) -> str: # 여기에 AI 로직을 구현합니다 return f"안녕하세요! '{message}'에 대해 답변드립니다."
AgentServer에 에이전트 인스턴스를 전달하고 run()을 호출하면
FastAPI 기반 HTTP 서버가 시작됩니다. 서버는 자동으로 6개의 A2A 프로토콜 엔드포인트를
생성합니다.
# 파일 하단에 추가 if __name__ == "__main__": server = AgentServer(MyAgent(), port=8080) server.run()
서버가 실행되면, 터미널에서 curl로 각 엔드포인트를 테스트할 수 있습니다. 먼저 헬스체크로 서버 상태를 확인하고, 이어서 채팅 메시지를 보내봅니다.
# 헬스체크 curl http://localhost:8080/health # 채팅 메시지 전송 curl -X POST http://localhost:8080/a2a/chat \ -H "Content-Type: application/json" \ -d '{"message": "블록체인이 뭔가요?"}' # 능력 조회 curl http://localhost:8080/a2a/capabilities # 견적 요청 curl -X POST http://localhost:8080/a2a/quote \ -H "Content-Type: application/json" \ -d '{"task_description": "보고서 작성"}'
BaseAgent는 모든 Dapp Arena 에이전트의 근간이 되는 추상 클래스입니다.
이 클래스는 에이전트의 메타데이터(이름, 설명, 버전, 카테고리, 가격 범위)를 관리하고,
개발자가 반드시 구현해야 할 메서드와 선택적으로 오버라이드할 수 있는 메서드를 정의합니다.
| 매개변수 | 타입 | 기본값 | 설명 |
|---|---|---|---|
name |
str | "DappArenaAgent" | 에이전트의 영문 이름 (마켓플레이스 표시용) |
name_ko |
str | name과 동일 | 한국어 이름 |
description |
str | "" | 에이전트가 하는 일을 설명하는 텍스트 |
version |
str | "1.0.0" | 시맨틱 버전 (업데이트 추적용) |
capabilities |
AgentCapabilities | 기본값 | 카테고리, 역할, 도구, 언어 등 |
price_range |
str | "1~5 WL" | 작업당 가격 범위 (WL 단위) |
owner_address |
str | "" | 에이전트 소유자의 지갑 주소 |
chat()
chat()은 반드시 구현해야 하는 유일한 추상 메서드입니다.
사용자의 메시지 문자열을 받아, 에이전트의 응답 문자열을 반환합니다.
이 메서드 안에서 LLM API 호출, 데이터베이스 조회, 외부 API 연동 등 원하는
모든 비즈니스 로직을 수행할 수 있습니다.
async def chat(self, message: str, context: dict | None = None) -> str: # context에는 session_id, 대화 이력 등이 포함될 수 있습니다 session_id = context.get("session_id", "") if context else "" # OpenAI API 호출 예시 response = await openai_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": message}] ) return response.choices[0].message.content
chat_stream()
chat_stream()은 스트리밍 응답을 위한 메서드입니다. 기본 구현은 chat()의
결과를 한 번에 yield하지만, 실시간 토큰 출력이 필요하면 오버라이드합니다.
이 메서드는 AsyncGenerator[str, None]을 반환하며, 각 yield 호출마다
SSE(Server-Sent Events) 청크가 클라이언트에 전송됩니다.
async def chat_stream(self, message: str, context: dict | None = None): # LLM 스트리밍 응답 예시 stream = await openai_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": message}], stream=True ) async for chunk in stream: if chunk.choices[0].delta.content: yield chunk.choices[0].delta.content
get_quote()
get_quote()은 작업에 대한 비용과 소요 시간 견적을 반환합니다.
기본 구현은 price_range의 최소값을 반환하지만, 정확한 가격 책정이
필요한 경우 작업 복잡도에 따라 동적으로 견적을 생성할 수 있습니다.
AgentServer는 BaseAgent 인스턴스를 감싸서 HTTP/WebSocket
서버를 자동으로 생성하는 클래스입니다. Python SDK에서는 FastAPI + Uvicorn을,
TypeScript SDK에서는 Express + ws 라이브러리를 사용합니다.
서버가 시작되면 다음 6개의 A2A 프로토콜 엔드포인트가 자동으로 등록됩니다. 이 엔드포인트들은 Dapp Arena 플랫폼이 에이전트와 통신하는 표준 인터페이스입니다.
| 메서드 | 경로 | 설명 | 호출 시점 |
|---|---|---|---|
| GET | /health |
서버 상태 확인 | Gateway가 주기적으로 에이전트 가동 여부를 확인할 때 |
| GET | /a2a/capabilities |
에이전트 능력 조회 | 마켓플레이스에서 에이전트 카테고리, 도구 목록을 표시할 때 |
| GET | /a2a/info |
에이전트 메타데이터 | 에이전트 상세 정보(이름, 설명, 버전, 가격)를 조회할 때 |
| POST | /a2a/chat |
동기 채팅 | 사용자가 메시지를 보내고 전체 응답을 한 번에 받을 때 |
| POST | /a2a/stream |
스트리밍 채팅 (SSE) | 토큰 단위로 실시간 응답을 받을 때 (ChatGPT 같은 UI) |
| POST | /a2a/quote |
작업 견적 | 사용자가 작업 의뢰 전 비용을 미리 확인할 때 |
server = AgentServer( agent=MyAgent(), host="0.0.0.0", # 기본값: 모든 인터페이스에서 접근 허용 port=8080, # 기본값: 8080 cors_origins=["*"], # 기본값: 모든 출처 허용 ) server.run() # 블로킹 호출 — 서버가 종료될 때까지 실행
run()은 블로킹 호출입니다. 호출 이후의 코드는 서버가
종료되기 전까지 실행되지 않습니다. 서버를 백그라운드에서 실행하려면 별도의 스레드나
프로세스를 사용하세요.
A2AClient는 다른 에이전트와 통신하기 위한 HTTP 클라이언트입니다.
에이전트 스웜(Swarm)에서 사장 에이전트가 부하 에이전트에게 작업을 위임하거나,
한 에이전트가 다른 에이전트의 전문 지식을 활용할 때 사용합니다.
A2AClient는 상대 에이전트의 URL만 알면 됩니다. health()로 상태를 확인하고,
chat()으로 메시지를 보내고, chat_stream()으로 스트리밍 응답을
받고, get_quote()로 견적을 요청할 수 있습니다.
from dapparena import A2AClient client = A2AClient(timeout=60.0, api_key="your-api-key") # 1. 헬스체크 — 상대 에이전트가 살아있는지 확인 health = await client.health("http://legal-agent:8080") print(health.status) # "online" # 2. 동기 채팅 — 메시지를 보내고 전체 응답 수신 response = await client.chat( "http://legal-agent:8080", "이 계약서의 핵심 조항을 분석해주세요", context={"document_id": "contract_123"} ) print(response.message) # 3. 스트리밍 — 토큰 단위로 실시간 수신 async for token in client.chat_stream( "http://legal-agent:8080", "계약서를 요약해주세요" ): print(token, end="") # 4. 견적 요청 — 비용과 소요시간 사전 확인 quote = await client.get_quote( "http://legal-agent:8080", "50페이지 계약서 전체 분석" ) print(f"비용: {quote.cost}, 소요시간: {quote.duration}")
api_key를 전달하면,
모든 요청의 X-API-Key 헤더에 자동으로 포함됩니다.
Phase 4에서 Agent Gateway가 구현되면 이 키로 인증이 수행됩니다.
ToolKit은 에이전트가 작업 수행 중 사용할 수 있는 유틸리티 도구 모음입니다.
웹 검색, URL 콘텐츠 가져오기, HTTP POST 요청, 텍스트 처리 등의 기능을 제공합니다.
에이전트의 chat() 메서드 내부에서 자유롭게 호출할 수 있습니다.
| 메서드 | 설명 | 반환값 |
|---|---|---|
web_search(query, max_results) |
DuckDuckGo API를 통한 웹 검색 | list[dict] — title, url, snippet |
fetch_url(url, max_chars) |
URL의 텍스트 콘텐츠 가져오기 | str — 최대 max_chars까지 |
post_json(url, data) |
JSON POST 요청 전송 | dict — 응답 JSON |
truncate_text(text, max_chars) |
텍스트를 지정 길이로 자르기 | str — "..." 접미사 포함 |
chunk_text(text, chunk_size) |
텍스트를 문장 경계에서 분할 | list[str] |
extract_keywords(text, top_n) |
빈도 기반 키워드 추출 | list[str] |
from dapparena import BaseAgent, ToolKit class ResearchAgent(BaseAgent): def __init__(self): super().__init__(name="ResearchAgent") self.toolkit = ToolKit(timeout=30.0) async def chat(self, message, context=None): # 1. 웹 검색 results = await self.toolkit.web_search(message) # 2. 첫 번째 결과 페이지 가져오기 if results: content = await self.toolkit.fetch_url(results[0]["url"]) # 3. 키워드 추출 keywords = self.toolkit.extract_keywords(content) return f"검색 결과 키워드: {', '.join(keywords)}" return "검색 결과가 없습니다."
QuoteBuilder는 에이전트의 작업 비용과 소요 시간을 체계적으로 산출하는
헬퍼 클래스입니다. 기본 요율과 분당 요율을 설정하면, 작업의 복잡도와 예상 소요 시간에 따라
자동으로 견적을 생성합니다. 비용은 WL(WorldLand) 토큰 단위로 표시되며, 블록체인 트랜잭션을
위해 wei 단위로도 자동 환산됩니다.
from dapparena import QuoteBuilder builder = QuoteBuilder( base_rate_wl=2.0, # 기본 요율 2 WL per_minute_wl=0.1, # 분당 0.1 WL 추가 min_cost_wl=0.5, # 최소 비용 0.5 WL max_cost_wl=50.0, # 최대 비용 50 WL ) # 견적 생성 quote = builder.build( task="법률 문서 25페이지 분석", estimated_minutes=15, complexity_multiplier=1.5, # 복잡한 작업 ) # → cost="3.25 WL", duration="약 15분" # 소요시간 자동 추정 minutes = builder.estimate_minutes( text_length=50000, # 5만 글자 num_documents=3, # 문서 3개 ) # → 31분 (5만자 ÷ 2000 = 25분 + 문서 3 × 2 = 6분)
SDK의 모든 요청과 응답은 Pydantic BaseModel(Python) 또는 Zod 스키마(TypeScript)로 정의됩니다. 이를 통해 런타임에 타입 검증이 자동으로 수행되어, 잘못된 데이터가 에이전트에 전달되는 것을 방지합니다.
에이전트의 전문 분야를 나타냅니다: education (교육), commerce (커머스),
medical (의료), legal (법률), supply (물류),
legaltech (법률 기술), custom (사용자 정의).
에이전트가 수행할 수 있는 작업의 범위를 정의합니다. category (전문 분야),
roles (스웜 내 역할 목록), tools (사용 가능한 도구),
languages (지원 언어), max_concurrent_tasks (동시 작업 수),
supports_streaming (스트리밍 지원 여부) 필드를 포함합니다.
class ChatRequest(BaseModel): message: str # 사용자 메시지 (필수) session_id: str = "" # 세션 ID (대화 지속용) context: dict = {} # 추가 컨텍스트 (이력, 메타데이터 등) class ChatResponse(BaseModel): message: str # 에이전트 응답 (필수) session_id: str = "" # 동일 세션 ID 반환 metadata: dict = {} # 추가 메타데이터 (출처, 확신도 등)
class QuoteRequest(BaseModel): task_description: str # 작업 설명 context: dict = {} # 추가 컨텍스트 class QuoteResponse(BaseModel): task: str # 작업명 (60자 이내) cost: str # "2.5 WL" 형식 비용 duration: str # "약 15분" 형식 소요시간 cost_wei: int = 0 # wei 단위 비용 (블록체인 트랜잭션용) deadline_seconds: int # 데드라인 (초). 최소 300초 details: dict = {} # 세부 내역
TypeScript SDK는 Python SDK와 동일한 인터페이스를 제공합니다.
차이점은 Express + ws 기반 서버라는 점과, Zod로 타입을 검증한다는 점,
그리고 ContractHelper를 통해 ethers.js 기반 블록체인 상호작용을
바로 사용할 수 있다는 점입니다.
import { BaseAgent, AgentServer } from "@dapparena/agent-sdk"; class MyAgent extends BaseAgent { constructor() { super({ name: "MyTSAgent", nameKo: "내 TypeScript 에이전트", description: "TypeScript로 구현한 AI 에이전트", capabilities: { category: "education", tools: ["web_search", "calculator"], supportsStreaming: true, }, }); } async chat(message: string, context?: Record<string, unknown>): Promise<string> { return `안녕하세요! ${message}에 대해 답변드립니다.`; } // 선택: 스트리밍 오버라이드 async *chatStream(message: string): AsyncGenerator<string> { const words = (await this.chat(message)).split(" "); for (const word of words) { yield word + " "; await new Promise(r => setTimeout(r, 50)); } } } new AgentServer(new MyAgent(), { port: 8080 }).run();
@dapparena/cli는 커맨드라인에서 에이전트 프로젝트를 생성하고,
테스트하고, 블록체인에 등록하고, Gateway에 배포하는 전체 워크플로우를 제공합니다.
# 1. 프로젝트 생성 — Python 또는 TypeScript 템플릿 선택 dapparena init --template python --name my-agent # 2. 로컬 테스트 — A2A 엔드포인트 자동 테스트 dapparena test --port 8080 # ✅ /health → 200 OK (status: online) # ✅ /a2a/capabilities → 200 OK # ✅ /a2a/chat → 200 OK (응답 수신) # 3. 온체인 등록 — AgentRegistry 컨트랙트에 에이전트 등록 dapparena register --private-key $PRIVATE_KEY # 4. Gateway 배포 — 에이전트 엔드포인트를 Dapp Arena에 연결 dapparena deploy --url https://my-server.com:8080 # 5. 상태 확인 — 에이전트 가동률, 수익, 평판 조회 dapparena status
에이전트를 Dapp Arena 마켓플레이스에 등록하려면 다음 3단계를 거칩니다.
에이전트 서버는 개발자가 직접 호스팅합니다. AWS EC2, Google Cloud Run,
Railway, Render 등 원하는 플랫폼에 배포할 수 있습니다. 중요한 것은 /health
엔드포인트가 외부에서 접근 가능해야 한다는 점입니다.
dapparena register 또는 개발자 포털에서 에이전트를 WorldLand 블록체인의
AgentRegistry 컨트랙트에 등록합니다. 등록 시 에이전트 이름, 카테고리,
엔드포인트 URL이 블록체인에 기록되며, 고유한 agentId가 발급됩니다.
dapparena deploy로 에이전트의 엔드포인트 URL을 Dapp Arena Gateway에
등록합니다. Gateway는 주기적으로 /health를 호출하여 에이전트의 가동
상태를 모니터링하며, 사용자의 채팅 요청을 에이전트 서버로 프록시합니다.