尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Guardrails 调用历史与日志体系全解析:从 Call、Iteration 到 Status 状态机

发布时间:2026/9/28 2:35:24

资讯中心
01
ARTICLE

Guardrails 调用历史与日志体系全解析:从 Call、Iteration 到 Status 状态机

Guardrails 调用历史与日志体系全解析:从 Call、Iteration 到 Status 状态机
AI 安全治理模型安全AI 应用【免费下载链接】guardrailsAdding guardrails to large language models.项目地址https://gitcode.com/gh_mirrors/gu/guardrails点击查看免费下载本文是一份面向 Guardrails 开发者的 History Logs 深度指南系统讲解一次 Guard 执行Call如何被记录为可回溯的调用历史对象、每次校验循环Iteration如何留存原始输出、解析输出与校验日志以及 Inputs / Outputs / CallInputs 等数据结构在其中的角色。读完本文你将能熟练通过guard.history读取每次调用的完整生命周期数据——包括 Token 消耗、ReAsk 消息、失败校验日志与最终守卫输出并理解pass/fail/error/not run状态机的判定逻辑。一、核心概念Call 与 Iteration 的关系在 Guardrails 中Call一次调用与Iteration一次迭代构成典型的一 对多层级关系。根据 history_and_logs.md 的定义一个 Call 代表一次 Guard 的执行。每当用户调用Guard.__call__、Guard.parse或Guard.validate方法时就会创建一个 Call。而一个 Iteration 则代表校验循环中的单次迭代包含一次如适用对 LLM 的调用。在一次 Call 中首个 Iteration 对应初始校验轮次此后每一次 ReAsk重新询问 LLM 以修正输出都会追加一个新的 Iteration。因此Call 用户发起的一次完整 Guard 执行可包含多次 LLM 调用Iteration 该 Call 内的一次 LLM 调用 一轮解析/校验Stack 二者在历史中都以栈Stack形式组织支持first/last/at(i)等访问方式。从源码看Call 继承自ArbitraryModel其核心字段为字段类型说明iterationsStack[Iteration]初始校验轮次 每次 ReAsk 产生的迭代的栈inputsCallInputs用户传入Guard.__call__/Guard.parse/Guard.validate的输入exceptionOptional[Exception]中断 Guard 执行的异常idstrcomputed该 Call 的唯一标识可用于标识某次具体执行在 guard.py 中可以看到 Call 的创建与入栈过程每次执行时先构造call_log Call(inputscall_inputs)随即self.history.push(call_log)把这次执行挂到 Guard 的历史栈上。同时Iteration还维护了index该迭代在 Call 内的零基下标与call_id所属 Call 的唯一标识见 iteration.py。Guard.history调用历史的入口每一次 Guard 执行产生的 Call 都会按顺序压入guard.history它是一个Stack[Call]默认最多保留最近 10 条历史history_max_length参数可调见 guard.py。集成测试 test_guard.py 中大量使用guard.history.first来断言首次调用的迭代数量例如assert call.iterations.length 2一次初始校验 一次 ReAsk。二、Call一次 Guard 执行的完整快照Call 是追溯一次执行的主入口围绕它可拿到这次执行的所有侧面。以下属性均来自 call.py与文档一一对应。2.1 输入侧属性prompt_paramsOptional[Dict]用户初始化或调用 Guard 时提供的提示词参数直接转发自self.inputs.prompt_paramsmessagesOptional[Union[Messages, list[dict[str, str]]]]用户初始化或调用 Guard 时提供的消息转发自self.inputs.messagescompiled_messagesOptional[list[dict[str, str]]]首次调用时真正传给 LLM 的已编译消息。源码实现中它会取首个 Iteration 的inputs.messages并逐条用prompt_params对content执行str.format(**prompt_params)将Prompt/Instructions对象还原为其源文本最终返回rolecontent结构。若没有迭代则返回Nonereask_messagesStack[Messages]ReAsk 期间使用的已编译消息栈不含初始消息——实现上先复制迭代栈、移除首项再逐条格式化 content。2.2 输出侧属性logsStack[str]汇总所有迭代的日志实现为遍历iterations并extend各迭代的logstokens_consumedOptional[int]所有迭代消耗的总 Token 数若没有任何迭代上报 Token则返回None。实现上只累加tokens_consumed不为None的迭代prompt_tokens_consumed/completion_tokens_consumed分别汇总所有迭代的 prompt/输入 Token 与 completion/输出 Tokenraw_outputsStack[str]所有 LLM 调用的原始输出。注意实现细节它取自每个迭代outputs.llm_response_info.output即LLMResponse.output若llm_response_info为None则放入Noneparsed_outputsStack[Union[str, List, Dict]]LLM 输出经过解析后、进入校验前的形态集合validation_responseOptional[Union[str, List, Dict, ReAsk]]跨迭代聚合的校验响应可能包含 ReAsk。源码中的合并逻辑很关键若计划全 schema ReAsk、迭代数 2、最后一次校验响应本身就是顶层ReAsk或字符串则直接返回最后一个迭代的响应否则通过merge_reask_output把各迭代的校验响应逐步合并fixed_outputOptional[Union[str, List, Dict]]应用了自动修复的累计输出由sub_reasks_with_fixed_values(self.validation_response)实现。若某项没有可用的修复值其中仍可能残留 ReAskguarded_outputOptional[Union[str, List, Dict]]全部校验阶段完成后的最终完整输出。从实现看只有当 Call 处于pass状态或最后一次迭代的失败校验全部为 no-op值在前后校验中未发生改变时才会返回非空值——这与文档中仅在 Guard 通过或 action 为 no-op 时有值的描述完全一致reasksStack[ReAsk]校验中产生且无法自动修复的 ReAsk 集合若还有剩余的 ReAsk 配额它们会被拼入下一次 LLM 调用的提示词validator_logsStack[ValidatorLogs]所有迭代中每一次独立校验的结果errorOptional[str]中断运行异常的字符串消息实现优先级为self.exception→ 无迭代时None→ 最后一个迭代的errorfailed_validationsStack[ValidatorLogs]全程校验失败的日志过滤条件是validation_result存在且outcome Outcome.FAILstatusstr基于最终合并输出有效性得出的累计状态取值见下文状态机一节treeTree返回 RichTree对象为每个迭代渲染一个Panel标题Step {i}其中包含 Messages 表、Raw LLM Output、Validated Output 面板若应用了修复且最终通过还会用修正后的Validated Output面板替换最后一个面板。可直接打印在终端里查看日志树。三、Iteration单轮校验循环的明细Iteration代表校验循环的单次迭代包含一次 LLM 调用其定义与实现见 iteration.py。它拥有四个字段id唯一标识、call_id所属 Call 标识、indexCall 内零基下标、inputs本轮输入与outputs本轮输出。其核心属性如下属性返回类型语义logsStack[str]本迭代的日志实现上通过作用域日志处理器get_scope_handler().get_logs(str(id(self)))按迭代实例 ID 取回tokens_consumedOptional[int]本迭代总 Tokenprompt completion任一项非空即求和prompt_tokens_consumedOptional[int]来自outputs.llm_response_info.prompt_token_countcompletion_tokens_consumedOptional[int]来自outputs.llm_response_info.response_token_countraw_outputOptional[str]LLM 的精确原始输出优先取LLMResponse.outputparsed_outputOptional[Union[str, List, Dict]]解析后、校验前的输出validation_responseOptional[Union[ReAsk, str, List, Dict]]单阶段校验的响应可能是合法输出与 ReAsk 的组合。文档特别提示Guard 可能因 ReAsk 运行多次校验要取最终输出请查看Call.guarded_outputguarded_outputOptional[Union[str, List, Dict]]校验通过的有效值部分值可能是校验中被修复的值字段级 ReAsk 发生时可能是不完整结构reasksSequence[ReAsk]校验产生的 ReAsk将拼入下一次 LLM 调用validator_logsList[ValidatorLogs]本迭代每次校验的结果。注意流式场景inputs.stream为 True会过滤掉没有validated_chunk的日志error/exceptionOptional[str]/Optional[Exception]中断本迭代的异常消息与异常对象failed_validationsList[ValidatorLogs]本迭代失败的校验日志error_spans_in_outputList[ErrorSpan]LLM 响应中的错误片段索引相对完整 LLM 输出statusstr本迭代终态OneOfpass/fail/error/not runIteration还暴露了rich_group属性用于在 Rich 终端中渲染 Messages 表、Raw LLM Output 与 Validated Output 三块面板——这正是Call.tree中每个Step {i}面板的内容来源。集成测试 test_guard.py 对 Iteration 与 Call 的联合断言非常直观call guard.history.first assert call.iterations.length 2 # 初始轮 一次 reask first call.iterations.first assert first.prompt_tokens_consumed 123 assert first.completion_tokens_consumed 1234 assert first.raw_output entity_extraction.LLM_OUTPUT assert first.validation_response entity_extraction.VALIDATED_OUTPUT_REASK_1 assert call.reask_messages.first[1][content] entity_extraction.COMPILED_PROMPT_REASK assert call.raw_outputs.at(1) json.dumps(entity_extraction.VALIDATED_OUTPUT_REASK_2) assert call.guarded_output entity_extraction.VALIDATED_OUTPUT_REASK_2四、Inputs / Outputs校验循环的输入与输出4.1 Inputsinputs.pyInputs代表传入校验循环的输入数据字段与文档一致llm_apiOptional[PromptCallableBase]用于调用 LLM 的构造类序列化时转为字符串反序列化时若无法还原为PromptCallableBase则返回Nonellm_outputOptional[str]用户通过Guard.parse提供的外部 LLM 调用输出字符串messagesOptional[List[Dict]]聊天模型调用时提供的消息历史序列化时会把Prompt对象展开为其source文本prompt_paramsOptional[Dict]将被格式化进最终 LLM 提示词的参数num_reasksOptional[int]允许的 ReAsk 总次数用户提供或使用默认值metadataOptional[Dict[str, Any]]用户提供、供校验阶段使用的元数据full_schema_reaskOptional[bool]ReAsk 是作用于整个 schema 还是字段级streamOptional[bool]是否使用流式默认False。4.2 Outputsoutputs.pyOutputs代表校验循环产出的数据llm_response_infoOptional[LLMResponse]LLM 响应信息。LLMResponse定义在 llm_response.py包含prompt_token_count别名promptTokenCount、response_token_count别名responseTokenCount与output三个字段是 Token 统计的直接来源raw_outputOptional[str]LLM 的精确输出parsed_outputOptional[Union[str, List, Dict]]解析后的输出即进入校验时的形态validation_responseOptional[Union[str, ReAsk, List, Dict]]校验过程返回的响应guarded_outputOptional[Union[str, List, Dict]]校验通过后的有效值可能含修复值字段级 ReAsk 时可能为部分结构reasksList[ReAsk]校验失败时用于构造 LLM ReAsk 的信息默认[]反序列化时通过to_reask将字典还原为ReAskvalidator_logsList[ValidatorLogs]每次独立校验的结果默认[]error/exception中断过程的错误消息与异常对象。Outputs还提供三个派生属性failed_validationsvalidator_logs中validation_result.outcome Outcome.FAIL的日志error_spans_in_output按验证器累计已校验文本长度把FailResult.error_spans的相对索引偏移为相对完整 LLM 输出的绝对索引status校验运行的终态。其判定顺序见 outputs.py为全部字段为空 →not run存在error→error存在没有fix_value的 ReAsk 失败结果 →failguarded_output为None且validation_response是ReAsk→fail否则 →pass。4.3 CallInputscall_inputs.pyCallInputs继承Inputs代表用户传入 Guard 的输入在父类基础上覆盖/新增llm_apiOptional[Callable[[Any], Awaitable[Any]]]用户在Guard.__call__/Guard.parse时提供的 LLM 函数messagesOptional[list[dict[str, str]]]用户提供的消息argsList[Any]默认[]传给 LLM 的额外位置参数kwargsDict[str, Any]默认{}传给 LLM 的额外关键字参数。注意序列化时会对键名含key或token的字符串值做脱敏只保留后 4 位其余以*代替避免 API Key 等敏感信息落盘。五、状态机pass / fail / error / not run历史对象的status统一使用四种字面量状态定义在 constants/init.pyerror、fail、pass、not run。Iteration.status直接透传outputs.status见 iteration.py判定逻辑见上文Outputs.statusCall.statuscall.py则更宏观迭代栈为空 →not run存在error→error存在未解决的失败_has_unresolved_failures()判定→fail否则 →pass。_has_unresolved_failures会检查是否还有未修复的 ReAsk以及fixed_output中对应property_path的值是否仍等于校验前值、或是Refrain/Filter等没有产生修复的占位对象。因此Call.status是最终合并输出有效性的累计表达而Iteration.status只代表单轮迭代的终态。测试 test_guard.py 给出了失败场景的断言call.status fail且call.guarded_output is None——此时即便raw_outputs.last有原始输出最终守卫输出也不会产生。六、ValidatorLogs 与失败追溯历史体系中另一个关键对象是ValidatorLogsvalidator_logs.py它记录单个验证器单次执行的完整信息字段别名说明validator_namevalidatorName验证器的类名registered_nameregisteredName验证器在注册表中的 IDvalue_before_validationvalueBeforeValidation校验前的值validation_resultvalidationResultPassResult/FailResult/ValidationResult之一反序列化时按outcome区分value_after_validationvalueAfterValidation校验后的值start_time/end_timestartTime/endTime校验起止时间序列化为 ISO 格式instance_idinstanceId验证器实例 IDproperty_pathpropertyPath被校验属性在 JSON 中的路径Call.failed_validations与Outputs.failed_validations正是在validator_logs基础上按Outcome.FAIL过滤得到的。这也解释了Call.guarded_output实现中对 no-op 的兼容当所有失败校验的value_after_validation与value_before_validation相同即 on-fail 动作为 no-op时即便整体不是pass也会返回最后一次迭代的guarded_output。七、序列化、反序列化与终端日志树所有历史对象均继承ArbitraryModelPydantic 模型因此序列化推荐model_dump(exclude_noneTrue, by_aliasTrue)源码同时保留了to_interface()/to_dict()/from_interface()/from_dict()等兼容方法但它们已被标记为deprecated文档与代码均建议改用model_dump/model_validate字段别名如callId、llmApi、numReasks、fullSchemaReask、validatorName、propertyPath等序列化时输出驼峰别名日志树Call.tree返回 RichTree配合Iteration.rich_group可在终端中按Step 0、Step 1分层展示每条迭代的消息、原始 LLM 输出与校验输出。你可以在自己的代码里直接print(call.tree)查看某次 Guard 执行的完整日志回放。八、实战小结如何读取一次调用的历史综合以上内容一次典型的读取流程如下执行guard(prompt_params...)或guard.parse(llm_output...)后通过call guard.history.first或guard.history.last拿到本次执行用call.status判断整体成败用call.guarded_output取最终输出用call.failed_validations定位失败校验需要明细时遍历call.iterationsiteration.raw_output原始输出、iteration.parsed_output解析后输出、iteration.validation_response单轮校验响应、iteration.prompt_tokens_consumed/completion_tokens_consumedToken 消耗需要排查 ReAsk 时使用call.reask_messages与call.reasks需要可视化时直接打印call.tree。这套Call 为骨架、Iteration 为细节、Inputs/Outputs 为数据载体、status 为结论的历史体系既服务于开发调试集成测试大量依赖它做断言也为后续基于历史做观测、审计与成本统计提供了统一的数据模型。赞分享AI 安全治理模型安全AI 应用【免费下载链接】guardrailsAdding guardrails to large language models.项目地址https://gitcode.com/gh_mirrors/gu/guardrails点击查看免费下载相关推荐Guardrails历史追踪与日志系统全面监控AI应用运行状态的终极指南Guardrails历史追踪与日志系统全面监控AI应用运行状态的终极指南 Guardrails是一款为大型语言模型 LLM 添加安全防护的开源工具其历史追踪AI 安全治理模型安全AI 应用NocoBase 日志体系全景服务端日志、审计日志与历史记录NocoBase 日志体系全景服务端日志、审计日志与历史记录 NocoBase 的日志体系由三类记录组成服务端日志系统运行日志 请求日志、审计日志低代码后端前端人工智能AI 应用工作流自动化TransformerLab 作业生命周期与状态机全解析从 QUEUED 到终态的状态流转、日志体系与交互式任务TransformerLab 作业生命周期与状态机全解析从 QUEUED 到终态的状态流转、日志体系与交互式任务 本篇技术指南围绕 docs/task exe人工智能大模型微调模型评测模型推理服务LLMOps本地部署后端CLI上一篇XSSTRON实战技巧如何高效利用浏览器界面进行Web安全测试下一篇GitHub_Trending/core97/coreRuntime原理插件系统架构分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。