news 2026/6/30 10:44:46

openYuanrong进阶教程——AI Agent 会话与亲和性调度

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
openYuanrong进阶教程——AI Agent 会话与亲和性调度

AI Agent 会话与亲和性调度

AI Agent 会话功能专为交互式应用场景(如 AI 智能体、多轮对话)设计。它支持函数执行过程中的主动等待与外部唤醒,并确保同一会话内的多次请求能够路由到同一个执行实例,从而实现低延迟的交互体验。

会话调度机制

AI Agent 会话的调度逻辑由faasscheduler模块负责,具有以下核心特点:

1. 会话亲和性 (Session Affinity)

当一个请求携带sessionId时,调度系统会尝试将其路由到该会话已经绑定的实例上。

  • 首次请求: 调度系统选择一个合适的实例,并建立sessionIdinstanceId的绑定关系。
  • 后续请求: 只要绑定关系有效,所有相同sessionId的请求都会定向到同一实例。

2. 弱亲和性与持久化

AI Agent 会话默认为弱亲和(TTL0)。

  • 生命周期: 当会话下的所有租约都释放后,绑定关系可能会失效。
  • 状态恢复: 会话的上下文数据(如历史记录)持久化在分布式数据系统中。当新请求到达且原实例不可用时,新实例会从数据系统重新加载会话状态。

SDK 使用说明

在启用了 AI Agent 会话的函数中,可以通过Context获取SessionService来操作会话对象。

Java SDK

核心接口:Session

Session对象提供了会话内同步和状态管理的能力。

  • wait(long timeoutMs): 挂起当前执行线程,等待输入。
  • notify(JsonObject payload): 唤醒正在wait的线程。
  • getInterrupted(): 检查当前会话是否已被外部中断。
Java 使用示例
importcom.google.gson.JsonObject;publicObjecthandle(Contextctx,JsonObjectinput){Sessionsess=ctx.getSessionService().loadSession(ctx.getSessionId());// 检查是否为 notify 请求,假设用户在 payload 字段中传入通知内容if(input.has("action")&&"notify".equals(input.get("action").getAsString())){sess.notify(input.getAsJsonObject("payload"));return"Notified";}JsonObjectuserInput=sess.wait(60000);if(userInput==null)return"Timeout";if(sess.getInterrupted())return"Interrupted";return"Got: "+userInput.toString();}

Python SDK

在 Python 函数实例中,yr模块提供了类似的会话操作能力。

核心接口:yr.SessionService
  • session.wait_for_notify(timeout_ms): 阻塞当前协程/线程,等待通知。
  • session.notify(payload): 发送通知。
  • session.is_interrupted(): 检查会话是否被中断。
Python 使用示例
importyrdefhandle(ctx,input):session_id=ctx.get_session_id()session=ctx.get_session_service().load_session(session_id)ifinput.get("action")=="notify":session.notify(input.get("payload"))return"Notified"# 等待通知user_input=session.wait_for_notify(60000)ifuser_inputisNone:return"Wait timeout"ifsession.is_interrupted():return"Session Interrupted"returnf"Received:{user_input}"

完整用例:多轮对话 AI Agent

以下是一个完整的 Java 示例,演示了如何利用wait/notify实现一个简单的多轮交互。

importorg.yuanrong.services.Context;importorg.yuanrong.services.session.Session;importorg.yuanrong.services.session.SessionService;importcom.google.gson.JsonObject;importjava.util.ArrayList;importjava.util.List;publicclassSimpleAgent{publicObjecthandle(Contextctx,JsonObjectinput){SessionServicesessService=ctx.getSessionService();Sessionsess=sessService.loadSession(ctx.getSessionId());// 1. 处理通知/唤醒请求if(input.has("action")&&"notify".equals(input.get("action").getAsString())){// 提取真正的通知载荷进行唤醒sess.notify(input.getAsJsonObject("payload"));returnnull;// Notify 请求通常不需要返回业务结果}// 2. 主执行流程try{ctx.getLogger().log("Agent Started, SessionID: "+ctx.getSessionId());// 第一轮交互ctx.getStream().write("你好!我是 AI 助手,请问有什么可以帮您?\n");JsonObjectinput1=sess.wait(30000);// 等待用户输入 30 秒if(input1==null)return"等待超时";Stringmsg1=input1.get("message").getAsString();ctx.getStream().write("收到指令:"+msg1+"\n正在为您处理...\n");// 模拟处理过程并更新历史List<String>history=newArrayList<>(sess.getHistories());history.add("User: "+msg1);sess.setHistories(history);// 第二轮交互ctx.getStream().write("处理完成。您还有其他问题吗?\n");JsonObjectinput2=sess.wait(30000);if(input2==null)return"等待超时";if(sess.getInterrupted()){return"会话已被外部中断";}Stringmsg2=input2.get("message").getAsString();ctx.getStream().write("好的,已收到您的进一步要求:"+msg2+"\n");}catch(Exceptione){ctx.getLogger().log("Error: "+e.getMessage());}return"Session Completed";}}

交互流程示意图

第一轮交互:逻辑挂起

  1. 客户端发起POST /invocations(携带SessionID:S1)
  2. 函数实例接收请求,执行业务逻辑,直到调用sess.wait()
  3. 函数实例释放会话锁,执行线程进入挂起状态,等待唤醒

第二轮交互:唤醒与继续

  1. 客户端发起第二个请求POST /invocations(相同SessionID:S1,Action:notify)
  2. 函数实例接收请求,由于会话亲和性,该请求进入同一实例
  3. 函数实例执行sess.notify(payload),唤醒之前挂起的线程
  4. 函数实例通知请求处理完成并返回200 OK
  5. 函数实例(原线程) 获取到notify传递的数据,继续执行后续逻辑
  6. 函数实例(原线程) 完成处理,向客户端返回第一轮请求的最终结果
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/30 10:43:36

Linux网络打印进阶:EPSON L3255驱动依赖库缺失排查与修复实录

1. 当打印机驱动装好了却不能用&#xff1a;一个真实案例的深度剖析 上周帮朋友调试一台EPSON L3255打印机&#xff0c;明明按照官网指引装好了驱动&#xff0c;点击打印却始终显示"渲染失败"。这种场景太典型了——表面看驱动安装顺利&#xff0c;实际底层依赖库早已…

作者头像 李华
网站建设 2026/6/30 10:39:25

爬虫分类科普:普通爬虫和聚焦爬虫差异、场景与实操要点

网络爬虫是数据采集的核心工具&#xff0c;按照抓取范围和运行逻辑划分&#xff0c;最常见的两类就是普通爬虫与聚焦爬虫&#xff0c;二者在设计初衷、工作方式和适用场景上的区别十分明显。普通爬虫走的是广覆盖的路线&#xff0c;不会限定具体的内容主题&#xff0c;通常采用…

作者头像 李华
网站建设 2026/6/30 10:38:40

文旅数字化实践:百度地图如何用时空大数据打通B端管理与C端服务

文旅数字化落地的核心矛盾&#xff0c;不是数据够不够多&#xff0c;而是数据和决策之间断层——管理者看不懂&#xff0c;游客用不上。 百度地图慧眼文旅的技术路径是&#xff1a;依托日均超1200亿次位置服务请求&#xff0c;构建客流监测、趋势预测、游客画像三层数据能力&am…

作者头像 李华
网站建设 2026/6/30 10:38:02

Magic源码探秘(二)——GDSII文件结构解析与二进制流解码实战

1. GDSII文件的前世今生 第一次接触GDSII文件时&#xff0c;我盯着满屏的十六进制代码直发懵。这玩意儿就像集成电路设计界的摩斯密码&#xff0c;记录着芯片版图的全部秘密。GDSII诞生于上世纪70年代&#xff0c;由Calma公司开发&#xff0c;后来被Cadence收购并逐步成为行业标…

作者头像 李华
网站建设 2026/6/30 10:37:57

Pytorch3D Linux部署实战:从预编译到源码构建的避坑指南

1. 为什么你需要这份Pytorch3D部署指南&#xff1f; 第一次接触Pytorch3D的开发者&#xff0c;往往会被它复杂的依赖关系搞得晕头转向。我见过太多人在安装环节就耗费一整天时间&#xff0c;最后还没能成功运行。这就像组装一台高性能电脑&#xff0c;如果连主板和CPU都装不上去…

作者头像 李华
网站建设 2026/6/30 10:37:52

Android 逆向实战:ApkTool 解包与重打包全流程解析

1. ApkTool 基础入门&#xff1a;逆向工程师的瑞士军刀 第一次接触ApkTool是在2014年分析一个恶意样本时&#xff0c;当时用zip解压APK后看到的全是乱码的二进制文件&#xff0c;那种挫败感至今记忆犹新。ApkTool就像一把打开Android应用黑匣子的万能钥匙&#xff0c;它能将经过…

作者头像 李华