尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Parlant Relationships 详解:用蕴含、优先级、依赖与消歧精确控制 Guideline 的行为协作

Parlant Relationships 详解:用蕴含、优先级、依赖与消歧精确控制 Guideline 的行为协作 Parlant Relationships 详解用蕴含、优先级、依赖与消歧精确控制 Guideline 的行为协作【免费下载链接】parlantBuild reliable customer-facing AI agents with Parlant: an interaction control harness optimized for controlled, consistent, and predictable LLM interactions.项目地址: https://gitcode.com/GitHub_Trending/pa/parlantParlant 的 Relationships 机制允许你在guideline指南与journey旅程之间显式声明行为关系当多条指南同时被会话状态激活时由你而非 LLM 的自由发挥决定谁蕴含谁、谁压过谁、谁依赖谁、谁需要向用户澄清。读完本文你将掌握 4 类核心关系entailment、priority、dependency、disambiguation与 observational guideline 的完整用法并能对照 relational_resolver.py 的引擎实现理解每种关系在推理阶段的具体执行算法。1. 背景与动机为什么按条件写规则还不够文档以团队构建的一个披萨销售 Agent 说起原文见 relationships.md。Agent 安装了以下两条指南offer_pepsi_instead_of_coke await agent.create_guideline( conditionThe customer wants a coke, actionTell them we only have Pepsi, ) handoff_if_upset await agent.create_guideline( conditionThe customer is becoming upset, actionApologize and tell them you will transfer them to a manager, tools[handoff_to_human_manager], )这起初工作得很好直到出现这样的对话Agent:Do you want anything to drink with your order?您想搭配什么饮品吗User:A coke please来杯可乐。Agent:Im sorry, we only have Pepsi.抱歉我们只有百事可乐。User:Wait, what? I hate Pepsi. Why the hell dont you have coke?什么我讨厌百事为什么没有可乐Agent:Im sorry for this inconvenience. Let me transfer you to a manager. Meanwhile, can I offer you a Pepsi?抱歉带来不便我把您转接给经理同时请问您要杯百事吗User:Are you taking the piss out of me?你在耍我吧Agent 的回应带有近乎嘲讽的攻击性——但它其实只是在忠实执行我们给它写的两条指南客户想喝可乐时推百事条件命中客户正在生气时道歉并转接经理条件也命中于是两个 action 被同时塞进了同一条回复。文档由此点出一个关键洞察管理指令不只是技术挑战更是一个人类建模挑战。你必须考虑这些指令在一个会非常字面地理解它们的自动 Agent 眼中应当如何相互关联尤其是细微情境下谁该让位于谁——而这最终只能由建模者决定。在这个例子中我们希望转接经理这条指南优先于推百事。在 Parlant 中这表达得非常简单await handoff_if_upset.prioritize_over(offer_pepsi_instead_of_coke)2. 关系模型总览source、target 与关系类型每条关系都连接一个源实体source记作 S和一个目标实体target记作 T。文档定义的核心关系有 4 种配合 SDK 方法如下关系类型SDK 方法语义Entailment蕴含await source.entail(target)S 被激活时T 也应始终被激活Priority优先级await source.prioritize_over(target)S 和 T 同时被激活时只保留 SDependency依赖await source.depend_on(target)S 被激活时若 T 未同时激活则取消 SDisambiguation消歧await source.disambiguate([target_1, target_2, ...])S 被激活且 ≥2 个目标 T 被激活时请客户澄清想要哪个动作对照 core/relationships.py 中的RelationshipKind枚举可以看到引擎内部实际支持7 种关系类型——文档面向建模者的 4 种之外还多出 3 种DEPENDENCY_ANY依赖的 OR 语义版本同组group_id相同目标中至少一个激活即可对应 SDK 的depend_on_any()REEVALUATION当目标 tool 被执行后在回复前重新评估源 guideline对应 SDK 的reevaluate_after(*tools)OVERLAP当两个 tool 关系都参与评估时应在同一批次中评估以防止冲突主要服务于工具调用侧。另外从 sdk.py 的结构看Guideline上每个关系方法的目标参数都不是单一 guidelineprioritize_over/exclude可接受Guideline | Journey | Tag | AllOfdepend_on/depend_on_any可接受Guideline | Journey | Tag | AnyOf | AllOf。其中AnyOfsdk.py#L1033把 Tag 包装成 ANY 语义只要该 tag 下至少一个成员处于激活状态依赖即满足AllOfsdk.py#L1043包装成 ALL 语义所有被标记成员都必须激活直接传裸Tag时默认就是 ALL 语义。这意味着关系不仅可以建在两条 guideline 之间还可以以 tag 为中介批量作用于一组 guideline、或作用于整条 journey。每个方法返回Relationship数据类列表sdk.py#L1088-L1094含id、kind、source、target可用于后续管理与审计。还有一个 API 层面的细节值得注意SDK 中 Tag 的关系方法会检查是否处于 server 启动作用域否则抛出SDKError(Tag relationships can only be created during the server startup scope.)sdk.py#L953-L961——即 tag 维度的关系属于配置期操作。3. Entailment让即将要做的事自动带出后续动作When S is activated, T should always be activatedS 被激活时T 也应始终被激活await source.entail(target)要理解蕴含的必要性文档先解释了 Parlant 如何为 Agent 选择激活哪些 guideline引擎审视会话当前状态对每条指南逐一提问——这条指南现在相关吗——而判断主要依据就是指南的condition。单独看这似乎足够直到你写下这样两条指南Guideline A:When X, Then Y当 X则做 YGuideline B:When Y, Then Z当 Y则做 Z设想这样一个场景检查会话后发现X确实成立但Y尚未成立。用朴素的逐条判断逻辑我们只会把做 Y这条指南喂给 Agent。可退一步看Agent 马上就要执行Y了按照我们装好的指南体系Z理应随之生效。蕴含做的就是这件事强制每当 A 被激活时B 也一并被激活。引擎侧的实现位于 relational_resolver.py 的_apply_entailment()它对每个已激活的 match 查询ENTAILMENT关系且使用indirectTrue传递闭包——即 A→B、B→C 会级联推导出 C 也需激活。这与 RelationshipDocumentStore.list_relationships() 中基于 NetworkXbfs_edges的广度优先遍历相对应被蕴含激活的 guideline 会生成一条新的GuidelineMatch其 rationale 被标记为[Activated via entailment] Automatically inferred from context分数继承自所有蕴含来源中得分最高的那个 match——也就是说被蕴含的指南会正常进入后续生成流程且在解释性输出中可追溯其来源若 target 是一个 tag则展开该 tag 下的所有成员 guideline 并继续向外传递。4. Priority互斥控制与对话流排序When both S and T are activated, only S should be activatedS 与 T 同时被激活时只保留 Sawait source.prioritize_over(target)文档指出 priority 有两个最常见用途创建互斥指南——两条指南不应同时生效控制对话内动作的流程与先后顺序。关于控制优先级文档给了一个银行场景示例。你可能有两条会同时激活的指南When the customer wants to make a transaction, Then guide them through the process to its completion客户想办理交易时引导其完成整个流程When the customer has less than $1,000 in their account, Then offer savings plans客户账户余额不足 1000 美元时推荐储蓄计划当客户正在提交交易的过程中会话引入了账户余额信息两条指南会同时命中。你希望推荐储蓄计划仍然会发生但时机要好一点——等交易完成之后。此时可以让完成交易优先于推荐储蓄计划交易完成后储蓄相关指南才会在下一轮被激活。引擎实现见_apply_prioritization()几个值得注意的行为从源码结构看不传递经过未激活中介的优先级_get_priority_relationships_for_match()只取indirectFalse的直接关系源码注释称之为reinstatement principle复权原则——避免一条指南因为链路中间某个环节当时不活跃而被错误地长期压制tag 中介链G1 → T1 → G2则通过对指南的每个 tag 显式追加查询来支持journey 级优先级journey 会以其专属 journey tag 作为目标参与优先级判定guideline 可以压过整条 journey反之亦然被压低的 journey 节点指南移除后整条 journey 也会被过滤传递性清理_filter_deprioritized_dependents()会再删掉那些依赖于已被压低实体的指南AND 依赖任一目标被压低即删除OR 组则整组目标全部被压低才失败防止主规则让位了副规则还在执行的矛盾状态每次压低都会记录ResolutionKind.DEPRIORITIZED解析记录并写 debug 日志Dropped (deprioritized by guideline): ...配合 Parlant 的可解释性能力可以追溯任何一次这条指南为什么没生效。此外exclude()是prioritize_over()的别名sdk.py#L1277-L1279语义相同可按代码风格选用。5. Dependency把边缘场景锚定在正确的基线上下文中When S is activated, deactivate it unless T is also activatedS 被激活时若 T 未同时激活则取消 Sawait source.depend_on(target)依赖确保一条 guideline只在其他基线条件也成立时才被激活。文档给出的典型用例是把具体条件语境化contextualizing specific conditions在构建流程时你可以通过让边缘场景依赖流程基线指南保证其评估总发生在正确的上下文中。以退货流程为例基线指南Baseline GuidelineWhen the customer wants to return an order, Then help them complete the return process客户想退货时帮助其完成退货流程依赖指南Dependent GuidelinesWhen the customer isnt able to provide the order number, Then load up their last orders items and ask them to confirm if that is their order客户无法提供订单号时调出其最近一笔订单的条目并请其确认When the customer specified the exact order number, Then load up that orders items and ask them to confirm if that is their order客户给出了确切订单号时调出该订单条目并请其确认让后两条depend_on基线指南后它们的评估就总是发生在客户正在退货这个语境里而不会在别的会话状态下误触发。引擎侧_apply_dependencies()是一个三阶段算法Phase 1 — Resolve为每条已命中指南收集其DEPENDENCY与DEPENDENCY_ANY关系把目标解析为具体的判定对象同时构建拓扑排序图Phase 2 — Topological sort用 Kahn 算法保证被依赖者优先于依赖者处理Phase 3 — Evaluate沿拓扑序逐条检查——AND 依赖要求所有目标都满足OR 组depend_on_any创建的、共享group_id的组要求每组至少一个目标满足不满足的指南被移除。拓扑序的意义在于级联失败若某条依赖目标本身因依赖不满足被移除它的下游依赖者会在随后的评估步中自然失败无需额外的传递查询。文档没有展开的depend_on_any()sdk.py#L1297-L1313在此同样受支持它用 UUID 作为group_id把多个目标编为一组。存储层则负责防止你写出无法求值的依赖环RelationshipDocumentStore.create_relationship() 用 NetworkX 有向无环图维护每种关系类型创建 DEPENDENCY / DEPENDENCY_ANY 时若新边会引入环包括跨 DEPENDENCY 与 DEPENDENCY_ANY 两种图之间的可达性会回滚数据库写入并抛出ValueError(Circular dependency detected: ...)。6. Disambiguation竞争指南同时命中时向客户澄清When S is activated and two or more of the targets T ∈ {T₁, T₂, ...} are activated, ask the customer to clarify which action they want to takeS 被激活且 ≥2 个目标被激活时请客户澄清想执行哪个动作await source.disambiguate([target_1, target_2, ...])典型场景银行 Agent 收到客户消息What are my limits?我的额度是多少而你有两条可能同时被引擎乐观激活的指南When the customer is inquiring about their ATM limits, Then fetch the data from their account profile客户询问 ATM 限额时从账户档案取数When the customer is inquiring about their credit cards limits, Then fetch them from the card provider客户询问信用卡限额时从卡提供方取数此时可以加一条观测指南来在两个动作之间消歧ambiguous_limits await agent.create_observation( conditionThe customer is inquiring about limits but it isnt clear which kind, ) await ambiguous_limits.disambiguate([fetch_atm_limits, fetch_credit_card_limits])对应地SDK 的disambiguate()要求至少两个目标否则抛SDKError且若目标是Journey会自动展开其triggers指南逐一建关系。引擎在 guideline 匹配策略中消费DISAMBIGUATION关系见 generic_guideline_matching_strategy.py当源条件命中且多个竞争目标同时激活时Agent 会转而生成一条澄清性问题而不是硬选一个动作。7. Observational Guidelines只观察、不行动的指南当你在用关系建模对话边缘场景时常会遇到这样一种需求只是想声明某种情境成立用一条 condition 表达然后仅在这些情境下通过关系去激活或抑制其他 guideline / journey。为此 Parlant 提供了observational guideline一条没有 action的指南它仍会参与上下文匹配但不携带任何要执行的动作专门用于确立条件 围绕条件建关系。observation await agent.create_observation(conditionCONDITION)文档给出的两种典型用法用观测指南压过其他指南在特定情境下禁用它们await observation.prioritize_over(other_guideline)把其他指南的作用范围限定在观测成立时才生效await other_guideline.depend_on(observation)实现上Agent.create_observation()就是create_guideline()的无 action 快捷方式sdk.py#L2763-L2784因此观测指南与常规指南在匹配、持久化、建关系上走的是同一套基础设施——这也解释了为什么第 6 节的消歧例子能直接用一条无动作的 condition 充当关系源头。8. 服务端视角关系如何被存储与暴露关系不仅可通过 SDK 在代码中声明也可以作为服务端资源管理存储模型。RelationshipDocument 持久化了source/target的 id 与实体类型guideline / tag_all / tag_any / tool、kind和可选group_id实体类型枚举见 RelationshipEntityKind。每种kind对应一张内存中的 NetworkX DiGraph 用于路径查询indirectTrue的列表操作即在这张图上做 BFS。HTTP API。api/relationships.py 暴露了完整 CRUDPOST /relationshipscreate请求体可传source_guideline/source_tag/source_tool与对应 target 字段加kind请求示例源码中的示例 JSON{ source_guideline: gid_123, target_tag: tid_456, kind: entailment }服务端会校验source 不能同时传 guideline 和 tag以及source 与 target 不能是同一实体违规返回 422见 create_relationship()GET /relationshipslist支持kind、indirect是否包含间接关系默认 true、guideline_id/tag_id/tool_id格式service_name:tool_name等查询参数GET /relationships/{relationship_id}与DELETE /relationships/{relationship_id}。验证与测试。关系解析行为有专门的稳定测试覆盖tests/core/stable/engines/alpha/test_relational_resolver.py 验证了 resolver 的各类行为disambiguation 批处理在 test_disambiguation_batch.pySDK 侧的 CRUD 在 tests/api/test_relationships.py 与 tests/sdk/test_labels.py 等文件中均有对应用例可作为各语义的活文档参考。9. 小结建模者视角的速查表你想解决的问题关系代码引擎执行点做 Y 时理应同时做 Z但 Z 的 condition 还没字面命中Entailmentawait a.entail(b)_apply_entailment()传递闭包两条指南不能同时生效或希望某动作等另一动作完成后才发生Priorityawait a.prioritize_over(b)_apply_prioritization()含依赖者传递清理边缘场景只在基线流程进行中才评估Dependencyawait edge.depend_on(baseline)_apply_dependencies()拓扑排序 AND/OR 判定同一句话可能指 A 也可能指 B先问清Disambiguationawait obs.disambiguate([a, b])匹配策略中消费 DISAMBIGUATION 关系生成澄清问题只想声明当前处于某种情境Observationawait agent.create_observation(condition...)与普通指南同走匹配流程无 action 注入从 Pizza Agent 的讽刺式转接到银行 Agent 的限额到底指哪个限额Parlant 的核心主张是一致的指南之间如何关联、在什么情境下谁让位于谁是只有建模者能做出的决定——而 Relationships 正是把这一决定显式化、可存储、可追溯通过 Resolution 记录与 debug 日志、并在推理时以确定性算法执行的机制。【免费下载链接】parlantBuild reliable customer-facing AI agents with Parlant: an interaction control harness optimized for controlled, consistent, and predictable LLM interactions.项目地址: https://gitcode.com/GitHub_Trending/pa/parlant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表