拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Agent结构化输出四层约束方案:Prompt、原生参数与代码校验

大家好这是一篇围绕大模型 Agent 面试与实战整理的笔记。最近在准备大模型应用开发相关的面试我发现自己最容易被追问的一个问题不是“你会不会写 Prompt”而是“如果 Agent 输出的内容不按约定结构返回线上系统怎么办”。很多业务场景都需要模型稳定地吐出 JSON、Markdown 表格、固定字段但模型不是数据库它的输出天然带有概率性。本文从工程落地角度整理了一套四层约束方案Prompt 强制、正反示例、原生参数、代码校验。每一层都有完整的思路和代码示例无论你是刚开始接触 Agent 开发还是已经在做 AI 应用落地都可以按这个框架去设计你的输出稳定性方案。1. 背景与核心概念为什么 Agent 的输出经常“不讲规矩”1.1 什么是 Agent 的结构化输出在 AI Agent 开发中结构化输出指的是模型返回的内容不是一段自由文本而是符合预先定义格式的数据比如 JSON、XML、Markdown 表格、固定枚举值等。实际业务系统需要拿这些字段去接数据库、对接下游接口、驱动 UI 渲染甚至直接作为代码参数执行。举个例子一个智能客服 Agent 需要判断用户意图并返回intent意图分类confidence置信度reply回复文本should_escalate是否需要转人工如果模型直接输出{ intent: 退款, confidence: 0.93, reply: 您的问题已记录正在为您处理退款流程。, should_escalate: false }程序很容易解析。但实际运行中模型可能会输出成{ intent: 退款, confidence: high, reply: 您的问题已记录正在为您处理退款流程。, should_escalate: 否 }也可能直接输出带解释的文字比如“这是一个退款意图置信度较高回复如下好的马上处理。”这种不可控的输出就是 Agent 落地时最让人头疼的问题之一。1.2 结构化输出为什么这么难大语言模型本质上是“预测下一个 token”的模型。你给模型一段指令它根据概率生成后文。你的 Prompt 可以要求它“必须输出 JSON”但在生成过程中模型仍然可能受到各种因素影响包括Prompt 中的措辞不够精确。模型误把示例中的错误格式当成了模仿对象。API 参数没有启用 JSON 模式。模型生成了多余的解释性文字。JSON 本身出现换行、引号转义问题。所以靠单一手段解决输出稳定性是不现实的。我们需要一套分层防线让每层策略各司其职在任何一个环节出问题都能被下一层兜住。1.3 四层约束整体思路本文讲到的“四层约束”是一个由软到硬、层层递进的结构层级名称核心作用典型手段第一层Prompt 强制从指令上约束模型明确输出格式、字段含义、禁止输出多余内容第二层正反示例从示例上引导模型Few-shot 示例包含正确格式与错误格式第三层原生参数从模型 API 层面限制response_format、function calling、JSON Mode第四层代码校验从程序上强制兜底解析 JSON、Pydantic 校验、失败重试我们可以把前两层看成“软约束”它们属于 Prompt Engineering 层面成本低、见效快第三层属于平台能力第四层属于工程兜底。当面试官问“怎么让 Agent 稳定输出结构化内容”时我们不要只说“加大模型 temperature 调低”而是要能把四层结构讲清楚并且给出每层的细节和坑。2. 环境准备与版本说明在开始写示例代码前先把环境整理一下。本文示例采用 Python这是目前 Agent 开发最主流的语言。为了保证不同读者都能理解我尽量用最通用的 API 写法并标注哪些参数需要根据你所用的模型版本调整。2.1 基础环境项目建议操作系统Windows / macOS / Linux 均可Python3.9 及以上依赖库openai、pydantic、python-dotenv模型接口OpenAI 兼容的 Chat Completions APIIDEVS Code、PyCharm 或任意编辑器如果你的网络环境和模型服务使用了国内大模型厂商提供的 OpenAI 兼容接口同样适用本文代码只需要修改base_url和api_key即可。2.2 安装依赖建议先创建一个虚拟环境避免污染系统环境python -m venv venv source venv/bin/activate # Windows 为 venv\Scripts\activate安装依赖pip install openai pydantic python-dotenv版本说明openai库在 1.x 版本后 API 风格发生较大变化本文代码以 1.x 为例。如果你使用的是 0.x 老版本需要将client.chat.completions.create的写法替换为旧版方式。实际开发中请以你安装的库版本文档为准。2.3 准备密钥在项目根目录创建.env文件OPENAI_API_KEY你的密钥 OPENAI_BASE_URLhttps://api.openai.com/v1如果是国内模型服务可以配置成对应的base_url。不要将.env提交到 Git 仓库。2.4 项目结构本文完整示例项目结构如下agent_structured_output/ ├── .env ├── main.py ├── schemas.py ├── prompts.py └── agent.py下面我们将按四层约束递进每层都有对应示例最后在agent.py中整合成完整可用的小型 Agent。3. 第一层约束Prompt 强制3.1 什么是 Prompt 强制Prompt 强制是最直接、成本最低的约束手段。我们通过在系统指令中明确告诉模型“输出什么格式、输出哪些字段、每个字段是什么类型、禁止输出什么”让模型在生成阶段就偏向于遵循格式。很多人写 Prompt 时会写“请返回 JSON”但这样太模糊。模型不知道 JSON 里要包含哪些键也不知道值该用什么类型。所以Prompt 强制的核心是把输出规范写得毫不含糊像一个接口文档一样给模型。3.2 一个不合格的 Prompt 示例先看一个反例请分析用户意图返回JSON。这种 Prompt 很可能让模型输出{意图: 退款, 可靠性: 0.9}或者根据用户输入用户的意图是退款置信度较高。以下是JSON{...}字段名不统一、键是中文、类型不一致、输出内容混乱给下游解析带来很大成本。3.3 改进后的 Prompt 模板下面是一份适合放进系统消息里的 Prompt你是智能客服系统的意图分类组件。请根据用户输入输出严格的 JSON 对象不要输出任何解释、标记或额外文字。 JSON 结构必须如下 { intent: 字符串必须是以下值之一退款、退货、物流查询、人工客服, confidence: 浮点数范围0到1表示模型对该意图的置信度, reply: 字符串面向用户的回复内容, should_escalate: 布尔值true表示需要转人工客服 } 约束 1. 只输出 JSON不要输出 json 代码块标记。 2. 不要添加任何说明性前缀或后缀。 3. 如果无法判断意图intent 输出人工客服confidence 输出0.0。这份 Prompt 做了几件事明确了输出格式是 JSON。定义了每个键名、键值类型和取值范围。对无法判断的情况给了兜底策略。明确禁止代码块标记和多余文字。3.4 Prompt 强制的局限即便我们把 Prompt 写得非常细模型仍然可能“违约”。比如模型生成的 JSON 里多了一个逗号或者 confidence 写成了字符串0.93又或者整个输出被包裹在 Markdown 代码块里。Prompt 只是概率上的“引导”不是“约束”。所以它必须和其他层配合使用。小结第一层要做好但不要指望它解决所有问题。面试时可以说Prompt 强制是结构化输出的基础它负责把期望格式传达给模型但受限于模型的概率生成机制还需要后续层兜底。4. 第二层约束正反示例4.1 为什么示例比指令更有效大模型在 Prompt 中“少样本学习”的能力很强。给模型一个“正确示例”和“错误示例”往往比反复强调“不要输出什么”更有效。原因在于示例为模型提供了具体的模仿目标模型在生成时会倾向于复制示例中的格式。正反示例有两个关键作用正向示例告诉模型“我想要的正确结果长什么样”。反向示例告诉模型“哪些输出会被系统判定为无效”。4.2 正向示例写法在系统 Prompt 中加入下面是两个正确处理示例 示例1 用户输入我要退货 正确输出 {intent: 退货, confidence: 0.95, reply: 已为您提交退货申请请确认商品状态。, should_escalate: false} 示例2 用户输入请问你们几点下班 正确输出 {intent: 人工客服, confidence: 0.62, reply: 我们的人工客服工作时间是9:00-18:00请问有什么可以帮您, should_escalate: true}这里要注意示例中的confidence数值要尽量真实不要让模型产生“只要填一个差不多的数字就行”的错觉。4.3 反向示例写法反向示例不需要太多一两个就够了。核心是清楚地告诉模型“这种输出会被打回”。下面是一个错误处理示例 用户输入我要退货 错误输出 {intent: 退货, confidence: 高, reply: 好的马上处理。, should_escalate: 是} 这段输出错误的原因 1. confidence 应为浮点数而不是字符串高。 2. should_escalate 应为布尔值而不是字符串是。 3. reply 过于简短没有提供有效处理信息。反向示例的价值在于它相当于给模型提供了一次“纠错训练”。模型生成时会主动避开这些错误模式。4.4 正反示例的组合使用在实际 Prompt 中我们可以将正反示例合并为一个完整模板。这里给出一个可复用的prompts.py文件片段# 文件路径prompts.py SYSTEM_PROMPT 你是智能客服系统的意图分类组件。请根据用户输入输出严格的 JSON 对象不要输出任何解释、标记或额外文字。 JSON 结构必须如下 { intent: 字符串必须是以下值之一退款、退货、物流查询、人工客服, confidence: 浮点数范围0到1表示模型对该意图的置信度, reply: 字符串面向用户的回复内容, should_escalate: 布尔值true表示需要转人工客服 } 正确示例1 用户输入我要退货 正确输出 {intent: 退货, confidence: 0.95, reply: 已为您提交退货申请请确认商品状态。, should_escalate: false} 正确示例2 用户输入请问你们几点下班 正确输出 {intent: 人工客服, confidence: 0.62, reply: 我们的人工客服工作时间是9:00-18:00请问有什么可以帮您, should_escalate: true} 错误示例 用户输入我要退货 错误输出 {intent: 退货, confidence: 高, reply: 好的马上处理。, should_escalate: 是} 错误原因confidence 必须是浮点数should_escalate 必须是布尔值reply 不能太短。 约束 1. 只输出 JSON不要输出 json 代码块标记。 2. 不要添加任何说明性前缀或后缀。 3. 如果无法判断意图intent 输出人工客服confidence 输出0.0。 这里需要注意示例不要放太多否则容易挤占上下文窗口也容易让模型产生“过度模仿”的问题。通常正向示例 1-3 个反向示例 1 个即可。4.5 第二层局限正反示例虽然效果好但仍属于“提示词”层面模型依然可能输出不规范内容。尤其是当模型上下文很长、或者用户输入很复杂时模型可能把示例中的格式遗忘。所以第二层是增强不是兜底。5. 第三层约束原生参数5.1 什么是原生参数约束原生参数指的是在模型 API 调用层面直接启用的能力。目前主流大模型 API 基本都支持以下几种方式response_format{type: json_object}强制模型返回 JSON 对象。JSON Schema / Structured Outputs让模型按给定 JSON Schema 生成。function calling / tools让模型选择并输出符合函数签名的参数。一些模型厂商还支持正则约束、grammar 约束等。使用原生参数的好处是模型在解码阶段就会受到更强的约束显著降低格式错误率。但也不是 100%所以我们仍然需要第四层代码校验。5.2 使用response_format强制 JSON在 OpenAI 兼容接口中一个常见的做法是from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL) ) response client.chat.completions.create( modelgpt-4o-mini, response_format{type: json_object}, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: 我要退货} ] ) print(response.choices[0].message.content)这里的关键参数是response_format{type: json_object}。它告诉模型“必须返回一个 JSON 对象”。不过要注意它的约束力度是“返回 JSON 对象”但不会强制对象里包含哪些键。有些模型要求必须在 Prompt 中出现“json”字样否则会报错。不同模型厂商的实现细节不一样需要查看对应文档。5.3 使用 JSON Schema 约束字段如果模型 API 支持Structured Outputs我们可以传入 JSON Schema让模型严格按照 Schema 输出。这是比json_object更强的约束。以 OpenAI 兼容接口为例代码大致如下response client.chat.completions.create( modelgpt-4o-mini, response_format{ type: json_schema, json_schema: { name: intent_result, schema: { type: object, properties: { intent: {type: string, enum: [退款, 退货, 物流查询, 人工客服]}, confidence: {type: number, minimum: 0, maximum: 1}, reply: {type: string}, should_escalate: {type: boolean} }, required: [intent, confidence, reply, should_escalate], additionalProperties: False } } }, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: 我要退货} ] )注意不是所有模型接口都支持json_schema而且各家的字段名称可能有差异。如果你们公司用的私有化模型只支持json_object就不要硬套json_schema字段。写代码前先查接口文档。5.4 使用 Function Calling 作为替代方案如果 Agent 本身要调用工具我们可以直接使用 function calling 机制把结构化输出放在函数参数中。比如定义一个analyze_intent工具tools [ { type: function, function: { name: analyze_intent, description: 分析用户意图并返回结构化结果, parameters: { type: object, properties: { intent: { type: string, enum: [退款, 退货, 物流查询, 人工客服] }, confidence: { type: number, minimum: 0, maximum: 1 }, reply: { type: string }, should_escalate: { type: boolean } }, required: [intent, confidence, reply, should_escalate] } } } ] response client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 我要退货}], toolstools, tool_choice{type: function, function: {name: analyze_intent}} ) # 从响应中提取函数参数 tool_calls response.choices[0].message.tool_calls if tool_calls: import json args json.loads(tool_calls[0].function.arguments) print(args)这种方式的好处是模型生成的内容天然就是函数参数 JSON而且我们可以在parameters中定义枚举、类型、必填字段像是给模型一个“类型系统”。不过要注意tool_choice强制指定函数时只适合“本次调用必须走这个工具”的场景如果 Agent 需要自主选择工具就不要强制tool_choice否则可能误用。5.5 第三层局限原生参数已经很强但依然有以下问题json_object不保证 key 齐全。json_schema也不是所有模型都支持部分私有化模型实现不完善。function calling 本身可能失败尤其当上下文较长或模型版本较老时。模型仍然可能输出非法的 JSON比如多余逗号、漏掉冒号。因此我们还需要第四层在代码里做最终校验。6. 第四层约束代码校验6.1 为什么代码校验必不可少无论前面三层做得多好Agent 的最终输出都要进入代码去解析和校验。代码校验是整个体系的“安全网”。它不信任模型只信任数据结构。当模型输出不符合预期时程序可以选择重试、修复、或者转入人工兜底。代码校验的核心是解析模型输出为 Python 对象。校验字段类型、取值范围、必填项。不通过时把错误信息反馈给模型让它重新生成。6.2 使用 Pydantic 定义数据模型Pydantic 是目前 Python 最流行的数据校验库之一。先定义我们的输出结构# 文件路径schemas.py from pydantic import BaseModel, Field from typing import Literal class IntentResult(BaseModel): intent: Literal[退款, 退货, 物流查询, 人工客服] confidence: float Field(ge0.0, le1.0) reply: str should_escalate: bool这里用Literal限定intent必须是给定值Field(ge0.0, le1.0)限定 confidence 范围should_escalate必须是布尔值。这样只要构造IntentResult成功就说明输出结构完全合法。6.3 解析与校验函数接下来写一个通用函数用于把模型输出字符串解析成IntentResult# 文件路径agent.py 片段 import json from pydantic import ValidationError from schemas import IntentResult def parse_intent_output(text: str) - IntentResult: 解析模型输出并校验。 输入是模型返回的字符串输出是 IntentResult 实例。 校验失败时抛出 ValueError由上层决定如何处理。 # 先尝试去除可能的 Markdown 代码块标记 cleaned text.strip() if cleaned.startswith(json): cleaned cleaned[7:] if cleaned.startswith(): cleaned cleaned[3:] if cleaned.endswith(): cleaned cleaned[:-3] cleaned cleaned.strip() # 解析 JSON try: data json.loads(cleaned) except json.JSONDecodeError as e: raise ValueError(f模型输出不是合法 JSON: {e}原始内容: {text}) # 校验结构 try: return IntentResult(**data) except ValidationError as e: raise ValueError(f模型输出字段不符合要求: {e}原始内容: {text})这段代码的处理逻辑是去除 Markdown 代码块标记。用json.loads解析。用IntentResult校验字段类型和取值。失败时抛出异常不放过任何非法输出。6.4 失败重试机制光校验还不够我们需要把校验失败的信息反馈给模型让它“重新写”。这就是 Agent 开发中常见的“修正循环”。思路是def generate_structured_intent(client, user_input, max_retries2): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input} ] for attempt in range(max_retries 1): response client.chat.completions.create( modelgpt-4o-mini, response_format{type: json_object}, messagesmessages, temperature0.2, ) content response.choices[0].message.content try: return parse_intent_output(content) except ValueError as e: if attempt max_retries: # 最后兜底返回一个默认结果或抛出异常 raise RuntimeError(f模型连续 {max_retries 1} 次输出不合法: {e}) # 把错误信息追加到对话中让模型自行修正 messages.append({role: assistant, content: content}) messages.append({ role: user, content: f你刚才的输出不符合要求错误信息{e}。请严格按要求的 JSON 格式重新输出。 }) raise RuntimeError(unreachable)可以看到当模型输出不合法时我们把原始输出和错误信息重新发给模型相当于给了它一次“改错提示”。这在实践中能有效提升最终成功率。但要注意不要无限重试否则会产生较大的 token 消耗。建议最多重试 2-3 次。6.5 第四层局限代码校验也不是万能的。它不能保证模型在语义上正确比如 model 把“退货”识别成了“退款”这种语义错误代码层无法直接发现。要解决这个问题还需要引入更多评估机制例如用另一个模型做交叉校验或者记录预测置信度做人工抽检。但至少代码校验能保证下游拿到的数据是“合法”格式不会因为多一个字段或类型错误导致系统崩溃。7. 完整实战案例搭建一个具备四层约束的 Agent7.1 需求分析我们现在做一个最小可运行的 Agent 示例功能是接收用户输入输出意图分类结果。要求模型输出必须满足IntentResult结构。我们将四层约束全部集成进去。7.2 创建项目文件项目结构如下agent_structured_output/ ├── .env ├── schemas.py ├── prompts.py ├── agent.py └── main.py7.3 编写 schemas.py# 文件路径schemas.py from pydantic import BaseModel, Field from typing import Literal class IntentResult(BaseModel): intent: Literal[退款, 退货, 物流查询, 人工客服] confidence: float Field(ge0.0, le1.0) reply: str should_escalate: bool7.4 编写 prompts.py# 文件路径prompts.py SYSTEM_PROMPT 你是智能客服系统的意图分类组件。请根据用户输入输出严格的 JSON 对象不要输出任何解释、标记或额外文字。 JSON 结构必须如下 { intent: 字符串必须是以下值之一退款、退货、物流查询、人工客服, confidence: 浮点数范围0到1表示模型对该意图的置信度, reply: 字符串面向用户的回复内容, should_escalate: 布尔值true表示需要转人工客服 } 正确示例1 用户输入我要退货 正确输出 {intent: 退货, confidence: 0.95, reply: 已为您提交退货申请请确认商品状态。, should_escalate: false} 正确示例2 用户输入请问你们几点下班 正确输出 {intent: 人工客服, confidence: 0.62, reply: 我们的人工客服工作时间是9:00-18:00请问有什么可以帮您, should_escalate: true} 错误示例 用户输入我要退货 错误输出 {intent: 退货, confidence: 高, reply: 好的马上处理。, should_escalate: 是} 错误原因confidence 必须是浮点数should_escalate 必须是布尔值reply 不能太短。 约束 1. 只输出 JSON不要输出 json 代码块标记。 2. 不要添加任何说明性前缀或后缀。 3. 如果无法判断意图intent 输出人工客服confidence 输出0.0。 7.5 编写 agent.py# 文件路径agent.py import json import os from dotenv import load_dotenv from openai import OpenAI from prompts import SYSTEM_PROMPT from schemas import IntentResult load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL) ) def parse_intent_output(text: str) - IntentResult: 解析并校验模型输出。 cleaned text.strip() if cleaned.startswith(json): cleaned cleaned[7:] elif cleaned.startswith(): cleaned cleaned[3:] if cleaned.endswith(): cleaned cleaned[:-3] cleaned cleaned.strip() try: data json.loads(cleaned) except json.JSONDecodeError as e: raise ValueError(f模型输出不是合法 JSON: {e}原始内容: {text}) try: return IntentResult(**data) except Exception as e: raise ValueError(f模型输出校验失败: {e}原始内容: {text}) def generate_intent(user_input: str, max_retries: int 2) - IntentResult: 四层约束完整调用入口。 messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input} ] for attempt in range(max_retries 1): response client.chat.completions.create( modelgpt-4o-mini, response_format{type: json_object}, messagesmessages, temperature0.2, ) content response.choices[0].message.content try: return parse_intent_output(content) except ValueError as e: if attempt max_retries: # 最后兜底直接抛错上层可以做告警、降级或人工处理 raise RuntimeError(f模型连续 {max_retries 1} 次输出不合法: {e}) messages.append({role: assistant, content: content}) messages.append({ role: user, content: f你刚才的输出不符合要求错误信息{e}。请严格按要求的 JSON 格式重新输出。 }) raise RuntimeError(unreachable)代码里用了第三层response_format同时也用了第四层parse_intent_output并在失败后自动把错误信息反馈给模型重试。这样Prompt 强制、正反示例、原生参数、代码校验就全部串联了起来。7.6 编写 main.py# 文件路径main.py from agent import generate_intent def main(): user_input input(请输入用户问题) try: result generate_intent(user_input) print(结构化输出) print(result.model_dump()) except Exception as e: print(处理失败, e) if __name__ __main__: main()7.7 运行与验证在项目目录执行python main.py输入我要退货预期输出类似结构化输出 {intent: 退货, confidence: 0.95, reply: 已为您提交退货申请请确认商品状态。, should_escalate: False}你还可以测试边界输入比如“你们晚上几点下班”、“退款退到哪里”观察intent和should_escalate是否符合预期。7.8 为什么这个示例能证明四层约束有效在这个示例里Prompt 强制系统消息中明确要求 JSON 结构和字段枚举。正反示例给出了正确和错误两种格式引导模型模仿正确格式。原生参数response_format{type: json_object}在 API 层提高了 JSON 输出概率。代码校验最终用 Pydantic 校验不合法就重试不信任模型。如果面试官继续追问还可以这样总结这四层不是“叠加越多越好”而是“每层解决不同问题”。Prompt 解决“模型知道规则”示例解决“模型模仿规则”原生参数解决“模型解码倾向”代码解决“系统不崩溃”。8. 常见问题与排查思路在实际落地过程中我们大概率会遇到下面几类问题。问题现象常见原因解决思路模型输出带json代码块导致json.loads失败Prompt 未禁止代码块或模型“习惯性”包裹 Markdown在解析前去除 标记在 Prompt 中强调禁止输出代码块字段类型错误如confidence输出为字符串Prompt 没有指定类型或示例不够清晰增加正反示例使用 JSON Schema / function calling 约束类型intent枚举值超出预期如“退货退款”枚举范围不明确在 Prompt 中列出所有合法值在代码校验中枚举不合法则重试模型输出包含解释性文本如“好的分析如下{...}”没有对多余文本做禁止Prompt 强化“只输出 JSON”代码提取第一个 { 或最后一个 }重试多次仍然失败模型能力不足、Prompt 表达不清、或者接口不支持 JSON Mode降低任务复杂度拆分为多个小步骤提高max_retries转入人工兜底调用response_format报错当前模型/接口不支持该参数去掉原生参数用 Prompt 校验兜底或升级到支持该参数的模型模型对语义判断错误比如把退货识别成退款字段枚举值之间存在语义重叠调整枚举定义提供更多正反示例用温度更低或更强模型排查时建议先打印模型原始输出确认是哪一个环节出了问题。不要直接改代码而是先看 Prompt 和模型输出之间的关系。9. 最佳实践与工程建议9.1 分层设计各司其职不要把所有赌注押在 Prompt 上也不要把所有希望寄托在response_format上。最稳妥的做法是第一层写清楚格式和约束。第二层给示例尤其是错误示例。第三层API 支持就开启 JSON Mode / Schema。第四层代码校验 重试。四层缺一不可但每一层的作用不同。实际项目中如果模型能力较强前两层效果可能就很好如果模型能力一般第三层和第四层才是稳定性的保障。9.2 设置重试上限与告警重试不是无限循环。每次重试都会增加 token 消耗和延迟。建议max_retries设置为 2 或 3。重试次数用尽后记录日志、告警并降级为人工客服或默认回复。对重试次数、失败率做监控。9.3 日志记录要完整无论是开发调试还是线上排障都需要记录原始模型输出。校验错误信息。第几次重试。最终是否成功。不要只记录最终结构否则出问题后很难定位。9.4 注意 Prompt 版本管理结构化输出的 Prompt 经常需要迭代。建议把 Prompt 当作代码一样管理使用独立的prompts.py文件或放到配置中心。记录版本号便于 A/B 测试和回滚。修改 Prompt 时同步更新示例和测试用例。9.5 验证不仅仅是格式还包括语义代码校验只能保证“格式对”不能保证“内容对”。为了评估模型效果你可以准备一批测试用例定期跑一下准确率。如果发现输出格式稳定但语义准确率下降可能需要调 Prompt 或换模型。不要只看 JSON 是否解析成功。9.6 使用评估集做回归测试当你修改 Prompt 时建议维护一个包含 20-50 条样本的小测试集。每个样本包括用户输入、期望意图、是否转人工等信息。每次改动后跑一遍看看格式成功率与语义准确率是否达标。这是 Agent 工程化必不可少的一步。9.7 对敏感场景做兜底如果 Agent 面向 C 端用户模型误判可能引发投诉。比如用户说“我要自杀”模型应该转人工客服而不是机械地执行退款。所以结构化输出之外建议设置敏感词或风险识别规则。将高风险 case 强制转入人工。对should_escalate等关键字段做额外规则判断。10. 面试回答思路提炼最后把“怎么让 Agent 稳定输出结构化内容”这个问题浓缩成一套面试回答思路你可以根据自己的项目经历调整细节。第一步点明问题本质大模型是概率生成模型不能像传统程序一样保证输出格式所以需要多级约束。第二步给出四层方案Prompt 强制把输出格式、字段、类型、枚举写清楚。正反示例给模型正确和错误示例强化模仿。原生参数开启 JSON Mode、JSON Schema、function calling。代码校验用 Pydantic 解析校验失败则重试或降级。第三步结合项目说明这时可以讲一个你实际做过的 Agent 例子说明你用了上述四层后结构化成功率从多少提升到多少。如果你没有真实数据可以说“结合我目前的实践四层方案能显著降低下游解析报错”不要编造具体百分比。第四步强调工程化思考包括重试上限、日志监控、Prompt 版本管理、语义评估。这样面试官会觉得你不仅会写 Prompt还懂系统落地。另外在具体开发中要记住结构化输出不是“把 temperature 调低”就能完全解决的。它是一个系统问题需要用系统方案来解决。如果大家在实际项目中还遇到其他输出不稳定的问题欢迎在评论区留言交流。我的建议是先从日志里拿一条真实失败案例逐层排查通常很快就能定位到问题。希望这篇内容对你准备 AI 大模型面试和 Agent 开发都有帮助也欢迎收藏备用后续实践时可以对照检查自己的实现。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门