三天上线AI旅游规划产品:MCP协议+Next.js+GPT-4o实战
1. 为什么我盯上了MCP这条技术路线先说清楚背景。我一个人三天时间从零开始做了一个AI旅游规划产品并且把它推上线了。这不是标题党产品现在能跑用户输入目的地、天数、预算和偏好它会自动生成一份带日程、交通建议、住宿区域推荐和预算拆解的完整旅行方案。整个项目的技术底座是MCP协议加Next.js加GPT-4o开发周期压缩到72小时以内。很多人第一次听到MCP会问“mcp是什么”。用一句话解释MCPModel Context Protocol是一套让大模型和外部工具、数据源之间标准化对话的协议。你可以把它理解成AI世界的USB-C接口——以前每接一个工具就要写一套适配代码现在只要工具端实现了MCP ServerAI端实现了MCP Client两边就能即插即用。这个类比不精确但足够让你理解它的价值所在。我为什么选MCP而不是传统的Function Calling硬编码原因很实际。旅游规划这个场景天然需要串联多个数据源景点信息、天气、地图距离、酒店价格区间、餐厅推荐。如果每个数据源都手写function schema光是维护参数格式就能把我三天时间吃光。而MCP把这些能力抽象成标准化的工具调用我只需要关注“调用哪个工具”和“怎么组织结果”不用关心底层接口长什么样。这个产品适合谁参考如果你是独立开发者想快速验证一个AI Agent产品的可行性这套方案可以直接抄。如果你是有前端基础但没怎么碰过Agent开发的工程师MCP的上手曲线比你想的平缓。如果你只是对AI旅游规划这个方向感兴趣也可以看看我是怎么把一个大而全的需求拆成三天能交付的MVP的。提示MCP目前生态还在快速演进不同客户端对协议版本的支持程度不一样。动手前先确认你用的SDK版本和Server端的兼容性否则会在调试上浪费大量时间。2. 三天上线的整体架构与选型逻辑2.1 为什么是Next.js而不是纯后端方案时间只有三天我不可能同时搞前端和后端两套工程。Next.js的App Router模式让我在一个项目里同时写页面和API Route部署时Vercel一键推上去省掉了服务器配置、Nginx反向代理、HTTPS证书这些琐事。对于一个人三天上线的目标来说任何需要额外运维的动作都是奢侈品。具体来说我用Next.js 14的App Router组织代码。前端页面负责收集用户输入和展示规划结果API Route负责跟GPT-4o和MCP Server通信。流式输出用Vercel AI SDK的streamText能力用户能看到规划内容一个字一个字蹦出来体验上比等十秒然后一次性刷新好太多。这里有个选型细节值得展开。Vercel AI SDK原生支持工具调用tool calling而MCP的工具发现和调用可以封装成AI SDK的tool定义。也就是说我不需要自己写一套MCP Client的底层通信逻辑而是把MCP Server暴露的工具转成AI SDK能识别的格式剩下的交给SDK处理。这个转换层大概花了半天时间调试但后面所有工具接入都变得极其顺畅。2.2 MCP Server的拆分策略旅游规划涉及的能力我拆成了三个MCP Server景点与活动Server负责根据目的地和偏好返回景点列表、开放时间、建议游玩时长交通与地理Server负责计算景点间距离、推荐交通方式、估算通勤时间预算与住宿Server负责根据预算档位推荐住宿区域、拆解各项花费占比为什么拆成三个而不是一个大Server因为MCP的设计哲学就是每个Server专注一个领域工具描述清晰、参数边界明确。如果全塞在一起GPT-4o在选择工具时容易混淆比如把“计算距离”的参数传给“查景点”的工具。拆开之后每个Server的工具数量控制在3到5个模型选择准确率明显提升。注意MCP Server的命名和工具描述直接影响模型调用准确率。工具名要用动词开头描述要写清楚“什么时候该用这个工具”而不是只写“这个工具能做什么”。2.3 GPT-4o在链路中的角色定位GPT-4o在这个产品里承担两个职责一是理解用户自然语言输入并提取结构化参数目的地、天数、预算、偏好标签二是根据MCP工具返回的数据组织成人类可读的旅行方案。它不直接生成景点信息因为大模型编造景点开放时间和门票价格是出了名的不可靠。所有事实性数据必须来自MCP工具GPT-4o只负责调度和表达。这个分工很关键。我见过不少AI旅游产品让模型直接“编”行程结果用户到了现场发现景点闭馆或者餐厅不存在。MCP的价值就在于把“事实查询”和“语言组织”分开模型只做它擅长的事。3. 核心环节的实操细节与参数配置3.1 MCP Client的初始化与工具发现在Next.js的API Route里初始化MCP Client核心代码如下import { Client } from modelcontextprotocol/sdk/client/index.js; import { StdioClientTransport } from modelcontextprotocol/sdk/client/stdio.js; const transport new StdioClientTransport({ command: node, args: [./mcp-servers/spots-server/index.js], }); const client new Client( { name: travel-planner, version: 1.0.0 }, { capabilities: {} } ); await client.connect(transport); const { tools } await client.listTools();这段代码做了三件事建立与MCP Server的传输通道、初始化Client实例、拉取Server暴露的工具列表。listTools()返回的tools数组里每个工具都有name、description和inputSchema这三个字段直接决定了GPT-4o能不能正确调用。我踩过的一个坑StdioClientTransport在Serverless环境比如Vercel的Edge Function里跑不起来因为Serverless不允许长期运行的子进程。解决办法是把MCP Server部署成独立的HTTP服务用SSEClientTransport或者Streamable HTTP Transport连接。这个改动花了我大概两个小时但换来的是部署后稳定运行。3.2 把MCP工具转成GPT-4o能识别的格式MCP的工具定义和OpenAI的function calling格式不完全一样需要做一层转换。核心映射关系是MCP的inputSchema直接对应OpenAI的parametersMCP的description对应OpenAI的description工具名保持一致。const openAITools tools.map((tool) ({ type: function as const, function: { name: tool.name, description: tool.description, parameters: tool.inputSchema, }, }));转换本身不复杂但有个细节要注意MCP的inputSchema是JSON Schema格式而OpenAI对JSON Schema的支持有一些限制比如不支持oneOf和anyOf的嵌套。如果你的工具参数用了这些结构需要在转换时做扁平化处理。我的做法是尽量让工具参数保持简单用枚举值代替联合类型用可选字段代替条件分支。3.3 流式输出与工具调用的协同流式输出和工具调用同时存在时处理逻辑会复杂一些。用户看到的是文字在流式生成但中间模型可能突然决定调用一个工具这时候流会暂停等工具返回结果后再继续。Vercel AI SDK的streamText已经处理了这种情况我只需要在onStepFinish回调里记录每一步的工具调用情况方便调试。const result streamText({ model: openai(gpt-4o), messages, tools: openAITools, maxSteps: 8, onStepFinish: ({ toolCalls, toolResults }) { console.log(工具调用:, toolCalls); console.log(工具结果:, toolResults); }, });maxSteps设成8是一个经验值。旅游规划通常需要调用5到7次工具查景点、查距离、查住宿、查预算等设太小会导致规划不完整设太大又浪费token。实测下来8步能覆盖90%以上的规划请求。提示工具调用的顺序会影响最终方案质量。我建议在System Prompt里明确告诉模型“先查景点再算距离最后算预算”这样生成的行程在逻辑上更连贯。3.4 System Prompt的设计要点System Prompt是决定输出质量的关键。我改了大概十几版最终稳定下来的结构是这样的你是一个专业的旅行规划师。你的任务是帮用户生成一份可执行的旅行方案。 工作流程 1. 先从用户输入中提取目的地、天数、预算档位、偏好标签 2. 调用景点工具获取候选景点列表 3. 调用距离工具计算景点间通勤时间 4. 根据通勤时间把景点分配到每天每天不超过4个景点 5. 调用住宿工具推荐住宿区域 6. 调用预算工具拆解花费 7. 用中文输出完整方案包含每日日程、交通建议、住宿推荐、预算表 约束 - 不要编造工具未返回的信息 - 如果工具返回空结果如实告知用户并建议调整偏好 - 每天的行程要留出用餐和休息时间 - 预算拆解要具体到交通、住宿、餐饮、门票四项这个Prompt里最重要的是“工作流程”部分。它把模型的思考过程显式地规定下来减少了模型自由发挥导致的不稳定。另外“约束”部分也很关键明确禁止编造信息这是保证产品可信度的底线。4. 开发过程中踩过的坑与排查实录4.1 MCP Server启动超时第一次跑通链路时API Route调用MCP Server经常超时。排查后发现是StdioClientTransport启动子进程需要时间而Serverless函数的冷启动叠加子进程启动总耗时超过了默认超时限制。解决办法有两个一是把MCP Server改成HTTP服务常驻运行二是给Client连接设置更长的超时时间并加retry逻辑。我最终选了第一种因为常驻服务还能复用连接减少每次请求的握手开销。4.2 工具调用参数格式错误GPT-4o有时候会把日期参数写成“2024-01-01”有时候写成“Jan 1, 2024”导致MCP Server解析失败。这个问题不能靠改Prompt完全解决因为模型对日期格式的理解本身就不稳定。我的做法是在MCP Server端做参数归一化用日期解析库把各种格式统一转成ISO 8601。同时在工具描述里明确写“日期格式为YYYY-MM-DD”双管齐下后错误率降到几乎为零。4.3 流式输出中断用户反馈规划生成到一半突然停了。查日志发现是某个MCP工具返回的数据量太大超过了模型单次处理的token上限。解决办法是在MCP Server端做分页每次最多返回10条景点信息如果用户需要更多再调用一次。这个改动同时也提升了响应速度因为模型不用等一个巨大的JSON返回。4.4 常见问题速查表问题现象可能原因排查方向解决方案工具调用返回空Server未正确注册工具检查listTools返回确认Server启动日志无报错模型不调用工具工具描述不清晰查看工具description补充“何时使用”说明流式输出卡住工具返回数据过大检查工具返回体大小分页返回单次限10条部署后连接失败Serverless不支持子进程查看部署环境限制改用HTTP Transport预算计算偏差大模型自行估算检查是否调用了预算工具在Prompt中强制调用4.5 实操心得先跑通再优化三天时间做产品最大的敌人是完美主义。我第一天的目标是“链路能跑通”哪怕输出质量很差。第二天才优化Prompt和工具描述。第三天做UI和部署。如果第一天就纠结于输出格式好不好看大概率三天结束还在调Prompt。先让数据从用户输入流到最终输出再逐步替换每个环节的质量这个节奏对独立开发者来说非常重要。另一个心得是日志要打够。MCP的工具调用是黑盒模型为什么选这个工具不选那个只能通过日志推断。我在每个工具调用的入口和出口都打了日志记录参数和返回摘要。调试阶段这些日志帮我省了至少半天时间。5. 上线部署与后续扩展方向5.1 部署清单与检查项部署到Vercel的流程不复杂但有几个检查项必须过一遍环境变量OpenAI API Key、MCP Server的HTTP地址都要在Vercel后台配好MCP Server独立部署我用的Railway部署三个MCP Server每个都是轻量Node服务超时设置Vercel的Serverless函数默认10秒超时流式输出需要改成Edge Runtime或者升级Pro计划域名和HTTPSVercel自动处理不用操心上线后我监控了两天主要看两个指标规划生成成功率和平均生成时长。成功率稳定在95%以上失败的主要原因是用户输入太模糊比如只写“帮我规划一下”没写目的地模型无法提取参数。平均生成时长在12到18秒之间流式输出让用户感知的等待时间短很多。5.2 这个架构还能怎么扩展MCP的插件化特性让扩展变得很容易。如果想加“实时航班查询”只需要再写一个MCP Server暴露航班查询工具然后在Client端注册进去GPT-4o会自动发现新工具并在合适的时候调用。不需要改主流程代码这是MCP相比硬编码Function Calling最大的优势。另一个扩展方向是多Agent协作。现在的架构是单Agent串行调用工具如果规划复杂行程比如跨国多城市可以拆成“景点Agent”“交通Agent”“预算Agent”并行工作最后汇总。MCP协议天然支持这种多Server并行调用的模式只是需要在Client端做结果聚合。5.3 给想复现的朋友几个实在建议如果你打算照着这个思路做我的建议是先把MCP的官方文档过一遍理解Client和Server的通信模型。然后从一个最简单的MCP Server开始比如只提供一个echo工具跑通“模型调用工具并返回结果”的完整链路。这一步通了后面加工具只是重复劳动。工具描述要反复打磨。我每个工具的description至少改了五版每次都是发现模型调用错误后回去改。工具描述写得好模型调用准确率能到95%以上写得模糊准确率可能只有60%。这个投入产出比非常高。最后不要低估部署环节的时间。我原本以为部署半小时搞定实际花了将近半天主要卡在Serverless环境和MCP Server的兼容性上。如果你也用Vercel建议直接上Edge Runtime加HTTP Transport的方案少走弯路。我在实际使用中发现MCP生态的工具链还在快速迭代今天能跑的方案下个月可能就有更优解。保持关注官方SDK的更新但不要为了追新而重构已经稳定的链路。产品能跑、用户能用比技术栈先进一步重要得多。

相关新闻

智能体工程化落地:从ReAct架构到安全评测与业务接入

智能体工程化落地:从ReAct架构到安全评测与业务接入

这周的GitHub Trending中文周报翻下来,我的第一感受是:智能体这个领域正在换赛道。前几个月刷出来的还都是各种各样的聊天Demo、带WebUI的RAG玩具,这周开始明显不一样了——大量项目把目标写成了"稳定运行""可观测""…

2026/10/9 0:25:44 阅读更多 →
从Prompt到Context:AI Agent上下文工程实战指南

从Prompt到Context:AI Agent上下文工程实战指南

最开始做 AI Agent 的时候,我以为把 Prompt 写漂亮就完事了。结果第一个真实项目上线不到两天,就被打脸了:用户在对话里提到一个半小时前交代的关键信息,Agent 直接“失忆”,开始自己编造需求。我一开始怀疑是模型不行…

2026/10/9 0:25:44 阅读更多 →
多Agent集群实战:DeepAgents+MCP+A2A+Skills全解析

多Agent集群实战:DeepAgents+MCP+A2A+Skills全解析

1. 为什么单Agent做长任务必翻车:上下文断链与工具失控先讲个我自己的经历。半年前接了一个需求:做一个能自动完成"需求调研→技术验证→输出文章"的Agent。第一次的直觉做法特别简单粗暴——把一个Agent塞满所有系统提示词,让它按…

2026/10/9 0:25:44 阅读更多 →

最新新闻

Piik原生屏幕捕获实现:WGC、WebCodecs与跨平台采集架构解析

Piik原生屏幕捕获实现:WGC、WebCodecs与跨平台采集架构解析

Piik原生屏幕捕获实现:WGC、WebCodecs与跨平台采集架构解析 【免费下载链接】Piik Free, open-source screen sharing for private live streams with friends. Watch together in a browser or self-host Piik. 免费开源的私密屏幕共享,支持游戏直播、一…

2026/10/9 0:52:36 阅读更多 →
REA引擎选择三法:--provider参数、provider_id与REA_ANALYSIS_PROVIDER环境变量

REA引擎选择三法:--provider参数、provider_id与REA_ANALYSIS_PROVIDER环境变量

REA引擎选择三法:--provider参数、provider_id与REA_ANALYSIS_PROVIDER环境变量 【免费下载链接】rea Reverse engineer anything with agents, from app behavior down to native binaries. 项目地址: https://gitcode.com/GitHub_Trending/rea2/rea REA 是…

2026/10/9 0:52:36 阅读更多 →
Flutter迁移OpenHarmony实战:文章详情页从0到1完整记录

Flutter迁移OpenHarmony实战:文章详情页从0到1完整记录

1. 项目概述1.1 核心需求解析先说结论:这是一次把 Flutter 应用跑到 OpenHarmony 设备上的完整实战,我挑的载体是一个口腔护理资讯类 App,核心功能集中在文章详情页的实现上。选择这个场景的原因很直接——文章详情页是内容型应用里面信息密度…

2026/10/9 0:52:36 阅读更多 →
模型服务规模化:调度、KV Cache 与资源池化的系统之道

模型服务规模化:调度、KV Cache 与资源池化的系统之道

SOSP 的 Session 1A 开场就是 Model Serving at Scale,这个安排本身就很能说明问题。这几年我和团队一直在做 LLM 推理服务化,眼看着这个方向从"AI 实验室里的小工具"变成了"真正意义上的系统软件"——调度、缓存、资源池化、故障恢…

2026/10/9 0:52:36 阅读更多 →
AI日报制作全攻略:从信息筛选到判断力训练的实操指南

AI日报制作全攻略:从信息筛选到判断力训练的实操指南

1. 一份“AI 日报”到底在记录什么每天早上打开电脑,我做的第一件事不是看邮件,而是花二十分钟把过去二十四小时里跟人工智能相关的动态过一遍。这个习惯坚持了快三年,从最开始只是随手记在备忘录里,到后来形成固定格式的日报&…

2026/10/9 0:52:36 阅读更多 →
光通信互联市场重构:数据中心光纤跳线选型与供应模式解析

光通信互联市场重构:数据中心光纤跳线选型与供应模式解析

数据中心机房扩建、企业园区网络改造以及高密算力集群的部署,将物理层布线推向了高频迭代周期。在采购决策过程中,网络工程师与采购团队往往试图通过检索各类口碑清单获取供应商参考。光通信布线涉及单模长距、多模短距互联以及高密MTP/MPO主干等多样化场…

2026/10/9 0:51:35 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →