尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
AI应用架构设计:从LLM选型到Agent与MCP的工程实践
1. 从一张架构图说起AI应用到底该怎么搭很多人第一次接触AI应用开发脑子里冒出来的第一个念头就是“调个API不就完了”。我刚开始也这么想直到真正接手一个需要多轮对话、工具调用、状态管理的项目才发现事情远没有那么简单。AI应用架构设计这件事本质上是在解决一个核心矛盾大模型本身是一个概率性的、无状态的文本生成器而我们要做的应用却需要确定性、有状态、可追溯。这个矛盾不解决做出来的东西永远停留在demo阶段。所谓AI应用架构说白了就是回答四个问题模型怎么选、上下文怎么管、工具怎么接、状态怎么存。这四个问题对应到具体的技术选型上就是LLM选型与接入、Prompt与记忆管理、Agent与工具调用协议、以及持久化与可观测性。我见过太多团队在这四个问题上反复横跳最后项目延期三个月上线后发现连最基本的“记住用户上一句话”都做不到。这篇文章适合谁看如果你正在做AI应用开发不管是刚入门的Java后端想转AI方向还是已经在做Agent开发但总觉得架构不够稳又或者你是技术负责人需要评估AI项目的技术方案那这篇内容应该能帮你省下不少试错时间。我会从架构设计的角度把LLM、Agent、MCP这些概念串起来讲清楚它们各自在架构中的位置和协作方式而不是孤立地解释名词。先给一个整体判断AI应用架构的核心不是模型本身而是模型与外部世界之间的那层“适配层”。这层适配层决定了你的应用能不能从“玩具”变成“产品”。下面我按架构设计的逻辑顺序从整体思路到具体实现再到问题排查一层层拆开讲。2. 架构设计的整体思路与核心分层2.1 为什么不能把LLM直接塞进业务代码我见过最粗暴的做法是在Controller里直接写一行调用大模型API的代码然后把返回结果拼到Response里。这种做法在原型阶段没问题但一旦业务逻辑超过三个分支代码就会变成一团乱麻。原因很简单LLM的调用是异步的、耗时的、可能失败的而且返回内容是不确定的。把这四件事和业务逻辑混在一起等于把不确定性引入了核心链路。正确的做法是在业务逻辑和LLM之间加一层编排层。这层编排层负责的事情包括决定什么时候调用LLM、调用哪个模型、传什么上下文、怎么解析返回结果、失败了怎么重试、超时了怎么降级。这层编排层就是AI应用架构的核心我习惯把它叫做“AI Gateway”或者“Agent Runtime”。从分层角度看一个完整的AI应用架构通常包含五层接入层处理HTTP/WebSocket请求做鉴权和限流编排层Agent逻辑、工具调用决策、多轮对话管理模型层LLM接入、模型路由、Prompt模板管理工具层MCP协议实现、外部API封装、函数调用基础设施层向量数据库、缓存、日志、监控这五层不是必须全部都有但缺了哪一层对应的能力就会缺失。比如没有工具层你的AI应用就只能聊天不能做事没有基础设施层出了问题你连日志都查不到。2.2 LLM选型不是越贵越好而是越合适越好选模型这件事我的经验是先看任务类型再看成本最后看延迟。任务类型决定了你需要什么级别的模型能力。如果是简单的意图分类、实体抽取7B参数的小模型微调一下就够了没必要上GPT-4。如果是复杂的多步推理、代码生成那必须用大参数模型。这里有个常见的误区很多人觉得模型越大越好结果用最贵的模型做最简单的任务成本直接爆炸。我一般会建议按任务分级任务类型推荐模型级别典型场景成本考量分类/抽取小模型7B-13B意图识别、情感分析极低对话/问答中模型70B级别客服机器人、知识问答中等推理/生成大模型GPT-4级别代码生成、复杂规划较高多模态专用多模态模型图像理解、文档解析高选型时还要考虑模型路由的问题。一个成熟的AI应用不应该只依赖一个模型而是根据任务动态路由。比如用户问“今天天气怎么样”路由到小模型加天气API就够了用户问“帮我分析这份财报”才路由到大模型。这种动态路由的设计能把整体成本降低60%以上。2.3 Agent架构从“问答”到“做事”的关键跃迁Agent这个词现在被用得有点泛滥但它的核心思想其实很清晰让LLM具备自主决策和工具使用的能力。传统的LLM应用是“你问我答”Agent是“你给目标我自己想办法完成”。Agent架构的核心组件包括规划器Planner把用户目标拆解成可执行的步骤执行器Executor调用工具执行每一步记忆Memory存储对话历史和中间结果反思器Reflector评估执行结果决定是否继续或重试我实测下来Agent架构最容易出问题的地方是规划器和执行器的边界。如果规划器规划得太粗执行器就不知道怎么做如果规划得太细又失去了灵活性。我的经验是让规划器只规划到“调用哪个工具”这一层具体的参数由执行器根据上下文填充。还有一个关键设计是容错。Agent执行过程中工具调用失败是常态不是异常。所以架构上必须支持工具调用失败后自动重试、重试失败后换备选工具、备选也失败后回退到让LLM重新规划。这套机制不做好Agent的可用性会非常差。2.4 MCP协议工具调用的标准化尝试MCPModel Context Protocol是最近比较热的一个概念它的目标是标准化LLM与外部工具的交互方式。在没有MCP之前每个AI应用接入工具的方式都不一样有的用Function Calling有的用自定义JSON Schema有的直接拼Prompt。MCP试图统一这件事。MCP的核心思想是工具提供方实现一个MCP Server暴露标准的接口描述AI应用作为MCP Client通过标准协议发现和调用工具。这样工具就可以跨应用复用不用每个应用都重新适配一遍。从架构角度看MCP带来的最大价值是解耦。工具的实现和AI应用的逻辑分离工具可以独立部署、独立升级。这对于企业级应用特别重要因为工具往往涉及内部系统不可能和AI应用部署在一起。不过MCP目前还在演进阶段实际落地时要注意版本兼容性和性能开销。我试过用MCP接入一个内部API发现每次工具调用都要走一次协议握手延迟比直接Function Calling高了30%左右。所以如果是性能敏感的场景可能还需要权衡。3. 核心细节解析与实操要点3.1 Prompt管理别把Prompt硬编码在代码里Prompt是AI应用的“源代码”但很多人把它当字符串硬编码在Java或Python文件里。这种做法的问题在于改一个Prompt要重新部署没法做A/B测试没法追踪版本多人协作时冲突不断。我的做法是Prompt模板化管理。具体来说把Prompt抽成独立的模板文件用占位符表示变量运行时渲染。模板文件放在配置中心或数据库里支持热更新。这样产品经理改Prompt不用找开发运营可以做A/B测试出问题可以快速回滚。一个典型的Prompt模板结构包括name: customer_service_reply version: v2.3 model: gpt-4 temperature: 0.7 max_tokens: 500 system: | 你是一个专业的客服助手语气友好回答简洁。 如果用户问题超出你的知识范围请引导用户联系人工客服。 user: | 用户问题{{question}} 历史对话{{history}} 相关知识{{context}}这里有几个实操要点temperature参数要根据任务调分类任务用0.1创意生成用0.8max_tokens要设上限防止模型输出过长导致费用失控system prompt要写清楚边界明确告诉模型什么能做、什么不能做。注意Prompt模板的版本管理很重要。我建议每次修改都保留旧版本线上出问题时可以快速对比。我踩过的坑是直接覆盖了旧版本结果新版本效果变差想回滚都回不去。3.2 上下文管理Token是有限的记忆是无限的LLM的上下文窗口是有限的但对话历史是无限增长的。怎么在有限的窗口里塞进最有用的信息这是上下文管理的核心问题。我的策略是分层记忆短期记忆最近N轮对话直接放进上下文中期记忆对话摘要用LLM压缩历史对话长期记忆向量化存储按需检索具体实现上短期记忆保留最近5-10轮中期记忆每10轮生成一次摘要长期记忆把关键信息向量化存入向量数据库。每次请求时根据当前问题检索相关的长期记忆和短期记忆一起拼进上下文。这里有个参数需要计算假设每轮对话平均200个token模型上下文窗口是8K那么最多能放40轮对话。但实际不能放满因为还要留空间给系统Prompt和模型输出。我的经验是上下文使用率控制在70%以内留30%的buffer。向量检索的相似度阈值也需要调。阈值太高检索不到相关内容阈值太低会引入噪音。我一般从0.7开始试根据实际效果调整。如果发现模型经常“答非所问”可能是检索到了不相关的记忆需要提高阈值。3.3 工具调用Function Calling的坑与技巧Function Calling是Agent执行任务的基础能力。它的原理是把工具的描述名称、参数、用途传给LLMLLM决定是否调用、调用哪个、传什么参数。实操中最大的坑是参数格式。LLM生成的参数经常不符合Schema定义比如该传数字的传了字符串该传数组的传了单个值。我的做法是在工具层做参数校验和转换不要指望LLM每次都生成完美参数。另一个坑是工具描述。工具描述写得好不好直接决定LLM能不能正确选择工具。我总结了几条经验工具名称要语义化用动词开头比如search_weather而不是weather参数描述要具体说明格式和取值范围在描述里给出使用示例LLM会参考工具数量不要太多超过20个LLM的选择准确率会明显下降如果工具确实很多可以分组先让LLM选组再选具体工具。这种两级选择的方式我实测能把准确率从60%提升到85%以上。3.4 状态管理无状态LLM如何支撑有状态应用LLM本身是无状态的每次调用都是独立的。但AI应用需要记住用户是谁、之前聊了什么、任务执行到哪一步了。这个状态管理必须由应用层来做。我的方案是用会话状态机。每个会话有一个状态对象包含用户ID、对话历史、当前任务、任务步骤、中间结果。这个状态对象存在Redis里设置合理的过期时间。状态机的设计要注意幂等性。因为网络抖动或超时同一个请求可能被重试如果状态更新不是幂等的就会出现重复执行。我的做法是给每个操作分配唯一ID状态更新前先检查这个ID是否已经处理过。还有一个细节是状态快照。Agent执行多步任务时每一步都应该保存状态快照。这样如果某一步失败可以从上一个快照恢复不用从头开始。这个设计在长任务场景下特别有用能大幅提升用户体验。4. 实操过程与核心环节实现4.1 从零搭建一个Agent Runtime假设我们要做一个“智能数据分析助手”用户可以用自然语言查询数据库、生成图表、导出报告。这个场景涉及LLM、Agent、工具调用、状态管理是一个比较完整的AI应用。第一步定义工具集工具包括query_database执行SQL查询、generate_chart生成图表、export_report导出报告、get_schema获取数据库表结构。每个工具用JSON Schema描述{ name: query_database, description: 执行SQL查询并返回结果只支持SELECT语句, parameters: { type: object, properties: { sql: { type: string, description: 要执行的SQL查询语句 }, limit: { type: integer, description: 返回结果的最大行数默认100 } }, required: [sql] } }第二步实现Agent循环Agent的核心是一个循环调用LLM - 解析工具调用 - 执行工具 - 把结果返回给LLM - 继续循环直到LLM决定不再调用工具。def agent_loop(user_input, session): messages session.get_history() messages.append({role: user, content: user_input}) for step in range(MAX_STEPS): response llm.chat(messages, toolsTOOLS) if response.tool_calls: for tool_call in response.tool_calls: result execute_tool(tool_call) messages.append({ role: tool, tool_call_id: tool_call.id, content: result }) else: session.save_history(messages) return response.content return 任务步骤过多已终止这里MAX_STEPS是关键参数防止Agent陷入死循环。我一般设10-15步根据任务复杂度调整。第三步状态持久化每次循环结束后把messages和session状态存入Redis。key用session:{session_id}过期时间设24小时。这样即使用户关闭页面再打开对话也能继续。第四步错误处理与降级工具执行失败时不要把异常直接抛给LLM而是返回结构化的错误信息{ error: SQL语法错误, detail: near SELEC: syntax error, suggestion: 请检查SQL语句确保以SELECT开头 }LLM看到这个错误信息后会尝试修正SQL重新调用。如果连续失败3次Agent应该放弃并告知用户。4.2 MCP接入的实操步骤MCP的接入流程分三步发现工具、调用工具、处理结果。发现工具MCP Client向MCP Server发送list_tools请求获取工具列表和Schema。这个过程通常在应用启动时做一次缓存结果。调用工具MCP Client发送call_tool请求带上工具名称和参数。MCP Server执行后返回结果。处理结果把MCP返回的结果转换成LLM能理解的格式通常是JSON字符串。实操中要注意超时设置。MCP工具调用可能涉及外部系统延迟不可控。我一般设30秒超时超时后返回错误让LLM决定是否重试。还有一个坑是工具名称冲突。如果多个MCP Server提供了同名工具需要加前缀区分。比如db.query和api.query。4.3 多模型路由的实现多模型路由的核心是一个路由决策函数。输入是用户请求输出是模型标识。def route_model(request): # 简单任务用小模型 if is_simple_task(request): return small-model # 需要推理用大模型 if needs_reasoning(request): return large-model # 多模态请求用多模态模型 if has_image(request): return multimodal-model return default-modelis_simple_task的判断可以用规则也可以用一个小模型做分类。我实测下来用规则关键词匹配能覆盖80%的场景剩下的20%用模型分类。路由的收益很明显我做过一个项目全量用大模型每月成本2万加了路由后降到6千效果几乎没有下降。4.4 可观测性建设AI应用的可观测性和传统应用不一样需要额外记录Prompt内容、模型返回、Token消耗、工具调用链路。我的做法是全链路Trace。每个请求分配一个trace_id所有LLM调用、工具调用都带上这个ID。日志系统按trace_id聚合出问题时可以完整回放整个请求链路。关键指标包括指标说明告警阈值LLM调用延迟P99延迟5sToken消耗每请求平均Token2000工具调用失败率失败次数/总次数10%Agent步数平均执行步数8步这些指标能帮你快速定位问题。比如Token消耗突然上升可能是Prompt变长了或者检索到了太多记忆工具失败率上升可能是外部系统出了问题。5. 常见问题与排查技巧实录5.1 Agent不调用工具怎么办这是最常见的问题。用户问“帮我查一下上个月的销售额”Agent却直接编了一个数字回复没有调用query_database。排查思路检查工具描述工具描述是否清晰说明了用途如果描述太模糊LLM不知道什么时候该用。检查System Prompt是否明确告诉LLM“涉及数据查询必须调用工具”检查工具数量工具太多会导致LLM选择困难尝试减少工具数量或分组。检查模型能力小模型可能不具备Function Calling能力换大模型试试。我的经验是在System Prompt里加一句“你不具备数据查询能力必须通过工具获取数据”能显著提升工具调用率。5.2 工具调用参数错误怎么处理LLM生成的参数不符合Schema比如该传数字的传了字符串。这种情况不要直接报错而是做参数修复。def fix_params(params, schema): for key, value in params.items(): expected_type schema[properties][key][type] if expected_type integer and isinstance(value, str): params[key] int(value) elif expected_type string and isinstance(value, (int, float)): params[key] str(value) return params如果修复不了把错误信息返回给LLM让它重新生成。我一般允许重试2次2次都失败就放弃。5.3 上下文超长怎么截断对话轮次多了上下文会超出模型窗口。截断策略很重要不能简单地从头删。我的策略是保留首尾压缩中间保留System Prompt必须保留最近5轮对话必须中间的历史对话生成摘要如果还是超长从中间摘要里再压缩摘要生成用一个小模型就够了成本很低。摘要的Prompt要明确要求“保留关键信息包括用户意图、已执行的操作、重要结论”。5.4 模型返回格式不稳定怎么解析LLM返回的JSON经常有格式问题比如多了markdown标记、少了引号、多了注释。解析时要做容错处理。def parse_json_safe(text): # 去掉markdown代码块标记 text re.sub(rjson\s*|\s*, , text) # 尝试直接解析 try: return json.loads(text) except: pass # 尝试提取JSON部分 match re.search(r\{.*\}, text, re.DOTALL) if match: try: return json.loads(match.group()) except: pass return None如果解析失败把原始文本返回给LLM让它重新生成。同时要在Prompt里强调“只返回JSON不要有其他内容”。5.5 常见问题速查表问题现象可能原因排查方法解决方案Agent不调用工具工具描述不清检查工具Schema优化描述加示例参数格式错误LLM生成不稳定打印原始参数参数修复重试上下文超长对话轮次过多统计Token数分层记忆摘要返回格式错误Prompt不够明确检查Prompt加格式约束容错解析响应延迟高模型太大/工具慢分段计时模型路由工具超时成本失控Token消耗大监控Token限制max_tokens缓存提示这些问题我几乎每个项目都会遇到建议在开发阶段就做好监控和日志不要等到上线后才发现。6. 一些踩坑后的个人体会做AI应用架构这件事最大的体会是不要试图让LLM做它不擅长的事。LLM擅长理解和生成不擅长精确计算和状态管理。把这两件事交给传统代码LLM只负责“决策”系统稳定性会好很多。另一个体会是缓存很重要。很多请求是重复的比如相同的知识问答、相同的工具调用。加一层语义缓存能把成本和延迟都降下来。我用Redis做缓存key是请求的向量表示相似度超过0.95就命中缓存。实测命中率能到30%左右。最后说一个细节Prompt里的示例比指令更有效。与其写“请用JSON格式返回”不如直接给一个JSON示例。LLM对示例的遵循度远高于对指令的遵循度。这个技巧我在多个项目里验证过能显著提升输出稳定性。架构设计没有银弹每个项目的情况都不一样。但核心原则是通用的分层解耦、状态外置、容错优先、可观测。把这四点做好AI应用的地基就稳了。
RELATED

相关推荐

用Java构建企业级AI Agent框架:核心原理与工程落地实践

用Java构建企业级AI Agent框架:核心原理与工程落地实践

去年开始,圈子里聊 AI Agent 的人越来越多,但翻来覆去,能落地的方案大都是 Python 那一套:LangChain、CrewAI、Dify 确实把 Agent 的门槛拉低了不少。可一旦你要把它塞进一个以 Java 为主的存量技术体系里,麻烦就跟着来…

📅 2026/10/25 9:35:01
表格与数据库数据进RAG:从CSV、Excel到LlamaHub的完整实战

表格与数据库数据进RAG:从CSV、Excel到LlamaHub的完整实战

做RAG做到一定阶段,你会发现一个尴尬的事实:那些PDF、Markdown、网页类文档喂进去,检索效果还能凑合,一旦上表格和数据库数据,整个知识库就开始"犯迷糊"。要么答案张冠李戴,要么直接一本正经地编…

📅 2026/10/25 9:29:59
OpenMontage 自动化剪辑管线:从时间线抽象到批量渲染的工程实践

OpenMontage 自动化剪辑管线:从时间线抽象到批量渲染的工程实践

1. OpenMontage 项目概述与核心定位第一次看到 OpenMontage 这个名字,我脑子里蹦出来的第一反应是:这大概率是一个跟视频剪辑、素材编排或者自动化合成相关的开源工具。Montage 这个词在影视后期领域太经典了,指的是把一堆零散镜头按照某种逻…

📅 2026/10/25 9:29:59
MORE NEWS

更多资讯

📰

openSCADA的jar部署与依赖管理:从classpath到模块加载避坑指南

简介:面向Java环境下OpenSCADA二次开发及OPC模块调试的工程师,这套资源将项目启动阶段最繁琐的依赖收集工作一次做完,按OpenSCADA/Java工程实际使用场景归拢全部必需组件。压缩包共480个文件,体积约30.92MB,主体为129个…

📰

普通人也能编程?Vibe Coding让AI帮你敲代码

先聊点反常识的:我这个搞了十来年编程的老家伙,最近被一个叫 Vibe Coding 的词整得有点坐不住。不是因为这个词有多高深,恰恰相反,它把编程这件事的门槛踩到了脚底下。你不需要先背一堆语法、不用理解什么是指针什么是闭包&#x…

📰

Scrapy多站点新闻爬虫实战:网易搜狐凤凰澎湃抓取与增量更新

简介:这是一份基于Scrapy框架的Python新闻爬虫项目源码,面向具备一定Python基础、希望学习分布式爬虫与数据采集的开发者。项目针对网易、搜狐、凤凰和澎湃四家新闻站点,实现文章标题、正文、评论及发布时间的抓取与本地保存,并支…

📰

AI基础数据服务全流程拆解:从采集标注到质检的成本与避坑指南

1. 一份行业白皮书为什么值得反复翻出来看2019年那份人工智能基础数据服务行业白皮书,我第一次拿到的时候其实没太当回事。那时候大家的注意力都在模型结构、算力规模、榜单排名上,谁会认真去看“数据标注”这种听起来就很苦很累的环节?但后来…

📰

AI产品定价策略:为何20美元订阅制在AI时代失效

1. 一个反常识的收入模型:18个月做到10亿美元年化,却劝你别做20美元订阅第一次看到“18个月、10亿美元年化收入”这组数字的时候,我的第一反应是——这又是一个靠融资烧出来的估值故事。但把Higgsfield这个案例翻来覆去看了几遍之后&#xff…

📰

DeepSeek+Dify本地知识库部署实战:Ollama与Docker全流程

简介:这份PDF资料面向希望零基础搭建本地AI知识库的技术爱好者与开发者,围绕DeepSeek大模型与Dify开源平台,给出从系统环境变量配置、Ollama安装、模型拉取到Docker与Dify部署的完整落地路径,帮助读者在个人电脑上跑通一套可对话、…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬