ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在 mcp-for-beginners 中用 Rust 构建接入 LLM 的 MCP 客户端:从环境配置到工具调用全解析

在 mcp-for-beginners 中用 Rust 构建接入 LLM 的 MCP 客户端:从环境配置到工具调用全解析 教程文档人工智能【免费下载链接】mcp-for-beginnersThis open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.项目地址https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners点击查看免费下载导读本文以 mcp-for-beginners 课程中「创建带 LLM 的客户端」03-llm-client一节的 Rust 解决方案为主线讲解如何在 Rust 中把 MCP 服务器暴露的工具能力交给大语言模型LLM让用户用自然语言完成对 MCP 工具的调用。读完本文你将掌握 Rust 环境下 LLM 客户端的完整搭建流程配置 Microsoft Foundry 模型端点、通过 stdio 拉起 calculator MCP 服务器、拉取并转换工具清单、驱动 LLM 发起函数调用function calling最终看到Calling tool: add与计算结果输出。为什么客户端需要接入 LLM在前面的课程02-client中客户端虽然已经能够连接服务器并显式列出 tools、resources 和 prompts但这种「手动点名调用」的交互方式并不实用。用户期待的是用自然语言与系统对话而不是关心底层是否使用 MCP 承载能力。解决方案就是在客户端一侧接入 LLM把 MCP 服务器注册的能力及其 JSON Schema 转换成 LLM 可以理解的形式让 LLM 自主决定调用哪个工具、传入什么参数。整体交互流程如下与 MCP 服务器建立连接本示例通过 stdio 拉起 calculator 服务器进程列出服务器的 capabilities、工具清单并保存其 schema将保存的能力与 schema 转换成 LLM 的函数调用格式把用户提示词连同工具清单交给 LLM由 LLM 决定是否触发工具调用再经由 MCP 客户端回传结果。Rust 解决方案的完整代码位于 solution/rust/src/main.rs工程配置见 Cargo.toml。运行前置条件本示例是 Rust 编写的 LLM 客户端需要满足以下前置条件已安装 Rust toolchaincargo与rustc可用并确保cargo在 PATH 中一个可通过 Azure OpenAI v1 端点访问的 Microsoft Foundry 模型部署即已部署的活跃模型如gpt-5.1一个可运行的 calculator MCP 服务器。若尚未创建请先完成 01-first-server 课程其 Rust 实现位于 01-first-server/solution/rust服务器通过 stdio 暴露一个add工具。提示课程主文档03-llm-client/README.md中其他语言的客户端方案各不相同——Java 客户端示例仍通过传统 HTTPSSE 传输并针对 MCP2025-11-25SDK新的远程客户端应使用2026-07-28兼容 SDK 与 Streamable HTTP。Rust 方案则使用 rmcp 的客户端特性与子进程传输transport-child-process。第一步配置 Microsoft Foundry 环境变量客户端通过 Azure OpenAI v1 端点调用已部署的模型。运行前必须设置三个环境变量# zsh/bash export AZURE_OPENAI_ENDPOINThttps://resource-name.openai.azure.com export AZURE_OPENAI_API_KEYapi-key export AZURE_OPENAI_DEPLOYMENTgpt-5.1PowerShell 下使用对应语法# PowerShell $env:AZURE_OPENAI_ENDPOINT https://resource-name.openai.azure.com $env:AZURE_OPENAI_API_KEY api-key $env:AZURE_OPENAI_DEPLOYMENT gpt-5.1三个变量的作用与取值要点如下变量用途说明AZURE_OPENAI_ENDPOINT资源端点形如https://resource-name.openai.azure.com客户端会在此基础上拼接/openai/v1AZURE_OPENAI_API_KEY访问密钥用于 Azure OpenAI 兼容端点的鉴权AZURE_OPENAI_DEPLOYMENT部署名称传给 LLM 的model参数注意它是部署名而非底层模型名二者可能不同在源码中AZURE_OPENAI_DEPLOYMENT是可选的缺省值为gpt-5.1let model std::env::var(AZURE_OPENAI_DEPLOYMENT) .unwrap_or_else(|_| gpt-5.1.to_string());见 main.rs选择模型前建议先查阅 Microsoft Foundry 的模型退役时间表如果部署名与底层模型名不一致API 调用中必须使用部署名。第二步构建示例进入 Rust 解决方案目录后执行cargo build依赖声明位于 Cargo.toml核心依赖如下[dependencies] async-openai { version 0.29.0, features [byot] } rmcp { version 1.4.0, features [client, transport-child-process] } serde_json 1.0.141 tokio { version 1.46.1, features [rt-multi-thread] }各依赖的角色async-openai社区维护的 OpenAI API Rust 客户端。官方并未提供 Rust 版 OpenAI 库这是社区中常用的替代方案。启用byotbring your own tools特性以支持自定义工具定义function callingrmcpRust 实现的 MCP 客户端/服务端库启用client与transport-child-process特性用于建立 MCP 客户端并管理子进程传输serde_json处理工具清单与 LLM 响应中的 JSON 数据tokio异步运行时rt-multi-thread。第三步运行示例并观察工具调用cargo run程序启动后依次完成以下动作拉起 calculator MCP 服务器进程、获取工具列表、调用部署模型、由模型决定调用add工具。预期输出中应能看到工具调用日志例如⚡ Calling tool: add以及该次调用的计算结果。源码级解析main.rs 如何串起「MCP LLM」链路接下来按执行顺序拆解 main.rs 的实现说明每一步与文档命令的对应关系。1. 初始化用户消息与 OpenAI 客户端let mut messages vec![json!({role: user, content: What is the sum of 3 and 2?})]; let endpoint std::env::var(AZURE_OPENAI_ENDPOINT)?; let api_key std::env::var(AZURE_OPENAI_API_KEY)?; let openai_client Client::with_config( OpenAIConfig::new() .with_api_base(format!({}/openai/v1, endpoint.trim_end_matches(/))) .with_api_key(api_key), );见 main.rs要点messages保存完整的对话历史起始是一条用户消息后续会不断追加助手消息与工具结果消息endpoint末尾的多余斜杠会被trim_end_matches(/)去除再拼上/openai/v1得到 Azure OpenAI 兼容端点OpenAIConfig同时注入 API Key用于后续completions().create_byot(...)请求鉴权。2. 以子进程方式启动 MCP 服务器let server_dir std::path::Path::new(env!(CARGO_MANIFEST_DIR)) .parent() // solution .and_then(|p| p.parent()) // 03-llm-client .and_then(|p| p.parent()) // 03-GettingStarted .map(|p| p.join(01-first-server/solution/rust)) .expect(Failed to resolve server directory path); let mcp_client () .serve( TokioChildProcess::new(Command::new(cargo).configure(|cmd| { cmd.arg(run).current_dir(server_dir); })) .map_err(RmcpError::transport_creation::TokioChildProcess)?, ) .await?;见 main.rs这里通过CARGO_MANIFEST_DIR向上回溯定位到课程根目录下的01-first-server/solution/rust然后用cargo run以子进程方式启动服务器建立 stdio 传输。也就是说cargo run一条命令会同时拉起服务器进程与客户端逻辑——服务器端add工具的实现见 01-first-server/solution/rust/src/main.rs其核心定义如下#[tool(description Adds a and b)] async fn add( self, Parameters(CalculatorRequest { a, b }): ParametersCalculatorRequest, ) - String { (a b).to_string() }参数结构CalculatorRequest { a: f64, b: f64 }通过schemars::JsonSchema自动生成 JSON Schema这正是后续format_tools所需inputSchema的来源。3. 获取 MCP 工具清单let tools mcp_client.list_tools(Default::default()).await?;见 main.rs返回的ListToolsResult中包含服务器注册的add工具及其 JSON Schema。4. 把 MCP 工具转换为 LLM 可理解的格式MCP 的工具定义不能直接交给 LLM需要转换成 OpenAI 兼容的 function calling 结构。format_tools完成这一转换async fn format_tools(tools: ListToolsResult) - ResultVecValue, Boxdyn Error { let tools_json serde_json::to_value(tools)?; let Some(tools_array) tools_json.get(tools).and_then(|t| t.as_array()) else { return Ok(vec![]); }; let formatted_tools tools_array .iter() .filter_map(|tool| { let name tool.get(name)?.as_str()?; let description tool.get(description)?.as_str()?; let schema tool.get(inputSchema)?; Some(json!({ type: function, function: { name: name, description: description, parameters: { type: object, properties: schema.get(properties).unwrap_or(json!({})), required: schema.get(required).unwrap_or(json!([])) } } })) }) .collect(); Ok(formatted_tools) }见 main.rs转换规则要点每个工具被映射为{type: function, function: {...}}结构从inputSchema中提取properties参数属性与required必填参数两个关键字段缺失properties或required时分别回退为空对象与空数组保证格式完整性。5. 调用 LLM 并让其决定是否调用工具async fn call_llm( client: ClientOpenAIConfig, messages: [Value], tools: ListToolsResult, ) - ResultValue, Boxdyn Error { let model std::env::var(AZURE_OPENAI_DEPLOYMENT) .unwrap_or_else(|_| gpt-5.1.to_string()); let response client .completions() .create_byot(json!({ messages: messages, model: model, tools: format_tools(tools).await?, })) .await?; Ok(response) }见 main.rs请求体同时携带对话历史、部署名model与格式化后的tools数组LLM 根据用户问题决定是否返回tool_calls。6. 处理 LLM 响应并回传工具结果process_llm_response是整个回路的核心解析choices[0].message若含content则打印模型文本若含tool_calls则逐条执行if let Some(tool_calls) message.get(tool_calls).and_then(|tc| tc.as_array()) { messages.push(message.clone()); // Add assistant message for tool_call in tool_calls { let (tool_id, name, args) extract_tool_call_info(tool_call)?; println!(⚡ Calling tool: {}, name); let result mcp_client .call_tool(CallToolRequestParam { name: name.into(), arguments: serde_json::from_str::Value(args)?.as_object().cloned(), }) .await?; messages.push(json!({ role: tool, tool_call_id: tool_id, content: serde_json::to_string_pretty(result)? })); } let response call_llm(openai_client, messages, mcp_tools).await?; Box::pin(process_llm_response( response, mcp_client, openai_client, mcp_tools, messages, )) .await?; }见 main.rs关键细节工具调用日志⚡ Calling tool: add即文档中「Calling tool: add」期望输出的来源每次工具调用后以role: tool消息携带tool_call_id与序列化结果追加进对话历史随后递归调用call_llm把工具结果交还给模型让模型基于真实计算结果生成最终答复实现完整的「思考—调用—再思考」循环。extract_tool_call_info负责从工具调用对象中拆出id、function.name与function.argumentsJSON 字符串供call_tool使用见 main.rs。与课程整体脉络的对应关系本 Rust 方案完整覆盖了课程03-llm-client/README.md中「创建带 LLM 的客户端」的全部四个步骤连接服务器子进程 stdio、列出 capabilitieslist_tools、转换 schemaformat_tools、处理用户提示词call_llmprocess_llm_response。与 TypeScript、Python、.NET、Java 等兄弟方案相比各语言实现分别位于 solution 目录Rust 方案的特点是以rmcp直接内嵌启动服务器进程无需预先单独启动借助async-openai的byot特性以原始 JSON 形式构建工具定义与请求体不依赖框架层面的自动绑定循环逻辑显式可见方便理解 function calling 协议本身。验证与排错要点运行cargo run后若未出现工具调用日志首先确认AZURE_OPENAI_ENDPOINT、AZURE_OPENAI_API_KEY已正确导出且AZURE_OPENAI_DEPLOYMENT对应的部署处于可用状态若服务器路径解析失败程序会输出Failed to resolve server directory path请确认在 solution/rust 目录下运行CARGO_MANIFEST_DIR的路径推导依赖该相对布局修改 Cargo.toml 后需重新cargo build与 calculator 服务器相关的工具定义、JSON Schema 生成细节可对照 01-first-server/solution/rust/src/main.rs 阅读add工具的入参{a, b}即CalculatorRequest的字段。至此一个「自然语言提问 → LLM 决策 → MCP 工具执行 → 结果回传模型」的完整闭环已经在 Rust 中跑通你可以在此基础上替换为任意 MCP 服务器与工具集扩展自己的 LLM Agent 应用。赞分享教程文档人工智能【免费下载链接】mcp-for-beginnersThis open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.项目地址https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners点击查看免费下载相关推荐mcp-for-beginners 实战使用 .NET 构建接入 LLM 的 MCP 客户端mcp for beginners 实战使用 .NET 构建接入 LLM 的 MCP 客户端 在本篇指南中你将基于 mcp for beginners 开源教程文档人工智能mcp-for-beginners 实战为 MCP 客户端接入 LLM构建自然语言驱动的工具调用闭环TypeScript / Python / .NET / Java / Rustmcp for beginners 实战为 MCP 客户端接入 LLM构建自然语言驱动的工具调用闭环TypeScript / Python / .NET教程文档人工智能mcp-for-beginners 实战为 Python MCP 客户端接入 LLM让用户用自然语言调用 MCP 工具mcp for beginners 实战为 Python MCP 客户端接入 LLM让用户用自然语言调用 MCP 工具 本文基于开源课程 mcp for b教程文档人工智能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表