Agent Planner输出不是合法JSON怎么办?Schema约束、提取、校验与自动修复
一、为什么Planner比普通问答更怕格式错误普通问答多一个标点通常没有影响。Planner输出却要被程序直接执行{steps:[{id:S1,task:查询订单,dependencies:[]}]}如果出现以下问题执行器就可能失败输出Markdown代码块JSON前后有解释文字使用单引号字段名称变化steps不是数组步骤ID重复依赖不存在循环依赖工具名称不存在步骤数量失控。所以Planner必须经过格式解析 → Schema校验 → 语义校验 → 图结构校验 → 安全校验二、先定义稳定的数据模型使用Pydantic 2frompydanticimportBaseModel,FieldfromtypingimportLiteralclassPlanStep(BaseModel):id:strField(patternr^S[1-9][0-9]*$)title:strField(min_length1,max_length80)description:strField(min_length1,max_length500)dependencies:list[str]Field(default_factorylist)tool_hint:str|NoneNoneexpected_output:strField(min_length1,max_length300)risk_level:Literal[low,medium,high]lowclassTaskPlan(BaseModel):objective:strField(min_length1,max_length500)assumptions:list[str]Field(default_factorylist)steps:list[PlanStep]Field(min_length1,max_length20)completion_criteria:list[str]Field(min_length1)Schema本身就限制ID格式字段长度步骤数量风险等级枚举必填字段。三、Prompt中给出严格输出协议你是任务规划器。 只输出一个JSON对象不要输出Markdown代码块、解释、前言或结尾。 输出必须符合以下规则 1. steps数量为1到20。 2. 步骤ID使用S1、S2、S3格式。 3. dependencies只能引用已经存在的步骤ID。 4. 不允许循环依赖。 5. 每个步骤必须可以独立判断是否完成。 6. 高风险动作标记risk_levelhigh。 7. 不得生成未注册工具名称。Prompt可以降低错误率但不能替代程序校验。四、提取JSON对象模型可能返回以下是计划 json {...}可以先去除代码围栏 python import re def strip_markdown_fence(text: str) - str: text text.strip() fence re.fullmatch( r(?:json)?\s*(.*?)\s*, text, flagsre.DOTALL | re.IGNORECASE ) if fence: return fence.group(1).strip() return text如果前后还有文字可以提取第一个完整JSON对象。推荐使用字符状态机而不是简单正则defextract_first_json_object(text:str)-str:starttext.find({)ifstart0:raiseValueError(响应中没有JSON对象)depth0in_stringFalseescapeFalseforindexinrange(start,len(text)):chartext[index]ifescape:escapeFalsecontinueifchar\\andin_string:escapeTruecontinueifchar:in_stringnotin_stringcontinueifin_string:continueifchar{:depth1elifchar}:depth-1ifdepth0:returntext[start:index1]raiseValueError(JSON对象不完整)五、执行JSON和Pydantic校验importjsonfrompydanticimportValidationErrordefparse_plan(raw_text:str)-TaskPlan:cleanstrip_markdown_fence(raw_text)json_textextract_first_json_object(clean)try:datajson.loads(json_text)exceptjson.JSONDecodeErrorasexc:raiseValueError(fJSON解析失败line{exc.lineno}, col{exc.colno}, msg{exc.msg})fromexctry:returnTaskPlan.model_validate(data)exceptValidationErrorasexc:raiseValueError(f计划Schema校验失败{exc.errors()})fromexc不要自动把单引号替换成双引号因为字符串内部可能包含单引号错误修复可能改变原意容易掩盖模型输出质量问题。六、校验步骤ID与依赖defvalidate_dependencies(plan:TaskPlan)-None:step_ids[step.idforstepinplan.steps]iflen(step_ids)!len(set(step_ids)):raiseValueError(存在重复步骤ID)knownset(step_ids)forstepinplan.steps:ifstep.idinstep.dependencies:raiseValueError(f步骤{step.id}不能依赖自己)unknownset(step.dependencies)-knownifunknown:raiseValueError(f步骤{step.id}引用未知依赖{sorted(unknown)})还可以要求依赖只能指向前面的步骤defvalidate_dependency_order(plan:TaskPlan)-None:positions{step.id:indexforindex,stepinenumerate(plan.steps)}forstepinplan.steps:fordependencyinstep.dependencies:ifpositions[dependency]positions[step.id]:raiseValueError(f{step.id}依赖了未提前定义的{dependency})如果执行器支持真正DAG不强制顺序也可以但必须做循环检测。七、检测循环依赖使用Kahn算法fromcollectionsimportdefaultdict,dequedefvalidate_acyclic(plan:TaskPlan)-None:graph:dict[str,list[str]]defaultdict(list)indegree:dict[str,int]{step.id:0forstepinplan.steps}forstepinplan.steps:fordependencyinstep.dependencies:graph[dependency].append(step.id)indegree[step.id]1queuedeque(step_idforstep_id,degreeinindegree.items()ifdegree0)visited0whilequeue:currentqueue.popleft()visited1fornext_stepingraph[current]:indegree[next_step]-1ifindegree[next_step]0:queue.append(next_step)ifvisited!len(plan.steps):raiseValueError(计划中存在循环依赖)典型错误S1依赖S3 S2依赖S1 S3依赖S2格式完全合法但永远无法开始执行。八、校验工具白名单REGISTERED_TOOLS{search_web,query_order,query_inventory,generate_report}defvalidate_tools(plan:TaskPlan)-None:forstepinplan.steps:if(step.tool_hintisnotNoneandstep.tool_hintnotinREGISTERED_TOOLS):raiseValueError(f步骤{step.id}使用未注册工具{step.tool_hint})Planner不能凭空创造不存在的工具执行器必须只接受已注册工具。九、把错误反馈给模型修复首次失败后不要简单重复原Prompt。应提供明确校验错误defbuild_repair_prompt(original_request:str,invalid_output:str,error_message:str)-str:returnf 你上一次生成的任务计划无法通过校验。 用户任务{original_request}校验错误{error_message}原始输出{invalid_output}请修复计划。 只输出完整JSON对象不要输出解释或Markdown代码块。 修复最多尝试1—2次defgenerate_valid_plan(client,user_request:str)-TaskPlan:rawclient.complete(build_plan_prompt(user_request))forattemptinrange(2):try:planparse_plan(raw)validate_dependencies(plan)validate_acyclic(plan)validate_tools(plan)returnplanexceptValueErrorasexc:ifattempt1:raiserawclient.complete(build_repair_prompt(user_request,raw,str(exc)))raiseRuntimeError(无法生成有效计划)十、不要无限修复如果连续失败应降级1. 使用更强模型重试一次 2. 切换到简单单步计划 3. 请求用户补充信息 4. 转人工处理建议记录planner_model attempt_count validation_error raw_output_hash repair_success十一、结构合法还不够以下计划Schema正确但没有执行价值{steps:[{id:S1,title:完成任务,description:把任务完成,dependencies:[],expected_output:任务完成,risk_level:low}]}需要语义规则步骤必须可执行不能简单重复用户目标expected_output必须可验证每一步粒度适中不得包含未提供的敏感信息高风险步骤必须标记。可以增加Reviewer模型但最终安全边界仍由规则控制。十二、生产级处理链模型生成 → 去除围栏 → 提取JSON → JSON解析 → Pydantic校验 → ID与依赖校验 → DAG循环检测 → 工具白名单 → 风险规则 → 自动修复一次 → 降级或人工总结Planner输出不是合法JSON不能只靠一句“请严格输出JSON”解决。可靠方案必须同时具备明确Schema 解析器 类型校验 图结构校验 工具白名单 有限修复 失败降级只有经过校验的计划才能进入执行器。

相关新闻

深入掌握 java -jar 命令:从基础到 Jenkins Agent 实战

深入掌握 java -jar 命令:从基础到 Jenkins Agent 实战

作为一名长期与 Java 和 Jenkins 打交道的工程师,java -jar 恐怕是每天执行频率最高的命令之一。它看起来简单,但背后涉及 JAR 规范、JVM 参数传递、程序参数解析以及与 CI/CD 工具的深度集成。本文将从背景知识到操作手册,再聚焦 Jenkins Ag…

2026/7/18 17:55:51阅读更多 →
2026年地质无缝钢管供应 行业优质企业经验分享

2026年地质无缝钢管供应 行业优质企业经验分享

2026 年地质无缝钢管供应 行业优质企业经验分享2026 年,地质无缝钢管供应行业面临着诸多挑战与机遇。对于从业者而言,如何保障稳定供应、提升产品质量、降低成本是亟待解决的问题。本文将分享行业优质企业的经验,为大家提供可落地的干货。背景…

2026/7/18 17:55:51阅读更多 →
PCB天线已经放在板边, 为什么装壳后还是失谐?

PCB天线已经放在板边, 为什么装壳后还是失谐?

射频PCB 板载天线 净空PCB天线已经放在板边, 为什么装壳后还是失谐? 净空不是只挖顶层铜板载天线与周围铜、器件和结构件共同工作,净空必须按系统管理PCB 天线放在板边只是起点。天线周围所有相关层的铜皮、走线、器件、电池、外壳、线缆和…

2026/7/18 17:55:51阅读更多 →
WarcraftHelper:魔兽争霸3终极优化指南,让经典游戏焕发新生

WarcraftHelper:魔兽争霸3终极优化指南,让经典游戏焕发新生

WarcraftHelper:魔兽争霸3终极优化指南,让经典游戏焕发新生 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还在为《魔兽…

2026/7/18 19:01:55阅读更多 →
MZmine 3:免费开源质谱数据分析的终极解决方案

MZmine 3:免费开源质谱数据分析的终极解决方案

MZmine 3:免费开源质谱数据分析的终极解决方案 【免费下载链接】mzmine3 mzmine source code repository 项目地址: https://gitcode.com/gh_mirrors/mz/mzmine3 你是否正在为昂贵的质谱分析软件发愁?面对复杂的代谢组学数据处理,是否…

2026/7/18 19:01:55阅读更多 →
如何用AtlasOS让Windows飞起来:7步打造极致性能系统

如何用AtlasOS让Windows飞起来:7步打造极致性能系统

如何用AtlasOS让Windows飞起来:7步打造极致性能系统 【免费下载链接】Atlas 🚀 An open and lightweight modification to Windows, designed to optimize performance, privacy and usability. 项目地址: https://gitcode.com/GitHub_Trending/atlas1…

2026/7/18 19:01:55阅读更多 →
文旅文博项目如何用气味打造沉浸式体验?

文旅文博项目如何用气味打造沉浸式体验?

做文旅项目久了会发现一个现象:游客拍了一堆照片,回去之后能记住的其实不多。真正能瞬间把人拉回某个场景的,往往是某种味道——海边潮湿的咸味、古镇里木头和苔藓混合的气息、博物馆展厅里淡淡的檀香。气味是文旅文博项目打造沉浸式体验、传…

2026/7/18 19:01:55阅读更多 →
STM32双系统实现与FSBL技术解析

STM32双系统实现与FSBL技术解析

1. STM32双系统运行的可能性探讨当我们在PC上轻松安装WindowsLinux双系统时,是否想过在资源有限的STM32微控制器上也能实现类似功能?这听起来像是天方夜谭,但通过FSBL(First Stage Boot Loader)技术的巧妙运用&#xf…

2026/7/18 19:01:55阅读更多 →
LDO电源管理:PSRR参数解析与优化设计

LDO电源管理:PSRR参数解析与优化设计

1. LDO基础与PSRR概念解析 低压差线性稳压器(LDO)是现代电子系统中的关键电源管理器件,其电源抑制比(PSRR)参数直接影响系统性能。PSRR定义为输出噪声与输入噪声的对数比值,单位为分贝(dB),数学…

2026/7/18 18:59:55阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/18 10:49:13阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/18 8:49:08阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/18 14:49:24阅读更多 →
从模糊意图到可执行指令:Claude PRD中Prompt Engineering与需求颗粒度的5级映射法则

从模糊意图到可执行指令:Claude PRD中Prompt Engineering与需求颗粒度的5级映射法则

更多请点击: https://kaifayun.com 第一章:从模糊意图到可执行指令:Claude PRD中Prompt Engineering与需求颗粒度的5级映射法则 在Claude驱动的产品需求文档(PRD)生成实践中,原始业务意图往往以自然语言片…

2026/7/18 0:00:14阅读更多 →
Cursor配置生成失效?3大隐藏陷阱+4行修复代码,资深工程师连夜整理的紧急补救清单

Cursor配置生成失效?3大隐藏陷阱+4行修复代码,资深工程师连夜整理的紧急补救清单

更多请点击: https://codechina.net 第一章:Cursor配置生成失效?3大隐藏陷阱4行修复代码,资深工程师连夜整理的紧急补救清单 Cursor 配置生成突然失效,是近期高频报障场景。表面看是 cursor.config.json 未更新或 LSP…

2026/7/18 0:00:14阅读更多 →
某智驾大牛创业

某智驾大牛创业

作者:钟声编辑:Mark出品:红色星际头图:智能驾驶图片据悉,国内某头部智驾公司端到端模型技术大牛Z投身创业,并且已经拿到融资。Z不仅是该头部公司内部最年轻的对标阿里P10级别技术负责⼈,更是业内…

2026/7/18 0:00:14阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/17 22:48:46阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/18 14:49:24阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/18 18:49:35阅读更多 →