AI+Web3 能做什么?LangChain+DeepSeek 智能决策系统实战解析
本实例代码及所涉场景仅作为 Web3 + AI 落地应用的技术案例,旨在展示两者结合的实现切入点与思路框架,不构成任何投资建议或交易诱导。代码中涉及的自动化交易策略存在资金损失风险,包括但不限于智能合约漏洞、市场流动性不足、预言机争议及模型决策失误。请勿将本代码直接用于真实资金交易,使用前应充分理解其机制并进行严格的安全审计。作者不对任何基于本代码的操作后果承担责任
前言及免责
本实例代码及所涉场景仅作为 Web3 + AI 落地应用的技术案例,旨在展示两者结合的实现切入点与思路框架,不构成任何投资建议或交易诱导。代码中涉及的自动化交易策略存在资金损失风险,包括但不限于智能合约漏洞、市场流动性不足、预言机争议及模型决策失误。请勿将本代码直接用于真实资金交易,使用前应充分理解其机制并进行严格的安全审计。作者不对任何基于本代码的操作后果承担责任。
一、预测市场的套利机会
Polymarket 作为全球最大的去中心化预测市场平台,其独特的二元市场结构(YES/NO)天然存在套利空间。在理想状态下,同一事件的 YES 和 NO 代币价格之和应等于 1.0 美元(因为事件必然发生或不发生)。然而,由于市场分割、流动性差异和信息传播延迟,这种平价关系经常出现偏离——这正是自动化套利机器人的狩猎场。
传统量化交易依赖硬编码规则,而本文介绍的系统创新性地引入大语言模型作为决策中枢,让 AI 自主理解策略目标、分析市场数据并执行交易。
二、系统架构设计
2.1 核心组件
我们的系统采用模块化设计,四个核心工具函数构成交易闭环:
// 工具矩阵:感知 → 决策 → 执行
const allTools = [
searchMarketTool, // 感知:扫描市场机会
getWalletBalanceTool, // 感知:风控检查(防止透支)
getOrderBookTool, // 感知:获取买卖深度
executeOrderTool // 执行:下单成交
];
关键设计决策:
- 余额前置检查:在每次交易前查询 USDC 余额,避免因余额不足导致的链上交易失败
- 金额-份数自动换算:Polymarket API 使用"份数"而非金额,系统自动计算
size = total_dollars / price - 硬性风控上限:单笔交易金额严格限制在 50 USDC,即使 LLM 被 prompt 注入攻击也无法突破
2.2 LLM 决策层
与传统策略不同,我们使用 DeepSeek-V3 作为推理引擎:
const llm = new ChatOpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: { baseURL: "https://api.deepseek.com" },
modelName: "deepseek-chat",
temperature: 0, // 确定性输出,减少随机交易
});
通过 createOpenAIFunctionsAgent,LLM 获得工具调用能力(Function Calling) 。当接收到策略指令时,AI 会自主决定调用哪些工具、以什么顺序调用,以及如何从工具返回中提取信息。
三、套利策略的工程实现
3.1 市场扫描与机会识别
搜索工具对接 Polymarket 的 Gamma API,提取关键字段:
// 返回结构化的套利分析数据
{
title: "2024 US Presidential Election",
markets: [{
question: "Will Trump win?",
clobTokenId: "0x...", // YES 代币 ID
prices: [0.62, 0.40], // [YES价格, NO价格]
outcomes: ["Yes", "No"]
}]
}
套利信号计算:当 YES价格 + NO价格 ≠ 1.0 时,存在套利空间。例如:
- YES = 0.62,NO = 0.40 → 总和 1.02 → 存在 2% 溢价
- 理论上可同时卖出 YES 和 NO,锁定 2% 无风险收益(需考虑手续费)
3.2 订单簿深度分析
获取订单簿不是为了显示,而是为了计算实际可成交的套利空间:
const book = await client.getOrderBook(tokenId);
// 分析前2档买卖盘,计算滑点成本
LLM 会评估:当前买一/卖一价差是否足够覆盖 3% 收益门槛?深度是否支持目标仓位?
3.3 安全下单机制
// 三重防护
if (total_dollars > 50) return "拒绝执行:单笔金额严禁超过 50 USDC";
const size = Math.floor(total_dollars / price);
if (size <= 0) return "错误:投入金额不足以购买 1 份";
为什么用限价单而非市价单?
- Polymarket 采用 CLOB(中央限价订单簿)模型
- 限价单避免在流动性不足时产生巨大滑点
- 符合"套利"本质:只有价格达到预期才成交
四、无人值守的运行时架构
4.1 主循环设计
while (true) {
console.log(`[${new Date().toLocaleTimeString()}] 开始新一轮扫描...`);
await executor.invoke({ input: strategyGoal });
// 强制冷却:2分钟观察期
await new Promise(resolve => setTimeout(resolve, 120000));
}
工程考量:
- API 频率限制:Polymarket API 有速率限制,2分钟间隔平衡了实时性与稳定性
- Token 成本控制:每次调用都消耗 DeepSeek API 费用,过度频繁的扫描会侵蚀利润
- 错误恢复:异常时进入 30 秒短休眠,避免错误雪崩
4.2 策略目标的自然语言描述
最精妙的设计在于:策略本身用自然语言描述:
startAutoTrading("搜索关于『2024美国大选』的市场,寻找 YES 和 NO 之间价格加总偏离 1.0 太多的套利机会,并执行操作。");
LLM 理解:
- 搜索范围:限定在"2024美国大选"主题
- 套利逻辑:YES + NO ≠ 1.0 时存在机会
- 行动指令:分析后执行交易(隐含收益率>3%和<50刀的风控)
这种声明式策略定义让非技术人员也能调整交易逻辑,无需修改代码。
五、风险与局限
5.1 已实现的风控
| 风险类型 | 防护措施 |
|---|---|
| 资金风险 | 单笔50 USDC硬性上限 |
| 透支风险 | 交易前查询链上余额 |
| 价格风险 | 限价单控制成交价格 |
| 操作风险 | 2分钟冷却防止过度交易 |
5.2 未解决的风险
- 智能合约风险:Polymarket 合约漏洞可能导致资金损失
- 预言机风险:事件结果判定争议(如 2024 大选结果争议场景)
- 流动性风险:小市场订单簿深度不足,理论套利无法实际成交
- 模型幻觉:LLM 可能误解工具返回的数据格式,导致错误决策
5.3 生产环境建议
- 增加模拟交易模式:
client.postOrder前增加dryRun参数空跑验证 - 多签钱包:大额资金改用 Gnosis Safe 多签管理
- 实时监控:接入 Telegram/Discord 机器人推送交易通知
- 策略回测:用历史订单簿数据验证策略有效性
六、技术栈总结
| 层级 | 技术选型 | 作用 |
|---|---|---|
| 区块链交互 | ethers.js |
Polygon 网络连接、USDC 合约查询 |
| 市场数据 | @polymarket/clob-client |
订单簿获取、下单执行 |
| AI 框架 | langchain |
Agent 编排、工具调用管理 |
| LLM 模型 | DeepSeek-V3 |
策略理解、决策推理 |
| 运行时 | Node.js + dotenv |
环境配置、无限循环守护 |
七、结语
这个系统展示了LLM Agent 在金融交易领域的应用潜力:不是让 AI "预测"价格(这仍然困难),而是让 AI 理解规则、执行流程、管理风险。在预测市场这种规则明确、数据结构化、套利逻辑清晰的场景中,LLM 的推理能力可以显著降低策略开发门槛。
未来演进方向包括:多市场并行监控、动态调整扫描频率、基于历史胜率的学习优化,以及与其他 DeFi 协议的组合套利(如结合期权、永续合约进行对冲)。
八、补充:示例代码
工具篇
import { ethers } from "ethers";
import { ClobClient } from "@polymarket/clob-client";
import { z } from "zod";
import dotenv from 'dotenv';
import { DynamicStructuredTool } from "@langchain/core/tools";
dotenv.config();
// --- 初始化驱动 ---
const provider = new ethers.JsonRpcProvider(process.env.POLYGON_RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const client = new ClobClient(
"https://clob.polymarket.com",
137,
wallet,
{
apiKey: process.env.POLY_API_KEY,
apiSecret: process.env.POLY_API_SECRET,
apiPassphrase: process.env.POLY_PASS_PHRASE,
}
);
// 1. 搜索工具(修正 URL 和数据结构)
const searchMarketTool = new DynamicStructuredTool({
name: "search_polymarket",
description: "搜索 Polymarket 市场。返回包含 YES 和 NO TokenID 及价格的市场列表,用于计算套利空间(YES价格 + NO价格 偏离 1.0)。",
schema: z.object({
query: z.string().describe("关键词,如 'Election'")
}),
func: async ({ query }) => {
try {
// 修正后的 Gamma API URL
const url = `https://gamma-api.polymarket.com{encodeURIComponent(query)}`;
const response = await fetch(url);
const data = await response.json();
// 提取完整的市场对比数据
return JSON.stringify(data.slice(0, 3).map(event => ({
title: event.title,
markets: event.markets.map(m => ({
question: m.question,
// 同时返回 YES 和 NO 的 TokenID 供 Agent 对比
clobTokenId: m.clobTokenId,
prices: m.outcomePrices, // 通常 [YES价格, NO价格]
outcomes: m.outcomes // 通常 ["Yes", "No"]
}))
})));
} catch (error) {
return `搜索失败: ${error.message}`;
}
},
});
// 2. 余额查询工具(新增:防止透支报错)
const getWalletBalanceTool = new DynamicStructuredTool({
name: "get_wallet_balance",
description: "查询当前钱包在 Polygon 网络上的 USDC 余额。",
schema: z.object({}), // 无需参数
func: async () => {
try {
// Polymarket 主要使用 USDC (Polygon 上的地址)
const usdcAddress = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
const abi = ["function balanceOf(address) view returns (uint256)"];
const contract = new ethers.Contract(usdcAddress, abi, provider);
const balance = await contract.balanceOf(wallet.address);
return `当前钱包余额: ${ethers.formatUnits(balance, 6)} USDC`;
} catch (e) {
return `查询余额失败: ${e.message}`;
}
}
});
// 3. 下单工具(修正:金额到份数的换算)
const executeOrderTool = new DynamicStructuredTool({
name: "execute_polymarket_order",
description: "在 Polymarket 下达限价单。注意:amount 是你想投入的美元金额,我会自动换算成购买份数。",
schema: z.object({
tokenId: z.string().describe("目标的 Token ID"),
price: z.number().describe("下单价格/赔率 (0.01-0.99)"),
total_dollars: z.number().describe("准备投入的总美元金额"),
side: z.enum(["BUY", "SELL"])
}),
func: async ({ tokenId, price, total_dollars, side }) => {
try {
// 风控:硬性上限
if (total_dollars > 50) return "拒绝执行:单笔金额严禁超过 50 USDC。";
// 换算:Polymarket API 需要的是 size (份数)
// 份数 = 投入金额 / 单价
const size = Math.floor(total_dollars / price);
if (size <= 0) return "错误:投入金额不足以购买 1 份。";
const order = await client.createOrder({
tokenID: tokenId,
price: price,
side: side.toUpperCase(),
size: size,
});
// 重要:如果是第一次测试,可以将下一行改为 return JSON.stringify(order) 进行空跑
const response = await client.postOrder(order);
return `订单提交成功!ID: ${response.orderID}, 购买份数: ${size}`;
} catch (e) {
return `交易失败: ${e.message}`;
}
}
});
// 4. 订单簿查询(保持不变)
const getOrderBookTool = new DynamicStructuredTool({
name: "get_market_orderbook",
description: "获取买卖盘深度。",
schema: z.object({ tokenId: z.string() }),
func: async ({ tokenId }) => {
try {
const book = await client.getOrderBook(tokenId);
return JSON.stringify({ asks: book.asks.slice(0, 2), bids: book.bids.slice(0, 2) });
} catch (e) { return `获取深度失败: ${e.message}`; }
}
});
export const Tools = {
searchMarketTool,
getWalletBalanceTool,
getOrderBookTool,
executeOrderTool
};
agent执行脚本
import dotenv from 'dotenv';
import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
// import { DynamicStructuredTool } from "@langchain/core/tools";
// import { z } from "zod";
dotenv.config();
// import { Tools } from "./tools.js";
// const { searchMarketTool, getOrderBookTool, executeOrderTool } = Tools;
import { Tools } from "./tools1.js";
// AgentExecutor.js 中修改这一行
const { searchMarketTool, getWalletBalanceTool, getOrderBookTool, executeOrderTool } = Tools;
const allTools = [searchMarketTool,getWalletBalanceTool, getOrderBookTool, executeOrderTool].filter(
(tool) => tool !== undefined
);
// 检查工具数量是否符合预期
if (allTools.length < 4) {
throw new Error(`工具加载不完整!期望 4 个,实际加载了 ${allTools.length} 个。`);
}
// 定义策略逻辑
async function startAutoTrading(strategyGoal) {
// --- 1. 定义策略目标 ---
const prompt = ChatPromptTemplate.fromMessages([
["system", `你是一个专业的无人值守套利机器人。
你的任务是:
1. 扫描市场。
2. 分析买卖深度,寻找价格差或不合理的赔率。
3. 计算预期收益率(需扣除交易成本)。
4. 只有在收益率 > 3% 且单笔风险 < 50 刀时才下单。
5. 每一轮操作后,总结你的动作。`],
["human", "{input}"],
new MessagesPlaceholder("agent_scratchpad"),
]);
// --- 2. 配置 DeepSeek 模型 ---
const llm = new ChatOpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: "https://api.deepseek.com",
},
modelName: "deepseek-chat",
temperature: 0,
});
const agent = await createOpenAIFunctionsAgent({ llm, tools: allTools, prompt });
const executor = new AgentExecutor({ agent, tools: allTools, verbose: true });
console.log("🚀 全自动交易机器人已启动...");
while (true) {
try {
console.log(`\n[${new Date().toLocaleTimeString()}] 开始新一轮扫描...`);
await executor.invoke({
input: strategyGoal
});
// 强制休眠 2 分钟,防止 API 频率受限或产生过多 token 费用
console.log("⏳ 扫描结束,进入观察期...");
await new Promise(resolve => setTimeout(resolve, 120000));
} catch (error) {
console.error("❌ 循环中出现异常:", error.message);
await new Promise(resolve => setTimeout(resolve, 30000)); // 遇到错误休息 30 秒
}
}
}
// 启动!
startAutoTrading("搜索关于『2024美国大选』的市场,寻找 YES 和 NO 之间价格加总偏离 1.0 太多的套利机会,并执行操作。");