
传统软件开发,是一个建立在“确定性”基石之上的世界。给定一个输入,程序的输出是可预测、可复现的。但当我们引入LLM时,等于在系统中嵌入了一个“概率引擎”,整个架构的底层范式都发生了动摇。这种从确定性到概率性的转变,给我们的系统带来了至少三个前所未有的核心挑战。
挑战一:幻觉(Hallucination)——最自信的“谎言”
“幻觉”是指LLM在看似正常的回答中,捏造事实、数据或代码的现象。对于一个依赖外部知识的问答机器人,这可能是个笑话;但对于一个嵌入生产系统的AI Agent,这可能就是一场灾难。一个用于生成数据库查询语句的AI,如果产生幻觉,可能会执行一条删除数据的破坏性指令。
架构风险: 不可预测的、错误的业务操作,数据污染,甚至安全漏洞。
挑战二:延迟抖动(Latency Jitter)——时快时慢的“神经刀”
LLM的响应时间极不稳定。一个简单的请求,有时可能1秒返回,有时可能需要10秒甚至更长。这种“延迟抖动”对于需要与外部服务进行实时交互的系统是致命的。一个高并发的API,如果其下游的AI服务响应缓慢,很容易引发请求积压,最终导致整个服务雪崩。
架构风险: 服务超时,线程池耗尽,级联故障,用户体验急剧下降。
挑战三:结果不可复现(Non-Reproducibility)——消失的“犯罪现场”
为了获得创造性,我们通常会将模型的temperature
参数设置得高于0。这导致了即使输入完全相同,每次的输出也可能不同。这给软件工程中最核心的环节——测试和调试——带来了巨大麻烦。当一个线上Bug出现时,你甚至无法在本地稳定地复现它,因为AI的“犯罪现场”已经消失了。
架构风险: 测试用例不稳定,自动化测试难以实现,线上问题追溯和修复成本极高。
架构应对策略:为你的AI系统套上“缰绳”
面对上述挑战,我们不能听之任之。架构师的职责,就是通过精巧的设计,为这个概率性的“黑盒”套上确定性的“缰绳”,确保整个系统的行为是可控、可靠的。
策略一:隔离舱(Bulkheading)与异步处理
原则: 将AI调用视为一个独立的、不可靠的第三方服务,严加隔离。
实践:
- 服务隔离: 将所有与LLM交互的逻辑,封装到一个独立的微服务中(AI Gateway)。主业务系统通过内部API与这个网关通信,而不是直接调用LLM。
- 异步处理: 对于非实时的AI任务(如生成报告、分析数据),坚决采用异步模式。主业务系统将任务丢进消息队列(如RabbitMQ, Kafka),AI服务作为消费者去处理,处理完再将结果写回数据库或通知主系统。这能彻底避免AI的延迟抖动影响核心业务的响应。
策略二:响应校验(Response Validation)与护栏(Guardrails)
原则: 永远不要直接信任AI的输出,必须“先安检,后使用”。
实践:
- 结构校验: 如果你期望AI返回的是JSON,那么在接收到响应后,第一件事就是用Pydantic等工具校验其格式是否正确、字段是否齐全。
- 内容护栏: 针对特定任务,建立规则或模型来拦截危险输出。例如,如果AI用于生成SQL,必须检查其输出是否包含
DROP
,DELETE
等高危关键字。如果AI用于客服,必须检查是否包含不当言论。这个校验层,就是系统的“护栏”。
策略三:智能重试(Smart Retries)与降级(Fallback)
原则: 一次失败不代表永久失败,但要有B计划。
实践:
- 指数退避重试: 对AI的调用失败(如API超时)应设置重试机制,但必须采用指数退避策略,避免在AI服务抖动时发起“DDoS攻击”。
- 模型降级: 当主力的、昂贵的模型(如GPT-4)调用失败或超时,可以自动降级,用一个更便宜、更快的模型(如GPT-3.5)来完成任务,保证服务的可用性。
- 人工降级: 对于最核心的业务,当所有AI路径都失败时,系统应能平滑降级到“人工处理”模式,例如生成一个工单,等待人工介入。
策略四:确定性缓存(Deterministic Caching for Testing)
原则: 在测试环境中,必须消除AI的不确定性。
实践:
- 建立测试用例库: 针对核心功能,将一批典型的输入和“理想的”AI输出,作为键值对存储起来。
- Mock Server/Cache: 在自动化测试环境中,用一个Mock Server或一个缓存层来拦截所有对AI的调用。当请求的输入在用例库中时,直接返回那个“理想的”输出。这让你的端到端测试变得完全确定和可复现。
总结
拥抱AI,意味着架构师必须从“确定性世界”的建设者,转变为“概率性世界”的风险管理者。我们的核心价值,不再仅仅是构建功能,更是要通过隔离、校验、降级、缓存等一系列架构工具,为充满不确定性的AI系统,构建一个“确定性”的防护外壳,确保整个商业系统的稳定、可靠与可信。