图片来源网络,侵权联系删。

文章目录
- [1. 引言](#1. 引言)
- [2. MCP 核心机制与 Web 技术栈的深度映射](#2. MCP 核心机制与 Web 技术栈的深度映射)
-
- [2.1 MCP 工作流程(Mermaid)](#2.1 MCP 工作流程(Mermaid))
- [3. 系统设计:基于 MCP 的股票分析助手架构](#3. 系统设计:基于 MCP 的股票分析助手架构)
-
- [3.1 功能需求](#3.1 功能需求)
- [3.2 工具定义(MCP Tool Schema)](#3.2 工具定义(MCP Tool Schema))
- [4. 工程实现:Java 后端 + Vue 前端全栈开发](#4. 工程实现:Java 后端 + Vue 前端全栈开发)
-
- [4.1 后端:Spring Boot 实现 MCP Agent 编排器](#4.1 后端:Spring Boot 实现 MCP Agent 编排器)
- [4.2 前端:Vue 3 展示分析结果](#4.2 前端:Vue 3 展示分析结果)
- [5. 生产级优化:提升可靠性、性能与安全性](#5. 生产级优化:提升可靠性、性能与安全性)
-
- [5.1 防幻觉:强制数据驱动回答](#5.1 防幻觉:强制数据驱动回答)
- [5.2 性能优化](#5.2 性能优化)
- [5.3 安全性](#5.3 安全性)
- [6. 总结与延伸:从股票助手到通用 MCP 平台](#6. 总结与延伸:从股票助手到通用 MCP 平台)
1. 引言

在 Web 开发中,我们早已习惯通过 API 获取数据、处理逻辑、渲染界面。而 MCP(Model Context Protocol)正是将这一范式扩展到 AI Agent 领域的标准协议------它让 LLM 能像调用 RESTful 接口一样,安全、可靠地使用外部工具。
对于有 Java/Node.js + Vue/React 经验的开发者来说,构建一个生产级股票分析助手不再是"AI 黑魔法",而是一次熟悉的全栈工程实践:
- 用户提问 → Agent 理解意图 → 调用金融 API → 分析数据 → 生成结构化报告 → 前端可视化
本文将基于 MCP 思想,手把手带你从零实现一个支持多工具调用、上下文记忆、防幻觉输出的股票分析系统,并提供完整可运行的代码示例。
2. MCP 核心机制与 Web 技术栈的深度映射

MCP 的本质是为 LLM 提供标准化的"操作系统接口",其三大核心组件与 Web 开发高度对应:
| MCP 概念 | Web 开发类比 | 作用 |
|---|---|---|
| Context(上下文) | HTTP Session / JWT Payload | 存储用户身份、对话历史、临时状态 |
| Tool(工具) | RESTful API / gRPC 服务 | 封装外部能力(如查股价、读新闻) |
| Protocol(协议) | OpenAPI Spec / JSON Schema | 定义工具输入/输出格式,确保类型安全 |
✅ 关键优势:Web 开发者无需学习新范式,只需将现有工程经验迁移到 Agent 场景。
2.1 MCP 工作流程(Mermaid)
News_API Financial_API MCP_Agent Backend Frontend User News_API Financial_API MCP_Agent Backend Frontend User "特斯拉最近一周表现如何?" POST /analyze { query: "...", sessionId: "abc" } 初始化上下文 + 注册工具 解析意图 → 需调用 get_stock_price & get_news GET /price?symbol=TSLA&days=7 返回股价数据 GET /news?symbol=TSLA&limit=3 返回新闻列表 基于数据生成结构化分析 { "summary": "...", "trend": "up", "confidence": 0.85 } 返回 JSON 渲染图表 + 文字结论
3. 系统设计:基于 MCP 的股票分析助手架构

3.1 功能需求
支持以下自然语言查询:
- "苹果公司最近股价走势?"
- "比较英伟达和 AMD 的基本面"
- "特斯拉有负面新闻吗?"
系统需具备:
- 实时股价获取(Alpha Vantage)
- 新闻情感分析(NewsAPI + LLM)
- 防幻觉机制(仅基于数据回答)
- 结构化输出(前端可直接解析)
3.2 工具定义(MCP Tool Schema)
json
// tools/stock_tools.json
[
{
"name": "get_stock_price_history",
"description": "获取某股票过去N天的收盘价",
"input_schema": {
"type": "object",
"properties": {
"symbol": { "type": "string", "description": "股票代码,如 AAPL" },
"days": { "type": "integer", "default": 7, "minimum": 1, "maximum": 30 }
},
"required": ["symbol"]
},
"output_schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": { "type": "string", "format": "date" },
"close": { "type": "number" }
}
}
}
},
{
"name": "get_company_news_with_sentiment",
"description": "获取某公司最近新闻及其情感倾向",
"input_schema": {
"type": "object",
"properties": {
"symbol": { "type": "string" },
"limit": { "type": "integer", "default": 5 }
},
"required": ["symbol"]
},
"output_schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": { "type": "string" },
"url": { "type": "string", "format": "uri" },
"sentiment": { "type": "string", "enum": ["positive", "neutral", "negative"] }
}
}
}
}
]
🔍 这相当于 Web 后端的 OpenAPI 文档,Agent 会据此安全调用工具。
4. 工程实现:Java 后端 + Vue 前端全栈开发

4.1 后端:Spring Boot 实现 MCP Agent 编排器
java
// McpAgentService.java
@Service
public class McpAgentService {
private final RestTemplate restTemplate;
private final OpenAiService openAiService; // 使用官方 SDK 或 LangChain4j
public StockAnalysisResponse analyze(String sessionId, String userQuery) {
// 1. 加载上下文(含历史对话)
McpContext context = contextStore.load(sessionId);
context.addUserMessage(userQuery);
// 2. 注册工具(实际项目中可动态加载)
context.registerTool("get_stock_price_history", this::fetchStockPrice);
context.registerTool("get_company_news_with_sentiment", this::fetchNewsWithSentiment);
// 3. 构建系统提示词(含工具说明)
String systemPrompt = """
你是一名专业金融分析师,请严格遵守:
- 仅基于工具返回的数据回答
- 若数据不足,回答"信息不足"
- 输出必须为以下 JSON 格式:
{"summary":"...","recommendation":"hold","confidence":0.8}
""" + context.getToolDescriptions();
// 4. 调用 LLM(启用 function calling)
ChatCompletionResult result = openAiService.createChatCompletion(
ChatCompletionRequest.builder()
.model("gpt-4o")
.messages(context.getMessagesForLLM(systemPrompt))
.tools(context.getOpenAIToolDefinitions())
.toolChoice("auto")
.build()
);
// 5. 执行工具调用(如有)
if (result.hasToolCalls()) {
for (ToolCall call : result.getToolCalls()) {
Object output = context.executeTool(call);
context.addToolResponse(call.getId(), output);
}
// 二次调用生成最终回答
result = openAiService.createChatCompletion(...); // 传入更新后的上下文
}
// 6. 保存上下文并返回结构化结果
contextStore.save(sessionId, context);
return parseJsonToResponse(result.getMessage().getContent());
}
private Object fetchStockPrice(Map<String, Object> args) {
String symbol = (String) args.get("symbol");
int days = (int) args.getOrDefault("days", 7);
// 调用 Alpha Vantage API
String url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=%s&apikey=%s"
.formatted(symbol, apiKey);
JsonNode response = restTemplate.getForObject(url, JsonNode.class);
// 解析并返回最近 days 天的数据(略)
return extractedData;
}
}
4.2 前端:Vue 3 展示分析结果
vue
<!-- StockAnalyzer.vue -->
<template>
<div class="analyzer">
<input v-model="query" @keyup.enter="analyze" placeholder="例如:英伟达值得投资吗?" />
<button @click="analyze">分析</button>
<div v-if="result" class="result">
<h2>分析摘要</h2>
<p>{{ result.summary }}</p>
<div class="metrics">
<span class="recommendation" :class="result.recommendation">
{{ result.recommendation.toUpperCase() }}
</span>
<span class="confidence">置信度: {{ (result.confidence * 100).toFixed(0) }}%</span>
</div>
<h3>相关新闻</h3>
<ul class="news-list">
<li v-for="news in result.news" :key="news.url">
<a :href="news.url" target="_blank">{{ news.title }}</a>
<span class="sentiment" :class="news.sentiment">{{ news.sentiment }}</span>
</li>
</ul>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import axios from 'axios'
const query = ref('')
const result = ref(null)
const sessionId = localStorage.getItem('session') || (localStorage.setItem('session', Date.now().toString()), Date.now().toString())
const analyze = async () => {
const res = await axios.post('/api/stock/analyze', {
query: query.value,
sessionId
})
result.value = res.data // 包含 summary, recommendation, confidence, news
}
</script>
<style scoped>
.recommendation.buy { color: green; font-weight: bold; }
.recommendation.sell { color: red; font-weight: bold; }
.recommendation.hold { color: orange; }
.sentiment.positive { color: green; }
.sentiment.negative { color: red; }
</style>
5. 生产级优化:提升可靠性、性能与安全性

5.1 防幻觉:强制数据驱动回答
在系统提示词中明确约束:
"你必须仅基于工具返回的数据生成回答。禁止猜测、编造或引用外部知识。若工具未返回有效数据,请回答'当前无足够信息进行分析'。"
5.2 性能优化
- 缓存 :使用 Redis 缓存
get_stock_price_history(AAPL, 7),TTL=5分钟 - 限流:对高频用户限制每分钟 3 次分析请求(类似 Web API 限流)
- 异步:复杂分析可转为后台任务,前端轮询结果
5.3 安全性
- 输入校验 :后端校验
symbol是否为合法股票代码(正则:^[A-Z]{1,5}$) - API Key 隔离:金融 API Key 不暴露给前端,由后端代理调用
- 日志脱敏:记录日志时移除敏感用户信息
6. 总结与延伸:从股票助手到通用 MCP 平台

通过本次实战,我们验证了:
✅ MCP 是 Web 开发者构建 Agent 的理想范式
✅ 股票分析助手 = 微服务 + 智能路由 + 结构化输出
✅ 工程化思维 > AI 理论深度
下一步建议
- 扩展工具集:接入财报 PDF 解析(LLM + PyPDF)、技术指标计算(TA-Lib)
- 支持多 Agent 协作:一个负责数据,一个负责风险评估,一个生成报告
- 部署到生产环境:使用 Docker + Kubernetes + Prometheus 监控
推荐资源
- 📊 Alpha Vantage 免费金融 API
- 🧠 LangChain4j(Java 版 LangChain)
- 📚 《Building Applications with LLMs》(O'Reilly,2025)
- 🌐 开源参考:LangChain Finance Agent Example
🌟 记住:你不是在"做 AI 项目",而是在"用 AI 升级你的 Web 工程能力"。
