智能体框架
借鉴 Trae IDE 的 Agent 架构,AI Crypto Wallet 的智能体由「思考循环 + 工具注册表 + 记忆系统」三块核心组成。本篇逐一拆解它们如何协作,让 AI 既能分析市场、又能安全地执行交易。
01AgentRuntime 思考循环
AgentRuntime 是智能体的「引擎」,它把一次任务拆解为「思考 → 行动 → 观察 → 再思考」的循环,直到得出最终结论。
关键参数
| 参数 | 值 | 说明 |
|---|---|---|
maxRounds | 8 | 思考循环最大轮数,防止无限循环,足够完成分析 + 1-2 笔交易 |
connectTimeout | 10s | LLM 连接建立超时 |
readTimeout | 60s | LLM 响应读取超时(大模型推理可能较慢) |
当 AI 在循环中调用工具时,每次工具结果都被注入上下文,作为下一轮 LLM 判断的依据。一旦 AI 不再请求工具,即输出最终回复,循环结束。
02AgentToolRegistry 工具集
AgentToolRegistry 声明 AI「能做什么」,共 12 个工具,分为只读与写入两类。所有工具统一返回 ToolResult(success + output/error),便于 AI 解析。
只读工具(不消耗 gas,无需 SafetyGate)
| # | 工具名 | 功能 | 安全级别 |
|---|---|---|---|
| 1 | get_wallet_address | 查询当前钱包地址 | 低 |
| 2 | get_native_balance | 原生币余额 + USD 价值 | 低 |
| 3 | get_token_balance | ERC20 代币余额 | 低 |
| 4 | get_token_price | 查询代币当前价格 | 低 |
| 5 | get_position | 查询所有持仓状态 | 低 |
| 6 | get_market_data | 拉取 K 线技术指标(RSI/MACD/MA/BB) | 低 |
| 7 | get_safety_status | 查询安全网关状态(熔断/限额/错误率) | 低 |
| 8 | call_contract_read | 只读合约调用(eth_call,不消耗 gas) | 低 |
写入工具(消耗 gas,必须经过 SafetyGate)
| # | 工具名 | 功能 | 安全级别 |
|---|---|---|---|
| 9 | call_contract_write | 任意写入合约调用 | 高(需审计描述) |
| 10 | swap_tokens | DEX 代币兑换(原生币↔USDT↔代币) | 高(白名单+限额) |
| 11 | approve_token | ERC20 授权 | 中 |
| 12 | send_native | 原生币转账 | 高(需确认地址) |
所有写入工具都要求 operation_desc(操作描述)用于审计;AI 在执行前应先调用 get_safety_status 确认未熔断;非白名单代币需用户确认;滑点保护默认 3%。
工具调用流程:AI 决定调用 → AgentToolRegistry.execute() → 只读工具直接执行;写入工具先过 SafetyGate.check(),通过则执行并回调 onTradeSuccess(),拒绝则返回错误原因让 AI 调整策略。
03AgentMemory 记忆系统
AgentMemory 是 AI 的「自述文件」,每个钱包独立一份,不共享不同步。它让 AI 记住自己的身份、交易偏好与长期经验。
存储位置:Android/data/com.aicryptowallet.app/files/agent_workspace/agent_memory.json,按钱包地址短码(前6+后4,如 0xfF7F_aAFae)分目录存放。
记忆文件结构
{
"version": "1.0",
"walletAddress": "0xfF7F...aAFae",
"identity": { "aiName": "AI 交易助手", "ownerName": "主人", "personality": "沉稳理性..." },
"trading": { "tradingChain": "BNB", "checkIntervalMinutes": 5, "maxDailyLoss": 50.0,
"newsReportIntervalHours": 24, "preferredCycle": "1h", "riskLevel": "medium" },
"preferences": { "avoidTokens": [], "favoriteTokens": [], "language": "zh-CN", "detailLevel": "concise" },
"longTermMemory": { "tradeJournal": [], "marketObservations": [], "userLessons": [] },
"meta": { "apiKeyMasked": "sk-****abcd", "customNotes": "", "createdAt": 1721484000000,
"updatedAt": 1721484000000, "exportCount": 0, "importSource": null }
}
字段说明
identity(身份)
| 字段 | 类型 | 默认值 | AI 可修改 |
|---|---|---|---|
| aiName | string | "AI 交易助手" | 是 |
| ownerName | string | "主人" | 是 |
| personality | string | "沉稳理性…" | 是 |
trading(交易配置)
| 字段 | 类型 | 默认值 | 范围 | AI 可修改 |
|---|---|---|---|---|
| tradingChain | string | "BNB" | 支持的链标识 | 是 |
| checkIntervalMinutes | int | 5 | 1-60 | 是 |
| maxDailyLoss | double | 50.0 | 0-10000 | 是 |
| newsReportIntervalHours | int | 24 | 1-168 | 是 |
| preferredCycle | string | "1h" | 15m/1h/4h/1d | 是 |
| riskLevel | string | "medium" | conservative/medium/aggressive | 是 |
preferences(偏好)
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| avoidTokens | string[] | [] | AI 应避免推荐的代币 |
| favoriteTokens | string[] | [] | 用户偏好的代币 |
| language | string | "zh-CN" | 回答语言 |
| detailLevel | string | "concise" | concise/normal/detailed |
longTermMemory(长期记忆)
| 字段 | 类型 | 说明 |
|---|---|---|
| tradeJournal | object[] | 重要交易记录(决策理由 + 结果) |
| marketObservations | string[] | AI 对市场的观察与判断(最多保留 20 条) |
| userLessons | string[] | 从交互中学到的用户偏好 |
meta(元数据)
| 字段 | 类型 | 说明 |
|---|---|---|
| apiKeyMasked | string | API Key 脱敏(前4后4),AI 不可修改 |
| customNotes | string | 用户 / AI 的自定义备注 |
| createdAt / updatedAt | long | 创建 / 更新时间戳 |
| exportCount | int | 被导出分享的次数 |
| importSource | string | 导入来源(可选) |
@SET 自修改机制
AI 通过回复中的 @SET 字段名=新值 指令修改自身配置。以 @SET identity.aiName=小智 为例:
// 从 AI 回复中提取 @SET 指令
Pattern pattern = Pattern.compile("@SET\\s+([\\w.]+)\\s*=\\s*(.+)");
Matcher matcher = pattern.matcher(aiReply);
while (matcher.find()) {
String field = matcher.group(1);
String value = matcher.group(2).trim();
applySetCommand(field, value);
}
// 从显示文本中过滤掉 @SET 指令
String displayText = aiReply.replaceAll("@SET\\s+[\\w.]+\\s*=\\s*.+", "").trim();
范围校验
| 字段 | 最小值 | 最大值 | 超出处理 |
|---|---|---|---|
| checkIntervalMinutes | 1 | 60 | 截断到范围内 |
| maxDailyLoss | 0 | 10000 | 截断到范围内 |
| newsReportIntervalHours | 1 | 168 | 截断到范围内 |
安全限制
- AI 不能修改
meta.apiKeyMasked(只能用户在设置中修改)。 - AI 不能修改
walletAddress(系统自动设置)。 - AI 不能修改
version(由代码控制)。 - AI 不能直接写
longTermMemory(通过对话自动积累)。
导出与导入
记忆文件支持通过系统分享菜单导出(微信 / QQ / Telegram / 飞书 / 邮件等),便于备份与迁移。导入时系统会校验文件格式、字段范围,并核对 walletAddress 是否与当前钱包匹配;导入前显示预览、必须手动确认、自动备份旧文件,且不导入 meta.apiKeyMasked(每个钱包的 API Key 独立配置)。
04系统提示词组装
每次 AI 被调用时,系统提示词由三层动态组装而成,开发者维护内置层,用户设置层取自记忆,上下文层实时注入:
内置提示词的核心是「安全红线」:AI 不需要知道私钥(签名本地完成)、所有写入必须过安全网关、非白名单代币需用户确认、熔断期间拒绝交易、绝不暴露敏感信息、每次决策必须给出分析依据。
上下文压缩规则
| 规则 | 说明 |
|---|---|
| 短期记忆 | 保留最近 10 轮对话原文 |
| 压缩触发 | 对话超过 10 轮时,将最早对话压缩为摘要 |
| 摘要格式 | [轮次N] 用户: 问题摘要 → AI: 回答要点 |
| 重要信息提取 | 交易决策 / 盈亏结果 / 用户偏好写入长期记忆 |
| Token 预算 | 整个提示词不超过 context window 的 70% |
| 压缩优先级 | 先压旧对话 → 再压工具结果 → 最后压市场数据 |
05动态轮次机制
思考循环的轮数并非固定,而是动态的:循环在 AI 连续不再请求工具时自然收敛,返回最终回复;同时受 maxRounds=8 硬上限约束,防止 LLM 陷入「反复调工具」的无限循环。
- 正常收敛:AI 完成分析后停止调工具,输出结论,循环结束(通常 2-4 轮)。
- 工具链:一次交易可能触发「查安全状态 → 查持仓 → 查市场数据 → swap」等多轮工具调用,均被计入轮数。
- 硬上限:达到 maxRounds 时强制结束,返回当前最佳结论,避免资源与 token 过度消耗。
动态轮次 = 「收敛优先」+「上限兜底」。既保证复杂任务有足够多轮次去采集与推理,又保证任何异常情况下智能体都无法失控地消耗资源。这与「证据驱动 + 安全优先」的架构原则一脉相承。