AI 代理是自主程序,旨在感知环境、处理信息并采取行动以实现特定目标。这类代理的形态多样,从简单的基于规则的机器人,到能够随时间自适应并优化决策的高级机器学习系统,不一而足。
在区块链和 DeFi 领域,AI 驱动的自动化浪潮为无缝、智能的链上交互开辟了新的可能。从自动化交易、风险评估、流动性管理等任务,到执行复杂的智能合约交互,AI 代理正在通过提升效率、减少人工干预,改变我们构建 dapp 的方式。
借助 ElizaOS 等框架,开发者可以构建能够与区块链协议交互、并对代币兑换、套利和投资组合管理做出实时决策的 AI 代理。本指南将带你完整了解一个 AI 代理的设计、搭建与实现过程——该代理利用 ElizaOS 内置功能自主执行交易。
前提条件
在开始构建之前,请确保已完成以下配置:
Node.js(v23.3.0 或更高版本)
PNPM 包管理器
带有测试网代币的 EVM 兼容钱包——用于执行交易(例如 Sepolia ETH)
RPC 提供商 URL——将你的应用连接到区块链,例如 Infura
模型提供商的 API 密钥——AI 交互所必需(例如 OpenAI)
以上准备就绪后,即可开始构建你的 AI 驱动区块链代理。
搭建 ElizaOS 环境
克隆 ElizaOS 仓库并切换到最新版本。
git clone https://github.com/elizaOS/eliza.git
cd eliza
git checkout $(git describe --tags --abbrev=0)
如果主版本无法正常运行,可切换到稳定版本。撰写本文时,推荐使用 stable-11-30 版本。运行以下命令即可切换:
git fetch --all
git checkout stable-11-30
安装依赖
pnpm install
配置环境变量
cp .env.example .env
`# EVM
EVM_PRIVATE_KEY=
EVM_PROVIDER_URL=
OPEN AI
OPENAI_API_KEY=`
以上配置对 ElizaOS 的正常运行至关重要:
EVM_PRIVATE_KEY**:** 用于签署交易的钱包私钥。Eliza 将使用该钱包进行代币转账和兑换,请确保其中已预存一定数量的 Sepolia 测试网 ETH。
EVM_PROVIDER_URL**:** 连接区块链节点的 RPC 端点,使 AI 代理能够与网络进行交互。
OPENAI_API_KEY**:** 授权访问 OpenAI 模型,使 AI 代理能够做出智能决策。
注意: 请确保私钥安全保存,并将其排除在版本控制之外。
Eliza 框架的核心概念
Eliza 框架由四个核心组件构成:
Characters(角色):JSON 配置文件,定义 AI 的个性、行为和沟通风格
Agents(代理):负责管理记忆、处理输入和执行行为的运行时模块
Providers(提供商):为交互提供上下文和实时信息的数据来源
Actions(动作):使代理能够执行任务并与外部系统交互的可执行函数
定义代币兑换与转账角色
角色定义了 AI 代理的沟通风格、语气和响应一致性,使交互更加自然流畅。一个精心设计的角色能确保 AI 与其预期用途高度契合。
本项目的核心功能是代币转账和兑换,因此我们将定义一个 Eliza 角色,用于规范 AI 代理与区块链协议的交互方式、交易执行逻辑以及向用户反馈信息的方式。该角色将确保代理清晰传达交易详情、遵循预设安全规则,并为用户提供流畅的使用体验。
创建新的角色文件。
cd characters
touch degen.character.json
将以下内容复制到新创建的文件中:
{
"name": "ETHMaxxer",
"clients": [],
"modelProvider": "openai",
"settings": {
"chains": {
"evm": ["sepolia"]
}
},
"plugins": ["@elizaos/plugin-evm"],
"bio": [
"ETH Transfers",
"ETHMaxxer is a crypto-native who lives and breathes Ethereum",
"Believes every dip is a 'generational buying opportunity'",
"Always sending ETH and reminding everyone 'gas fees are part of the game'",
"Claims 'BTC is cool, but ETH is the future of finance'",
"Frequently checks gas prices but still sends transactions anyway"
],
"lore": [
"Started stacking ETH in the early days, never looked back",
"Loves discussing new L2s, staking, and Ethereum upgrades",
"Firm believer in 'not your keys, not your coins'",
"Survived multiple bull and bear cycles but still max bullish"
],
"knowledge": [
"Sending ETH transactions",
"Gas fee optimization",
"Ethereum staking",
"Layer 2 scaling solutions",
"DeFi applications",
"Smart contract risks",
"On-chain security",
"Bridging assets",
"Crypto market trends"
],
"messageExamples": [
[
{
"user": "{{user1}}",
"content": {
"text": "How do I send ETH?"
}
},
{
"user": "ETHMaxxer",
"content": {
"text": "ser, just fire up your wallet, enter the recipient, and set that gas. if it's an L1 tx, brace for the fees but ngl, sending ETH is always worth it ",
"action": "SEND_ETH"
}
}
],
[
{
"user": "{{user1}}",
"content": {
"text": "Gas fees are high, what do I do?"
}
},
{
"user": "ETHMaxxer",
"content": {
"text": "fren, welcome to the ETH experience . either wait for a low-gas window, use an L2 like Arbitrum, or just send it and embrace the pain. ngmi if you're scared of gas fees "
}
}
],
[
{
"user": "{{user1}}",
"content": {
"text": "Is ETH going up?"
}
},
{
"user": "ETHMaxxer",
"content": {
"text": "anon, ETH is always going up... eventually. if not today, then after the next hard fork or bull cycle. remember, '1 ETH = 1 ETH', just hodl "
}
}
]
],
"postExamples": [
"gas is pain, but ETH is life ",
"sending ETH and feeling rich, until I check my gas fees ",
"L2s are cool, but real maxxers still send ETH on mainnet "
],
"topics": [
"eth_transfers",
"ethereum_news",
"gas_fees",
"staking",
"crypto_markets"
],
"style": {
"all": [
"Crypto-maximalist",
"ETH-focused",
"Slightly degen",
"Loves talking about gas fees and upgrades"
],
"chat": [
"Casual",
"Crypto-slang heavy",
"Slightly memetic",
"Uses emojis frequently"
],
"post": ["Short", "Bullish", "Relatable", "Memetic"]
},
"adjectives": [
"ETH-maxi",
"Bullish",
"Crypto-native",
"Gas-tolerant",
"Future-focused",
"Layer 2 curious"
]
}
上述文件定义了名为 ETHMaxxer 的 AI 代理配置,指定 "modelProvider": "openai" 并将 Sepolia 设为指定区块链网络。
Agents(代理)
Eliza 框架中的代理是核心运行时组件,负责将 AI 角色赋予生命。它们通过 AgentRuntime 类管理行为和交互。AgentRuntime 类正常运行需要若干关键组件,其中部分由 Eliza 框架开箱即用地提供:
数据库适配器:负责 AI 代理信息的存储与检索,包括记忆存储、关系追踪和知识管理。
插件:扩展 AI 代理的功能,支持与区块链、社交媒体等外部服务集成。本项目中,我们指定 AI 代理使用 @elizaos/plugin-evm 与区块链交互。
模型提供商:定义用于处理和生成响应的 AI 模型来源。可选项包括 Anthropic、Grok 等,本项目选用 OpenAI,已在角色文件中定义。
认证令牌:所选模型提供商所必需,应作为环境变量传入,例如 OPENAI_API_KEY。
角色配置文件:我们之前定义的角色文件,概述了 AI 代理的特征和行为。
所有这些组件均在 /agent/src/index.ts 文件中定义。与我们代理相关的 AgentRuntime 代码片段如下:
return new AgentRuntime({
databaseAdapter: db,
token,
modelProvider: character.modelProvider,
evaluators: [],
character,
plugins: [
getSecret(character, "EVM_PUBLIC_KEY") ||
(getSecret(character, "WALLET_PUBLIC_KEY") &&
getSecret(character, "WALLET_PUBLIC_KEY")?.startsWith("0x"))
? evmPlugin
: null
]
})
Providers(提供商)
提供商负责处理钱包集成、区块链交互和数据访问等专项功能,确保 AI 代理能够与外部系统无缝连接。它们充当执行交易、获取实时数据以及管理跨服务交互的网关。
在 @elizaos/plugin-evm 中,提供商使 AI 代理能够与 EVM 兼容区块链交互,支持发送交易、查询智能合约和监控区块链活动。通过利用 Infura 等服务提供的 RPC 端点,代理无需运行专用节点即可执行链上操作。
以下是 @elizaos/plugin-evm 中提供商的实现方式:
export class WalletProvider {
private cache: NodeCache;
private cacheKey: string = "evm/wallet";
private currentChain: SupportedChain = "mainnet";
private CACHE_EXPIRY_SEC = 5;
chains: Record<string, Chain> = { ...viemChains };
account: PrivateKeyAccount;
constructor(
accountOrPrivateKey: PrivateKeyAccount |
0x${string},
private cacheManager: ICacheManager,
chains?: Record<string, Chain>
) {
this.setAccount(accountOrPrivateKey);
this.setChains(chains);
if (chains && Object.keys(chains).length > 0) {
this.setCurrentChain(Object.keys(chains)[0] as SupportedChain);
}
this.cache = new NodeCache({ stdTTL: this.CACHE_EXPIRY_SEC });
}
getAddress(): Address {
return this.account.address;
}
getCurrentChain(): Chain {
return this.chains[this.currentChain];
}
getPublicClient(
chainName: SupportedChain
): PublicClient<HttpTransport, Chain, Account | undefined> {
const transport = this.createHttpTransport(chainName);
const publicClient = createPublicClient({
chain: this.chains[chainName],
transport,
});
return publicClient;
}
getWalletClient(chainName: SupportedChain): WalletClient {
const transport = this.createHttpTransport(chainName);
const walletClient = createWalletClient({
chain: this.chains[chainName],
transport,
account: this.account,
});
return walletClient;
}
getChainConfigs(chainName: SupportedChain): Chain {
const chain = viemChains[chainName];
if (!chain?.id) {
throw new Error("Invalid chain name");
}
return chain;
}
async getWalletBalance(): Promise<string | null> {
const cacheKey = "walletBalance_" + this.currentChain;
const cachedData = await this.getCachedData<string>(cacheKey);
if (cachedData) {
elizaLogger.log(
"Returning cached wallet balance for chain: " +
this.currentChain
);
return cachedData;
}
try {
const client = this.getPublicClient(this.currentChain);
const balance = await client.getBalance({
address: this.account.address,
});
const balanceFormatted = formatUnits(balance, 18);
this.setCachedData<string>(cacheKey, balanceFormatted);
elizaLogger.log(
"Wallet balance cached for chain: ",
this.currentChain
);
return balanceFormatted;
} catch (error) {
console.error("Error getting wallet balance:", error);
return null;
}
}
async getWalletBalanceForChain(
chainName: SupportedChain
): Promise<string | null> {
try {
const client = this.getPublicClient(chainName);
const balance = await client.getBalance({
address: this.account.address,
});
return formatUnits(balance, 18);
} catch (error) {
console.error("Error getting wallet balance:", error);
return null;
}
}
addChain(chain: Record<string, Chain>) {
this.setChains(chain);
}
}
Actions(动作)
动作定义了 AI 代理可执行的具体行为,使其能够与外部系统交互、处理请求并自动化任务。每个动作均设计用于执行特定功能,例如发送交易、检索数据或执行智能合约调用,确保代理在其环境中高效运作。
在 @elizaos/plugin-evm 中,动作支持代币转账、兑换和区块链交互,使 AI 代理能够直接在 EVM 兼容网络上执行交易。这些动作由用户输入或预定义逻辑触发,确保区块链相关操作的无缝执行。
以下是 @elizaos/plugin-evm 中代币转账动作的实现方式:
async transfer(params: TransferParams): Promise<Transaction> {
console.log(
Transferring: ${params.amount} tokens to (${params.toAddress} on ${params.fromChain})
);
if (!params.data) {
params.data = "0x";
}
this.walletProvider.switchChain(params.fromChain);
const walletClient = this.walletProvider.getWalletClient(
params.fromChain
);
try {
const hash = await walletClient.sendTransaction({
account: walletClient.account,
to: params.toAddress,
value: parseEther(params.amount),
data: params.data as Hex,
kzg: {
blobToKzgCommitment: function (_: ByteArray): ByteArray {
throw new Error("Function not implemented.");
},
computeBlobKzgProof: function (
_blob: ByteArray,
_commitment: ByteArray
): ByteArray {
throw new Error("Function not implemented.");
},
},
chain: undefined,
});
return {
hash,
from: walletClient.account.address,
to: params.toAddress,
value: parseEther(params.amount),
data: params.data as Hex,
};
} catch (error) {
throw new Error(
Transfer failed: ${error.message}
完成环境变量配置、角色文件定义以及 Eliza 插件指定后,让我们将所有内容整合起来,测试我们的 AI 代理。
构建项目
pnpm build
运行角色
pnpm start --character="characters/degen.character.json"
启动客户端
pnpm start:client
现在,让我们与代理交互,要求它执行特定任务。
总结
构建一个能够与以太坊及 EVM 兼容区块链交互的 AI 代理,为自动化、智能化的链上交互开辟了全新可能。本指南完整介绍了 Characters、Agents、Providers 和 Actions 的定义方式,使代理能够自主完成代币转账和兑换。
借助 ElizaOS 的模块化框架,开发者可以打造 AI 驱动的 DeFi 助手、交易机器人或投资组合管理工具,与区块链网络无缝交互。现在你已掌握基础,不妨尝试扩展其功能、优化逻辑,并集成新特性,进一步提升链上自动化能力。