Skip to content

好的!我们用 全 JavaScript/TypeScript 技术栈 来搭建这个多 Agent 系统的 最小可行性原型(MVP)。我们会从最核心的功能开始,逐步迭代,让你快速看到效果。

一、MVP 核心范围与技术选型

MVP 核心目标(先做这3件事)

  1. 数据采集:获取 BTC/USDT 现货行情数据(K线、成交量)
  2. 双 Agent 协同:实现「技术面分析 Agent」+「决策融合 Agent」的基础协同
  3. 极简交互:一个简单的 Web 界面,输入标的,输出分析报告

全 JS 技术栈

模块技术选型说明
运行环境Node.js 20+后端/Agent 运行环境
Agent 编排LangChain.js (LangGraph)核心:JS 版的多 Agent 状态管理与流程控制
大模型OpenAI GPT-4o (API) / Ollama (本地 Llama 3)闭源/开源二选一,都有完善的 JS SDK
数据采集CCXT (JS版)对接全球交易所的统一 API
链上数据Viem / Ethers.js v6轻量级以太坊/链上数据交互
数据库SQLite (better-sqlite3)轻量级,无需额外安装服务,Node.js 原生支持
缓存ioredis (可选)缓存行情数据,减少 API 调用
后端框架Express.jsNode.js 生态最成熟的轻量级 Web 框架
前端框架VitePress(在 docs/ 目录,通过 API 调用后端)
可视化ECharts / TradingView Lightweight Charts行情图表展示

二、第一步:环境搭建与项目初始化

1. 基础环境准备

确保你已安装:

  • Node.js 20+ (推荐使用 nvm 管理)
  • 代码编辑器 (VS Code)
  • Git (可选,用于版本管理)

2. 创建项目目录

bash
# 创建并进入项目文件夹
mkdir crypto-agent-express-mvp
cd crypto-agent-express-mvp

# 初始化 Node.js 项目
npm init -y

# 安装 TypeScript (可选但推荐,保持类型安全)
npm install -D typescript @types/node tsx
npx tsc --init

3. 安装核心依赖

bash
# 后端框架与中间件
npm install express cors dotenv

# Agent 与 AI 相关
npm install langchain @langchain/langgraph @langchain/openai

# 数据与工具
npm install ccxt better-sqlite3 viem

4. 配置环境变量

在项目根目录创建 .env.local 文件:

txt
# 大模型 API (二选一,推荐先用 OpenAI 快速验证)
OPENAI_API_KEY=你的_OpenAI_API_Key

# 如果用本地 Ollama (无需 API Key)
# OLLAMA_BASE_URL=http://localhost:11434
# OLLAMA_MODEL=llama3:70b

# 数据库路径 (默认即可)
DATABASE_URL=./crypto_data.db

三、第二步:数据层开发(行情数据采集)

先实现最基础的行情数据采集,用 CCXT 获取 Binance 的 BTC/USDT 数据。

1. 创建数据采集模块

app/lib/ 目录下创建 marketData.ts

typescript
// app/lib/marketData.ts
import ccxt from 'ccxt';

// 初始化 Binance 交易所 (仅读取行情,无需 API Key)
const exchange = new ccxt.binance({
  enableRateLimit: true, // 开启限流,避免被封
});

// 获取 K线数据
export async function fetchKlineData(
  symbol: string = 'BTC/USDT',
  timeframe: string = '1h',
  limit: number = 100
) {
  try {
    const ohlcv = await exchange.fetchOHLCV(symbol, timeframe, undefined, limit);
    // 格式化数据,方便后续处理
    return ohlcv.map(kline => ({
      timestamp: kline[0],
      open: kline[1],
      high: kline[2],
      low: kline[3],
      close: kline[4],
      volume: kline[5],
    }));
  } catch (error) {
    console.error('获取行情数据失败:', error);
    throw error;
  }
}

2. 简单测试数据采集

app/api/test-data/route.ts 创建一个测试接口:

typescript
// app/api/test-data/route.ts
import { NextResponse } from 'next/server';
import { fetchKlineData } from '@/lib/marketData';

export async function GET() {
  const data = await fetchKlineData('BTC/USDT', '1h', 50);
  return NextResponse.json({ data });
}

启动项目 npm run dev,访问 http://localhost:3000/api/test-data,如果能看到 K线数据,说明数据层通了!


四、第三步:核心 Agent 开发(用 LangChain.js)

我们先实现两个核心 Agent:技术面分析 Agent决策融合 Agent

1. 初始化 LangChain 与大模型

app/lib/agents/ 下创建 llm.ts

typescript
// app/lib/agents/llm.ts
import { ChatOpenAI } from '@langchain/openai';

// 初始化 GPT-4o (如果用 Ollama,换成 ChatOllama)
export const llm = new ChatOpenAI({
  model: 'gpt-4o',
  temperature: 0.1, // 温度低一点,分析更严谨
  apiKey: process.env.OPENAI_API_KEY,
});

2. 技术面分析 Agent

这个 Agent 的职责是:接收 K线数据,用大模型分析技术面,输出多空观点。 创建 app/lib/agents/technicalAnalysisAgent.ts

typescript
// app/lib/agents/technicalAnalysisAgent.ts
import { llm } from './llm';
import { z } from 'zod';
import { StructuredOutputParser } from 'langchain/output_parsers';

// 定义输出格式(用 Zod 结构化,避免大模型瞎输出)
const TechnicalAnalysisOutput = z.object({
  trend: z.enum(['bullish', 'bearish', 'neutral']).describe('趋势判断:看涨/看跌/震荡'),
  keySupport: z.number().describe('关键支撑位'),
  keyResistance: z.number().describe('关键阻力位'),
  reasoning: z.string().describe('分析逻辑,100字以内'),
});

const parser = StructuredOutputParser.fromZodSchema(TechnicalAnalysisOutput);

// 技术面分析 Agent 主函数
export async function technicalAnalysisAgent(klineData: any[]) {
  // 1. 准备 Prompt
  const formatInstructions = parser.getFormatInstructions();
  const prompt = `
你是一个资深加密货币技术面分析师。请分析以下 BTC/USDT 1小时 K线数据,给出技术面判断。

K线数据(最近20根):
${JSON.stringify(klineData.slice(-20), null, 2)}

要求:
1. 判断当前趋势(看涨/看跌/震荡)
2. 给出关键支撑位和阻力位
3. 简要说明分析逻辑

${formatInstructions}
  `;

  // 2. 调用大模型
  const response = await llm.invoke(prompt);
  
  // 3. 解析结构化输出
  try {
    return parser.parse(response.content as string);
  } catch (e) {
    console.error('解析技术面分析失败:', e);
    return {
      trend: 'neutral',
      keySupport: klineData[klineData.length - 1].low * 0.98,
      keyResistance: klineData[klineData.length - 1].high * 1.02,
      reasoning: '数据解析失败,给出中性判断',
    };
  }
}

3. 决策融合 Agent

这个 Agent 负责汇总所有分析(目前只有技术面),生成最终报告。 创建 app/lib/agents/decisionAgent.ts

typescript
// app/lib/agents/decisionAgent.ts
import { llm } from './llm';

export async function decisionAgent(technicalAnalysis: any) {
  const prompt = `
你是一个加密货币交易决策助手。请根据以下技术面分析,生成一份简洁的行情分析报告。

技术面分析结果:
${JSON.stringify(technicalAnalysis, null, 2)}

报告要求:
1. 标题:BTC/USDT 1小时行情分析
2. 核心观点:一句话总结
3. 技术面解读:翻译成人话,不要太技术
4. 操作建议:轻仓尝试方向,止损止盈参考支撑阻力
5. 风险提示:必写,提示市场高风险

请用 Markdown 格式输出,控制在300字以内。
  `;

  const response = await llm.invoke(prompt);
  return response.content as string;
}

五、第四步:多 Agent 编排(用 LangGraph)

现在我们用 LangGraph 把这两个 Agent 串起来,形成一个简单的工作流。

创建 app/lib/workflow.ts

typescript
// app/lib/workflow.ts
import { StateGraph, END } from '@langchain/langgraph';
import { technicalAnalysisAgent } from './agents/technicalAnalysisAgent';
import { decisionAgent } from './agents/decisionAgent';
import { fetchKlineData } from './marketData';

// 1. 定义状态(State):工作流中流转的数据
interface AgentState {
  klineData?: any[];
  technicalAnalysis?: any;
  finalReport?: string;
}

// 2. 定义工作流节点
const workflow = new StateGraph<AgentState>({
  channels: {
    klineData: null,
    technicalAnalysis: null,
    finalReport: null,
  },
})
  // 节点1:获取行情数据
  .addNode('fetchData', async (state: AgentState) => {
    console.log('正在获取行情数据...');
    const klineData = await fetchKlineData('BTC/USDT', '1h', 100);
    return { klineData };
  })
  // 节点2:技术面分析
  .addNode('technicalAnalysis', async (state: AgentState) => {
    console.log('正在进行技术面分析...');
    const analysis = await technicalAnalysisAgent(state.klineData!);
    return { technicalAnalysis: analysis };
  })
  // 节点3:生成最终报告
  .addNode('generateReport', async (state: AgentState) => {
    console.log('正在生成分析报告...');
    const report = await decisionAgent(state.technicalAnalysis!);
    return { finalReport: report };
  });

// 3. 定义边(流程顺序)
workflow
  .setEntryPoint('fetchData') // 入口
  .addEdge('fetchData', 'technicalAnalysis')
  .addEdge('technicalAnalysis', 'generateReport')
  .addEdge('generateReport', END); // 结束

// 4. 编译工作流
export const app = workflow.compile();

六、第四步:Express 后端服务搭建

1. API 路由 (src/routes/analyze.ts)

创建分析接口,触发工作流:

typescript
// src/routes/analyze.ts
import express from 'express';
import { app as workflow } from '../lib/workflow';

const router = express.Router();

// POST /api/analyze
router.post('/', async (req, res) => {
  try {
    console.log('收到分析请求,启动工作流...');
    
    // 触发 LangGraph 工作流
    const result = await workflow.invoke({});
    
    res.json({
      success: true,
      data: {
        report: result.finalReport,
        technicalAnalysis: result.technicalAnalysis,
      }
    });
  } catch (error) {
    console.error('工作流执行失败:', error);
    res.status(500).json({
      success: false,
      message: '分析失败,请稍后重试',
    });
  }
});

export default router;

2. 后端入口文件 (src/index.ts)

启动 Express 服务,托管前端静态文件:

typescript
// src/index.ts
import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import path from 'path';
import analyzeRouter from './routes/analyze';

dotenv.config();
const app = express();
const PORT = process.env.PORT || 3001;

// 中间件
app.use(cors()); // 允许跨域
app.use(express.json());

// 托管前端静态文件 (public 目录)
app.use(express.static(path.join(__dirname, 'public')));

// API 路由
app.use('/api/analyze', analyzeRouter);

// 启动服务
app.listen(PORT, () => {
  console.log(`
    🚀 服务已启动!
    📡 后端 API: http://localhost:${PORT}/api/analyze
    🌐 前端页面: http://localhost:${PORT}
  `);
});

关键注意事项

  1. 先跑通 MVP,再谈优化:不要一开始就想做全,先让两个 Agent 跑起来,有正向反馈再迭代
  2. 善用开源库:CCXT、LangChain.js 帮你省了几年的开发量,不要重复造轮子
  3. 数据安全第一:永远不要把 API Key 上传到 GitHub,本地测试用环境变量
  4. 敬畏市场:这只是一个技术原型,不要直接用于实盘交易!实盘前必须经过严格的回测和模拟盘验证

需要我帮你深入实现其中某个具体模块(比如链上分析 Agent 或 LangGraph 并行工作流)吗?