Documentation
¶
Index ¶
- Constants
- Variables
- func AssignEvidenceIDs(r *Report)
- func CheckEvidenceRefs(r *Report) []string
- func DecisionEventPayload(v Verdict, escalated bool, reason string) map[string]any
- func EnvelopeCandidates(raw string, envelopeFirst bool) []string
- func GuidanceAgentRegistered(agentName string) bool
- func IsConfidenceKindValid(k string) bool
- func IsConfidenceValid(c string) bool
- func IsDecisionSourceValid(s string) bool
- func IsEscalationReasonValid(r string) bool
- func IsSeverityValid(s string) bool
- func MaxSeverity(a, b string) string
- func PayloadCandidates(raw string, envelopeFirst bool) []string
- func Render(r *Report) string
- func RenderView(r *Report, view ReportView) string
- func RenderViewWith(r *Report, view ReportView, opt RenderOptions) string
- func SetGuidanceAgentNames(names ...string)
- func SeverityRankOf(s string) int
- func StructuredPayload(raw string) (string, bool)
- func UnwrapMCPText(raw string) string
- func ValidateStructured(schemaSrc, envelope string) error
- func ValidateVerdict(v Verdict) error
- type ChartEdge
- type ChartEvent
- type ChartItem
- type ChartNode
- type ChartPoint
- type ChartSeries
- type ChartSpec
- type Evidence
- type ExploreGap
- type Followup
- type Rec
- type RenderOptions
- type Report
- type ReportProfile
- type ReportView
- type StepMeta
- type StringList
- type StringMap
- type Verdict
- type VerdictItem
- type Verdicts
Constants ¶
const ( // DecisionSourceRule 确定性规则(词面/规则面)。 DecisionSourceRule = "rule" // DecisionSourceLLM 生成面(自回归模型)。 DecisionSourceLLM = "llm" // DecisionSourceClassifier 判定面(非自回归判定模型:一次前向 pass 出有限标签 // + 概率分布 + 校准置信度)。 // // 刻意**不叫 decision**:本仓的 decision 一词已占用于「处置/审批决策」, // 同一仓里一个词两义是最贵的漂移源。 DecisionSourceClassifier = "classifier" // DecisionSourceClarify 反问衔接(由澄清产生)。 DecisionSourceClarify = "clarify" // DecisionSourceFallback 兜底(未命中任何判定面时的默认路径)。 DecisionSourceFallback = "fallback" // DecisionSourceManual 人工判定。 DecisionSourceManual = "manual" // DecisionSourceUnknown 来源不可知(解析失败/上游未标注)。 DecisionSourceUnknown = "unknown" )
判定来源词表。
const ( // ConfidenceKindOrdinal 序数档(high|medium|low):档位语义,非概率。 ConfidenceKindOrdinal = "ordinal" // ConfidenceKindCalibrated 分布集中度(0-1):由概率分布算出,**可跨模型比较** // (同一口径下才有意义——口径随候选集规模变化,跨候选集仍不可移植)。 ConfidenceKindCalibrated = "calibrated_distribution" // ConfidenceKindSelfReported 模型自评(0-1):**不可跨模型比较**。 ConfidenceKindSelfReported = "self_reported" // ConfidenceKindRuleHit 规则命中:命中即确定,**不是概率**。 ConfidenceKindRuleHit = "rule_hit" )
置信语义种类词表(**跨种类不可比**)。
const ( // EscalationLowConfidence 置信未达门槛。 EscalationLowConfidence = "low_confidence" // EscalationError 判定面调用报错。 EscalationError = "error" // EscalationTimeout 判定面调用超时。 EscalationTimeout = "timeout" EscalationUnavailable = "unavailable" // EscalationUnknown 原因不可知。 EscalationUnknown = "unknown" )
升级/回落原因词表(判定面 → 生成面 / 人工 的移交原因)。
const ( ActionKillAndRestart = "kill_and_restart" ActionTune = "tune" ActionNone = "none" )
recommendation.action 白名单(粗粒度枚举,hook/校验用)。
const ( RiskTierMin = 1 RiskTierMax = 4 )
编目声明风险档的合法区间(curated_risk)。此前只写在字段注释里而不校验, 99 或 -1 会原样放行,宿主拿它当「引擎基线下限」时得不到任何信号。 0 不参与判定:字段带 omitempty,0 与「未声明」不可区分。
const ( DecisionPending = "pending_approval" DecisionApproved = "approved" DecisionRejected = "rejected" ConfidenceHigh = "high" ConfidenceMedium = "medium" ConfidenceLow = "low" )
决策与置信枚举。
const ( SeverityInfo = "info" SeverityLow = "low" SeverityMedium = "medium" SeverityHigh = "high" SeverityCritical = "critical" )
严重度枚举(批次一百三十七,终报结构化补缺):info|low|medium|high|critical。 与 confidence 相互独立——confidence 说「结论可信到什么程度」,severity 说「问题本身 有多重」。专家可不填(空=未评估,渲染与聚合按缺席处理);聚合面取子报告最高值 (只升不降),dispute 钳制与 confidence 同钳 ≤medium。
const ( VerdictAdopt = "adopt" VerdictDispute = "dispute" VerdictReject = "reject" )
合议三值裁决(verdict-judge 专属;spec 2026-09-15-verdict-judge-design §6)。
const SnippetMax = 200
SnippetMax evidence.snippet 长度上限;超长仅 warn 不截断(证据保真)。
Variables ¶
var ( // ErrNotReport 输出不是统一报告 JSON(调用方降级读 markdown 主体,不阻塞)。 ErrNotReport = errors.New("protocol: 输出不是统一报告 JSON") // ErrViolation schema 白名单违规(必须拦截,违规项经 errors.Join 附带)。 ErrViolation = errors.New("protocol: 报告未通过 schema 白名单校验") )
Functions ¶
func AssignEvidenceIDs ¶
func AssignEvidenceIDs(r *Report)
AssignEvidenceIDs 为报告内缺编号的证据确定性挂号:`<AgentName>#E<序号>`。 AgentName 为空(引擎合成报告)时退化 `report#E<n>`。已有编号不覆盖——LLM 自报编号 与引擎挂号同规则时天然一致;聚合/合并只追加不重排,编号全程稳定。
自动挂号必须避开已被占用的编号 ¶
旧实现用「数组下标 + 1」当编号,于是撞号是必然的:
evidence[0] 无编号 → 自动编成 "probe#E1" evidence[1] 模型自报 "probe#E1"(非空,不覆盖)
结果两条证据同号。而同号让「引用证据说理」**失去指向**:verdict 引用 "probe#E1" 时,消费方无从知道说的是哪一条;CheckEvidenceRefs 看到该编号 存在,也就不会报缺失——**歧义是静默的**,比缺失更难查。
故挂号前先收齐已被占用的编号(模型自报的一律优先,不覆盖),自动编号从 第一个未被占用的序号起取。
func CheckEvidenceRefs ¶
CheckEvidenceRefs 引用完整性校验:返回 verdicts 引用了但本报告 evidence 集中不存在 的编号(去重保序)。合议裁决引用的是「输入报告」的证据编号,合并进终报后终报 evidence 集包含全部被引条目——调用时机=合并组装完成后(finalizeWithPlan / 只读收尾)。 缺失只在留痕面告警(调用方 logf),不拦截不回改:引用是增强通道,不是数据本体。
func DecisionEventPayload ¶
DecisionEventPayload 判定面事件载荷(decision_answered / decision_escalated 共用)。
载荷是**扁平**的:宿主落库与看板聚合都按这几个键取,不解析嵌套信封(嵌套的 键名各宿主各写各的必然漂移——扁平键是跨仓聚合的最低共同底座)。
escalated=true 时带 reason(升级/回落原因,EscalationReason 词表)。
func EnvelopeCandidates ¶
EnvelopeCandidates 信封候选文本序列(批次二十八:credential unwrapMCPJSON / host parseProbeResult / executors parseShellResult 三处解析器共享信封骨架——各自的契约 谓词与候选顺序由调用方保留):
- envelopeFirst=true:内层文本段在前、裸串兜底在后——目标是无判别谓词的 map 直解 (信封本身也是合法 map,必须先试内层防误命中);
- envelopeFirst=false:裸串在前——调用方谓词能识别并拒绝信封形态。
批次一百零八起程序化消费方迁移 PayloadCandidates(structuredContent 优先); 本函数保留为纯信封骨架(LLM 观测/文本路径仍用 UnwrapMCPText)。
func GuidanceAgentRegistered ¶
GuidanceAgentRegistered 报告该 agent 名是否已被宿主登记为引导声位(诊断用)。
func IsConfidenceKindValid ¶
IsConfidenceKindValid 置信语义种类是否在词表内。
func IsConfidenceValid ¶
IsConfidenceValid 合议触发门用(scheduler 层过滤无效报告)。
func IsDecisionSourceValid ¶
IsDecisionSourceValid 来源是否在词表内。
func IsEscalationReasonValid ¶
IsEscalationReasonValid 升级/回落原因是否在词表内。
func PayloadCandidates ¶
PayloadCandidates 程序化消费候选序:structuredContent 优先(规范主通道,形态由 server 侧 outputSchema 对拍兜底),其余同 EnvelopeCandidates——调用方谓词不识别 的候选自然落空,缺 structuredContent 的旧 server 行为不变。envelopeFirst 语义 与 EnvelopeCandidates 一致。
func Render ¶
Render 用户可见 Markdown(完整档;历史唯一出口,签名不变零漂移)。 大纲:标题→现象→结论→证据要点→影响范围→方案与下一步→风险与回退→未决项与置信度 →合议裁决→小结。
func RenderView ¶
func RenderView(r *Report, view ReportView) string
RenderView 按受众档位渲染(未注入宿主配置项)。full 档在历史大纲上增量补四类结构化 面:证据编号(可回溯)、裁决证据引用、severity、impact_scopes——缺省字段不渲染, 存量报告逐字节兼容。形态档分支:answer=通用轨直答大纲,其余(含零值)一律诊断大纲。
签名与语义保持不变:宿主既有调用零改动。需要宿主文案的走 RenderViewWith。
func RenderViewWith ¶
func RenderViewWith(r *Report, view ReportView, opt RenderOptions) string
RenderViewWith 按受众档位渲染并注入宿主配置项。
func SetGuidanceAgentNames ¶
func SetGuidanceAgentNames(names ...string)
SetGuidanceAgentNames 注册/清空引导声位名集合(传空/不传即清空)。 宿主在装配期调用一次即可;重复调用覆盖而非累加。
func StructuredPayload ¶
StructuredPayload 提取 MCP 工具返回的 structuredContent 主通道(MCP 2025-06-18, 批次一百零八):agentkit 侧 invokableTool json.Marshal 整个 CallToolResult,故 structuredContent 原文字节可从信封串直取(server 侧 RawStructuredContent 同字节 直通)。旧形态/纯文本工具无此字段,返回 false。
func UnwrapMCPText ¶
UnwrapMCPText 解 MCP 工具返回的信封取首个非空内层文本;非信封形态原样返回—— 快照/结果进证据条目时,snippet 配额应留给有效数据而非包装层。
func ValidateStructured ¶
ValidateStructured 客户端 SHOULD 校验(MCP 2025-06-18,批次一百一十一):工具 的 structuredContent 对照其声明 outputSchema。仅对注册表在册工具生效(schemaSrc 空 = 未声明,合法态直接放行);信封无 structuredContent(旧 server/纯文本工具) 同样放行——双写兼容语义。校验失败=服务端漂移信号:返回 error 交调用方可视化 (metrics/事件),不阻断主流程——text 镜像谓词兜底仍成立。
func ValidateVerdict ¶
ValidateVerdict 校验判定信封(fail-closed):来源/种类必须在词表内;置信字段 必须**与 kind 匹配**(数值置信 ∈ [0,1];序数档 ∈ high|medium|low); kind=rule_hit 时两个置信字段都不得填(规则命中不是概率)。
未知来源/种类一律拒(不是落 unknown)——信封是契约面,校验面必须闭合。
Types ¶
type ChartEvent ¶
type ChartEvent struct {
Time string `json:"time,omitempty"`
Label string `json:"label"`
Status string `json:"status,omitempty"` // ok|warn|down|空(漂移词在解码期归一)
Desc string `json:"desc,omitempty"`
}
ChartEvent 时间线事件(type=timeline 用:故障演进/事件时序可视化)。 Time 是展示字面("14:02"、"Day1"),协议不解析时刻语义——数据必须来自 真实采集/日志时间戳,平台侧执行时间线另由前端从步骤簿记确定性派生。
type ChartItem ¶
ChartItem 饼图扇区;ChartPoint/ChartSeries 折线图数据点与系列。 charts 是报告可选的可视化附件(type=pie 用 items,type=line 用 series), 数据必须来自真实采集——协议层只管忠实承载,不做语义校验。
type ChartNode ¶
type ChartNode struct {
ID string `json:"id"`
Label string `json:"label"`
Status string `json:"status,omitempty"` // ok|warn|down|空(漂移词在解码期归一)
Group string `json:"group,omitempty"` // 分层/分区名(接入层/应用层…)
}
ChartNode 拓扑图节点;ChartEdge 有向边(type=topo 用:部署/架构/依赖关系可视化)。
type ChartPoint ¶
type ChartSeries ¶
type ChartSeries struct {
Label string `json:"label"`
Points []ChartPoint `json:"points"`
}
type ChartSpec ¶
type ChartSpec struct {
Type string `json:"type"` // pie|line|bar|topo|timeline(空=无效 spec,调用方跳过)
Title string `json:"title,omitempty"`
Unit string `json:"unit,omitempty"`
Items []ChartItem `json:"items,omitempty"`
Series []ChartSeries `json:"series,omitempty"`
Nodes []ChartNode `json:"nodes,omitempty"` // type=topo 用
Edges []ChartEdge `json:"edges,omitempty"` // type=topo 用
Events []ChartEvent `json:"events,omitempty"` // type=timeline 用
}
ChartSpec 单个图表定义。真实 LLM 的形态漂移(type 写成 donut/bar_chart、 数值写成 "62.4%")在 UnmarshalJSON 内归一——畸形只损失该图表本身, 绝不影响整份报告解析(宽容留给格式,拦截留给白名单)。
func (*ChartSpec) UnmarshalJSON ¶
UnmarshalJSON 容错解码:type 漂移归一、数值字符串化容忍、无效数据点丢弃。 解析失败一律返回 nil 并置空 spec——图表是锦上添花,不能成为报告的故障点。
type Evidence ¶
type Evidence struct {
Tool string `json:"tool"`
Snippet string `json:"snippet"`
Interpretation string `json:"interpretation"`
ID string `json:"id,omitempty"`
}
Evidence 蒸馏后的单项证据:发现 + 关键行(snippet ≤200 且须含具体数据点)。 模型常把工具名写在 type/item/name/source 键下——解码时回退到 tool。 ID 证据编号(批次一百三十七,结论可回溯面):`<agent>#E<n>`,ParseReport 侧确定性 挂号(已有值不覆盖);verdicts[].evidence_ids 引用它,聚合/合并只追加不重排,编号 全程稳定。
func (*Evidence) UnmarshalJSON ¶
type ExploreGap ¶
ExploreGap 勘探缺口(批次二百零八 GE2 迭代勘探,spec 2026-10-07-promotion-channel-generalexec-design.md §7):综合环节自判证据不足时输出 的续轮勘探缺口——aspect=方向名(进环节标签「勘探·<aspect>」),query=建议勘探问题。 仅通用轨评估流在 generalist.iterative_explore 开(缺省关)时消费;其余报告携带本 字段=无消费方零影响。
type Followup ¶
type Followup struct {
By string `json:"by,omitempty"`
What string `json:"what"`
Why string `json:"why,omitempty"`
}
Followup 结构化接力指令(批次一百二十七):谁(By)该做什么(What)、为什么(Why)。 与 NeedsFollowup 字符串列表双通道过渡——引擎侧新增接力语义走本类型(注入视图/模板 变量 {{followups}} 消费),旧字符串字段保留供存量前端渲染;LLM 输出协议不含本字段 (防线段字段清单不收、repair 层不游走),由引擎侧(合议否决/链终止/聚合透传)填写。 前端跟进作栏后撤 needs_followup 字符串双写。
type Rec ¶
type Rec struct {
Action string `json:"action"` // kill_and_restart|tune|none
Steps StringList `json:"steps"`
RequiresExecution bool `json:"requires_execution"`
RequiresApproval bool `json:"requires_approval"`
ChangeRef string `json:"change_ref,omitempty"` // 编目变更块 slug(可选)
ChangeParams StringMap `json:"change_params,omitempty"` // 编目参数(string_list 值逗号分隔;容错解码见 StringMap)
CuratedRisk int `json:"curated_risk,omitempty"` // 编目声明风险档 1-4(引擎基线下限;LLM 评估只升不降)
}
Rec recommendation 子结构(处方)。批次九十四起支持编目形态:change_ref+ change_params 引用已装包的变更块(<包>/changes/<slug>.yaml),平台渲染模板得 最终 steps——LLM 只给参数不给命令本体;自由 steps(未编目)仍合法,审批卡 标注「未编目」,站点可用 approval.curated_only 收紧为仅编目可执行。
type RenderOptions ¶
type RenderOptions struct {
// DefaultTitle AgentName 为空时的标题兜底。留空 = 用中性兜底「诊断报告」。
DefaultTitle string
}
RenderOptions 渲染可配置项:宿主注入其品牌/文案面,内核不内置任何宿主文案。
设计纪律:报告标题这类**展示文案属于宿主**——内核硬编码兜底标题等于把某个宿主 的品牌写进内核,换宿主就是一处需要改内核的债。故留空即用中性兜底。
func (RenderOptions) WithTitle ¶
func (o RenderOptions) WithTitle(title string) RenderOptions
WithTitle 返回带指定兜底标题的副本(便捷构造)。
type Report ¶
type Report struct {
AgentName string `json:"agent_name"`
Domain string `json:"domain"`
Symptom string `json:"symptom"` // 首句须含「检测对象:」标注
Conclusion string `json:"conclusion"`
Evidence []Evidence `json:"evidence,omitempty"`
Charts []ChartSpec `json:"charts,omitempty"` // 可视化附件(占比→pie、时序→line、对比→bar、部署/依赖→topo、演进/时间线→timeline),畸形由 ChartSpec 容错
Impact string `json:"impact,omitempty"`
ImpactScopes StringList `json:"impact_scopes,omitempty"` // 受影响对象清单(批次一百三十七,结构化补缺:host/服务/pod 级;聚合去重合并)
Severity string `json:"severity,omitempty"` // 严重度 info|low|medium|high|critical(批次一百三十七;聚合取最高、dispute 钳 ≤medium;空=未评估)
Recommendation *Rec `json:"recommendation,omitempty"`
RequestType string `json:"request_type,omitempty"` // 细粒度动作类别(风险分级用)
Risk string `json:"risk,omitempty"`
Rollback string `json:"rollback,omitempty"`
RollbackSteps StringList `json:"rollback_steps,omitempty"`
NeedsFollowup StringList `json:"needs_followup,omitempty"`
Confidence string `json:"confidence"` // high|medium|low
Verdicts Verdicts `json:"verdicts,omitempty"` // 合议裁决(workflow/verdict-judge 专属)
Followups []Followup `json:"followups,omitempty"` // 结构化接力指令(批次一百二十七;引擎侧填写,非 LLM 输出字段)
Meta *StepMeta `json:"meta,omitempty"` // 环节执行元数据(批次一百二十七;引擎回填,非 LLM 输出字段)
// ExploreGaps 勘探缺口(批次二百零八):GE2 迭代勘探的综合环节输出通道——LLM 在
// iterative_explore 开时按提示词输出,引擎按缺口发起受限续轮扇出。与 Followups 同属
// 「特定流专属通道」,其余流出现即无消费方。
ExploreGaps []ExploreGap `json:"explore_gaps,omitempty"`
// Profile 报告形态档(批次二百一十七,引擎侧确定性填写,非 LLM 输出字段):flow
// 按轨设置,空=diagnosis 存量兼容。随 FinalReportJSON 落库,handler 受众投影
// (view=summary 重渲染)因此自动按档分支,消费面零改动。
Profile ReportProfile `json:"profile,omitempty"`
Summary string `json:"summary"`
Scope string `json:"scope,omitempty"` // in|out(kyaiops 扩展字段)
Redirect string `json:"redirect,omitempty"` // scope=out 时的目标 slug,仅一层
Decision string `json:"decision,omitempty"` // pending_approval|approved|rejected
ExecutedSteps StringList `json:"executed_steps,omitempty"`
// AwaitingUser 待确认态专属标记(批次三百三十四,调度器 clarify 分支持位,非 LLM
// 输出字段):反问轮的回答不是诊断结论——渲染器以「待确认」替代「结论」标签,
// 消除「要诊断哪个集群?」落 **结论** 体的生硬文案(可点选卡照常承担交互)。
AwaitingUser bool `json:"awaiting_user,omitempty"`
// Guidance 对话直答标记(引擎侧确定性填写,非 LLM 输出字段):置位表示本条是
// 调度引导/元问题/寒暄一类的对话回复而非诊断报告,markdown 走轻装视图
// (不出 agent 标题与置信度)。内核不依赖任何命名约定判定该形态——判定依据
// 由宿主通过本字段或 SetGuidanceAgentNames 注册,二选一。
Guidance bool `json:"guidance,omitempty"`
}
Report 统一报告协议(所有专业/流程/治理层 agent 的最终消息)。
func ParseLLMReport ¶
ParseLLMReport 解析**模型输出**,并剥离全部引擎侧字段。
与 ParseReport 的唯一差别就是这五个字段;其余解析行为完全一致。 宿主解析 LLM 产出处必须走本函数,走 ParseReport 等于把呈现权交给模型。
func ParseReport ¶
ParseReport 解析报告,**保留**引擎侧字段(followups / meta / profile / awaiting_user / guidance)——它是落库往返的入口,不是「外部输入」入口。
形态档随 FinalReportJSON 落库、再经本函数读回必须保真,handler 的受众投影 靠它自动按档重渲染(见 report_profile_test.go TestProfileRoundTrip)。
解析模型输出请用 ParseLLMReport ¶
这五个字段在定义处标注的是「引擎侧确定性填写 / 非 LLM 输出字段」,却直接 决定**呈现**:profile 切答案视图会丢掉影响范围、风险回退、合议与 severity 渲染;guidance 置位走轻装视图(不出 agent 标题与置信度)。让模型能写它们, 等于让它自己决定「哪些治理信息不必呈现」——与本包 fail-closed 的口径相反。
曾经试过让 ParseReport 直接剥离(安全默认),但它同时是往返入口,那会把 历史报告的 followups/meta 静默抹掉,把治理信息缺失伪装成「更安全的解析」。 故拆成两个入口:信任级别不同,函数名也不同,比布尔开关更难用错。
type ReportProfile ¶
type ReportProfile string
ReportProfile 报告形态档(批次二百一十七):同底座分形态——protocol.Report 契约、 落库双写、流式分片与受众投影全轨共用一份,仅渲染大纲按档切换(单点在 report_render.go)。diagnosis=诊断大纲(现役缺省;零值同义,存量报告零漂移); answer=通用轨直答大纲(结论先行,不硬撑诊断专属面)。确定性由 flow 侧设置—— LLM 输出协议不含本字段(防线段字段清单不收),与 Followups/Meta 同属引擎侧填写。
const ( ProfileDiagnosis ReportProfile = "diagnosis" ProfileAnswer ReportProfile = "answer" )
type ReportView ¶
type ReportView string
ReportView 渲染受众档位(批次一百三十七):full=完整档(历史行为);summary=摘要档 (管理层/通知面——留结论/影响/方案动作/裁决 stance,省证据明细/步骤/回退)。 渲染层不做受众推断,调用方(API/通知)显式选档。
const ( ViewFull ReportView = "full" ViewSummary ReportView = "summary" )
type StepMeta ¶
type StepMeta struct {
DurationMS int64 `json:"duration_ms,omitempty"`
ToolCalls int `json:"tool_calls,omitempty"`
Iterations int `json:"iterations,omitempty"`
}
StepMeta 环节执行元数据(批次一百二十七,引擎回填非 LLM 输出):环节耗时/工具调用 次数/LLM 轮次——信封级质量信号,注入视图与聚合面可引用,与报告内容分离(对标 ZCode AgentCompletedOutput 的 usage/耗时字段)。报告落库随 meta 序列化;LLM 产出不经此字段。
type StringList ¶
type StringList []string
func (StringList) MarshalJSON ¶
func (s StringList) MarshalJSON() ([]byte, error)
func (*StringList) UnmarshalJSON ¶
func (s *StringList) UnmarshalJSON(data []byte) error
type StringMap ¶
StringMap 容错字符串参数表(change_params 专用):编目参数声明 string_list 值 逗号分隔,但 LLM 偶发把数值/布尔形态写进值位——标准 unmarshal 对 map[string]string 硬失败会炸掉整份报告解析(ErrNotReport 降级读 markdown 主体, 比单工具失败更疼;http_query per_page:20 同型实弹在案后对本协议面巡检补齐)。 数值/布尔 coerce 为文本,null/数组/对象丢键不炸;Marshal 形态与普通 map 一致。
func (*StringMap) UnmarshalJSON ¶
type Verdict ¶
type Verdict struct {
// Source 判定来源(DecisionSource 词表)。
Source string `json:"source"`
// Kind 置信语义种类(ConfidenceKind 词表)。
Kind string `json:"confidence_kind"`
// Value 判定结果(标签;语义由来源决定)。
Value string `json:"value"`
// Confidence 数值置信(0-1)。仅 kind=calibrated_distribution / self_reported 有意义。
Confidence float64 `json:"confidence,omitempty"`
// Ordinal 序数置信档(high|medium|low)。仅 kind=ordinal 有意义。
Ordinal string `json:"confidence_ordinal,omitempty"`
// Distribution 概率分布(候选 → 概率);判定面给,生成面可空。
Distribution map[string]float64 `json:"distribution,omitempty"`
// Reason 一句话依据(可空)。
Reason string `json:"reason,omitempty"`
}
Verdict 判定结果信封:来源 + 置信语义 + 判定值。
**置信字段按 kind 二选一**(别都填、也别都不填):
kind=calibrated_distribution → Confidence(0-1)有意义,Ordinal 不填 kind=ordinal → Ordinal(high|medium|low)有意义,Confidence 不填 kind=self_reported → Confidence(0-1)有意义但**不可跨模型比较** kind=rule_hit → 两者都不填(命中即确定,不是概率)
Distribution 是判定面的概率分布(候选 → 概率):它让「为什么是这个结论」可复算, 也是跨来源核对的唯一共同底座(两边的分布可比,自评不可比)。
func (Verdict) Comparable ¶
Comparable 两个判定的置信**是否可比**。
规则:同 kind,且该 kind 的语义允许跨来源比较——
- ordinal:同一套档位词表 ⇒ 可比;
- calibrated_distribution:同一口径下可比(**跨候选集仍不可移植**:口径随 候选集规模变化);
- self_reported:模型自评 ⇒ **不可比**(不同模型的 0.9 不是一回事);
- rule_hit:命中即确定 ⇒ 不比数值。
这条判定面是「置信不可跨 kind 混用」纪律的唯一实现点——别在别处再写一份。
type VerdictItem ¶
type VerdictItem struct {
Agent string `json:"agent"`
Stance string `json:"stance"` // adopt|dispute|reject
Reason string `json:"reason,omitempty"`
// EvidenceIDs 裁决依据的证据编号(批次一百三十七):引用所依据报告的 evidence.id
//(形如 specialists/memory-analysis#E2)——「引用证据说理」从 prompt 软要求升级为
// 结构化引用通道;容忍单字符串/数组双形态(StringList 宽容解码),引用不存在的
// 编号由引擎侧合并后校验(CheckEvidenceRefs),只在留痕面告警不拦截。
EvidenceIDs StringList `json:"evidence_ids,omitempty"`
}
VerdictItem 合议对单份专家报告的裁决。
type Verdicts ¶
type Verdicts []VerdictItem
Verdicts 宽容解码(仿 ChartSpec):stance 非法或 agent 为空的条目丢弃,绝不影响整报解析。