资讯动态

AI能力边界与工程化应对:从幻觉到RAG的可靠性实践

发布时间:2026/8/30 3:48:36 来源:尧图企业网站定制
从无所不能到一测就崩AI的能力边界到底在哪过去两年几乎所有技术团队都在拥抱大模型。从代码补全、文档生成到智能客服、内容审核AI 似乎已经渗透到软件开发的每一个环节。打开各种技术社区铺天盖地都是AI 取代程序员大模型改变软件工程的论调。但如果你真的把大模型接入生产环境长期跑过几条核心业务链路你就会发现一个反直觉的现象AI 在 demo 里无所不能在真实场景里却频频翻车。它可以写出结构优美的论文摘要却会在接口参数校验上犯低级错误它可以帮你生成一段完整的业务代码却会在事务边界上给出完全错误的建议它甚至会用极其自信的语气告诉你一个根本不存在的 API 存在。这个现象值得深思。当我们把 AI 当作统治者一样信任和依赖时它其实并没有那么胜任。这个标题——Not so competent AI overlords——说的正是这件事AI 远没有我们想象的那么全知全能它更像一个知识面极广但缺乏常识的高级实习生。理解它的能力边界反而是在实际项目中用好它的前提。这篇文章我会从三个层面展开先说清楚为什么大模型会看似强大实则脆弱再给出可复现的测试方法让你在自己的业务场景上验证这些局限最后分享一套工程化的应对方案帮助你把 AI 从不可靠的生成器变成可控的生产力工具。无论你是在做 Agent 开发、AI 应用集成还是仅仅想评估某个大模型能否接入你的系统这篇文章都应该对你有实际帮助。1. 这篇文章真正要解决的问题1.1 为什么必须正视 AI 的脆弱性先看一个真实的工程现象。很多团队在引入大模型时都会经历这样一个过程初期惊艳——模型在内部测试集上表现优异什么需求都能回答代码生成又快又好中期困惑——进入联调阶段后模型开始时不时给出错误答案而且出错的场景毫无规律后期回归理性——大家学会了把 AI 当增强搜索引擎用而不再指望它独立完成复杂任务。这个过程几乎是所有 AI 应用团队的必经之路。问题不在于模型不好而在于我们对模型的预期错了。大模型的本质是一个概率系统它的所有输出都基于上下文中的 token 序列预测下一个 token 的概率分布。这意味着它的知识来自训练数据而不是实时世界。它的推理本质上是模式匹配而不是逻辑推导。它的自信程度与答案的准确程度并不直接相关。这些特性决定了 AI 在某些任务上是高效的助手在另一些任务上则是不可靠的幻觉发生器。如果我们不能区分这两类场景就很容易在 production 环境里吃大亏。1.2 谁最应该读这篇文章如果你属于以下几类人群这篇文章值得你花十几分钟读完正在做 AI Agent 开发的工程师你的 Agent 在执行多步任务时是否经常跑偏怎么设计纠错机制准备把大模型接入生产系统的架构师模型输出的不确定性对你的系统 SLA 意味着什么AI 应用产品的技术负责人如何评估一个模型在你的垂直场景下是否真的可用刚接触大模型 API 的初中级开发者如何避免把大模型的输出直接当作可靠数据源本文的目标不是否定 AI 的价值而是帮你建立一套评估、验证、兜底的工程方法论。只有当你清楚一个系统在哪些地方不可靠你才能真正地在工程上把它用可靠。2. 基础概念与核心原理2.1 能力边界大模型到底知道什么大模型的能力边界由训练过程决定。以 Transformer 架构为例它通过海量文本上的自监督学习学习的是 token 与 token 之间的统计相关性。通俗解释大模型就像一个阅读了互联网上几乎所有公开文本的人。它知道如果用户说感谢通常应该回复不客气它知道Python 的函数定义以 def 开头。但它没有真正的世界模型它没有亲自运行过代码没有操作过数据库也没有验证过它输出的每一个事实。这意味着核心能力边界有两个知识时间边界训练数据有截止日期之后发生的事情它无法知晓。推理深度边界需要长时间逻辑链条的问题模型容易在中间步骤上出错而且无法自我觉察。2.2 AI 幻觉最危险的自信错误AI 幻觉Hallucination是大模型在生产环境中最突出的问题。所谓幻觉就是模型生成的内容不符合事实或在逻辑上不成立但表达方式极其流畅自然。为什么会产生幻觉从技术视角看可以归结为三点训练目标偏差模型被优化的是生成自然文本的能力而不是确保生成真实内容。流畅性优先于事实性。上下文窗口限制模型能处理的上下文长度有限当相关信息超出窗口范围时它只能基于不完整的信息进行合理猜测。知识融合错误训练数据中如果某些信息频繁共现模型可能学到错误的关联。例如它可能观察到某类问题配某类答案在语料中很常见于是形成错误映射。危害在哪里幻觉的可怕之处不是它出错而是它出错时的表达方式与正确回答在形式上没有区别。都是完整的句子、流畅的逻辑、笃定的语气。这就会干扰人的判断尤其是当用户缺乏足够的领域知识来辨别时。2.3 过度自信概率与事实的错位与幻觉紧密相关的是模型的过度自信现象。在语言模型的内部机制中每个 token 的输出都有对应的概率分布。但模型对这个答案有把握的自我评估与答案的真实正确率并不一致。换句话说模型判断我确信和我正确是两个独立的事件。这个设计带来的工程后果非常直接如果单纯依赖模型的置信度分数来决定是否采信答案系统很容易被自信的错误带偏。2.4 传统软件与 AI 系统的核心差异要理解为什么 AI 应用工程和传统软件工程不一样我们需要对比一下维度传统软件AI 应用输出确定性同输入必有同输出同输入可能不同输出错误模式异常、报错、崩溃流畅、自然但可能错误测试方式断言输入输出需要评估语义、概率和分布可解释性通过日志/断点排查难以定位为什么给出这个答案上线心态测试通过即可发布需要持续监控和反馈这个对比揭示了一个核心矛盾传统软件的可靠性建立在确定性基础上而 AI 系统天然是概率性的。工程化的关键不是试图消灭不确定性而是为不确定性设计防御机制。3. 如何在真实业务场景中验证 AI 的能力边界3.1 为什么要做边界验证很多团队在评估大模型时用的测试集是模型厂商提供的样例或网上公开的 benchmark。这有一个很大的问题这些评测数据往往已经出现在模型的训练语料里了。一个经过训练的模型在见过答案的题目上表现好并不能说明它在你的私有业务场景中表现好。要真正评估模型的可用性必须使用未参与训练的真实业务数据进行验证。3.2 一个可复用的评测流程我建议采用以下五步法来评估一个模型是否适合你的业务场景第一步构建评测集。从真实业务中抽取 100 到 200 条有代表性的输入。覆盖不同难度、不同风格、不同边界条件。不要只选简单的故意加入一些易混淆的、有歧义的、需要深层推理的样本。第二步定义评测标准。对于生成类任务纯人工打分成本太高可以先定义客观规则如关键词覆盖率、格式正确率和主观维度如逻辑一致性、事实准确性。第三步批量测试。将模型 API 接入测试脚本逐条跑测试集保留所有输出。特别注意保存模型的元信息如 token 数、耗时、温度参数。第四步错误聚类。人工分析错误回答对错误类型进行分类。是知识过时逻辑错误格式问题还是幻觉编造这一步决定了后续应该采用什么策略来修复。第五步压力测试。在超出模型舒适区的场景下测试比如超长上下文的对话、多条件约束的生成、需要精确计算的推理题。这能尽早暴露模型的天花板。# 文件路径evaluate_model.py import json import time from openai import OpenAI client OpenAI() def load_test_set(path): with open(path, r, encodingutf-8) as f: return json.load(f) def evaluate_single(prompt, modelgpt-4o, temperature0.2): start_time time.time() try: response client.chat.completions.create( modelmodel, messages[ {role: system, content: 你是一个专业的技术助手请准确回答用户问题。}, {role: user, content: prompt} ], temperaturetemperature ) return { answer: response.choices[0].message.content, latency: time.time() - start_time, token_usage: response.usage.total_tokens, error: None } except Exception as e: return { answer: None, latency: time.time() - start_time, token_usage: 0, error: str(e) } def main(): test_set load_test_set(test_prompts.json) results [] for item in test_set: result evaluate_single(item[prompt]) result[case_id] item[id] result[expected_contains] item.get(expected_contains, []) results.append(result) print(f案例 {item[id]} 测试完成耗时 {result[latency]:.2f}秒) with open(evaluation_results.json, w, encodingutf-8) as f: json.dump(results, f, ensure_asciiFalse, indent2) print(评测完成结果已保存到 evaluation_results.json) if __name__ __main__: main()// 文件路径test_prompts.json [ { id: case_001, prompt: 请将以下代码从 Java 翻译为 Python并保持逻辑完全一致 public boolean isValid(String s) { StackCharacter stack new Stack(); for (char c : s.toCharArray()) { if (c ( || c { || c [) { stack.push(c); } else { if (stack.isEmpty()) return false; char top stack.pop(); if (c ) top ! () return false; if (c } top ! {) return false; if (c ] top ! [) return false; } } return stack.isEmpty(); }, expected_contains: [def, append, pop] }, { id: case_002, prompt: 请总结下面这段日志中出现的所有错误类型\n[ERROR] 2024-01-15 10:22:31 Connection refused: localhost:8080\n[WARN] 2024-01-15 10:22:35 Retrying...\n[ERROR] 2024-01-15 10:22:40 Timeout after 5000ms\n[INFO] 2024-01-15 10:22:41 Application started, expected_contains: [Connection refused, Timeout] }, { id: case_003, prompt: 在一个订单系统中一张订单可以包含多个商品一个商品可以属于多个订单。请设计数据库表结构保证可以查询每种商品的销售总额。, expected_contains: [order_item, JOIN, SUM] } ]在运行脚本前先测试几条确认 API 密钥和模型名称没有问题。批量跑完后重点检查evaluation_results.json中的失败案例按错误类型打标签。这一步很有价值因为错误类型的分布直接决定了你的 AI 应用应该采用什么架构策略。3.3 从评测结果反推架构策略评测不只是为了判断这个模型行不行更是为了设计系统应该怎么兜底。如果评测结果显示错误集中在知识类问题例如问事实、问版本号那么你的系统应该接入检索增强生成RAG用外部知识库补充模型的知识盲区。如果错误集中在逻辑类问题例如多条件判断、路径规划那么模型可能不适合直接做决策更稳妥的方式是让模型只做信息抽取和格式化具体的逻辑判断交给传统代码。如果错误集中在指令跟随类问题例如用户给了详细格式要求模型仍输出不符合格式的内容那就要在 prompt 侧增加 few-shot 示例并且在后端增加校验和控制流程。这是我反复强调的一个观点测试不是一次性动作它是你决定 AI 在系统中扮演什么角色的依据。没有这一步后续所有的工程优化都是盲目的。4. AI 角色定位Agent、辅助工具还是协作者4.1 三个层级的角色划分根据大模型的能力边界在实际系统中可以给它分配不同的角色。我把它们分为三个层级第一层生成式工具Generator。AI 负责生成内容草稿例如代码注释、接口文档、SQL 初稿。所有生成内容都必须经过人工审阅或程序校验后才能使用。这是目前可靠性要求较高的系统中最常见的用法风险最低。第二层结构化抽取器Extractor。AI 负责从非结构化数据中抽取结构化字段例如从客服对话中提取用户意图、从邮件中提取待办事项。这类任务模型表现得相当稳定因为边界清晰不需要太多发散思维。第三层自主智能体Agent。AI 被赋予目标自行规划步骤并调用工具完成任务。这是最吸引人但风险最高的一层。Agent 容易在中间步骤上出错而且一旦错误被放大可能产生严重的连锁反应。4.2 Agent 到底卡在哪里Agent 开发是当前 AI 工程领域最热的方向之一但实际生产中真正跑通的 Agent 应用并不多。问题通常出在以下几个方面步骤规划的不可靠性。Agent 需要把大目标分解为小步骤。但模型对步骤的规划是在推理时动态生成的同一个任务不同运行得到的步骤可能完全不同。这意味着系统的行为不可预测。工具调用的错误传播。Agent 通过调用工具与环境交互。如果第一步工具调用返回了错误数据后续所有步骤都会基于错误数据进行推理。而且 Agent 往往无法意识到工具返回的数据是错误的。缺乏自我评估能力。人类在完成一项任务后可以回头看检查是否遗漏了重要条件。但 Agent 在循环中执行时如果没有显式的验证步骤它几乎没有自我纠错能力。它会沿着错误的初始假设一路走下去。4.3 在实践中如何降低 Agent 的不确定性一个可落地的做法是缩小 Agent 的决策空间。与其让 Agent 自由规划所有步骤不如由开发者在代码中定义好任务的工作流workflowAgent 只负责在工作流的特定节点上进行局部决策。# 文件路径agent_workflow.py from typing import Dict, Any class OrderWorkflow: 将订单处理的 Agent 流程固定化减少模型自主决策空间。 def __init__(self, llm_client): self.llm llm_client def extract_order_info(self, raw_text: str) - Dict[str, Any]: 步骤1从用户输入中抽取结构化订单信息。这一步交给 LLM但用 JSON schema 约束输出。 prompt f 从以下用户输入中抽取订单信息严格按照 JSON 格式输出 {{ customer_name: string, items: [{{name: string, quantity: integer, price: float}}], shipping_address: string }} 用户输入 {raw_text} response self.llm.chat(prompt, response_format{type: json_object}) return self.validate_order_schema(response) def validate_order_schema(self, data: Dict[str, Any]) - Dict[str, Any]: 步骤2代码校验如果 LLM 输出不符合 schema直接抛异常不进入下一步。 required_fields [customer_name, items, shipping_address] for field in required_fields: if field not in data: raise ValueError(f缺少字段: {field}) if not isinstance(data[items], list) or len(data[items]) 0: raise ValueError(订单必须包含至少一个商品) for item in data[items]: if item.get(quantity, 0) 0: raise ValueError(商品数量必须大于 0) return data def calculate_total(self, items: list) - float: 步骤3金额计算使用确定性代码绝不依赖 LLM。 total 0.0 for item in items: total item[quantity] * item[price] return round(total, 2) def process(self, raw_text: str) - Dict[str, Any]: order_info self.extract_order_info(raw_text) total self.calculate_total(order_info[items]) return { order_info: order_info, total_amount: total }这段代码演示了一个核心原则让 LLM 做它擅长的事——自然语言理解而把确定性计算和规则校验留给传统代码。这个模式可以扩展到更复杂的 Agent 设计LLM 负责理解用户意图和抽取参数工作流引擎负责步骤编排领域规则引擎负责合法性校验最终结果由代码逻辑保证确定性。5. 面向不确定性设计系统RAG、校验与兜底机制5.1 用 RAG 弥补知识不足RAGRetrieval-Augmented Generation检索增强生成是目前业界公认的、能够显著降低模型幻觉率的方案。它的核心思想是在模型生成回答之前先从外部知识库中检索相关信息把检索结果放入上下文再让模型基于这些信息生成回答。RAG 的优势在于知识可以实时更新不依赖模型训练时的时间截点。回答可以被溯源——用户可以看到模型依据了哪些资料。对私有领域知识特别有效因为这部分知识完全不在模型的训练语料中。一个工程上的重要提醒RAG 的效果高度依赖于检索质量。如果检索到的资料与问题不相关那么把它拼进 prompt 只会让模型更困惑。所以先要完善文档切分和向量检索的精度再用 RAG 增强回答而不是反过来。5.2 输出校验让规则代码做最后的守门员在实际生产系统中完全信任模型输出是危险的。无论生成质量多好都建议在模型输出后面加一层程序化的校验。以 JSON 结构化输出为例# 文件路径response_validator.py import json from jsonschema import validate, ValidationError ORDER_RESPONSE_SCHEMA { type: object, properties: { order_id: {type: string}, customer_id: {type: string}, items: { type: array, items: { type: object, properties: { product_id: {type: string}, quantity: {type: integer, minimum: 1}, unit_price: {type: number, minimum: 0} }, required: [product_id, quantity, unit_price] } }, total_amount: {type: number, minimum: 0} }, required: [order_id, customer_id, items, total_amount] } def validate_llm_response(response_text: str) - dict: 对 LLM 的响应进行格式校验和基础逻辑校验。 校验失败时抛出异常防止无效数据流入下游。 try: data json.loads(response_text) except json.JSONDecodeError as e: raise ValueError(f非法 JSON 格式: {e}) try: validate(instancedata, schemaORDER_RESPONSE_SCHEMA) except ValidationError as e: raise ValueError(fJSON 校验失败: {e.message}) # 金额一致性校验计算机求和与模型输出的总额做比对 calculated_total sum( item[quantity] * item[unit_price] for item in data[items] ) if abs(calculated_total - data[total_amount]) 0.01: raise ValueError( f金额不一致: 模型输出 {data[total_amount]}, f实际计算 {calculated_total} ) return data def retry_with_fallback(llm_call, response_text: str, max_retries: int 2): 当校验失败时可选择重新生成或使用兜底策略。 for attempt in range(max_retries): try: return validate_llm_response(response_text) except ValueError as e: print(f第 {attempt 1} 次校验失败: {e}) if attempt max_retries - 1: raise response_text llm_call()# 文件路径config/rag_config.yaml embedding: provider: openai model: text-embedding-3-small dimension: 1536 vector_store: type: qdrant collection_name: knowledge_base distance: cosine chunking: chunk_size: 512 chunk_overlap: 50 retrieval: top_k: 5 score_threshold: 0.65 search_type: hybrid # 向量检索 关键词检索 generation: model: gpt-4o temperature: 0.1 max_tokens: 800# 文件路径config/system_config.yaml validation: enabled: true schema_path: schemas/order_response.json check_amount_consistency: true max_retries: 2 fallback: strategy: rule_engine # 当校验失败时降级到规则引擎 rule_engine_endpoint: http://localhost:8081/parse monitoring: log_prompts: true log_responses: true error_rate_alert: 0.05 latency_alert_ms: 3000强调一下这里的核心思想LLM 是生成器它负责把人类的自然语言转成结构化的中间表示而校验代码是守门员它确保只有符合业务规则的输出才能进入下游系统。中间表示越结构化、越严格系统整体的可靠性就越高。5.3 兜底机制失败不是意外而是预期在生产环境设计中我们应该把模型出错当作预期内的事件而不是意外。因此需要为每个关键路径设计兜底方案。常见的兜底策略包括降级策略模型服务不可用或输出校验失败时降级到传统的规则引擎或模板匹配。人工审核队列低置信度的输出进入人工审核队列确保关键决策不依赖不稳定的模型输出。多模型表决对于高风险场景同时调用多个模型取结果交集或按投票规则决定最终结果。6. 完整示例构建一个稳定可控的 AI 客服助手前面讲了很多原则这一节用一个完整的示例把它们串起来。假设我们要构建一个客服助手能够根据企业内部知识库回答用户问题并自动创建工单。6.1 系统架构整个系统的处理链路如下用户输入问题。RAG 检索模块从向量数据库中检索相关文档。组装 prompt调用大模型生成回答。回答经过格式校验和敏感信息过滤。如果模型认为是工单类问题则调用结构化抽取模块创建工单。所有流程都有日志记录支持后续回溯和分析。6.2 核心代码实现# 文件路径customer_service_agent.py import json import logging from typing import Dict, Any, Optional from rag_retriever import RAGRetriever from response_validator import validate_llm_response logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) logger logging.getLogger(__name__) class CustomerServiceAgent: def __init__(self, config: Dict[str, Any]): self.config config self.retriever RAGRetriever(config.get(rag_config, {})) self.llm_client config.get(llm_client) self.sensitive_words [密码, 验证码, 身份证号] def _build_prompt(self, user_query: str, context_docs: list) - str: context \n\n.join( f[文档{i1}] {doc[content]} for i, doc in enumerate(context_docs) ) return f 你是企业的客服助手。请严格根据提供的文档内容回答用户问题。 如果文档中没有相关信息请明确回答抱歉我没有找到相关信息不要编造。 参考文档 {context} 用户问题{user_query} 请用简洁、友善的语气回答。如果用户要求查询订单、退款或开票请同时输出创建工单所需的结构化信息。 def _check_sensitive_info(self, response: str) - bool: 检查回答中是否包含敏感信息若包含则拒绝返回。 for word in self.sensitive_words: if word in response: logger.warning(f检测到敏感词: {word}) return True return False def handle_user_query(self, user_query: str) - Dict[str, Any]: # 1. 检索知识库 docs self.retriever.search(user_query, top_k3) if not docs: return { answer: 抱歉知识库中暂时没有相关信息请转人工处理。, should_create_ticket: False } # 2. 生成回答 prompt self._build_prompt(user_query, docs) response self.llm_client.chat(prompt, temperature0.1) # 3. 敏感信息过滤 if self._check_sensitive_info(response): return { answer: 该问题涉及敏感信息请通过人工渠道处理。, should_create_ticket: True } # 4. 尝试创建工单如果是工单类请求 try: ticket_data self._extract_ticket_data(user_query, response) if ticket_data is not None: logger.info(f创建工单: {json.dumps(ticket_data, ensure_asciiFalse)}) return { answer: response, should_create_ticket: True, ticket_data: ticket_data } except Exception as e: logger.error(f工单创建失败: {e}) return {answer: response, should_create_ticket: False} def _extract_ticket_data(self, user_query: str, model_response: str) - Optional[Dict[str, Any]]: 用第二个 LLM 调用抽取工单信息并经过 schema 校验。 extraction_prompt f 判断用户是否在请求客服处理。如果是请从对话中抽取工单信息以 JSON 格式返回 {{ category: order_query/refund/invoice/other, description: string, priority: low/medium/high }} 如果用户不是要请求客服处理返回 {{needs_ticket: false}}。 用户问题{user_query} 模型回答{model_response} try: raw self.llm_client.chat(extraction_prompt, temperature0) data json.loads(raw) if data.get(needs_ticket) is False: return None return validate_ticket_data(data) except Exception as e: logger.warning(f工单抽取失败: {e}) return None# 文件路径rag_retriever.py from typing import List, Dict, Any import numpy as np class RAGRetriever: 一个轻量的向量检索器示例实际项目中可替换为 Qdrant、Milvus 或 ElasticSearch。 def __init__(self, config: Dict[str, Any]): self.embedding_model config.get(embedding_model) self.top_k config.get(top_k, 3) self.documents [] self.embeddings [] def add_documents(self, docs: List[Dict[str, str]]): 添加文档并计算向量。 for doc in docs: self.documents.append(doc) vec self.embedding_model.embed(doc[content]) self.embeddings.append(np.array(vec)) def search(self, query: str, top_k: int 3) - List[Dict[str, Any]]: 余弦相似度检索。 query_vec np.array(self.embedding_model.embed(query)) if not self.embeddings: return [] scores [self._cosine_similarity(query_vec, vec) for vec in self.embeddings] top_indices np.argsort(scores)[-top_k:][::-1] return [ { content: self.documents[idx][content], score: float(scores[idx]) } for idx in top_indices if scores[idx] 0.5 ] staticmethod def _cosine_similarity(vec_a: np.ndarray, vec_b: np.ndarray) - float: return float(np.dot(vec_a, vec_b) / (np.linalg.norm(vec_a) * np.linalg.norm(vec_b) 1e-9))6.3 部署与运行验证# 启动 RAG 服务示例使用轻量内存模式生产环境建议使用 Qdrant/Milvus python -m rag_server --port 8001 # 启动客服 Agent 服务 python -m customer_service_agent --port 8000 # 发送测试请求 curl -X POST http://localhost:8000/query \ -H Content-Type: application/json \ -d {user_query: 你好我上周买的东西到现在还没有发货请问可以帮我查一下吗}如果一切正常你会收到回复并在服务端日志中看到对应的工单抽取记录。你可以故意输入一个知识库中没有的问题观察系统是否正确返回没有找到相关信息而不是开始编造答案。6.4 验证结果分析运行上述示例后重点观察三个指标幻觉率知识库没有覆盖的问题模型是否诚实地回答不知道。如果模型开始编造说明 prompt 中的约束不够强或者温度参数偏高。工单抽取准确率模型能否从对话中正确识别工单要素并且通过 JSON schema 校验。端到端时延从用户提问到最终回答的总耗时。RAG 检索、LLM 生成、校验过滤每个环节都会贡献延迟需要针对瓶颈优化。7. 常见问题与排查思路7.1 模型总是输出格式不正确的 JSON问题现象可能原因排查方式解决方案回答不是合法 JSON模型没有严格遵循格式指令在日志中查看原始输出在 prompt 中增加 few-shot 示例使用 response_format 参数JSON 结构正确但字段缺失schema 约束不严查看校验器的报错信息强制使用 JSON Schema 校验缺失字段直接触发重试JSON 中金额计算结果错误模型自行计算而非使用代码检查校验日志禁止模型输出计算类字段由后端代码统一计算7.2 RAG 检索结果不相关导致回答质量下降问题现象可能原因排查方式解决方案检索结果与问题无关文档切分不合理检查 top_k 检索结果的得分调整 chunk_size 和 overlap 参数语义相似但事实不对向量模型与业务领域不匹配抽取代表性 query人工检查检索结果微调 embedding 模型或切换领域模型检索得分很高但内容陈旧知识库未及时更新检查文档更新时间建立文档定期刷新机制7.3 Agent 在多步任务中执行中途跑偏问题现象可能原因排查方式解决方案Agent 在第二步就停止了工具调用返回了异常格式查看工具调用日志为工具增加输入输出校验失败时返回明确错误信息Agent 绕过了必要的校验步骤工作流定义不严谨检查 Agent 的步骤规划输出将关键校验步骤从 LLM 决策中剥离改为代码强制执行Agent 循环执行同一个工具模型陷入了重复模式查看步骤的执行轨迹增加最大迭代次数达到上限后强制人工介入7.4 模型服务响应慢影响用户体验问题现象可能原因排查方式解决方案单次请求耗时超过 5 秒上下文过长查看 token 使用统计精简 prompt控制上下文长度使用 prompt 缓存并发请求时性能骤降API 速率限制查看服务端返回码增加请求队列、接入限流器、考虑多模型负载均衡检索环节耗时占比过高向量数据库索引效率低查看分阶段耗时使用 HNSW 索引增加缓存层幂等查询加缓存8. 最佳实践与工程建议8.1 明确 AI 在系统中的职责边界这是最重要的一条建议。在系统设计阶段就明确哪些环节由 AI 负责哪些环节由 AI 生成但需要人工/代码审核哪些环节完全不允许 AI 介入。建议把经 AI 处理和未经 AI 处理的数据流分开标记让每个环节的负责人对系统的可靠性边界有清晰的认知。例如代码生成AI 生成草案 → 程序员 review → 单元测试通过后才合并。代码执行不允许 AI 直接在生产服务器上执行代码。数据删除任何删除操作必须经过人工确认AI 只有建议权没有执行权。权限变更AI 可以生成变更请求但必须由管理员审批后执行。这个边界意识能避免大量生产事故。8.2 Prompt 与配置的工程化管理生产环境中的 Prompt 不应该散落在代码里。建议把 prompt 模板、few-shot 示例、模型参数统一放到配置中心通过版本管理追踪变化。# 文件路径config/prompts/product_query.yaml system_prompt: | 你是产品查询助手。请仅根据提供的产品库信息回答。 如果产品库中没有用户询问的商品请回答当前没有找到相关产品信息。 不要推荐任何不在产品库中的商品。 few_shot_examples: - user: 你们有没有支持 PD 快充的充电宝 assistant: 根据产品库信息以下产品支持 PD 快充产品A容量10000mAh、产品B容量20000mAh。 - user: 有没有 5G 手机 assistant: 当前没有找到相关产品信息。 parameters: temperature: 0.1 top_p: 0.9 max_tokens: 300这样做的好处是当模型版本更新、业务规则变化时你可以单独调整 prompt 而不用改代码并且可以回溯到任意历史版本。8.3 观测性与日志体系AI 应用的可观测性比传统应用更复杂因为除了系统日志还需要记录prompt、模型输出、校验结果、人工反馈这四个维度的信息。建议建立以下监控指标模型调用量按 API 接口、模型名称、业务场景分类统计。token 消耗按场景统计用于成本核算和异常检测。校验通过率模型输出通过程序化校验的比例这个指标直接反映了生成质量。人工修正率如果流程中有人工审核环节统计人工修改回答的比例用于评估 prompt 的持续效果。延迟分布p50、p95、p99 延迟作为服务质量的核心指标。# 文件路径monitor/metrics.py from dataclasses import dataclass, field import time from typing import List, Dict dataclass class CallRecord: timestamp: float model: str prompt_tokens: int completion_tokens: int latency_ms: int validation_passed: bool error_type: str class MetricsCollector: def __init__(self): self.records: List[CallRecord] [] def record(self, model: str, prompt_tokens: int, completion_tokens: int, latency_ms: int, validation_passed: bool, error_type: str ): self.records.append(CallRecord( timestamptime.time(), modelmodel, prompt_tokensprompt_tokens, completion_tokenscompletion_tokens, latency_mslatency_ms, validation_passedvalidation_passed, error_typeerror_type )) def summary(self) - Dict[str, float]: if not self.records: return {} passed [r for r in self.records if r.validation_passed] total len(self.records) pass_rate len(passed) / total * 100 latencies sorted([r.latency_ms for r in self.records]) p95 latencies[int(total * 0.95)] if total 20 else latencies[-1] total_tokens sum(r.prompt_tokens r.completion_tokens for r in self.records) return { call_count: total, validation_pass_rate: pass_rate, p95_latency_ms: p95, total_tokens: total_tokens, error_types: self._error_type_summary() } def _error_type_summary(self) - Dict[str, int]: error_types {} for r in self.records: if r.error_type: error_types[r.error_type] error_types.get(r.error_type, 0) 1 return error_types8.4 安全与合规底线AI 应用的安全边界与传统软件不同有三个需要特别注意的点提示注入防护。用户输入可能包含恶意指令试图覆盖系统 prompt。处理方式是对用户输入进行转义把用户输入和系统指令在 prompt 中做明确分隔对模型输出做内容安全过滤关键操作必须走代码流程不能依赖模型判断。数据隐私保护。不要将包含敏感信息的对话直接发送给外部模型 API。如果使用第三方模型服务确保数据脱敏后再发送并签署数据处理协议。最小权限原则。AI 系统对接下游系统时只授予完成当前任务所需的最小权限。AI 没有权限执行删除、批量修改等高危操作所有此类操作都走人工审批流。8.5 测试驱动的持续优化AI 应用的优化应该是数据驱动的而不是靠感觉。建立一套完整的评测集每次修改 prompt、换模型、调参数都跑一遍评测集对比指标变化。# 在 CI 中集成回归测试 python evaluate_model.py --test-path test_prompts.json --model gpt-4o --output baseline_results.json python evaluate_model.py --test-path test_prompts.json --model gpt-4o-mini --output comparison_results.json # 对比两个模型在同一测试集上的表现 python compare_results.py baseline_results.json comparison_results.json一个小小的建议把评测集分成必须全部通过和尽量提升两层。必须全部通过的样例是你业务的核心场景不允许有任何答错尽量提升的样例是优化空间可以逐步完善。这样可以防止优化过程中引入回归。9. 总结与后续学习方向写这篇文章的初衷是想把AI 并不那么全能这件事讲透。过去一年多接触了不少做 AI 应用开发的团队发现最成功的项目不是那些让 AI 全权负责的项目而是那些把 AI 放到正确位置、用工程手段兜底的系统。AI 更像一个能力很强但需要被管理的新员工——你给它清晰的职责边界准备好校验和兜底机制它就能发挥巨大的价值你让它自由发挥它就会给你制造无穷无尽的麻烦。如果你正在设计一个新的 AI 应用建议从今天开始做三件事第一建立属于你自己业务场景的评测集。不要依赖公开 benchmark真实的业务数据才是验证模型可靠性的唯一标准。第二把模型输出和程序校验解耦。让 LLM 专注于它擅长的自然语言理解和生成用传统代码保证业务规则的确定性。第三为系统设计好降级和兜底路径。把模型不可用、输出错误当成预期内的情况来对待而不是侥幸地希望它在生产环境保持完美。如果你想继续深入以下几个方向值得关注RAG 的文档切分策略优化和重新排序Agent 的工具调用协议设计和规划算法改进函数调用Function Calling的结构化学输出约束模型蒸馏和小规模模型在垂直场景的微调AI 系统的可观测性框架设计。AI 的能力边界不会一夜之间消失但工程化的方法可以让我们在边界内做出稳定可靠的产品。希望这篇文章能给你一些启发也欢迎在实际项目中验证这些思路。如果遇到具体问题欢迎在评论区交流。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价