1991 字
约 6 分钟
11
从 API 到 Agent:配置驱动的动态装配,如何构建可扩展的 AI 应用

从 API 到 Agent:配置驱动的动态装配,如何构建可扩展的 AI 应用

当 AI 应用只有一个模型、一个固定提示词时,直接在代码中初始化客户端通常已经足够。但当系统需要支持多个模型供应商、多个知识库、不同的 MCP 工具组合,以及“写博客、修订文章、发布内容”等多类任务时,把这些能力全部写死在代码中,会很快失去可维护性。

更通用的思路是:将 Agent 看作由配置驱动的装配结果,而不是写死在某个 Controller 或 Service 中的一段调用代码。

一、问题的本质:不是动态调用,而是动态装配

很多人会把这类设计理解成“动态调用 API”。其实 API 调用只是其中一个环节。真正发生的是下面这条链路:

读取配置 → 创建组件 → 注册或缓存组件 → 组合为 Agent → 执行任务

配置可以来自数据库、配置中心或管理后台。例如,一套“技术博客助手”可以配置为:

模型:某个兼容 OpenAI 协议的模型服务
知识库:产品文档与历史文章
工具:联网检索、创建草稿、更新文章、发布文章
角色:技术编辑
规则:发布前必须人工确认

另一套“客服助手”则可以使用不同模型、不同知识库和不同工具。两者无需分别开发一套业务代码,只需在装配时选择不同配置。

二、区分四个核心对象

要让系统可控,首先要把几个容易混在一起的概念拆开。

对象 职责 示例
Agent 定义 描述一类任务如何完成 blog-publish-v3
Agent 运行实例 记录某一次具体任务 “生成一篇 MCP 入门文章”
Client 连接某种外部能力的对象 OpenAiApiBlogCmsClient
MCP Server 对外部系统能力的安全封装 搜索、CMS、知识库服务

Agent 定义是蓝图,Client 是零部件,Agent 运行实例则是一次真实生产任务。

三、为什么要动态创建 Client

以模型 API 为例,数据库中可以保存:

apiId: 1001
baseUrl: https://api.example.com
apiKey: ******
chatPath: /v1/chat/completions
embeddingPath: /v1/embeddings

装配器读取配置后创建客户端:

OpenAiApi api = OpenAiApi.builder()
    .baseUrl(config.getBaseUrl())
    .apiKey(config.getApiKey())
    .completionsPath(config.getChatPath())
    .embeddingsPath(config.getEmbeddingPath())
    .build();

随后以稳定的名字保存或注册,例如 ai_client_api_1001。后续构建聊天模型、Embedding 模型时,只需要按 ID 找到这个 Client。

这套方法不局限于大模型接口。任何“由配置决定、需长期复用、数量可控”的外部能力都可以采用相同机制:

能力 可动态创建的对象
博客平台 BlogCmsClient
搜索服务 SearchClient
知识库 KnowledgeBaseClient
通知系统 EmailClientSlackClient
对象存储 S3ClientMinioClient

四、一次 Agent 装配应如何运行

一个典型装配过程可以分为五步。

1. 加载配置

根据 agentIdclientId 查询模型、接口、提示词、顾问能力、工具和权限策略。查询可以并行,但结果应汇总到本次装配上下文中。

这个上下文只是本次装配的“零件箱”,不适合作为长期运行对象的存储位置。

2. 创建基础 Client

先创建模型 API Client、CMS Client、搜索 Client 等基础对象。对于 Spring 应用,可以将这类对象动态注册为 Bean;对于其他技术栈,也可以保存在受版本管理的 Client Registry 或连接池中。

3. 组装模型与工具

在 API Client 之上构建 Chat Model、Embedding Model,并连接 MCP Server。此时还应限定这套 Agent 可使用的工具范围:

blog-publish-v3 可使用:
- search_articles
- create_post_draft
- publish_post
- record_blog_metadata

工具白名单是权限边界的一部分,而不是提示词里的建议。

4. 组装角色、提示词和上下文

系统提示词、文章写作规范、用户请求、检索结果、记忆和知识库片段,会被组合成一次模型请求。模型在需要时发起工具调用,后端执行工具并将结果回传给模型,直到产生最终的结构化结果。

5. 创建运行记录并执行

每次执行都应产生 AgentRun:记录所用 Agent 版本、输入、工具调用、审批状态、输出与失败原因。这样既便于重试,也便于审计。

五、博客场景的推荐工作流

不要让一个万能 Agent 同时随意生成、修改和发布。将副作用不同的任务拆开,系统会可靠得多。

生成草稿:检索资料 → 生成文章 → 创建草稿
修订文章:读取文章 → 根据反馈修改 → 保存新版本
确认发布:校验用户确认 → 发布 → 保存文章元数据

发布是高风险动作。模型可以提出“调用 publish_post”,但不能凭一句提示词就拥有发布权。应由后端策略强制要求人工确认:

draft → pending_approval → published

只有用户在界面中确认后,后端才签发一次性确认令牌,并允许发布工具执行。

六、动态注册 Bean 的边界

在 Spring 中,动态注册 Bean 很适合配置驱动的组件装配,但不应把一切对象都注册进容器。

适合动态注册的对象:

  • 按 Agent 或平台区分的模型、CMS、搜索 Client;
  • 生命周期较长且可复用的连接对象;
  • 数量有限、名称明确、可审计的组件。

不适合动态注册的对象:

  • 每一次请求的临时数据;
  • 每个用户各不相同且数量巨大的会话对象;
  • 未校验的用户输入配置;
  • 需要频繁热替换的已被其他单例对象注入的依赖。

后者通常应放在请求上下文、缓存或数据库中。动态替换 Bean 后,已经注入旧对象的单例未必会自动获得新依赖;生产系统更稳妥的方式是按 agentId + version 从注册表获取正确组件。

七、安全与工程化原则

要让配置驱动的 Agent 能进入生产环境,至少要坚持以下规则:

  1. 凭证只保存在服务端,浏览器和模型都不直接持有 API Key。
  2. MCP 工具参数使用严格 Schema,禁止提供“任意路径写文件”之类的宽泛工具。
  3. 发布、删除、付款等动作必须经后端策略校验和人工确认。
  4. 每次运行使用幂等键,避免任务重试造成重复发布。
  5. 配置、提示词和工具集合都要版本化,确保任务可复现、可追踪。

结语

动态装配的价值,不在于让模型“更自由”,而在于让系统能以可配置、可治理的方式组合能力。

当模型、知识库、MCP 工具、提示词和权限策略都被当作可装配组件时,一个 AI 应用就可以从单一聊天窗口,演进为支持多 Agent、多任务和多平台发布的业务系统。模型负责理解与生成;代码负责权限、流程、状态和可靠性。两者各司其职,才能真正把 Agent 从演示功能做成可长期运行的产品。

从 API 到 Agent:配置驱动的动态装配,如何构建可扩展的 AI 应用
http://clxhxhhr.top/posts/607/
作者
clxstart
发布于
2026-09-14
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。