FastAPI入门:一个浦东奶爸的深夜后端自救指南
作者:两个娃的奶爸,坐标上海浦东,和女朋友合租在张江,房租3500(别笑,是合租两室一厅的次卧)
01. 凌晨2点,我还在改接口文档
上周五晚上11:47,小宝终于睡了——不是假睡,是真的闭眼打呼那种。我轻轻把手机塞回枕头底下,蹑手蹑脚走到客厅,打开那台服役三年的MacBook Air,屏幕亮起的瞬间,仿佛打开了另一个世界。
我的目标很朴素:用FastAPI搭个简单的AI Agent服务,支持Llama模型调用,顺便练练Prompt工程。
但现实是——我在和Swagger UI搏斗。
“为啥这个路径参数老是报422?”我一边敲代码一边小声嘀咕,生怕吵醒隔壁房间刚哄睡的大宝。女友从卧室探出头:“又搞你那个‘后端’?明天还要上班呢。”
“就半小时!”我嘴上这么说,心里清楚:今晚不搞定,下周项目评审又要被Java组的老王diss。
是的,我在一家传统金融公司做数据分析,月薪15k,技术栈主要是Pandas + SQL + Excel宏。但最近公司要搞“智能化转型”,老板拍板上AI Agent系统,而我们组——因为会Python——被临时抓壮丁,负责搭建后端服务。
问题是:我会Python,但我不会后端。
02. 被Java组按在地上摩擦的日子
事情得从去年十月说起。
那天晨会,CTO宣布要开发一个“智能客服AI Agent”,能自动回答客户关于理财产品的疑问。技术选型会上,Java组的老王推了推眼镜:“后端肯定用Spring Boot,稳定、成熟、有生态。”
我弱弱举手:“能不能试试FastAPI?写起来快,还自带文档,而且我们数据团队都熟悉Python……”
会议室突然安静。老王冷笑一声:“FastAPI?玩具框架吧?扛得住高并发吗?有熔断限流吗?日志监控呢?”
我哑口无言。那一刻,我感觉自己像个拿着乐高积木冲进核电站的幼儿园小朋友。
结果可想而知:后端由Java组主导,我们数据团队只负责提供模型输出。但问题来了——他们要的接口格式极其复杂,光是JSON Schema就写了三页A4纸。每次改个字段,我都得重新跑测试、写文档、开评审会。
更糟的是,他们根本不理解什么叫“Prompt工程”。有一次,我提交了一个优化后的提示词模板,老王直接在Jira上批注:“这不是业务逻辑,别乱改输入格式。”
我差点当场裂开。
那段时间,我每天下班回家,看着两个孩子满地爬,脑子里全是RESTful API和HTTP状态码。女友看我状态不对,某天晚饭时认真问我:“要不要换个工作?或者……学点真本事?”
我沉默了很久,最后说:“我想自己搭个后端服务,证明Python也能干正事。”
于是,FastAPI成了我的救命稻草。
03. FastAPI:奶爸的深夜第一行代码
我选FastAPI,不是因为它多牛,而是因为它简单到离谱。
安装?一行命令:
pip install fastapi uvicorn
Hello World?
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "浦东奶爸"}
运行?
uvicorn main:app --reload
浏览器打开 http://localhost:8000,Swagger UI 自动弹出来,连文档都不用写。
那一刻,我差点哭出来——这不就是我想要的吗?所见即所得,改完立刻生效,不用等Maven构建十年。
但很快,现实又给我上了一课。
04. 接入Llama:当奶爸遇上大模型
我的目标很明确:做一个API,接收用户问题,用Llama模型生成回答,并允许通过参数调整Prompt。
但本地跑Llama?我的MacBook Air内存只有8G,光加载模型就得卡死。
解决方案:调用远程推理API(比如Together.ai或OpenRouter),或者用Ollama本地轻量部署。
我选择了后者,毕竟晚上11点后网络不太稳,远程调用容易超时。
装好Ollama,拉了个 llama3:8b 模型(占了20多G硬盘,心疼我那256G SSD),然后写了个调用函数:
import requests
def call_llama(prompt: str) -> str:
response = requests.post(
"http://localhost:11434/api/generate",
json={
"model": "llama3",
"prompt": prompt,
"stream": False
}
)
return response.json()["response"]
接着,把FastAPI接口串起来:
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.post("/ask")
def ask_question(user_input: str):
try:
# 这里可以做Prompt工程!
system_prompt = "你是一个专业理财顾问,请用简洁语言回答问题。"
full_prompt = f"{system_prompt}\n\n用户问题:{user_input}"
answer = call_llama(full_prompt)
return {"answer": answer}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
跑起来!测试!
结果:小宝半夜惊醒,大哭不止。原来是我调试时不小心开了扬声器,LLM生成的回答声音太大……
但功能确实跑通了。那一刻,凌晨1:30,我靠在沙发上,啃着冷掉的泡面,心里有种说不出的爽——我居然真的做出了一个能工作的AI Agent后端。
05. Prompt工程:不是魔法,是手艺
很多人以为Prompt工程就是随便写几句“请聪明一点回答”,其实完全不是。
在我的FastAPI服务里,Prompt是可配置的业务逻辑。
比如,我可以加个参数控制回答风格:
@app.post("/ask")
def ask_question(user_input: str, tone: str = "professional"):
tones = {
"professional": "你是一个专业理财顾问",
"friendly": "你是个亲切的邻居阿姨",
"strict": "你是个严厉的财务总监"
}
system_prompt = tones.get(tone, tones["professional"])
full_prompt = f"{system_prompt}\n\n用户问题:{user_input}"
answer = call_llama(full_prompt)
return {"answer": answer, "tone_used": tone}
这样一来,前端可以根据场景切换语气,而不需要改模型或重训。
这才是真正的Prompt工程——把提示词当成产品功能来设计,而不是玄学调参。
06. 和Java组的“和平共处”
两周后,我又在会议上提出:“我们的AI Agent后端可以用FastAPI独立部署,通过HTTP对接你们的Java服务。”
这次我没说“替代”,而是说“补充”。
老王皱眉:“稳定性怎么保证?”
我早有准备:“Uvicorn用Gunicorn+Uvicorn workers部署,Docker容器化,Prometheus监控,日志接入ELK——这些都有现成方案。而且,它只负责AI部分,核心交易还是走你们的Spring Boot。”
他沉默了几秒,点点头:“行,你先做个Demo,跑两周压测看看。”
我知道,这是突破口。
更让我惊喜的是,HR上周找我谈话,说公司考虑设立“AI工程岗”,问我想不想转岗,薪资可能涨到22k。
我和女友商量了一晚上。她说:“你要是真喜欢搞这个,就去。反正……两个娃我也能扛。”
我鼻子一酸。
07. 给同样挣扎的新手几点建议
如果你也像我一样:
- 不是科班出身
- 白天搬砖,晚上带娃
- 想学后端但被Spring Boot吓退
那么,请听一个浦东奶爸的真心话:
✅ 别怕“玩具框架”
FastAPI不是玩具,它是现代Python后端的事实标准。Starlette + Pydantic 的组合,类型安全、自动文档、异步支持,该有的都有。
✅ 先跑起来,再优化
别一上来就想搞分布式、微服务。先把一个能工作的API跑通,哪怕只服务你一个人。完成比完美重要一万倍。
✅ Prompt工程是产品思维
别把LLM当成黑盒。你的Prompt就是用户界面,是业务规则,是你可以控制的变量。
✅ Java不是敌人
承认吧,很多公司还是Java为主。但你可以用FastAPI做“边缘智能层”,和Java核心系统解耦。协作,不是取代。
✅ 时间挤一挤总会有
我每天只有晚上11点到凌晨1点是自由时间。但这2小时,足够我写50行代码、读一篇文档、跑一次测试。持续的小进步,胜过一次性的大冲刺。
08. 写在最后:技术人的尊严,不在框架,而在解决问题
有时候我会想:为什么我要在哄睡两个娃之后,还熬夜折腾FastAPI?
不是为了跳槽涨薪(虽然也不错),也不是为了和Java组较劲。
而是因为——我不想再当那个只能提需求、不能动手实现的人。
在这个AI爆炸的时代,会调用LLM不算本事,能把AI变成可靠服务,才是工程师的价值。
FastAPI给了我这个机会。它简单、透明、不装逼,就像一个深夜陪我加班的朋友。
也许哪天,我的两个娃长大了,会问我:“爸爸,你当年做什么工作?”
我希望我能说:“我用Python,给世界写了几个有用的接口。”
——哪怕只是帮客户问清楚了一个理财产品的收益率。
附:我的极简FastAPI启动模板(奶爸亲测可用)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import requests
app = FastAPI(title="AI Agent for Sleep-Deprived Dads")
class QueryRequest(BaseModel):
question: str
tone: str = "professional"
def generate_with_llama(prompt: str) -> str:
try:
resp = requests.post("http://localhost:11434/api/generate",
json={"model": "llama3", "prompt": prompt, "stream": False},
timeout=30)
return resp.json().get("response", "")
except Exception as e:
raise HTTPException(status_code=500, detail=f"LLM error: {str(e)}")
@app.post("/ai/ask")
def ask_ai(req: QueryRequest):
system_prompts = {
"professional": "你是一名专业金融顾问。",
"friendly": "你是一位热心邻居,用简单话解释。",
"strict": "你是一名风控官,回答必须严谨。"
}
prompt = f"{system_prompts.get(req.tone, system_prompts['professional'])}\n\n问题:{req.question}"
answer = generate_with_llama(prompt)
return {"answer": answer, "used_tone": req.tone}
部署命令(Docker版下次再写,今晚小宝又醒了……)
作者备注:本文写于2024年6月15日凌晨1:23,浦东张江某小区次卧。孩子刚睡,代码刚跑通,泡面还没凉。如果你也在深夜coding,记得——你不是一个人。

评论 0