编写第一个LobeChat插件:天气查询功能实现
在智能助手日益普及的今天,用户早已不满足于“讲个笑话”或“解释一个概念”这类静态问答。他们希望AI能真正帮自己完成任务——比如出门前问一句“北京今天要带伞吗?”,就能立刻得到准确、实时的天气建议。这背后的关键,不是让大模型记住气象数据,而是让它知道如何获取信息。
LobeChat 正是朝着这个方向演进的代表性开源项目。它不仅支持多种主流大语言模型,更通过一套简洁而强大的插件系统,将AI从“知识库”升级为“行动者”。本文就带你亲手打造第一个实用插件:天气查询。我们将用 Next.js 实现服务端逻辑,接入和风天气 API,并最终让 LobeChat 理解自然语言中的城市与意图,返回结构化天气数据。
整个过程无需深入前端框架,也不依赖复杂部署工具,重点在于理解“模型+插件”架构的设计哲学与落地细节。
现代大语言模型的强大之处在于语义理解和上下文推理,但其知识截止于训练数据,也无法主动调用外部资源。当你问“今天的金价是多少?”时,即使是最新的模型也无能为力。这就是插件系统的用武之地。
LobeChat 的插件机制本质上是一种轻量级服务集成协议,基于 OpenAPI 兼容的 RESTful 接口进行通信。它的核心设计非常干净:每个插件只需暴露两个端点:
GET /manifest.json:描述自己是谁、能做什么、需要什么参数;POST /call:接收运行时输入并返回执行结果。
当用户提问时,LobeChat 会先扫描所有注册插件的manifest文件,判断是否有匹配的功能。如果有,则根据 schema 自动提取参数,发起调用,并将返回的数据交还给大模型,由其转化为自然语言回复。
这种“声明式+Schema驱动”的方式极大降低了开发门槛。你不需要修改主应用代码,也不必关心 UI 渲染逻辑,只要你的服务能正确响应这两个接口,就可以被无缝集成。
以天气查询为例,我们希望用户说“上海明天天气怎么样?”时,系统能够识别出这是一个天气请求,自动提取“上海”作为城市参数,并调用插件获取数据。这就要求我们在manifest中清晰定义输入格式。
{ "name": "天气查询", "description": "根据城市名称获取当前天气情况", "avatar": "🌤️", "version": "1.0.0", "api": { "url": "/api/weather/call", "schema": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如北京、上海", "required": true } } } } }这个manifest.json就像是插件的“简历”——告诉 LobeChat:“我能查天气,需要一个叫 city 的字符串参数。”一旦注册成功,任何包含相关语义的对话都可能触发它。
接下来是真正的业务逻辑:调用第三方天气 API。这里选择和风天气(QWeather),原因很实际:中文文档完善、免费额度够用(每月1000次)、覆盖全国城市,且提供地理编码与天气数据分离的接口设计,非常适合做演示。
使用它的流程也很标准:
1. 注册账号,获取 API Key;
2. 通过城市名调用地理编码接口/v2/city/lookup获取 location ID;
3. 使用该 ID 调用/v7/weather/now获取实时天气;
4. 提取关键字段并封装成结构化对象。
整个过程可以通过 Node.js 的fetch轻松完成。我们使用Next.js来构建这个微服务,因为它天然支持 API Routes,无需额外配置路由或服务器。
在pages/api/weather/manifest.js中,我们直接导出一个 handler 函数:
export default function handler(req, res) { res.status(200).json({ name: "天气查询", description: "根据城市名称获取当前天气情况", avatar: "🌤️", version: "1.0.0", api: { url: "/api/weather/call", schema: { type: "object", properties: { city: { type: "string", description: "城市名称,如北京、上海", required: true, }, }, }, }, author: "Developer", }); }而真正的调用逻辑放在pages/api/weather/call.js:
const QWEATHER_KEY = process.env.QWEATHER_KEY; async function getWeatherByCity(city) { const locationRes = await fetch( `https://geoapi.qweather.com/v2/city/lookup?location=${encodeURIComponent(city)}&key=${QWEATHER_KEY}` ); const locationData = await locationRes.json(); if (!locationData.location?.length) { throw new Error("未找到该城市,请检查城市名称是否正确。"); } const locationId = locationData.location[0].id; const weatherRes = await fetch( `https://devapi.qweather.com/v7/weather/now?location=${locationId}&key=${QWEATHER_KEY}` ); const weatherData = await weatherRes.json(); if (weatherData.code !== "200") { throw new Error("天气服务暂时不可用,请稍后再试。"); } const now = weatherData.now; return { city, temperature: `${now.temp}°C`, condition: now.text, humidity: `${now.humidity}%`, feelsLike: `${now.feelsLike}°C`, updateTime: weatherData.updateTime, }; } export default async function handler(req, res) { if (req.method !== "POST") { return res.status(405).json({ error: "仅支持 POST 请求" }); } const { arguments: args } = req.body; const { city } = args; if (!city) { return res.status(400).json({ error: "缺少必要参数:city" }); } try { const result = await getWeatherByCity(city); res.status(200).json({ response: result }); } catch (error) { res.status(500).json({ error: error.message }); } }注意几个关键点:
- 使用
process.env.QWEATHER_KEY读取环境变量,避免密钥硬编码; - 所有错误都应被捕获并返回统一结构,防止前端解析失败;
- 返回值包裹在
{ response: ... }中,符合 LobeChat 插件协议规范。
本地开发时,创建.env.local文件存入你的密钥:
QWEATHER_KEY=your_actual_api_key_here启动开发服务器后,访问http://localhost:3000/api/weather/manifest可验证元信息是否正常输出。
接下来,在 LobeChat 的插件管理页面中添加插件地址(如http://localhost:3000/api/weather),保存后即可在聊天中测试。输入“杭州现在天气如何?”如果一切正常,你应该能看到类似这样的回复:
“杭州当前天气晴,气温22°C,体感温度23°C,相对湿度56%。”
这一切的背后,是完整的链路协同:NLU 模块识别意图 → 匹配插件 schema → 提取参数 → 发起 call 调用 → 获取 JSON 数据 → LLM 生成自然语言。
当然,真实场景下还需考虑更多工程细节。
首先是错误处理。网络抖动、API 限流、城市拼写错误都是常见问题。与其返回冷冰冰的“500 错误”,不如给出用户友好的提示,比如“无法定位‘北平’,请确认城市名称是否正确”。
其次是性能优化。频繁查询同一城市会导致重复请求地理编码和天气接口。可以引入内存缓存(如memory-cache)或 Redis,对热点城市做短时缓存(例如 5 分钟),显著降低延迟和 API 消耗。
安全方面,虽然本地调试可跳过认证,但在生产环境中建议增加 Token 验证机制。可以在manifest中声明auth字段,要求调用方携带 Bearer Token,服务端通过中间件校验合法性。
最后是可扩展性。目前只实现了“当前天气”,未来可轻松扩展为多模式查询:
- 添加
forecast参数支持逐日预报; - 增加
aqi子命令查询空气质量; - 支持经纬度输入,提升定位精度;
- 透传
lang和unit参数实现国际化。
这些都可以通过丰富schema定义来实现,而无需改动整体架构。
这套模式的价值远不止于天气查询。它可以复用于几乎所有需要动态数据的场景:查快递、看股价、查航班、控制智能家居……只要你能找到对应的 API,就能快速构建出一个可用的插件。
更重要的是,它体现了现代 AI 应用的核心范式:大模型负责“思考”,插件负责“行动”。就像人的大脑不会亲自去翻日历,但它知道“该查一下日程了”。LobeChat 的插件系统正是为 AI 提供了这样一双“手”和一对“眼睛”。
对于开发者而言,这意味着一种全新的构建逻辑——不再是从零开始做一个完整应用,而是专注于“能力单元”的设计与组合。你可以像搭积木一样,把已有的插件拼接成复杂的自动化流程,比如:
“如果明天下雨,就提醒我带伞,并推迟户外会议。”
这种低耦合、高复用的架构,正是推动 AI 助手走向个性化与实用化的关键路径。
随着 LobeChat 社区生态的成长,我们有望看到越来越多高质量插件涌现。它们或许来自企业内部团队,用于提升办公效率;也可能出自个人开发者之手,解决某个具体的生活痛点。而这一切的起点,往往就是这样一个简单的“天气查询”插件。
所以,不妨现在就开始动手。你下一个插件想做什么?
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考