《FGO》影之国圣杯战线图文教程汇总 影之国的舞斗会圣杯战线图文操作步骤
2026-08-08
2026-08-14 0
前几篇我们把简历 Agent 从"会输出"一路推到了"带证据、能给建议"。但所有代码都长这样:

result = agent.run_sync(resume_text)print(result.output)
这在自己机器上调试没问题。可一旦要交给前端页面、别的系统、或者自动化流程去调,这种脚本就不够了——它没有地址、没有边界、出错时也不知道该怎么告诉调用方。
今天这篇,把 Agent 包成一个能被稳定调用的 API 服务。核心一句话:
用户传进来的东西,不能照单全收。今天定义了请求模型:
代码语言:python复制class AnalyzeRequest(BaseModel):resume_text: str = Field(min_length=20,max_length=8000,description="待分析的简历文本,不能太短,也不能无限长",)target_role: str | None = Field(default=None,max_length=80,description="目标岗位,例如:AI Agent 工程师、数据工程师",)
它的作用是:在请求进入 Agent 之前,先把不合理的数据拦在门外。
简历文本太短 → 不进 Agent文本太长 → 不进 Agent字段格式不对 → FastAPI 直接返回错误这一步让我明白一个事实:AI 应用不能直接相信用户输入。输入边界越清楚,后面的 Agent 越稳定。把脏数据挡在门口,比让模型在内部纠错便宜得多。
光管输入不够,输出也得有统一格式。今天定义了响应模型:
代码语言:python复制class AnalyzeResponse(BaseModel):profile: ResumeAnalysistarget_role: str | None = Nonewarnings: list[str] = Field(default_factory=list)
以前可能直接把分析结果一股脑返回:
代码语言:json复制{ "summary": "...", "skills": [] }
现在包成统一外层:
代码语言:json复制{"profile": { "...": "Agent 分析结果" },"target_role": "AI Agent 工程师","warnings": []}
好处是:以后内部的 ResumeAnalysis 再怎么变复杂,API 外层结构依然稳定。
这是工程化里一条很重要的原则:
调用方只认 profile / target_role / warnings 这三样,你内部怎么重构都不影响他。
把接口挂起来的关键就一行:
代码语言:python复制@app.post("/analyze_resume", response_model=AnalyzeResponse)
response_model=AnalyzeResponse 这句话告诉 FastAPI:这个接口的返回值必须符合 AnalyzeResponse 的结构。
于是 FastAPI 自动帮你做完五件事:
请求参数校验响应结果校验JSON 转换API 文档生成(Swagger)错误信息返回这也是 PydanticAI 和 FastAPI 天生一对的原因:PydanticAI 管 Agent 的结构化输出,FastAPI 管 Web API 的结构化输入输出。 两端都用 Pydantic 定义边界,衔接没有缝隙。
今天的简历服务已经跑通这条链:
代码语言:shell复制用户 / 前端 ↓AnalyzeRequest 校验输入 ↓FastAPI 接口 ↓analyze_resume(resume_text) ↓PydanticAI Agent ↓ResumeAnalysis ↓AnalyzeResponse 包装输出 ↓返回 JSON
它比单个脚本更像一个真实项目,已经具备后端服务的雏形。
今天最大的收获: