Next.js + FastAPI + Agno 搭建内网知识库 Agent 的三个踩坑实录


本文总阅读量次

nextjs-fastapi-agno-agent-pitfalls.png


最近用 Next.js + FastAPI + Agno 拼了一套内网知识库 Agent。整体架构并不复杂,标准的前后端分离。

不过在内网部署和测试的过程中,踩了三个非常典型、但在公网环境下很容易被忽视的坑:大文件直接被拒、流式响应到半截卡死,以及部分页面在内网加载直接白屏。

分享一下这个过程中具体的排查原因和解决方案。

搞定几十 MB 知识库文件上传被拒

传大文档(几十 MB)或者同时批量传多个文件时,接口直接拒收,导致解析入库失败。

这里的问题在于双重拦截:前端 Next.js 的代理层和后端 FastAPI 底层的表单解析层,都存在默认的极小体积限制,必须两端同时放行。(当然也可以不用 rewrites, 这样可能改动会相对大一些。)

前端 Next.js 放行配置

Next.js 的 rewrites 代理默认限制了请求体大小。需要在 next.config.ts 的 experimental 中显式调整 proxyClientMaxBodySize:

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "standalone",
  experimental: {
    // 放宽默认上传体积限制至 250MB
    proxyClientMaxBodySize: "250mb",
  },
  async rewrites() {
    return [
      {
        source: "/api/v1/:path*",
        destination: `${apiProxyTarget}/api/v1/:path*`,
      },
    ];
  },
};

export default nextConfig;

后端 FastAPI 放行配置

FastAPI 底层的 Starlette 对 request.form() 的 Multipart 解析有极严的限制(单 Part 默认仅 1MB)。必须在处理文件上传的接口内,显式重写解析参数:

# 知识库文件上传接口内部
form = await request.form(
    max_files=settings.rag_kb_upload_max_files,   # 放宽最大文件数限制
    max_fields=settings.rag_kb_upload_max_fields,  # 放宽表单字段限制
    max_part_size=50 * 1024 * 1024,                # 单个文件大小上限放宽到 50MB
)

解决流式输出 30 秒超时与内网代理干扰

当 Agent 处理长文本输出,或需要多步复杂的 RAG/Tool 调用时,前端经常吐字到一半直接断开。查日志发现,中断时间点精准发生在请求发出的第 30 秒。

这是由于 Next.js 的代理层,以及 Agno 底层调用 LLM API 的 HTTP 客户端,均设置了 30 秒的默认超时限制。

前端延长超时间隔

修改 next.config.ts 中的 proxyTimeout 属性:

// next.config.ts
const nextConfig: NextConfig = {
  output: "standalone",
  experimental: {
    proxyClientMaxBodySize: "250mb",
    proxyTimeout: 300000, // 延长至 5 分钟 (300000 ms)
  },
};

后端显式设定超时并避让系统代理

Agno 初始化 OpenAILike 时,可以显式配置超时属性:

import httpx
from agno.models.openai.like import OpenAILike

timeout = 300  # 5 分钟

model = OpenAILike(
    id=model_id,
    api_key=api_key,
    base_url=base_url,
    temperature=temperature,
    timeout=timeout
)

排查内网页面白屏(ChunkLoadError)

在公网测试一切正常,一搬到内网,大部分页面好好的,唯独个别路由点进去直接白屏。控制台报错 Uncaught ChunkLoadError: Loading chunk xxx failed,网络面板中对应的 .js 静态资源报 403 或 404 拒绝。

这个问题的根源在构建工具的命名策略。Next.js 默认的构建工具(Turbopack)生成 Chunk 文件名时,会携带 ~ 这类特殊字符。内网环境的防火墙或 WAF 策略通常比公网严苛得多,会将带有此类字符的 URL 判定为非法或风险请求直接拦截。

解决方案

在 package.json 中把构建命令显式切回传统的 Webpack,其生成的 Chunk 文件名只包含常规英数字符,可直接绕过内网 WAF 的字符规则拦截:

-    "build": "next build",
+    "build": "next build --webpack",

本站总访问量次