AI 工具全栈不是“调一个模型 API”那么简单。专业视角下,它至少包含六层:模型接入层、编排层、工具层、数据与记忆层、应用层、运维与安全层。模型负责推理,工具负责行动,编排负责控制流,数据层负责上下文,应用层负责交互,运维层负责稳定性、成本与合规。
下面用一个最小可运行示例,演示如何用 FastAPI + OpenAI 兼容接口实现一个支持函数调用的 AI 工具服务。
核心原则:模型不直接信任,工具最小权限,服务端做最终校验。
安装依赖:
pip install fastapi uvicorn openai pydanticmain.py:
import os, json, ast
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL"),
)
app = FastAPI(title="AI Tool Fullstack Demo")
class ChatRequest(BaseModel):
message: str
TOOLS = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询城市天气,仅用于演示",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "计算简单数学表达式",
"parameters": {
"type": "object",
"properties": {"expression": {"type": "string"}},
"required": ["expression"],
},
},
},
]
def get_weather(city: str) -> dict:
# 真实项目应调用天气 API,并做缓存、限流、错误处理
return {"city": city, "weather": "晴", "temperature": 26}
def calculate(expression: str) -> dict:
node = ast.parse(expression, mode="eval")
allowed = (
ast.Expression, ast.BinOp, ast.UnaryOp, ast.Constant,
ast.Add, ast.Sub, ast.Mult, ast.Div, ast.USub, ast.UAdd,
)
for n in ast.walk(node):
if not isinstance(n, allowed):
raise ValueError("表达式包含不允许的语法")
result = eval(compile(node, "<calc>", "eval"), {"__builtins__": {}}, {})
return {"result": result}
TOOL_MAP = {"get_weather": get_weather, "calculate": calculate}
@app.post("/chat")
def chat(req: ChatRequest):
messages = [
{"role": "system", "content": "你是助手。需要时调用工具,不要编造工具结果。"},
{"role": "user", "content": req.message},
]
for _ in range(5):
resp = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL", "gpt-4o-mini"),
messages=messages,
tools=TOOLS,
tool_choice="auto",
)
msg = resp.choices[0].message
messages.append(msg.model_dump(exclude_none=True))
if not msg.tool_calls:
return {"reply": msg.content}
for call in msg.tool_calls:
fn = TOOL_MAP.get(call.function.name)
try:
args = json.loads(call.function.arguments)
result = fn(**args) if fn else {"error": "unknown tool"}
except Exception as e:
result = {"error": str(e)}
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result, ensure_ascii=False),
})
raise HTTPException(status_code=500, detail="工具调用轮次超限")启动:
uvicorn main:app --reload前端调用:
const res = await fetch("/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: "北京天气如何?再算一下 12*(3+4)" })
});
console.log(await res.json());eval 不可信输入。AI 工具全栈的专业性,不在于接入了多少模型,而在于能否把模型、工具、数据、应用和运维串成稳定、安全、可观测的系统。先用最小闭环跑通“模型决策—工具执行—结果回填—最终回答”,再逐步加入 RAG、多 Agent、工作流引擎和评估平台。代码可以简单,但权限、校验、日志和合规不能省。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。