老李聊架构 · 第26篇
上周四晚上十点,我接到一个电话。
团队做AI功能的工程师打过来的,声音里带着疲惫和困惑。他说:"老李,我们的智能客服上线两周了,用户反馈很不稳定,有时候回答特别准,有时候答非所问,乱说一气。我们查了半天,CPU正常,内存正常,接口延迟也还行,但就是不知道问题出在哪里。"
我问他:"你们有没有记录用户问了什么问题?"
他说:"没有,我们只记了接口调用日志和响应时间。"
我又问:"那你们知道大模型收到的prompt长什么样吗?"
他沉默了几秒:"prompt是组装的,中间加了很多上下文,但具体长什么样,我们也没存……"
挂掉电话,我叹了口气。这个场景太典型了。
传统监控系统在这时候完全派不上用场。你能看到服务器没挂、接口没超时,但你对大模型收到的内容一无所知,更不知道它为什么会输出这样的回答。这种"黑盒"状态,是AI系统最让人头疼的地方。
做后端系统的同行都熟悉那套监控体系:CPU使用率、内存占用、网络带宽、接口QPS、错误率、延迟分布。这些指标构成了系统可观测性的基础,出问题了能从监控里找到线索。
AI系统确实也需要这些基础指标,但你很快会发现,纯粹靠这些,你会陷入一种奇怪的困境——系统明明"健康",用户却在骂街。
问题在于,AI系统的质量瓶颈不在基础设施层面,而在大模型的行为层面。
你不知道用户输入了什么。你可能记录了"用户发送了一条消息",但这条消息经过了多少处理、最终变成什么样的prompt送给大模型,你不清楚。
你不知道大模型收到了什么上下文。很多AI功能不是简单地把用户问题转发给大模型,而是会拼接系统提示词、加入历史对话、挂载检索到的文档、打上各种标签。这一套组装下来,最终的prompt可能跟用户原始输入相差十万八千里。
你不知道模型输出了什么。响应内容没存,回溯问题的时候只能靠用户截图回忆,效率低得可怜。
你不知道调用成本怎么分布。月底结账单的时候看着数字发呆,但不知道钱花在哪儿了,是哪个功能、哪个用户、哪个场景烧掉了大部分预算。
这些问题堆在一起,就形成了一个非常不透明的系统。你在运维它,但你不理解它。
围绕一条用户请求的生命周期,我们至少要关注这几个层面。
先说Prompt层面。
Prompt是用户请求进入大模型之前的最后一站,也是最值得监控的地方。
你需要知道用户原始输入是什么。这不是说要记录用户说的每一句话——那样太占存储,而且涉及隐私问题——但至少要能回溯。用户反馈"回答不对"的时候,你得有个办法还原他当时问了什么。
你需要知道最终发送给大模型的完整prompt是什么。这包括系统提示词、few-shot examples、上下文文档等等加在一起的总和。如果你的prompt是经过多步组装、转换、压缩的,那组装后的最终版本才是你需要监控的对象。
Prompt长度是个硬指标。单位是token,不是字符数。不同模型的tokenize规则不一样,但大致可以按"一个token约等于0.75个英文单词或1.5个中文汉字"来估算。如果某个prompt突然变得特别长,可能是上下文泄漏了,也可能是某些环节把不该塞进去的东西塞进去了。
监控prompt长度还有个实际意义:帮你估算成本。Token数和API费用直接挂钩。
再说推理层面。
模型推理这部分,监控的是大模型本身的运行状态。
首先要知道调用的是哪个模型版本。模型供应商会更新模型版本,同一个API可能今天调的是4-turbo,明天就悄悄换成了4o。如果你的效果突然变差但其他都没变,先看看是不是模型版本变了。
推理延迟要单独拎出来看。大模型推理比普通API调用慢很多,而且波动大。同一个模型,P50延迟可能500毫秒,P99可能能飙到十几秒。你需要知道这种分布,而不是只看平均值。
输出token数也要统计。这决定了单次调用的成本,也反映了模型回答的详细程度。如果某个场景的输出token数突然减少,可能意味着模型在偷懒或者上下文窗口快满了。
输出内容采样存储是必要的,但不建议全量存。全量存储成本太高,而且敏感信息太多。合理的做法是按比例采样,比如每100次请求存1次,或者只存出问题的那些。
如果你的AI系统是Agent形态,那就还需要监控工具调用的全过程。
一次用户请求可能触发多次工具调用。比如用户问"帮我查一下这个项目的代码是谁写的",系统可能要先去代码仓库搜索、再去Git历史查作者、再整理成回答。这整个链条上,每次工具调用都要记录:调用的工具名称、传入的参数、返回的结果、调用是否成功、耗时多少。
工具调用失败是个高频问题。有时候是大模型生成的参数格式不对,有时候是工具本身超时,有时候是权限不足。分清楚是哪类问题,才能有针对性地优化。
还有个容易被忽视的点:工具调用的循环。有些Agent设计得不好,会陷入反复调用同一个工具的死循环,直到token用光才停。这种情况必须能检测出来并及时告警。
最后说成本层面。
AI系统的成本监控比传统系统更复杂,因为它是按token消耗来计费的。
单次调用的成本要能算出来。API费用=输入token数×输入单价+输出token数×输出单价,不同模型单价不一样,混合调用的时候要分别计算。
成本需要多维度分摊。按功能分,你能知道是哪个AI功能最烧钱;按用户分,你能发现哪些用户在"滥用"服务;按时间分,你能看成本趋势是涨是跌;按模型分,你能比较不同模型的经济性。
成本监控的终极目标是让每一分钱都花得明白。不是说不让大家用,而是要知道钱花哪儿了、花得值不值、能不能优化。
聊完了要监控什么,再说说怎么实现。核心技术方案绕不开三板斧:Tracing、Logging、Metrics。
先说Tracing(全链路追踪)。
Tracing解决的是串联问题。一次用户请求进来,中间经过prompt组装、可能多次工具调用、模型推理、输出处理,最终返回给用户。这整条链路上的所有环节,需要用一个Trace ID串联起来。
有了Trace ID,你就能在出问题时,从头到尾还原整个请求的生命周期。用户说"我刚才问了个问题,回答错了",你就能通过他的用户ID加时间戳找到对应的Trace,然后看到prompt是什么、调用了什么工具、模型返回了什么。
实现上推荐用OpenTelemetry。这是CNCF旗下的标准,已经成了可观测性领域的事实规范。OpenTelemetry支持多语言SDK,你可以在Python、Java、Node等主流语言里埋点,trace数据可以发送到Jaeger、Zipkin或者商业平台。
埋点的关键点在于跨度(Span)的划分。一次完整的请求是一个trace,内部每个处理环节是一个span。比如一个Agent请求,内部可能有"组装prompt"、"调用模型"、"解析输出"、"执行工具A"、"执行工具B"等多个span,父span包含子span,形成树形结构。
with tracer.start_as_current_span("user_request") as trace: trace.set_attribute("user_id", user_id) trace.set_attribute("request_type", "chat") with tracer.start_as_current_span("build_prompt") as span: final_prompt = build_prompt(user_input, context) with tracer.start_as_current_span("call_model") as span: span.set_attribute("model", "gpt-4o") span.set_attribute("input_tokens", count_tokens(final_prompt)) response = call_model(final_prompt) span.set_attribute("output_tokens", count_tokens(response)) trace_result(trace, response)这段代码糙了点,但表达的意思很清楚:每个关键环节都打上span,记录必要的信息。
再说Logging(结构化日志)。
Logging的核心是记录足够的信息用于事后分析,同时要做好隐私保护。
Prompt日志要存,但有讲究。用户原始输入里的敏感信息要先脱敏,比如手机号、邮箱、身份证号这些。脱敏方式可以是替换、哈希或者直接移除,取决于你的合规要求。
模型输入输出的日志可以采样存储。前面说过,不建议全量存,成本扛不住。采样策略可以这样设计:正常情况下按1%采样;被标记为"问题请求"的100%采样;随机抽取一定比例的请求补齐样本量。
日志格式要结构化。存JSON而不是存文本,这样后续查询和分析都方便。必填字段包括:Trace ID、请求时间戳、用户ID(脱敏后)、请求类型、模型名称、token消耗、响应状态、自定义标签。
还有个实际经验:错误日志要详细,正常日志可以简略。出问题的时候你最想知道的就是为什么出错,所以错误路径上的日志要尽可能完整;正常请求走的是Happy Path,日志可以精简一些。
最后是Metrics(指标聚合)。
Metrics是把Tracing和Logging里的数据聚合起来,形成可以直接查看的统计指标。
Token吞吐量:单位时间内处理的token总数。这个指标反映的是系统负载,不是请求数量——同样100次请求,prompt短的和prompt长的,吞吐量差好几倍。
推理延迟:P50、P95、P99的分位数。P50是中位数,P95是95%的请求都在这个时间内,P99是99%。一般P99最有参考价值,因为它反映的是最坏情况下的用户体验。如果P99延迟太高,用户会明显感觉到卡顿。
错误率:模型调用失败、超时、内容解析异常等情况占总请求的比例。注意区分是模型供应商的问题还是你自己的问题。
成本速率:单位时间的API花费。这是个业务指标,直接跟钱挂钩。我建议在仪表盘上单独放一个区块,让所有人都能看到当前的成本消耗情况。
Prompt工程的从业者都知道,prompt改完之后效果变差是最让人崩溃的事情。改代码有Git,改prompt怎么办?
Prompt版本管理是AI可观测性的延伸。你不仅要能观测prompt执行的结果,还要能管理prompt本身的变更历史。
核心需求就两个:能回滚,能A/B测试。
回滚机制可以借鉴代码的思路。Prompt模板存在一个版本化的存储里,每次修改生成一个新版本,打上版本号和变更说明。上线后发现效果变差,一键切回上一个版本。
A/B测试框架是另一个必需品。你的团队里可能有人坚持认为"加上更多例子效果更好",有人觉得"简洁才是王道",谁也说服不了谁。那就别吵了,做实验。让两种prompt各跑50%的流量,然后看实际效果数据。
A/B测试要注意统计显著性。别用10个样本就下结论,样本量不够的时候任何差异都可能是随机波动。
Prompt管理的工具链可以简单也可以复杂。简单的方案,用一个JSON文件管理prompt模板,Git做版本控制,每次发布手动切换版本号。复杂的方案,用专门的Prompt管理平台,支持版本对比、灰度发布、效果监控告警。
选哪个看团队规模。创业公司三五个人,简单方案够用了。等AI功能多了、prompt模板几十上百个的时候,再考虑上平台。
终于聊到钱了,这是老板最关心的话题。
AI系统的成本监控有三个层次:实时仪表盘、异常告警、优化建议。
一个合格的成本仪表盘,至少要展示这些信息:
今日累计成本。这个数字要足够醒目,让任何人都能一眼看到花了多少钱。你可以按功能维度拆开,看是智能客服、还是文档摘要、还是代码生成,哪个功能消耗最大。
成本趋势图。看看过去一周、一个月成本的走势。是稳定增长、还是突然飙升、还是有周期性波动。趋势图能帮你发现规律。
成本构成饼图。按模型分,按功能分,按用户分,看成本分布是否健康。如果80%的成本来自1%的用户,这明显有问题。
异常成本告警是成本监控的重头戏。很多成本超支不是因为正常增长,而是因为异常。
用户行为异常。比如某个用户突然发起了大量请求,或者某个用户提交的prompt长度暴增。可能是用户在调试、可能是被攻击、也可能是有bug导致了死循环。这种情况要能检测出来并及时告警。
Prompt模板异常。如果某个prompt模板的平均token数突然增大,可能是上下文泄漏了,也可能是上游数据源出问题了。
模型版本切换。有些模型供应商会悄悄切换默认版本,新版本可能定价不同,或者token消耗模式不同。这个要提前知晓,不能月底看账单才知道。
告警阈值怎么定?有个经验公式:日均成本的3倍标准差之外,触发告警。前提是你的日均成本本身要稳定,如果业务在快速增长,那就要动态调整基线。
监控到问题之后,还得能给出解决方案。
缓存建议。如果两个用户的请求足够相似,结果可以缓存复用。比如语义相近的问题、相同文档的摘要请求。缓存命中率是个关键指标,命中率越高,成本节省越明显。
模型降级建议。不是所有请求都需要用最强的大模型。一些简单的问题、只需要快速响应的场景,用小一点的模型能省不少钱。这需要你在架构层面支持模型动态路由。
Token压缩建议。如果发现某些prompt存在大量冗余信息,可以考虑做prompt压缩。去掉重复表述、简化指令、精简few-shot examples,都能在保证效果的前提下减少token消耗。
讲个我亲自处理过的案例。
前两年给一家公司做AI系统咨询。上线一段时间后,客户反映API成本涨得厉害,比预期高了两三倍。团队排查了一阵子,没找到原因。
我让他们把成本数据按用户维度拆开。一看才发现,有个用户的token消耗是其他所有用户的总和还多。进一步查这个用户的行为日志,发现他每次提问都喜欢把整本书的内容粘贴进来,附上一句"请根据以上内容回答我的问题"。
当时他们的系统没做任何prompt长度限制。用户想塞多少就塞多少,大模型照单全收,成本自然就上去了。
处理方案很简单:加prompt长度限制。超过一定token数的输入,要么截断、要么拒绝、要么提示用户精简输入。同时加上用户维度的成本告警,一旦某个用户的日均成本超过阈值,自动发通知。
实施之后,成本立刻回落,稳定在合理范围内。
这个案例教会我两件事。第一,用户行为是不可预测的,你以为大家都懂"简洁提问",实际上总有人会整段整段地粘贴。第二,成本监控必须细化到用户维度,否则异常用户会被平均值掩盖。
说了这么多,可能有人觉得AI可观测性是个大工程,要上很多工具、建很多平台。
其实不是。可以从小处着手。
第一步,先把请求日志记起来。不需要一上来就搞完整的Trace体系,只要能通过某个ID查到某次请求的prompt和响应,你就已经比什么都没做强了。
第二步,给关键指标画几张图。成本、延迟、错误率,这三个先盯起来。Excel都能画,不需要什么高大上的平台。
第三步,定几个告警规则。比如成本日环比涨超50%、P99延迟超过30秒、错误率超过5%,这些情况触发通知。
做到这三点,你对AI系统的可见性就会大幅提升。后续再根据需要逐步完善Tracing体系、Prompt管理平台、成本优化能力。
AI系统的可观测性不是什么神秘的技术,它是帮助你理解系统行为、控制成本、保证质量的必要手段。你监控它,才能驾驭它。
传统软件的可观测性我们搞了十几年,监控体系已经相当成熟。但AI系统是个新物种,大模型的行为不像代码逻辑那样确定,它的输入输出更加复杂,成本结构更加精细,需要的监控维度也完全不同。
这不是说传统可观测性失效了,而是它需要扩展。在已有的基础设施监控之上,加上Prompt监控、Token监控、成本监控,你才能真正把AI系统运维好。
下期聊聊架构评审怎么开。不是为了挑错,是为了提前发现问题。很多团队开架构评审就是在走过场,怎么让评审真正产生价值,下期细聊。
下一篇:27 老李聊架构|架构评审怎么开:不是为了挑错,是为了提前发现问题
夜雨聆风