使用Python在Bot Framework中通过Middleware捕获Bot响应的相关咨询
实现思路
- 首先明确Bot Framework Python SDK的中间件工作逻辑:中间件是挂载到适配器上的处理管道,每一轮活动(Activity)收发都会依次经过中间件的
on_turn方法,你需要在这个方法里捕获bot的输出活动。 - 核心实现逻辑:在
on_turn方法里,先调用下一层中间件/业务逻辑的处理,等处理完成后,从上下文(TurnContext)的send_activities回调里拿到所有bot即将发送的响应内容。 - 注意要捕获所有响应,包括文本、附件、卡片等不同类型的Activity,不要只过滤文本类型。
代码实现示例
首先编写自定义中间件类:
from botbuilder.core import Middleware, TurnContext from typing import List, Callable class ResponseCaptureMiddleware(Middleware): async def on_turn(self, context: TurnContext, next: Callable): # 存储捕获到的响应内容 captured_responses: List[dict] = [] # 定义send_activities的拦截钩子 async def capture_send(activity, next_send): # 把响应内容序列化后存入列表,可根据需求过滤字段 captured_responses.append(activity.serialize()) # 继续执行发送逻辑,不阻塞原流程 return await next_send() # 把钩子挂载到当前上下文的发送回调链上 context.on_send_activities(capture_send) try: # 执行后续的中间件和bot业务逻辑 await next() finally: # 这里可以对捕获到的响应做后续处理,比如落库、日志上报等 # 示例:打印所有捕获的响应内容 for resp in captured_responses: print(f"捕获到Bot响应: {resp.get('text', '')}")
然后将中间件挂载到适配器上即可生效:
from botbuilder.core import BotFrameworkAdapter # 初始化适配器,填你自己的AppId和AppPassword adapter = BotFrameworkAdapter(AppId, AppPassword) # 挂载自定义中间件,注意中间件的顺序会影响执行顺序 adapter.use(ResponseCaptureMiddleware())
注意事项
- 如果你的bot有延迟回复、主动推送的场景,需要额外处理主动发送的Activity捕获,这类Activity不会经过当前会话的TurnContext,需要在主动发送的入口处单独加捕获逻辑。
- 不要在中间件的捕获逻辑里加耗时同步操作,会阻塞整个消息处理流程,异步操作也要控制超时时间。
- 如果需要修改响应内容,可以在
capture_send方法里直接修改activity的字段再发送,不需要额外处理。
内容的提问来源于stack exchange,提问作者user9855045
相关产品推荐
相关产品推荐

