Spring-AI-Alibaba初体验(调用Streamable-http MCP Server)_spring ai alibaba
2023年LLM兴起之后,发展到2025年各家技术公司都推出了自家基于AI的各种实现。Alibaba作为中文互联网公司的巨头之一,其推出的Spring-AI-Alibaba备受关注,下面就Spring-AI-Alibaba的初体验总一些个人简陋的总结,希望大佬批评指正。
以下文章和代码参考了:
> https://github.com/springaialibaba/spring-ai-alibaba-examples
> https://github.com/modelcontextprotocol/java-sdk
> Gemini - PydanticAI
Spring-AI-Alibaba 初体验
1. 易用性强
Spring AI Alibaba依托Spring框架,使用熟悉的Spring注解和配置方式,极大降低了AI功能集成的门槛。开发者可以像使用普通Spring组件一样调用AI服务,体验流畅。
2. 示例丰富
官方提供了大量示例项目,涵盖文本生成、图像识别、自然语言处理等多种AI能力,帮助用户快速理解和应用AI技术。
3. 与阿里云AI能力深度集成
该框架整合了阿里云多种AI能力,支持调用阿里云开放的AI接口,便于在企业级应用中快速部署智能功能。
4. 社区活跃,(中文)文档完善
该项目在GitHub上有较多star和fork,社区活跃,且官网提供了详细文档和教程,便于学习和交流。
# 1.mcp_server_see.py 主程序,以Streamable-http方式启动,部署在阿里云上,由Spring-AI-Alibaba调用。提供的主要工具有run_cmd(执行shell命令),远程调用浏览器进行截图保存等。
# 1.mcp_server_see.py 主程序,以Streamable-http方式启动,部署在阿里云上。# MCP = modle control protocol, invented by Anthropic# This is a demo of how to use MCP with a custom tool# and run it with FastMCP, a fast implementation of MCP.# The tool will return the host information in JSON format.# The MCP server will run and listen for requests, responding with the host information.# The server can be run with different transports, such as stdio or SSE.from starlette.applications import Starlettefrom starlette.routing import Mount, Hostimport uvicornfrom mcp.server.fastmcp import FastMCPimport tools# Create a FastMCP instance with a namemcp = FastMCP(\"host info mcp\", host=\"0.0.0.0\", port=8000, stateless_http=True)# Add the custom tool to the MCP instancemcp.add_tool(tools.webpage_capture)mcp.add_tool(tools.run_cmd,name=\"run_cmd\",description=\"run a command in the host\")@mcp.tool()def system_info(): \"\"\"Get system information and return it as a JSON string.\"\"\" print(f\"Running system_info()\") import platform import json system_info = { \"system\": platform.system(), \"node\": platform.node(), \"release\": platform.release(), \"version\": platform.version(), \"machine\": platform.machine(), \"processor\": platform.processor(), \"platform\": platform.platform(), } return json.dumps(system_info, indent=2)def main(): mcp.run(transport=\"streamable-http\")if __name__ == \"__main__\": main()# 2. tools.py, 由mcp server引入的工具import subprocessdef webpage_capture(url) -> str: \"\"\"capture the webpage and return the screen short path saved in the host Returns: str: the screen short path saved in the host \"\"\" received_url = url print(f\"running webpage_capture({received_url})\") # 打印接收到的URL(可选) if received_url: print(f\"Received URL: {received_url}\") # call node.js script to capture the webpage try: result = subprocess.run( [\'node\', \'capture_url.js\', received_url], capture_output=True, text=True, check=True ) return result.stdout.strip() except subprocess.CalledProcessError as e: return f\"Error capturing webpage: {e.stderr.strip()}\"def run_cmd(command: str) -> str: \"\"\"run a Linux command in the host. such as, run a command like `ls -l /home/user` to list the files in the directory \"/home/user\". The command can be any valid Linux command. or run a command like `cd /home/user && ls -l` to change directory to \"/home/user\" and list the files in the directory. or run a command like `curl https://www.example.com` to fetch the content of a webpage. or run a command like `python -c \"print(1+1)\"` to run a Python script, it will return \"2\" or run a python command like `python -c \"print(\'strawberry\'.count(\'r\'))\"` to count the number of occurrences of the letter \'r\' in the string \"strawberry\", it will return \"3\". Args: command (str): the command to run Returns: str: the output of the command \"\"\" print(f\"Running command: {command}\") # command_list = command.split() if isinstance(command, str) else command # if not isinstance(command, list): # return \"Error: command must be a string or a list of strings.\" try: result = subprocess.run( command, shell=True, capture_output=True, text=True, check=True ) return result.stdout.strip() except subprocess.CalledProcessError as e: return f\"Error: {e.stderr.strip()}\" if __name__ == \'__main__\': # print(webpage_capture(\"https://www.baidu.com\")) run_cmd(\"ls -lrt . | wc -l \") # Example command to list files in a directory
/// const puppeteer = require(\'puppeteer\');// 从命令行参数中获取URLconst args = process.argv.slice(2);const url = args[0];// 获取中国时区(东八区)时间戳字符串function getCnTimeISOString() { const date = new Date(); const utcTime = date.getTime() + (date.getTimezoneOffset() * 60000); // 转为 UTC 时间 const cnTime = new Date(utcTime + (3600000 * 8)); // 加上 8 小时得到北京时间 return cnTime.toISOString().replace(/[^0-9]/g, \'\');}if (!url) { console.error(\'❌ 请提供一个URL作为参数!\'); console.log(\'示例: node capture_url.js https://www.example.com\'); process.exit(1);}(async () => { const browser = await puppeteer.launch({ headless: true, // 改成 true 就不显示窗口 args: [ \'--no-sandbox\', \'--disable-setuid-sandbox\', \'--disable-blink-features=AutomationControlled\', // \'--proxy-server=http://127.0.0.1:8086\' ], }); const page = await browser.newPage(); // 设置类似真实浏览器的 UA await page.setUserAgent( \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36\' ); // 访问网站 try { // await page.goto(url, { waitUntil: \'networkidle2\' }); await page.goto(url); } catch (err) { console.error(\'页面加载失败:\', err.message); await browser.close(); process.exit(1); } // 处理URL,用于文件名 const urlForFilename = url .replace(/^https?:\\/\\//, \'\') // 去除 \"http://\" 或 \"https://\" .replace(/\\//g, \'_\'); // 将 \"/\" 替换为 \"_\" // 截图查看效果 // 构建截图路径 // const screenshotPath = `images/${new Date().toISOString().replace(/[^0-9]/g, \'\')}_${urlForFilename}.png`; const timestamp = getCnTimeISOString(); const screenshotPath = `images/${timestamp}_${urlForFilename}.png`; await page.screenshot({ path: screenshotPath }); console.log(`${screenshotPath}`); await browser.close();})();
// 2. 通过Spring-AI-Alibaba的java客户端调用远程mcp Server
1. 在Spring Boot项目中引入Spring AI Alibaba依赖。
2. 配置阿里云AI相关的密钥和参数。
3. 注入`OpenAiClient`,调用对应的API方法。
4. 处理返回结果,实现业务逻辑。
org.springframework.ai spring-ai-autoconfigure-model-openai org.springframework.ai spring-ai-autoconfigure-model-chat-clientorg.springframework.boot spring-boot-starter-web com.alibaba.cloud.ai spring-ai-alibaba-core 1.0.0.1 com.alibaba.cloud.ai spring-ai-alibaba-mcp 1.0.0.1
// MCP 客户端配置@Configurationpublic class McpClientConfig { @Bean public McpSyncClient mcpSyncClient(McpClientProperties properties) { return new McpSyncClient(properties); }}// Tool请求@Data@AllArgsConstructor@NoArgsConstructorpublic class MyToolInput { private String message;}// 调用 Tool@Servicepublic class McpCallerService { private final McpSyncClient mcpSyncClient; public McpCallerService(McpSyncClient mcpSyncClient) { this.mcpSyncClient = mcpSyncClient; } public String callTool(String userMessage) { MyToolInput input = new MyToolInput(userMessage); ToolExecutionRequest request = ToolExecutionRequest.builder() .toolName(\"myTool\") .arguments(input) .build(); ToolExecutionResponse response = mcpSyncClient.call(request); return response.getResult().toString(); }}// Controller@RestController@RequestMapping(\"/mcp\")public class McpController { private final McpCallerService callerService; public McpController(McpCallerService callerService) { this.callerService = callerService; } @PostMapping(\"/call\") public ResponseEntity callMcpTool(@RequestBody Map payload) { String message = payload.get(\"message\"); String result = callerService.callTool(message); return ResponseEntity.ok(result); }}