你会得到一个带请求/响应校验、环境变量管理、自动生成接口文档的最小可行 Agent 后端。 内容速览· 一个让本地 LLM“开口接客”的痛点场景· 用餐厅点餐比喻拆解 Agent 到底是个啥· FastAPI Ollama Pydantic 的最小实战代码· 请求生命周期从你的问题到 Agent 那句回答· 几个一偷懒就翻车的坑帮你提前绕开 第一部分那把“钥匙”到底在哪儿看个案例小媛说他在本地把 Llama3 跑起来了想给自己的客服系统加个自动回复接口。需求不复杂前端扔一段用户问题过来后端问 Ollama然后把答案送回去。她觉得这应该半小时搞定。结果呢她先是卡在“怎么把每次的提问包装成 API”然后又纠结“返回的结果该用啥格式”最后看着一堆手动拼的 JSON schema 叹了口气。这就是典型的手里有发动机却没给车架和轮胎。FastAPI 正好就是那套车架帮我们把发动机LLM稳稳地装上去还顺带送个仪表盘Swagger。 第二部分Agent 这套“套餐”到底怎么理解先别急着敲代码咱们聊聊 Agent 的本质。我特别喜欢用快餐店点餐来打比方‍ LLM—— 就是后厨那个万能大厨你提啥要求他都能给整出个菜。 工具—— 是大厨手边的锅铲、烤箱、菜刀。没有工具他只能干聊有了工具他才能查天气、调数据库、执行函数。 编排逻辑—— 是前台那张点餐流程单先确认需求再选择合适的工具最后让大厨出餐错了还要打回重做。所以一个最简化的 Agent 接口不是直接把用户的话丢给 Ollama 完事而是要在代码里体现这三层。今天我们先把基础路走通让“大厨”先能出餐后面再加“工具”就容易了。⚡ 第三部分动手从零搭一个 /chat 端点先晒一下我们的目标——一个跑在本地、用 Swagger 就能聊天的接口。你发一段话它回一段话背后调的是 Ollama。咱们的项目目录就简简单单几个文件├── main.py # 主服务入口 ├── models.py # 请求/响应模型 ├── config.py # 环境变量配置 └── pyproject.toml好咱们先来搞定环境。我默认你已经装好了 Ollama 并且拉取了模型比如 llama3。然后一行命令把依赖装齐uv add fastapi[standard] httpx对你没看错连httpx都得装一会儿我们要用它去异步调 Ollama 的 API这时候就别用 requests 同步请求了一上量接口直接卡成 PPT。接下来重点来了定义请求和响应模型。打开 models.py用Pydantic来管住进出。我喜欢把这事儿交给 Pydantic比手写字典强一万倍——自动校验还能直接喂给 Swagger。from pydantic import BaseModel class ChatRequest(BaseModel): message: str class ChatResponse(BaseModel): reply: str这里再说个容易翻车的点模型里字段如果写成 msg 这种简写回头对接前端的人会恨你一辈子。老老实实把可读性拉满。然后是 config.py咱们用 pydantic-settings 管理环境变量。这样不用把地址硬编码在代码里随时可以通过 .env 或环境变量覆盖。from pydantic_settings import BaseSettings class Settings(BaseSettings): ollama_base_url: str http://localhost:11434 model_name: str llama3 class Config: env_file .env settings Settings()官方文档虽然默认就支持 .env但根据以往的经验一定要在根目录放一个 .env 文件并且记得加进 .gitignore。不然某天队友的 API Key 就被你公之于众了那场面可太尴尬。主角来了main.py。我们先搭个骨架再用依赖注入把 settings 传进去给 /chat 端点用。from fastapi import FastAPI, Depends from models import ChatRequest, ChatResponse from config import Settings, settings import httpx app FastAPI(titleAI Agent 接口, version0.1.0) def get_settings(): return settings app.post(/chat, response_modelChatResponse) async def chat( req: ChatRequest, config: Settings Depends(get_settings) ): async with httpx.AsyncClient() as client: resp await client.post( f{config.ollama_base_url}/api/generate, json{ model: config.model_name, prompt: req.message, stream: False }, timeout30.0 ) resp.raise_for_status() data resp.json() return ChatResponse(replydata[response])你可能会问“就这Agent 的‘工具’和‘编排’呢”别急今天咱们先把大厨请出来。后面几篇我会慢慢给这个骨架添上“菜单”——工具调用逻辑让它可以查天气、搜文档。现在先跑起来体验一下从零到一的快感。最后啰嗦一句启动命令就一行 fastapi run main.py 。然后打开 http://localhost:8000/docs 你会看到一个自带交互界面的 Swagger。直接在里面 Try it out 测试看到回复的那一瞬间你心里一定会喊一声“舒坦”。 第四部分一个请求的完整生命周期为了让你心里更有谱我把整个过程拆成五步❶ 前端或 Swagger把 用户的一句话 按 ChatRequest 格式发到 /chat❷ FastAPI 自动校验字段不对就立刻返回 422 错误省得垃圾数据钻进大模型❸ 依赖注入 把 Settings 对象默默准备好代码里直接用❹ 用 httpx 异步调用 Ollama 的 /api/generate把大厨喊醒❺ Ollama 返回的 response 字段塞进 ChatResponseSwagger 自动渲染成漂亮的 JSON 文档你瞧整个链路清晰得就像一条笔直的大路每个弯拐在哪里一目了然。以后想加缓存、加日志、加工具只要顺着这条路插进去就行。⚠️ 注意事项与进阶思考· 千万别在公网暴露 Ollama 的 11434 端口这家伙默认没鉴权· 生产环境一定要加请求频率限制大模型慢分分钟把你的 FastAPI 线程池打满。· stream: False 用着爽但做打字机效果时记得换成流式响应那又是另一个好玩的话题。· 接下来我会在这个例子上逐步加上工具调用比如用搜索引擎的 API让 Agent 真的“动手干活”。