本示例演示如何使用框架的 Filter 与 Callback 能力,在 Model 调用前后进行拦截处理,实现对 LLM 请求/响应的可观测与干预。
- Model Filter 拦截:通过
@register_model_filter注册自定义ModelFilter,在流式调用的start / event / end阶段插入日志,验证 Filter 链路的完整性 - Before/After Model Callback:通过
before_model_callback和after_model_callback分别在 LLM 请求发出前、响应返回后执行自定义逻辑 - 工具调用能力:通过
FunctionTool接入天气工具函数,验证 Filter 和 Callback 在工具调用场景下的触发行为 - 流式事件处理:通过
runner.run_async(...)处理 partial/full event,并打印工具调用与工具返回 - 多轮测试覆盖:覆盖"无工具调用的纯文本回复"与"触发工具调用的天气查询"两类场景
本例是单 Agent 示例,重点展示 Filter + Callback 的拦截机制:
weather_agent (LlmAgent)
├── model: OpenAIModel (filters_name=["model_filter"])
├── tools:
│ └── get_weather_report(city)
├── before_model_callback: before_model_callback
├── after_model_callback: after_model_callback
└── session: InMemorySessionService (state 注入 user_name / user_city)
关键文件:
- examples/filter_with_model/agent/agent.py:构建
LlmAgent、挂载工具、注册 Filter 与 Callback - examples/filter_with_model/agent/filter.py:
ModelFilter实现与before/after_model_callback定义 - examples/filter_with_model/agent/tools.py:天气查询工具实现
- examples/filter_with_model/agent/prompts.py:提示词模板
- examples/filter_with_model/agent/config.py:环境变量读取
- examples/filter_with_model/run_agent.py:测试入口,执行 2 轮对话
这一节用于快速定位"Filter 注册、Callback 注入、拦截触发"三条核心链路。
- 使用
@register_model_filter("model_filter")装饰器将ModelFilter注册到框架 - 在
run_stream方法中,通过handle()获取上游事件流,在start、每个event、end阶段分别打印日志 - 通过
event.is_continue判断流是否结束,实现对流式生命周期的完整拦截
before_model_callback在每次 LLM 请求发送前触发,接收InvocationContext和LlmRequest,可用于请求审计或修改after_model_callback在每次 LLM 响应返回后触发,接收InvocationContext和LlmResponse,可用于响应审计或过滤- 在
agent.py中通过LlmAgent的before_model_callback/after_model_callback参数完成挂载
- 在
OpenAIModel初始化时通过filters_name=["model_filter"]指定要应用的 Filter 名称 - 框架在运行时自动查找已注册的 Filter 并组装到调用链中
- Python 3.12
git clone https://github.com/trpc-group/trpc-agent-python.git
cd trpc-agent-python
python3 -m venv .venv
source .venv/bin/activate
pip3 install -e .在 examples/filter_with_model/.env 中配置(或通过 export):
TRPC_AGENT_API_KEYTRPC_AGENT_BASE_URLTRPC_AGENT_MODEL_NAME
cd examples/filter_with_model
python3 run_agent.py🆔 Session ID: 5e81eef1...
📝 User: What's the weather like today?
🤖 Assistant:
==== run model filter run_stream start ===
@before_model_callback context: <class 'trpc_agent_sdk.context._invocation_context.InvocationContext'>, llm_request: <class 'trpc_agent_sdk.models._llm_request.LlmRequest'>
@after_model_callback context: <class 'trpc_agent_sdk.context._invocation_context.InvocationContext'>, llm_response: <class 'trpc_agent_sdk.models._llm_response.LlmResponse'>
==== run model filter run_stream event ===
Could you please specify the city for which you'd like to know the weather?
==== run model filter run_stream end ===
----------------------------------------
🆔 Session ID: aa164824...
📝 User: What's the current weather in Beijing?
🤖 Assistant:
==== run model filter run_stream start ===
@before_model_callback context: <class 'trpc_agent_sdk.context._invocation_context.InvocationContext'>, llm_request: <class 'trpc_agent_sdk.models._llm_request.LlmRequest'>
@after_model_callback context: <class 'trpc_agent_sdk.context._invocation_context.InvocationContext'>, llm_response: <class 'trpc_agent_sdk.models._llm_response.LlmResponse'>
==== run model filter run_stream event ===
🔧 [Invoke Tool: get_weather_report({'city': 'Beijing'})]
==== run model filter run_stream end ===
📊 [Tool Result: {'temperature': '25°C', 'condition': 'Sunny', 'humidity': '60%'}]
==== run model filter run_stream start ===
@before_model_callback context: <class 'trpc_agent_sdk.context._invocation_context.InvocationContext'>, llm_request: <class 'trpc_agent_sdk.models._llm_request.LlmRequest'>
@after_model_callback context: <class 'trpc_agent_sdk.context._invocation_context.InvocationContext'>, llm_response: <class 'trpc_agent_sdk.models._llm_response.LlmResponse'>
==== run model filter run_stream event ===
The current weather in Beijing is sunny with a temperature of 25°C and humidity at 60%.
==== run model filter run_stream end ===
----------------------------------------
结论:符合本示例测试要求。
- Filter 生命周期完整:每次 Model 调用均触发
run_stream start → event(s) → end的完整日志链路 - Callback 触发正确:
before_model_callback在请求前触发,after_model_callback在每次流式响应事件后触发 - 工具调用场景验证:第 2 轮触发工具调用后,Model 被二次调用以生成最终回复,Filter 和 Callback 在两次调用中均正确触发
- 纯文本场景验证:第 1 轮未触发工具调用,Filter 和 Callback 在单次 Model 调用中正常工作
说明:该示例每轮使用新的 session_id,主要验证 Filter 与 Callback 的拦截能力,不强调跨轮记忆一致性。
- 验证 Model Filter 的注册与流式拦截能力:适合使用本示例
- 验证 Before/After Model Callback 的触发时机:适合使用本示例
- 需要测试 Agent 级别的 Filter 拦截(而非 Model 级别):建议使用
examples/filter_with_agent