pocketflow库实现guardrail

目录

    • 代码
    • 代码解释
      • 1. 系统架构
      • 2. 核心组件详解
        • 2.1 LLM调用函数
        • 2.2 UserInputNode(用户输入节点)
        • 2.3 GuardrailNode(安全防护节点)
        • 2.4 LLMNode(LLM处理节点)
      • 3. 流程控制机制
    • 示例运行

代码

from pocketflow import Node, Flowfrom openai import OpenAIdef call_llm(messages):client = OpenAI(api_key = "your api key",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")response = client.chat.completions.create(model="qwen-turbo",messages=messages,temperature=0.7)return response.choices[0].message.contentclass UserInputNode(Node):def prep(self, shared):# Initialize messages if this is the first runif "messages" not in shared:shared["messages"] = []print("Welcome to the Travel Advisor Chat! Type 'exit' to end the conversation.")return Nonedef exec(self, _):# Get user inputuser_input = input("\nYou: ")return user_inputdef post(self, shared, prep_res, exec_res):user_input = exec_res# Check if user wants to exitif user_input and user_input.lower() == 'exit':print("\nGoodbye! Safe travels!")return None  # End the conversation# Store user input in sharedshared["user_input"] = user_input# Move to guardrail validationreturn "validate"class GuardrailNode(Node):def prep(self, shared):# Get the user input from shared datauser_input = shared.get("user_input", "")return user_inputdef exec(self, user_input):# Basic validation checksif not user_input or user_input.strip() == "":return False, "Your query is empty. Please provide a travel-related question."if len(user_input.strip()) < 3:return False, "Your query is too short. Please provide more details about your travel question."# LLM-based validation for travel topicsprompt = f"""
Evaluate if the following user query is related to travel advice, destinations, planning, or other travel topics.
The chat should ONLY answer travel-related questions and reject any off-topic, harmful, or inappropriate queries.
User query: {user_input}
Return your evaluation in YAML format:
```yaml
valid: true/false
reason: [Explain why the query is valid or invalid]
```"""# Call LLM with the validation promptmessages = [{"role": "user", "content": prompt}]response = call_llm(messages)# Extract YAML contentyaml_content = response.split("```yaml")[1].split("```")[0].strip() if "```yaml" in response else responseimport yamlresult = yaml.safe_load(yaml_content)assert result is not None, "Error: Invalid YAML format"assert "valid" in result and "reason" in result, "Error: Invalid YAML format"is_valid = result.get("valid", False)reason = result.get("reason", "Missing reason in YAML response")return is_valid, reasondef post(self, shared, prep_res, exec_res):is_valid, message = exec_resif not is_valid:# Display error message to userprint(f"\nTravel Advisor: {message}")# Skip LLM call and go back to user inputreturn "retry"# Valid input, add to message historyshared["messages"].append({"role": "user", "content": shared["user_input"]})# Proceed to LLM processingreturn "process"class LLMNode(Node):def prep(self, shared):# Add system message if not presentif not any(msg.get("role") == "system" for msg in shared["messages"]):shared["messages"].insert(0, {"role": "system", "content": "You are a helpful travel advisor that provides information about destinations, travel planning, accommodations, transportation, activities, and other travel-related topics. Only respond to travel-related queries and keep responses informative and friendly. Your response are concise in 100 words."})# Return all messages for the LLMreturn shared["messages"]def exec(self, messages):# Call LLM with the entire conversation historyresponse = call_llm(messages)return responsedef post(self, shared, prep_res, exec_res):# Print the assistant's responseprint(f"\nTravel Advisor: {exec_res}")# Add assistant message to historyshared["messages"].append({"role": "assistant", "content": exec_res})# Loop back to continue the conversationreturn "continue"# Create the flow with nodes and connections
user_input_node = UserInputNode()
guardrail_node = GuardrailNode()
llm_node = LLMNode()# Create flow connections
user_input_node - "validate" >> guardrail_node
guardrail_node - "retry" >> user_input_node  # Loop back if input is invalid
guardrail_node - "process" >> llm_node
llm_node - "continue" >> user_input_node     # Continue conversationflow = Flow(start=user_input_node)shared = {}
flow.run(shared)

代码解释

这个示例展示了如何使用PocketFlow框架实现一个带有guardrail(安全防护)机制的旅行顾问聊天机器人。整个系统由三个核心节点组成,通过条件流控制实现智能对话管理。

1. 系统架构

用户输入 → 安全验证 → LLM处理 → 用户输入↑         ↓←─────────┘(验证失败时重试)

2. 核心组件详解

2.1 LLM调用函数
def call_llm(messages):client = OpenAI(api_key = "your api key",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")
  • 使用阿里云DashScope的兼容OpenAI API接口
  • 配置qwen-turbo模型,temperature=0.7保证回答的创造性
2.2 UserInputNode(用户输入节点)
class UserInputNode(Node):def prep(self, shared):if "messages" not in shared:shared["messages"] = []

功能

  • prep:初始化对话历史,首次运行时显示欢迎信息
  • exec:获取用户输入
  • post:检查退出条件,将输入存储到共享状态,返回"validate"进入验证流程
2.3 GuardrailNode(安全防护节点)

这是系统的核心安全组件,实现多层验证:

基础验证

if not user_input or user_input.strip() == "":return False, "Your query is empty..."
if len(user_input.strip()) < 3:return False, "Your query is too short..."

LLM智能验证

prompt = f"""
Evaluate if the following user query is related to travel advice...
Return your evaluation in YAML format:
```yaml
valid: true/false
reason: [Explain why the query is valid or invalid]
```"""

验证流程

  1. 基础格式检查(空输入、长度)
  2. 使用LLM判断是否为旅行相关话题
  3. 解析YAML格式的验证结果
  4. 根据验证结果决定流向:
    • 失败:返回"retry"重新输入
    • 成功:返回"process"进入LLM处理
2.4 LLMNode(LLM处理节点)
def prep(self, shared):if not any(msg.get("role") == "system" for msg in shared["messages"]):shared["messages"].insert(0, {"role": "system", "content": "You are a helpful travel advisor..."})

功能

  • prep:确保系统提示词存在,定义AI助手角色
  • exec:调用LLM生成回答
  • post:显示回答,更新对话历史,返回"continue"继续对话

3. 流程控制机制

user_input_node - "validate" >> guardrail_node
guardrail_node - "retry" >> user_input_node
guardrail_node - "process" >> llm_node
llm_node - "continue" >> user_input_node

流程说明

  1. 正常流程:用户输入 → 验证通过 → LLM处理 → 继续对话
  2. 安全拦截:用户输入 → 验证失败 → 重新输入
  3. 退出机制:用户输入"exit" → 程序结束

示例运行

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fetch API 使用详解:Bearer Token 与 localStorage 实践

Fetch API&#xff1a;现代浏览器内置的用于发送 HTTP 请求的 API&#xff0c;Bearer Token&#xff1a;一种基于令牌的身份验证方案&#xff0c;常用于 JWT 认证&#xff0c;localStorage&#xff1a;浏览器提供的持久化存储方案&#xff0c;用于在客户端存储数据。 token是我…

Netty自定义协议解析

目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…

驭码 CodeRider 2.0 产品体验:智能研发的革新之旅

驭码 CodeRider 2.0 产品体验&#xff1a;智能研发的革新之旅 在当今快速发展的软件开发领域&#xff0c;研发效率与质量始终是开发者和企业关注的核心。面对开发协作流程繁琐、代码生成补全不准、代码审核低效、知识协同困难以及部署成本与灵活性难以平衡等问题&#xff0c;…

NLP学习路线图(二十六):自注意力机制

一、为何需要你?序列建模的困境 在你出现之前,循环神经网络(RNN)及其变种LSTM、GRU是处理序列数据(如文本、语音、时间序列)的主流工具。它们按顺序逐个处理输入元素,将历史信息压缩在一个隐藏状态向量中传递。 瓶颈显现: 长程依赖遗忘: 随着序列增长,早期信息在传递…

【渲染】Unity-分析URP的延迟渲染-DeferredShading

我是一名资深游戏开发&#xff0c;小时候喜欢看十万个为什么 介绍 本文旨在搞清楚延迟渲染在unity下如何实现的&#xff0c;为自己写延迟渲染打一个基础&#xff0c;打开从知到行的大门延迟渲染 输出物体表面信息(rt1, rt2, rt3, …) 着色(rt1, rt2, rt3, …)研究完感觉核心…

华为OD机考- 简单的自动曝光/平均像素

import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…

java 乐观锁的实现和注意细节

文章目录 1. 前言乐观锁 vs. 悲观锁&#xff1a;基本概念对比使用场景及优势简述 2. 基于版本号的乐观锁实现代码示例注意事项 3. 基于CAS机制的乐观锁实现核心思想代码示例关键点说明 4. 框架中的乐观锁实践MyBatis中基于版本号的乐观锁实现示例代码 JPA&#xff08;Hibernate…

河北对口计算机高考C#笔记(2026高考适用)---持续更新~~~~

C#笔记 C#发展史 1998年,C#发布第一个版本。2002年,visual studio开发环境推出C#的特点 1.语法简洁,不允许直接操作内存,去掉了指针操作 2.彻底面向对象设计。 3.与Web紧密结合。 4.强大的安全机制,语法错误提示,引入垃圾回收器机制。 5.兼容性。 6.完善的错误,异常处理…

C# dll版本冲突解决方案

随着项目功能逐渐增加&#xff0c;引入三方库数量也会增多。不可避免遇到库的间接引用dll版本冲突&#xff0c;如System.Memory.dll、System.Buffer.dll等。编译会报警&#xff0c;运行可能偶发异常。 可使用ILMerge工具合并动态库&#xff0c;将一个库的多个dll合并为一个dll。…

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…

随机访问介质访问控制:网络中的“自由竞争”艺术

想象一场自由辩论赛——任何人随时可以发言&#xff0c;但可能多人同时开口导致混乱。这正是计算机网络中随机访问协议的核心挑战&#xff1a;如何让多个设备在共享信道中高效竞争&#xff1f;本文将深入解析五大随机访问技术及其智慧。 一、核心思想&#xff1a;自由竞争 冲突…

设计模式作业

package sdau;public class man {public static void main(String[] args) {show(new Cat()); // 以 Cat 对象调用 show 方法show(new Dog()); // 以 Dog 对象调用 show 方法Animal a new Cat(); // 向上转型 a.eat(); // 调用的是 Cat 的 eatCat c (Cat)a…

Kaspa Wasm SDK

文章目录 1. 简要2. github地址 1. 简要 kaspa wallet SDK&#xff0c;在官方WASM基础上封装了应用层的方法&#xff0c;简便了WASM的初始化及调用。 核心功能包括如下&#xff1a; 账户地址生成及管理Kaspa Api 和 Kasplex Api的封装kaspa结点RPC 封装P2SH的各个场景script封…

ROS mapserver制作静态地图

ROS mapserver制作静态地图 静态地图构建 1、获取一个PNG地图&#xff0c;二值化 2、基于PNG地图&#xff0c;生成PGM地图&#xff0c;可以通过一些网站在线生成&#xff0c;例如Convertio 文件配置 1、将文件放置于/package/map路径下。 2、编写yaml文件&#xff0c;如下…

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…

浏览器工作原理05 [#] 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的

引用 浏览器工作原理与实践 一、提出问题 在上一篇文章中我们介绍了导航相关的流程&#xff0c;那导航被提交后又会怎么样呢&#xff1f;就进入了渲染阶段。这个阶段很重要&#xff0c;了解其相关流程能让你“看透”页面是如何工作的&#xff0c;有了这些知识&#xff0c;你可…

DrissionPage爬虫包实战分享

一、爬虫 1.1 爬虫解释 爬虫简单的说就是模拟人的浏览器行为&#xff0c;简单的爬虫是request请求网页信息&#xff0c;然后对html数据进行解析得到自己需要的数据信息保存在本地。 1.2 爬虫的思路 # 1.发送请求 # 2.获取数据 # 3.解析数据 # 4.保存数据 1.3 爬虫工具 Dris…

android 布局小知识点 随记

1. 布局属性的命名前缀规律 与父容器相关的前缀 layout_alignParent&#xff1a;相对于父容器的对齐方式。 例如&#xff1a;layout_alignParentTop"true"&#xff08;相对于父容器顶部对齐&#xff09;。layout_margin&#xff1a;与父容器或其他控件的边距。 例如…

GeoDrive:基于三维几何信息有精确动作控制的驾驶世界模型

25年5月来自北大、理想汽车和 UC Berkeley 的论文“GeoDrive: 3D Geometry-Informed Driving World Model with Precise Action Control”。 世界模型的最新进展彻底改变动态环境模拟&#xff0c;使系统能够预见未来状态并评估潜在行动。在自动驾驶中&#xff0c;这些功能可帮…

Java高频面试之并发编程-25

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天又来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;CAS都有哪些问题&#xff1f;如何解决&#xff1f; CAS 的问题及解决方案 CAS&#xff08;Compare and Swap&#xff0…