
우리의 온체인 자율 에이전트(On-Chain Autonomous Agent)를 위한 누락된 운영 매뉴얼
요약
Solana devnet에서 작동하는 온체인 자율 에이전트 구축을 위한 아키텍처와 운영 매뉴얼을 소개합니다. 모델 적응성, 턴 제한, 정책 엔진을 통한 안전성 확보 및 관측 가능성의 중요성을 다룹니다.
핵심 포인트
- 모델은 도구 출력에 따라 금액을 나누는 등 동적으로 적응함
- API 비용 절감 및 무한 루프 방지를 위해 턴 제한 설정 필수
- 프롬프트 외부에 별도의 정책 엔진을 두어 트랜잭션 안전성 확보
- 상세한 로그를 통한 관측 가능성이 자율 에이전트 디버깅의 핵심
- 에이전트는 고정 스크립트가 아닌 환경 관찰과 추론을 통해 동작함
이번 한 주를 마무리하며, 우리는 지갑 잔액을 확인하고, 전송을 실행하며, 엄격한 코드 수준의 안전 경계 내에서 작동하는 Solana devnet 자율 에이전트를 구축했습니다. 아래는 시스템의 종합적인 런북(runbook) 및 아키텍처 분석입니다.
아키텍처 교훈
- 모델 적응 (Model Adaptation): 모델은 도구(tool) 출력에 동적으로 반응합니다. 트랜잭션이 정책 거부(policy rejection)로 인해 차단되면, LLM은 금액을 더 작고 유효한 조각으로 나누어 적응합니다.
- 턴 제한(Turn Limits)은 필수적입니다: 제어되지 않는 루프는 높은 API 사용 비용을 초래할 수 있습니다. 턴 제한을 강제함으로써 에이전트가 정체될 경우 종료되도록 보장합니다.
- 안전은 프롬프트 외부에 존재합니다: 프롬프트 엔지니어링(Prompt engineering)만으로는 안전한 동작을 보장할 수 없습니다. 모델이 무엇을 결정하든 상관없이, 모든 트랜잭션은 블록체인에 도달하기 전에 반드시 정책 엔진(policy engine)을 통과해야 합니다.
- 관측 가능성(Observability)이 신뢰를 구축합니다: 상세한 로그 덕분에 모든 추론 단계, 모든 도구 호출(tool call), 그리고 모든 정책 결정을 쉽게 검증할 수 있었습니다. 로그가 없었다면 자율적 동작을 디버깅하는 것이 훨씬 더 어려웠을 것입니다.
- 자율성은 자동화 그 이상입니다: 에이전트는 고정된 스크립트를 실행하지 않습니다. 대신 환경을 관찰하고, 도구 출력에 대해 추론하며, 필요할 때 계획을 조정하고, 목표 달성이 불가능해지거나 성공적으로 완료되면 중단합니다.
엔드 투 엔드(End-to-End) 요청 흐름
다음 다이어그램은 일반적인 영어 요청이 확정된 Solana devnet 트랜잭션이 될 때까지 스택을 통해 어떻게 전달되는지 보여줍니다.
자연어 목표 (Natural Language Goal)
│
▼
...
에이전트 자체는 Solana와 직접 통신하지 않습니다. 모든 쓰기 요청은 반드시 정책 계층(policy layer)을 먼저 통과해야 하며, 이로 인해 정책 엔진이 모든 자금 이동에 대한 단일 게이트키퍼(gatekeeper) 역할을 수행합니다.
시스템 구성 요소
우리의 에이전트 스택(agentic stack)은 조화롭게 작동하는 다섯 가지 모듈형 부분으로 구성됩니다:
- Agent Loop (agent-workflow.mjs): OpenAI에 의해 구동되는 핵심 추론 엔진 (core reasoning engine)으로, 자연어 목표를 입력받아 도구 호출 (tool calls)을 결정하고 턴 제한(
MAX_TURNS = 12)까지 이를 실행합니다. - Read/Write Tools: 모델에
get_balance및transfer_sol을 노출하는 Solana Web3 RPC 호출을 감싸는 얇은 Javascript 래퍼 (wrappers)입니다. - MCP Server (server.ts): 표준 stdin/stdout 프로토콜을 사용하여 우리의 도구를 외부 클라이언트(예:
.vscode/mcp.json을 통한 VS Code Copilot)에 연결합니다. - Policy Engine (policy.mjs): 기본 거부 (deny-by-default) 규칙을 강제하며, 제안된 모든 지출을 수신자 허용 목록 (allowlist) 및 예산 상한선 (budget caps)과 대조하여 확인합니다.
- On-Chain Solana Devnet: 트랜잭션 서명 (transaction signatures)이 검증되고 기록되는 결제 계층 (settlement layer)입니다.
도구 참조 (Tool Reference)
도구: get_balance
- 입력 (Inputs):
address(string, base58 Solana 주소) - 반환 (Returns): 계정 주소와 lamports 단위의 잔액을 포함하는 문자열화된 JSON.
- 부수 효과 (Side Effects): 없음 (읽기 전용).
도구: transfer_sol
- 입력 (Inputs):
to(string, base58 수신자 주소),lamports(number, 전송할 금액) - 반환 (Returns): 트랜잭션 상태(
confirmed,denied, 또는failed), 트랜잭션 서명, 또는 실패 이유를 포함하는 JSON 객체. - 부수 효과 (Side Effects): 승인될 경우 온체인 상에서 에이전트의 지갑에서 차감하고 수신자 지갑으로 입금합니다.
실제 실행 로그 분석 (Log Analysis of a Real Run)
다음은 우리의 Day 96 테스트 실행 로그 분석으로, 에이전트가 정상, 제한, 그리고 불가능한 시나리오 하에서 어떻게 행동하는지 보여줍니다.
시나리오 A: 정상적인 목표 추구 실행 (0.2 SOL 목표)
초기 저축 지갑은 896,000 lamports를 보유하고 있습니다. 목표는 200,000,000 lamports (0.2 SOL)입니다.
- Turn 1: 모델이 운영 지갑(operating wallet)과 저축 지갑(savings wallet) 모두에 대해
get_balance를 호출합니다. - Turn 2: 차액(
199,104,000lamports)을 계산하고transfer_sol을 호출합니다. - Policy Check (정책 확인): 승인됨 (단일 전송 한도인 0.25 SOL 미만).
- Turn 3: 모델이 다시
get_balance를 호출하여 저축 지갑에 정확히200,000,000lamports가 있는지 확인하고 최종 보고서를 출력합니다.
목표가 달성되었을 때 다시 시도하는 상황도 적절하게 처리됩니다.
시나리오 B: 한도 미만에서의 다단계 전송 (0.4 SOL 목표)
초기 저축 지갑은 0.2 SOL을 보유하고 있습니다. 전송당 한도는 50,000,000 lamports로 설정되어 있습니다.
- Turn 1: 모델이 잔액을 확인하고,
200,000,000lamports의 부족분을 결정합니다. - Turn 2:
200,000,000lamports를 전송할 것을 제안합니다. 정책 엔진(policy engine)은 전송당 한도를 초과했으므로 이를 차단합니다. - Turns 3-6: 에이전트가 이를 조정하여
50,000,000lamports씩 4회 연속 전송을 실행합니다. 4회 모두 승인 및 확인됩니다. - Turn 7: 새로운 잔액인
400,000,000lamports를 확인하고 성공적으로 종료합니다.
시나리오 C: 불가능한 목표 (5 SOL 목표)
- Turn 1: 에이전트(Agent)가 잔액 확인: 운영 지갑(operating wallet)에 1.55 SOL, 저축 지갑(savings)에 0.4 SOL이 있음.
- Turn 2: 에이전트(Agent)는 4.6 SOL이 필요하지만 운영 지갑에는 1.55 SOL만 있다는 것을 인지함. 즉시 작업을 중단하고 목표 달성이 불가능함을 보고하여, 불필요한 트랜잭션(transaction) 시도를 방지함.
가드레일(Guardrails)로서의 정책(Policy) 활용
언어 모델(language model)이 다음 행동을 계획하는 책임을 지지만, 스스로 자금을 이동시킬 권한은 없습니다.
모든 전송 요청은 블록체인(blockchain)에 도달하기 전 정책 엔진(policy engine)을 통과합니다.
현재 정책 규칙은 다음과 같습니다:
- 기본 동작 (Default action): 명시적으로 허용되지 않는 한 모든 전송을 거부함.
- 수취인 검증 (Recipient Validation): 승인된 지갑 주소만 자금을 받을 수 있음.
- 전송 한도 (Transfer Cap): 설정된 최대 금액을 초과하는 모든 전송을 거부함.
- 예산 집행 (Budget Enforcement): 설정된 지출 예산을 초과하는 전송을 거부함.
- 입력 검증 (Input Validation): 잘못된 형식의 주소나 유효하지 않은 전송 금액을 거부함.
모델(model)의 관점에서 거부된 전송은 단순히 또 다른 도구 응답(tool response)이 됩니다.
실행을 강제하는 대신, 모델(model)은 계획을 수정하거나 목표를 완료할 수 없다고 결론지어야 합니다.
이러한 책임의 분리는 전체 시스템의 핵심 불변성(invariant)을 생성합니다:
프롬프트(prompt)는 변할 수 있습니다. 모델(model)은 변할 수 있습니다. 추론 경로(reasoning path)도 변할 수 있습니다. 하지만 정책 엔진(policy engine)을 통과하지 않고 자금을 이동시키는 트랜잭션(transaction)은 없습니다.
교훈 및 놀라운 점
이번 Arc 14 전반에 걸쳐 가장 놀라웠던 점은 모델이 변화하는 상황에 얼마나 자연스럽게 적응하는가였습니다.
이전 설정된 정책 한도(policy limit)를 초과하는 전송이 발생했을 때, 모델은 동일한 잘못된 요청을 반복하지 않았습니다. 대신, 거절된 상황을 새로운 정보로 해석하고 전송을 승인 가능한 더 작은 청크(chunks)로 나누어 전략을 조정했습니다.
또 다른 흥미로운 관찰 결과는 동일한 프롬프트(prompt)를 사용한 두 번의 실행이 항상 동일한 도구 호출(tool-call) 시퀀스를 생성하지는 않는다는 점이었습니다. 추론(reasoning) 과정은 약간씩 달랐지만, 모든 행동이 동일한 정책 계층(policy layer)에 의해 제약되었기 때문에 최종 결과는 일관되게 유지되었습니다.
아마도 가장 중요한 교훈은 안전의 진정한 원천이 프롬프트가 아니라 정책 엔진(policy engine)이라는 점을 깨달은 것입니다. 프롬프트 지침은 행동에 영향을 줄 수 있지만, 자금 이동 가능 여부를 궁극적으로 결정하는 것은 실행 가능한 규칙(executable rules)입니다.
향후 방향
이번 Arc를 통해 직면한 과제들은 Solana를 넘어 확장 가능한 하나의 아키텍처 원칙을 강화해 주었습니다:
추론(Reasoning)은 무엇을 할지 결정해야 합니다. 정책(Policy)은 그것이 허용되는지 결정해야 합니다. 블록체인(Blockchain)은 실제로 일어난 일을 기록해야 합니다.
이러한 책임들을 분리함으로써 시스템은 감사(audit)하기 더 쉬워지고, 확장하기 용이해지며, 프롬프트 지침에만 의존하는 것보다 훨씬 더 안전해집니다.
이 구현체는 의도적으로 devnet으로 제한되어 있지만, 동일한 계층형 아키텍처(layered architecture)는 향후 더 유능한 온체인 자율 에이전트(on-chain autonomous agents)를 위한 토대로 활용될 수 있습니다.
이 기사는 #100DaysOfSolana의 Arc 14(92~98일 차) 동안 완료된 에이전트 워크플로우(agent workflow)를 요약합니다.
Week 14 Workspace를 확인해 보세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기



