如何用FastAPI和Ollama搭建一个智能查天气助手?

摘要:春节时看到公众号有个留言:“能不能搞个AI助手,要能聊天气、查限行,还得私有部署。” 别慌!这篇手记用FastAPI + Ollama + 开源模型,加上一点点天气数据微调,跑通一个能对话查询天气的dem
📝 摘要: 春节时看到公众号有个留言:“能不能搞个AI助手,要能聊天气、查限行,还得私有部署。” 别慌!这篇手记用FastAPI + Ollama + 开源模型,加上一点点天气数据微调,跑通一个能对话查询天气的demo。全程口语化,附代码、踩坑记录,直接可以搬到你的项目里。 🚨 一、公众号留言 我盯着手机,脑子里闪过一万个念头:从头训练?没卡;调API?数据出局;用开源模型?怎么让它懂实时天气? 这场景是不是特眼熟?别问我怎么知道的,上周我刚经历过。好在折腾几天总算跑通了,今天就把这套FastAPI + Ollama + 微调的组合拳拆给你看,代码直接复制,改改就能用。 🗺️ 二、先画张地图:我们要干三件事 🔹 第一 —— 用Ollama跑一个开源大模型(比如qwen2.5:3b),让它能对话。 🔹 第二 —— 给模型装个“工具包”:通过FastAPI调用天气API,实现实时查询。 🔹 第三 —— 用过去一年的天气数据做个LoRA微调,让模型更懂天气问答的口气。 🔹 附赠 —— 用Docker Compose一键启动,扔给运维同事不吵架。 ⚙️ 三、地基:Ollama + FastAPI 极简搭 Ollama 这东西,我愿称之为“大模型界的Docker”,一行命令拉模型,一行命令起服务。咱们先用它跑个轻量模型: # 安装ollama(mac/linux都有脚本,windows有exe) curl -fsSL https://ollama.com/install.sh | sh # 拉取一个3b模型,够用还不吃显卡 ollama pull qwen2.5:3b # 启动服务(默认11434端口) ollama serve 接下来是FastAPI,它就像个智能接线员,把用户的提问转给大模型,再把模型回话包装成API。先写个最简版本: # main.py from fastapi import FastAPI from pydantic import BaseModel import httpx app = FastAPI() OLLAMA_URL = "http://localhost:11434/api/generate" class ChatRequest(BaseModel): message: str @app.post("/chat") async def chat(req: ChatRequest): async with httpx.AsyncClient() as client: payload = { "model": "qwen2.5:3b", "prompt": req.message, "stream": False } resp = await client.post(OLLAMA_URL, json=payload) return {"reply": resp.json()["response"]} ⚠️ 踩坑预警: 我第一次写忘了加stream=False,结果返回了一堆流式chunk,前端直接崩了。记住,简单demo就别开流式了。 🌤️ 四、让模型学会“查天气”:工具调用 + 微调双保险 现在模型只会瞎聊,得让它知道:当用户问天气时,要去调外部API。有两种路子: 🔸 方法A:函数调用(function calling) —— 让模型输出特定格式,我们解析后调接口。简单直接,适合快速验证。 🔸 方法B:微调(fine-tuning) —— 用一批天气问答数据训练模型,让它内化“查天气”这个动作。效果更自然,但需要数据。 我两个都试了,最后用了“微调+工具调用”混搭——微调让模型更主动问地点,工具调用保证数据实时。先看工具调用咋写: # 给ollama的prompt里加入工具描述 SYSTEM_PROMPT = """ 你是一个天气助手。当用户询问天气时,你必须输出JSON格式的查询参数,例如:{"city": "北京"}。我会根据这个参数去调用天气API,然后把结果给你,你再生成自然语言回复。
阅读全文