从 LangChain 演示到生产就绪的 FastAPI 后端

发布: (2026年1月2日 GMT+8 10:26)
7 分钟阅读
原文: Dev.to

Source: Dev.to

为什么 LangChain 需要合适的后端架构

大多数 LangChain 示例都停留在真正的后端工作开始的地方。

许多 AI 示例存在于 notebook、脚本或 Streamlit 演示中,但一旦需要在生产后端系统中运行,它们很快就会崩溃。只要 AI 成为 API 的一部分,就必须遵循与其他后端组件相同的规则:输入输出必须明确定义,依赖需要显式声明,整体结构必须能够在不重写全部代码的情况下进行更改。

本文正是针对这一起点。

我们将建立一个干净且易于维护的 FastAPI 端点,以后端友好的方式集成 LangChain。目标是创建一个坚实的架构基础,能够一步步扩展。在此阶段,实现故意保持简洁;后续文章将逐步在此基线之上引入更高级的 LLM 和代理功能。

这里的重点 不是 展示 LangChain 的特性,而是定义一个清晰且稳健的端点架构,使其在复杂度提升时仍然易于理解、可测试且可扩展。


将 AI 视为后端组件

在查看代码之前,先统一对 AI 在后端系统中应如何处理的认识很重要。目标 不是 直接暴露 LLM,而是将 AI 逻辑封装在一个稳定且可预测的 API 背后。

一个后端就绪的 AI 端点应提供以下保证:

  • 明确的请求与响应合约
  • 显式的依赖编排
  • 将 AI 逻辑与 HTTP 关注点分离
  • 可验证且可被其他系统消费的可预测输出

FastAPI 自然契合此模型,因为它已经通过 Pydantic 模型和依赖注入强制结构。这使得在不使用特例或临时粘合代码的情况下集成 LangChain 成为可能。


使用 Pydantic 定义合约

第一个构建块是严格的 API 合约。输入和输出通过 Pydantic 模型显式定义。

# Request model
class InsightQuery(BaseModel):
    question: str
    context: str

# Response model
class Insight(BaseModel):
    title: str
    summary: str
    confidence: float

    @field_validator("confidence")
    @classmethod
    def clamp_confidence(cls, v):
        """Clamp confidence to the range [0.0, 1.0]."""
        if v is None:
            return 0.0
        if v  1:
            return 1.0
        return float(v)

该合约确保无论底层 AI 逻辑如何演进,API 都保持可预测。confidence 验证器还演示了一个重要原则:即使 AI 产生不完美的数值,后端也会在返回响应前强制一致性。若没有此类校验,LLM 输出很快会变得不可预测,难以在真实系统中集成。


通过 FastAPI Depends 注入 LLM

不要在端点(或链)内部直接创建 LLM,而是使用 FastAPI 的依赖注入进行注入。

# FastAPI endpoint definition
@router.post(path="/query", response_model=Insight)
def create_insight(
    request: InsightQuery,
    settings: Settings = Depends(get_settings),
    llm: BaseChatModel = Depends(init_openai_chat_model),
):
    ...

语言模型本身在单独的依赖函数中初始化。

def init_openai_chat_model(settings: Settings = Depends(get_settings)):
    """
    Initializes and returns the LangChain OpenAI chat model.
    """
    return ChatOpenAI(
        model=settings.openai_model.model_name,
        temperature=settings.openai_model.temperature,
        api_key=settings.openai_model.api_key,
    )

优势

  • 端点专注于编排。
  • 配置集中管理。
  • 在测试时可以轻松替换或 mock LLM。

从 FastAPI 的角度来看,语言模型只是另一个依赖。

Source:


封装 LangChain 逻辑

LangChain 的逻辑本身被封装在一个专用函数中。端点不需要了解链是如何构建或执行的。

def run_insight_chain(
    prompt_messages: ChatModelPrompt,
    llm: BaseChatModel,
    question: str,
    context: str,
) -> Insight:
    """
    Builds and runs the LangChain insight chain.
    """
    prompt_template = ChatPromptTemplate([
        ("system", prompt_messages.system),
        ("human", prompt_messages.human),
    ])

    parser = PydanticOutputParser(pydantic_object=Insight)

    chain = prompt_template | llm | parser

    response = chain.invoke({
        "format_instruction": parser.get_format_instructions(),
        "question": question,
        "context": context,
    })

    return response

这种设计将关注点清晰地分离。提示构建、模型执行和输出解析都集中在同一个位置。其余的应用只需要处理输入和输出。


在 FastAPI 端点中编排一切

端点现在成为一个轻量的编排层。

@router.post(path="/query", response_model=Insight)
def create_insight(
    request: InsightQuery,
    settings: Settings = Depends(get_settings),
    llm: BaseChatModel = Depends(init_openai_chat_model),
):
    """
    POST /query – Creates a new insight for a given context and related question.
    """
    prompt_messages = load_prompt_messages(
        settings.prompt.insight_path,
        settings.prompt.insight_version,
    )

    response = run_insight_chain(
        prompt_messages,
        llm,
        request.question,
        request.context,
    )

    return response

该端点现在:

  1. 加载相应的提示模板。
  2. 调用封装好的 LangChain 函数。
  3. 返回经过验证的 Insight 响应。

小结

  • 将 AI 视为后端组件:稳定的契约、显式的依赖和封装的逻辑。
  • 使用 Pydantic 实现严格的请求/响应模型。
  • 利用 FastAPI 的依赖注入 来管理 LLM 实例。
  • 将 LangChain 链封装 为可复用函数。

有了这些基础,你可以自信地添加更复杂的 LLM 功能、代理编排、缓存、监控和测试,而无需重写核心端点逻辑。

# Fullscreen Mode

The endpoint coordinates configuration, prompt loading, and chain execution without embedding business logic. This keeps the API readable and makes future extensions straightforward.

为什么这种结构可扩展

即使示例很简单,结构也有意向前兼容。

  • 检索以后可以作为另一个依赖添加。
  • 代理逻辑可以替换链函数,而无需触碰端点契约。
  • 状态处理和错误管理可以叠加在上层,而无需重写核心流程。

最重要的是,AI 被视为后端关注点,而不是特例。它遵循与生产系统中其他组件相同的架构规则。

最后思考

本文展示了在 AI 实验与将其作为后端系统的一部分进行运营之间的区别。它奠定了面向生产的 AI 后端的第一块基石。从此,加入检索、记忆或代理等功能就成为一种架构决策,而不再是重构。

💻 GitHub 代码:
hamluk/fastapi-ai-backend/part-2

Back to Blog

相关文章

阅读更多 »

RGB LED 支线任务 💡

markdown !Jennifer Davishttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%...

Mendex:我为何构建

介绍 大家好。今天我想分享一下我是谁、我在构建什么以及为什么。 早期职业生涯与倦怠 我在 17 年前开始我的 developer 生涯……