小节三:我们为什么选用 Flask——让 Agent 能被其他系统调用

很多 Agent 教程最后停在这一行:

agent.run("帮我分析这个项目")

对学习原理来说,这当然够。

但真实系统通常不是这样被使用的。

你的网页前端不能直接调用本地 Python 对象;飞书机器人不能直接访问你的 AgentEngine 实例;另一个 Java 服务也不能直接 import 你的 Python 类。

真实架构需要一个服务边界:

Web / App / CLI / 其他系统
            ↓
         HTTP API
            ↓
       Agent Server
            ↓
       Agent Harness

这就是 Flask 在本课程里的位置。

Flask 不是 Agent。

Flask 也不负责“思考”。

它主要负责:

  • 接收 HTTP 请求;
  • 校验请求参数;
  • 创建 Session / Run;
  • 调用 Agent Service;
  • 把结果返回客户端;
  • 后面进一步支持 Streaming;
  • 暴露 Trace、Run 状态等接口。

一个非常关键的设计原则是,Flask 是服务层,不是 Agent 核心层。

错误写法通常是这样:

@app.route("/agent", methods=["POST"])
def agent():
    # 这里直接写几百行 Agent Loop
    # 这里直接执行 Tool
    # 这里直接操作数据库
    # 这里直接管理上下文
    # 这里直接写日志
    ...

一开始能跑,后面会越来越难维护。

更好的结构是:

Flask Route
    ↓
AgentService
    ↓
AgentEngine
    ↓
Harness

这样即使以后不用 Flask,换成 CLI,也可以:

CLI
 ↓
AgentService
 ↓
AgentEngine

核心逻辑完全复用。

把这层调用关系画出来以后,Flask 的位置就不容易放错了:

图片[1]-小节三:我们为什么选用 Flask——让 Agent 能被其他系统调用-大赛人网

Web、App 或 CLI 可以共享同一套 AgentService 和 AgentEngine。Flask Route 只处理 HTTP 边界,Tool、Memory、Tracing 等能力仍由可复用核心统一组织。这样将来更换入口时,不需要把 Agent 的执行逻辑重新写一遍。

一个最小 Flask Agent API

下面我们先看一个完整可运行的最小示例。

先安装 Flask:

pip install flask

创建文件:

demo/
└── app.py

app.py 内容如下:

from flask import Flask, jsonify, request


app = Flask(__name__)


def run_agent(message: str) -> dict:
    return {
        "status": "completed",
        "answer": f"收到任务:{message}。当前这是一个最小 Agent Server 示例。"
    }


@app.post("/api/v1/chat")
def chat():
    payload = request.get_json(silent=True) or {}
    message = str(payload.get("message", "")).strip()

    if not message:
        return jsonify({
            "error": "message 不能为空"
        }), 400

    result = run_agent(message)
    return jsonify(result)


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000, debug=False)

启动:

python3 app.py

然后可以通过命令行测试:

curl -X POST http://127.0.0.1:5000/api/v1/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"检查这个 Python 项目"}'

你会得到类似:

{
  "answer": "收到任务:检查这个 Python 项目。当前这是一个最小 Agent Server 示例。",
  "status": "completed"
}

你会得到类似:

{
  "answer": "收到任务:检查这个 Python 项目。当前这是一个最小 Agent Server 示例。",
  "status": "completed"
}

这还不是最终 Agent。

但它让我们第一次看到:

Client
 ↓
HTTP
 ↓
Flask
 ↓
Agent Function
 ↓
Result

后面我们会逐步把 run_agent() 替换成真正的 Agent Engine。

为什么还需要 Run?

真实 Agent 经常不是 100 毫秒就返回。

它可能需要:

读项目
 ↓
调用 LLM
 ↓
读 4 个文件
 ↓
跑测试
 ↓
再次调用 LLM
 ↓
修改代码
 ↓
再跑测试

整个过程可能持续几十秒,甚至更久。

这时我们就不能只想着:

POST /chat → 等结果

而要有任务生命周期:

run_id
status
start_time
end_time
steps
error

于是后面的 API 会逐渐变成:

POST /api/v1/runs
GET  /api/v1/runs/{run_id}
GET  /api/v1/traces/{run_id}

这就是从“脚本思维”进入“服务思维”。

为什么需要 Streaming?

用户提交一个任务以后,如果页面一直显示:

Loading...

体验会很差。

更好的方式是实时看到:

正在扫描项目...
已发现 28 个文件...
正在读取 pyproject.toml...
正在运行测试...
发现 ImportError...
正在检查依赖...

因此课程后面会使用 SSE,把 Agent 的步骤实时推给前端。

所以我们在开篇就要建立一个认知,Agent 不只是一个智能函数,它还是一个长任务执行系统。

一旦把它当成长任务系统,Session、Run、状态、持久化、Streaming、Tracing 自然都会出现。

从一次请求的生命周期来看,Run 和 Streaming 解决的是两件不同的事:Run 保存任务当前处于什么状态,SSE 则把正在发生的步骤持续推给调用方。

图片[2]-小节三:我们为什么选用 Flask——让 Agent 能被其他系统调用-大赛人网

图中即使任务还在扫描项目、读取文件或运行测试,客户端也不必一直面对一个没有信息的 Loading 页面;与此同时,status、steps、error 和 Trace 会持续沉淀下来,后续查询、恢复与复盘才有可靠依据。

Flask 的边界也必须清楚

我们不会把 Flask 学成一门完整后端课。

课程只讲和 Agent 服务化直接相关的东西:

  • 路由;
  • 请求与响应;
  • JSON;
  • Session / Run API;
  • SSE;
  • 错误处理;
  • 服务层分层;
  • SQLite 持久化;
  • 基础安全边界。

我们的主线永远是 Agent Harness。

真正做项目时,你还会遇到进程模型、反向代理、鉴权、限流、队列等后端问题。开篇不把这些一次讲完,是为了避免把课程重心带偏。我们会在需要的时候,只引入恰好够用的服务化知识。目标是让你知道“Agent 如何成为一个可调用服务”,而不是把 Flask 从入门到源码全部学一遍。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发
头像-大赛人网
欢迎您留下宝贵的见解!
提交
头像-大赛人网

昵称

取消
昵称

    请登录后查看评论内容