Help us shape the future of Go! Take the 2026 Go Developer Survey

jsonrepair

package
v0.28.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package jsonrepair LLM 输出宽容 JSON 修复骨架:栅栏剥离 → 散文抽对象/抽数组 → 语法级修复 → 标量归一。报告/领域 schema 由调用方持有;本包只做格式宽容。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CoerceString

func CoerceString(v any) (string, bool)

CoerceString coerceString 的导出面:调用方在 Schema.OnMap 域内钩子里做 自定义归一(枚举收敛/布尔翻转等)时复用同一标量 coerce 口径,避免再造平行实现。

func ExtractArray added in v0.18.0

func ExtractArray(s string) string

ExtractArray 提取文本中第一个平衡的 JSON 数组(字符串字面量感知; 未闭合则返回剩余文本由 Repair 补全括号)。无数组返回 ""。

与 ExtractObject 对称的一对面(issue #37):对象面有抽取件、数组面此前没有—— 数组文本只能被 ExtractObject 抽成「数组里的第一个对象」,对数组语义是错的 (ExtractObject(`[{"a":1}]`) = `{"a":1}`)。调用方要抽数组只能自己手搓 IndexAny + 深度扫描。

括号栈而非单一深度计数:数组可嵌套数组(`[[1,2],3]`)也可含对象字段数组 (`[{"b":[2]}]`),只数 '[' 会把内层 ']' 当作数组收尾、切出半截。

func ExtractJSON

func ExtractJSON(s string) string

ExtractJSON 从模型输出中提取 JSON 文本:剥 ``` 围栏(语义单源 textutil.StripCodeFence——取第一个围栏块)、截取首个 {/[ 到末个 }/]。 快路径切片,不做语法修复——半损坏输出的宽容解析走 Unmarshal/ParseLenient; 两者围栏语义一致,宽容回退链不会静默换目标块。

func ExtractObject

func ExtractObject(s string) string

ExtractObject 提取文本中第一个平衡的 JSON 对象(字符串字面量感知; 未闭合则返回剩余文本由 Repair 补全括号)。无对象返回 ""。

func Normalize

func Normalize(raw json.RawMessage, schema *Schema) (string, error)

Normalize 把字符串位的 bool/数字统一转成文本(宽容留给格式,拦截留给白名单)。 raw 非法 JSON 时返回 error。

func ParseLenient

func ParseLenient(raw string, v any, schema *Schema) error

ParseLenient 栅栏剥离 → 直接解析 → Repair 重试 → ExtractObject+Repair 重试 → ExtractArray+Repair 重试。schema 为 nil 时跳过 Normalize(空 schema 下归一 仍是 Unmarshal+递归+Marshal 三趟纯开销,对解析结果无贡献)。

抽取兜底对象面/数组面对称(issue #37):此前只有 ExtractObject 一件,多段数组 与散文含 '{' 的数组文本整段作废。顺序固定为「对象面先、数组面后」——目标类型 决定哪个形状能解析成功([]T 只吃数组、map 只吃对象),而 any/json.RawMessage 这类通吃形状的目标必须保住对象面既有行为(`{"items":[1,2]}` 仍抽成整个对象, 不能被内层数组抢走)。

func Repair

func Repair(s string) string

Repair 轻量 JSON 修复:全角结构标点、非法转义(如 \| → |)、尾逗号、未闭合 括号。只处理语法级损坏;语义归一化由 Normalize / 调用方承担。

单遍字符串感知扫描(第六轮审计重构):此前尾逗号/非法转义走全文正则、不辨 字符串边界——字符串里合法的 `", }"` / `"\x"` 序列会被当损坏静默改写(修复器 的错误成功比失败更贵)。现在三类修复共用一个 inStr/esc 状态机,与 scanOpenBrackets/ExtractObject 同一纪律:字符串外才动结构位,字符串内只修 转义。

func StripCodeFence added in v0.23.1

func StripCodeFence(s string) string

StripCodeFence 剥离 markdown 代码围栏:取第一个 ``` 围栏块;无围栏原样 TrimSpace 返回。多围栏块输出(模型补多段代码)语义为「取第一块」——与 宽容解析链一致。

本函数是**围栏语义的单源**(下游 oagentkit/agentkit、agentkit-bisect、 textx 各自的 textutil.StripCodeFence 均为此语义的副本,pkg#74 起因): 围栏口径(多块取哪块、是否识别 json 变体等)要改只改此处,副本会漂移。

只剥围栏、不做 JSON 切片——需要「提取 JSON 文本」请用 ExtractJSON, 需要「宽容解析」请用 Unmarshal / ParseLenient。

func Unmarshal

func Unmarshal(text string, v any) error

Unmarshal 模型输出 JSON 的宽容解析出口,三级尝试:

  1. ExtractJSON + encoding/json——快路径,命中则零额外开销;
  2. 切片结果经 Repair 做语法级修复(全角结构符/非法转义/尾逗号/未闭合括号) 后再解析;
  3. ParseLenient 全链兜底(剥围栏→直解→修复→抽对象/抽数组,可救散文包裹、 多段与截断)。

全部失败时返回同时携带严格与宽容两路错误的包装——调用方把它回喂 LLM 重试时 无需再自行拼装失败原因。宿主的领域 schema 校验(字段语义、枚举约束)仍归调用方。

func UnmarshalLenient added in v0.11.0

func UnmarshalLenient(text string, v any) (partial bool, err error)

UnmarshalLenient 宽容解析:在 ParseLenient 同款修复链之外,尽力闭合截断 的数组/对象。partial=true 表示原文不完整、结果来自闭合后的截断前缀 (内容可能缺失,如闭合的半截字符串/补位的 null);false 表示完整解析。 纯垃圾(登录过期提示、HTML 错误页等)仍返回 err。

与 ParseLenient 的分工:需要 Schema 归一走 ParseLenient;需要感知截断 (界面区分「解析失败」与「数据不全」)走本函数。

func UnmarshalWithOpts added in v0.11.0

func UnmarshalWithOpts(text string, v any, opts ...UnmarshalOption) error

UnmarshalWithOpts 带选项的宽容解析。无选项时与修复链保守语义一致 (截断报错,不闭合——结果要么完整要么失败),传 WithAllowPartialArray 开启宽松模式。

Types

type Schema

type Schema struct {
	// StringKeys 期望为字符串的键:bool/数字 → 文本;对象/数组 → 扁平化文本。
	StringKeys map[string]bool
	// ListKeys 期望为数组的键:标量 → 单元素数组(或空数组);元素内标量 → 文本。
	ListKeys map[string]bool
	// OnMap 每个 map 在其子节点归一完成后的领域钩子(可 nil)。可增删改键。
	OnMap func(m map[string]any)
}

Schema 标量归一化作用范围(领域键集合由调用方提供)。

type UnmarshalOption added in v0.11.0

type UnmarshalOption func(*unmarshalOpts)

UnmarshalOption 是 UnmarshalWithOpts 的选项类型 (AGENTS「XxxOption 禁止裸 Option」规约,多包 co-import 不冲突)。

func WithAllowPartialArray added in v0.11.0

func WithAllowPartialArray() UnmarshalOption

WithAllowPartialArray 宽松模式:尽力闭合截断的数组/对象——补悬空字符串 引号(含 EOF 悬挂转义)、丢 EOF 悬空逗号、悬空冒号补 null、按栈序闭合 未闭括号。截断前缀能闭合出合法 JSON 即解析成功:「宁可少显示,不能显示 一半」的取舍由调用方做出。纯垃圾(无法闭合出合法 JSON)仍然报错, 不编造数据。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL