☰
AI系统设计实战:上下文管理、成本控制与降级策略
2026/10/14 5:09:59 网站建设 项目流程

1. 为什么程序员需要补上AI系统设计这一课

这两年跟不少做后端、前端甚至嵌入式转过来的朋友聊,发现一个特别普遍的现象:大家用AI写代码、调API、跑个demo都挺溜,但一旦要把AI能力塞进一个真实的生产系统里,问题就全冒出来了。模型响应忽快忽慢、上下文一长就崩、并发一上来成本直接失控、出了badcase根本不知道从哪查起。说白了,会调模型和会设计AI系统,中间隔着一整套工程化的鸿沟。

我自己最早做AI相关项目的时候也踩过这个坑。当时接了一个智能问答的需求,心想不就是调个接口拼个prompt嘛,两天就上线了。结果上线第一周就被现实教育:高峰期请求排队导致超时、用户连续追问三轮之后模型开始答非所问、日志里全是token消耗但根本定位不到是哪段逻辑在烧钱。后来花了差不多一个月重构,才把整个链路理顺。那次之后我才真正意识到,AI系统设计和传统CRUD系统设计,底层思路完全不是一回事。

这份内容就是把我这些年做AI系统踩过的坑、总结出来的设计套路,系统地梳理一遍。它适合谁看?如果你是有一定开发经验、但AI系统设计经验偏少的程序员,或者你正在从传统业务开发往AI方向转,再或者你团队里要落地一个AI功能但你不知道架构该怎么搭,那这份东西应该能帮你少走不少弯路。我不打算讲太玄的算法原理,重点放在工程视角下的AI系统怎么设计、怎么拆、怎么兜底。

核心关键词就几个:AI系统设计、上下文管理、成本控制、降级策略、可观测性。这几个词贯穿全文,你把这几个搞明白了,大部分AI系统的骨架就立起来了。

2. AI系统设计的整体思路与架构拆解

2.1 先搞清楚AI系统和传统系统的本质差异

传统业务系统的输入输出基本是确定的,你传一个订单ID,返回一个订单详情,逻辑路径清晰,测试用例能覆盖绝大多数情况。AI系统不一样,它的核心是一个概率模型,同样的输入可能给出不同的输出,而且输出质量还受上下文、温度参数、模型版本等一堆因素影响。这就导致传统那套"输入确定→逻辑确定→输出确定"的设计范式,在AI系统里直接失效。

我一般会把AI系统拆成四层来看:接入层、编排层、模型层、数据层。接入层负责请求的接收、鉴权、限流;编排层是整个系统的大脑,负责prompt组装、上下文管理、多模型路由、结果后处理;模型层就是实际调用大模型或者小模型的地方;数据层则包括向量库、缓存、日志存储这些。这么拆的好处是,每一层的职责边界清晰,出了问题能快速定位是哪一层的事。

注意:很多人一上来就把所有逻辑写在一个函数里,prompt拼接、模型调用、结果解析全糊在一起。这种写法demo阶段没问题,但只要需求一变,改起来就是灾难。分层不是为了好看,是为了让你在半夜被报警叫醒的时候能快速找到病灶。

2.2 编排层才是AI系统真正的核心

如果只能选一个地方重点设计,我会毫不犹豫选编排层。为什么?因为模型本身你是改不了的(除非你自己训),但编排层完全在你掌控之中。编排层决定了你给模型喂什么、怎么喂、喂完之后怎么处理,这三个环节直接决定了最终效果和成本。

编排层里我通常会做几件事。第一是prompt模板管理,把prompt从代码里抽出来,做成可配置的模板,这样调优的时候不用改代码重新部署。第二是上下文窗口管理,这个后面会单独展开讲,是重中之重。第三是多模型路由,简单请求走便宜的小模型,复杂请求走大模型,这个策略能省下大量成本。第四是结果校验和后处理,模型输出不一定符合格式要求,得有一层兜底逻辑。

我见过一个团队,他们的编排层做得特别糙,所有请求无脑走最贵的模型,prompt也是硬编码在代码里。结果一个月账单出来,成本是预期的五倍,而且因为prompt改一次要发一次版,调优效率极低。后来他们把编排层重做,加了模型路由和prompt模板化,成本直接降到原来的三分之一,调优速度也快了好几倍。这个案例我印象特别深,因为它说明编排层的设计质量,直接和你的钱包以及迭代速度挂钩。

2.3 方案选型:自建编排还是用现成框架

这里有个绕不开的选择:编排层是自己从零写,还是用现成的编排框架。我的经验是,早期用框架快速验证,规模上来之后逐步替换成自建。现成框架的好处是上手快,各种连接器、记忆管理、工具调用都给你封装好了,适合快速跑通MVP。但框架的抽象层往往比较厚,你想做一些精细控制的时候会发现处处受限,而且框架本身的性能开销和稳定性也是变量。

自建编排的好处是可控性拉满,每一行逻辑你都清楚,性能也能优化到极致。代价就是前期投入大,很多东西要自己造轮子。我一般的做法是,核心链路自建,边缘能力用框架或者开源组件。比如上下文管理、模型路由这种核心逻辑自己写,而像文档解析、向量检索这种相对标准化的能力,直接用成熟组件就行,没必要重复造。

选型的时候还有一点容易被忽略,就是团队的技术栈匹配度。你团队全是Python背景,那就别硬上Node.js的框架,维护成本会很高。技术选型从来不是选最强的,而是选最适合你团队、最能长期维护的。

3. 核心细节解析与实操要点

3.1 上下文管理:AI系统最容易翻车的地方

上下文管理我要单独拎出来讲,因为这是AI系统里最容易出问题、也最考验设计功力的地方。大模型的上下文窗口是有限的,你不可能把历史对话无限往里塞。但如果你粗暴地截断,用户会明显感觉到"聊着聊着它就忘了前面说过什么",体验极差。

我的做法是分层管理上下文。第一层是系统级上下文,就是那些固定的角色设定、输出格式要求,这部分永远保留。第二层是近期对话,保留最近N轮完整对话,保证短期记忆连贯。第三层是长期记忆摘要,把更早的对话用模型压缩成摘要,需要的时候再注入。第四层是外部知识,通过向量检索按需召回,不占用常驻上下文。

具体参数怎么定?我一般会先算一笔账。假设模型上下文窗口是8K token,系统级上下文占500,每轮对话平均200 token,那理论上能放三十多轮。但实际不能这么算,因为你要给模型输出留空间,还要留buffer应对突发长文本。我通常会把可用上下文的60%给对话历史,20%给外部知识召回,剩下20%作为弹性空间。这个比例不是死的,要根据你的实际场景调。

实操心得:上下文压缩不要等超限了才做,要在接近阈值(比如70%)的时候就开始异步压缩。等超限了再处理,用户会感知到明显的延迟。我一般会在后台起一个异步任务,把早期对话慢慢摘要掉,用户完全无感。

3.2 Prompt工程:从"能跑"到"稳定"的关键

Prompt这东西,写一个能跑的版本可能只要十分钟,但要写一个在各种边界情况下都稳定的版本,可能要调好几天。我总结下来,一个生产级的prompt应该包含这几个部分:角色定义、任务描述、输入数据、输出格式约束、边界情况处理、示例。

角色定义要具体,别写"你是一个助手",要写"你是一个专门处理电商售后问题的客服助手,只回答退换货相关问题"。任务描述要明确,把你要它做什么、不做什么都写清楚。输出格式约束尤其重要,如果你需要结构化输出,一定要在prompt里明确JSON schema,并且加上"只输出JSON,不要有任何其他文字"这类强约束。

边界情况处理是很多人会漏掉的。比如用户问了超出范围的问题怎么办、输入为空怎么办、输入包含敏感内容怎么办,这些都要在prompt里给出明确的处理指令。我一般会加一句"如果问题超出你的知识范围,请明确告知用户你无法回答,不要编造信息",这一句能挡掉大量幻觉问题。

示例部分,我建议至少给两到三个,覆盖正常情况和边界情况。示例的质量直接决定模型输出的稳定性,一个精心设计的示例胜过十句描述。

3.3 成本控制:别让token账单变成惊吓

AI系统的成本主要是token消耗,而token消耗的大头往往在你看不见的地方。我见过最离谱的一个案例,某系统每次请求都把整个知识库塞进prompt,一次请求消耗几万token,成本高得离谱。后来改成向量检索按需召回,成本直接降了90%以上。

成本控制我一般从三个维度入手。第一是减少无效token,比如精简prompt、去掉冗余的示例、压缩上下文。第二是模型分级,简单任务用小模型,复杂任务才用大模型。怎么判断简单还是复杂?我一般用规则先过滤,比如意图识别用一个小模型或者关键词匹配就能搞定,只有真正需要推理的才走大模型。第三是缓存,相同或相似的请求直接返回缓存结果,这个在FAQ类场景里效果特别明显。

这里给一个我常用的成本估算方法。假设你的系统每天处理1万次请求,平均每次消耗2000 token(输入+输出),模型单价是每百万token 10块,那每天成本就是200块,一个月6000块。如果你能把平均token降到1000,成本直接砍半。所以优化token消耗的ROI是非常高的,值得花时间去做。

优化手段典型降本幅度实施难度适用场景
Prompt精简10%-30%低所有场景
上下文压缩20%-50%中多轮对话
模型分级路由30%-70%中请求复杂度差异大
结果缓存40%-80%低FAQ、重复查询多
向量按需召回50%-90%高知识库问答

3.4 可观测性:出了问题你得知道去哪查

AI系统的可观测性和传统系统很不一样。传统系统你看QPS、延迟、错误率就够了,AI系统你还得看输出质量。但输出质量这东西很难量化,我一般会用几个代理指标:用户反馈(点赞点踩)、输出格式合规率、重试率、人工抽检评分。

日志这块,我建议把每次请求的完整信息都记下来:输入prompt、模型输出、token消耗、耗时、模型版本、用户ID。这些数据在排查问题的时候极其有用。我遇到过好几次线上问题,都是靠回放日志才定位到根因的。比如有一次用户反馈某个问题总是答错,我把日志拉出来一看,发现是上下文压缩的时候把关键信息压没了,这种问题不看日志根本想不到。

注意:日志里可能包含用户隐私信息,存储和访问都要做好权限控制。我一般会对敏感字段做脱敏处理,并且设置合理的日志保留周期,别无限期存着。

4. 实操过程与核心环节实现

4.1 从零搭建一个AI问答系统的完整流程

假设你现在要做一个企业内部的智能问答系统,我按我的实际做法把流程走一遍。第一步是需求拆解,明确这个系统要回答什么问题、用户是谁、并发量大概多少、对延迟的容忍度是多少。这些决定了后面的技术选型。比如内部系统并发不高,那架构可以简单点;如果是对外的C端产品,那限流、降级、缓存一个都不能少。

第二步是数据准备。把企业内部的文档、FAQ、历史工单整理出来,做清洗和分块。分块大小我一般控制在300到500字,太大了检索精度下降,太小了语义不完整。分块之后做向量化,存进向量库。这里有个细节,分块的时候要保留一定的重叠,比如每个块和相邻块重叠50字,这样能避免关键信息被切断。

第三步是编排层开发。我一般会先写一个最简版本:接收问题→向量检索→组装prompt→调用模型→返回结果。跑通之后再逐步加东西:加上下文管理、加模型路由、加缓存、加降级。不要一上来就追求完美架构,先跑通再优化,这样你能快速拿到反馈,知道哪里是真正的瓶颈。

第四步是测试和调优。准备一批测试问题,覆盖正常问题、边界问题、超纲问题,跑一遍看效果。重点看几个指标:回答准确率、格式合规率、平均延迟、平均token消耗。根据结果针对性调优,可能是调prompt,可能是调检索参数,可能是换模型。

4.2 关键代码结构示例

编排层的代码结构我一般会这么组织,用Python举例:

class AIOrchestrator: def __init__(self, config): self.prompt_manager = PromptManager(config) self.context_manager = ContextManager(config) self.model_router = ModelRouter(config) self.cache = CacheLayer(config) self.retriever = VectorRetriever(config) def process(self, user_input, session_id): # 1. 查缓存 cached = self.cache.get(user_input, session_id) if cached: return cached # 2. 组装上下文 context = self.context_manager.build(session_id, user_input) # 3. 按需检索外部知识 if self._need_retrieval(user_input): knowledge = self.retriever.search(user_input) context = self.context_manager.inject_knowledge(context, knowledge) # 4. 选择模型 model = self.model_router.select(user_input, context) # 5. 组装prompt并调用 prompt = self.prompt_manager.render(context) result = model.invoke(prompt) # 6. 后处理和校验 result = self._post_process(result) # 7. 更新上下文和缓存 self.context_manager.update(session_id, user_input, result) self.cache.set(user_input, session_id, result) return result

这个结构的好处是每个环节职责清晰,你想改哪块就改哪块,不影响其他部分。比如你想换向量库,只改retriever就行;想加一个新的模型,只改model_router。

4.3 参数选择与计算过程

模型调用有几个关键参数需要仔细调。temperature控制输出的随机性,问答类场景我一般设0.1到0.3,保证输出稳定;创意类场景可以设0.7到0.9。max_tokens限制输出长度,这个要根据你的场景定,太短了回答不完整,太长了浪费token还可能跑偏。我一般会设一个合理上限,比如800,同时在prompt里要求模型简洁回答。

top_p和temperature一般二选一调,我习惯固定top_p为1,只调temperature。超时时间也很关键,我一般设15到30秒,超过就触发降级。降级策略可以是返回缓存结果、返回兜底话术、或者切换到更快的模型。

关于上下文窗口的计算,我前面提过按比例分配,这里给个更具体的例子。假设模型窗口8K,系统prompt占400,输出预留1500,那可用上下文是6100。按60/20/20分配,对话历史3660,外部知识1220,弹性空间1220。每轮对话平均250 token,那对话历史大概能放14轮。超过14轮就开始压缩最早的对话。

实操心得:这些参数不要拍脑袋定,要基于你的实际数据算。我一般会先跑一批真实请求,统计平均输入长度、平均输出长度、平均轮次,然后反推参数。这样定出来的参数才是贴合实际的。

5. 常见问题与排查技巧实录

5.1 模型输出不稳定怎么办

这是最高频的问题。同样的输入,有时候回答得很好,有时候答非所问。排查思路我一般按这个顺序来:先看prompt是不是有歧义,再看temperature是不是设太高,然后看上下文是不是有干扰信息,最后看模型本身是不是不适合这个任务。

prompt歧义是最常见的原因。比如你写"回答用户的问题",模型不知道你要详细回答还是简短回答,不知道要不要举例。改成"用不超过三句话回答用户的问题,不需要举例",输出就稳定多了。temperature如果设到0.7以上,问答场景下输出波动会很明显,降到0.2左右通常能解决。

上下文干扰也容易被忽略。如果你检索回来的知识里有一些不相关的内容,模型可能会被带偏。我一般会在prompt里加一句"只根据以下参考资料回答,如果参考资料中没有相关信息,请明确说明",这样能减少干扰。

5.2 响应延迟太高怎么优化

延迟高一般有几个来源:模型推理本身慢、检索慢、上下文太长、网络往返多。排查的时候先分段打点,看时间花在哪。如果是模型推理慢,考虑换更快的模型或者用流式输出,让用户先看到部分结果。如果是检索慢,看向量库的索引是不是没建好,或者召回数量是不是设太大了。

上下文太长导致的延迟经常被忽略。上下文越长,模型推理越慢,这是线性的关系。所以压缩上下文不仅省成本,还能降延迟。我一般会把上下文控制在模型窗口的50%以内,这样延迟和效果比较平衡。

还有一个技巧是并行化。比如检索和上下文组装可以并行做,不用串行等。模型调用如果有多步,能并行的也尽量并行。这些优化加起来,延迟降个30%到50%是很常见的。

5.3 常见问题速查表

问题现象可能原因排查方向解决手段
输出格式不对prompt约束不够检查prompt的格式要求加JSON schema和强约束语句
答非所问上下文干扰或prompt歧义回放日志看输入精简上下文、明确prompt
延迟突然升高上下文变长或模型限流看token数和模型状态压缩上下文、加限流重试
成本超预期无效token多或模型选错统计token消耗分布模型分级、缓存、精简prompt
多轮后失忆上下文被截断检查上下文管理逻辑加摘要层、优化压缩策略
并发上不去同步阻塞或连接池小看线程和连接使用异步化、扩连接池

5.4 几个我踩过的坑

第一个坑是过度依赖模型自身能力。早期我总觉得模型够强,很多逻辑不用写,让模型自己判断就行。结果发现模型在边界情况下的表现很不稳定,该拒绝的时候不拒绝,该追问的时候不追问。后来我学乖了,能用规则搞定的就用规则,模型只负责它真正擅长的部分。

第二个坑是忽略降级设计。有一次模型服务商那边出了故障,我们的系统直接全线不可用,用户那边就是一直转圈。后来加了降级策略,模型不可用的时候返回缓存结果或者兜底话术,至少保证系统可用。AI系统一定要假设模型随时会挂,这个心态很重要。

第三个坑是日志记太少。早期为了省存储,日志只记了请求ID和耗时,出了问题根本没法排查。后来改成全量记录,存储成本是上去了,但排查效率提升了好几个量级。这个投入是值得的。

6. 进阶方向与持续优化思路

6.1 从单模型到多模型协同

当系统规模上来之后,单模型往往满足不了所有需求。我现在的做法是多模型协同:意图识别用小模型,知识问答用中等模型,复杂推理用大模型,代码生成用专门的代码模型。每个模型各司其职,整体效果和成本都比单模型好。

多模型协同的难点在于路由策略。我一般用两层路由:第一层用规则或者小模型做粗分类,第二层根据分类结果和当前负载做精细路由。路由策略要能动态调整,比如某个模型响应变慢的时候自动把流量切到备用模型。

6.2 评估体系的建立

没有评估体系,优化就是盲人摸象。我一般会建一个评估集,包含几百条标注好的问答对,每次改动之后跑一遍,看准确率、召回率、格式合规率这些指标的变化。评估集要覆盖各种场景,包括正常问题、边界问题、对抗性问题。

除了自动评估,人工抽检也不能少。我一般每周抽一批线上请求人工看一遍,重点看那些自动指标看不出来的问题,比如回答的语气是不是合适、有没有隐含的偏见。这些细节自动评估很难覆盖,但用户能感知到。

6.3 持续迭代的节奏

AI系统的优化是个持续过程,不存在一劳永逸。我一般会保持一个固定的迭代节奏:每周看一次核心指标,每月做一次全面评估,每季度做一次架构review。有大的模型版本更新的时候,及时做对比测试,看要不要切换。

迭代的时候要注意小步快跑,一次只改一个变量,改完看效果。同时改多个东西,出了问题你都不知道是哪个改动导致的。这个原则在AI系统调优里尤其重要,因为AI系统的变量太多了,不控制变量根本没法归因。

我个人在实际操作中的体会是,AI系统设计这件事,工程能力比算法能力更重要。你不需要会训模型,但你需要知道怎么把模型用好、怎么让它在生产环境里稳定运行、怎么在效果和成本之间找平衡。这些能力,才是程序员在AI时代真正的护城河。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询