Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions examples/llmagent_with_model_retry/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copy this file or edit it in place before running the example.
# The example uses an OpenAI-compatible endpoint.

TRPC_AGENT_API_KEY=
TRPC_AGENT_BASE_URL=
TRPC_AGENT_MODEL_NAME=

# Optional model retry tuning.
# num_retries is the number of retry attempts in addition to the initial call.
TRPC_AGENT_MODEL_RETRY_NUM_RETRIES=2
TRPC_AGENT_MODEL_RETRY_INITIAL_BACKOFF=1.0
TRPC_AGENT_MODEL_RETRY_MAX_BACKOFF=8.0
TRPC_AGENT_MODEL_RETRY_BACKOFF_MULTIPLIER=2.0
TRPC_AGENT_MODEL_RETRY_JITTER=true
TRPC_AGENT_MODEL_RETRY_RESPECT_RETRY_AFTER=true
156 changes: 156 additions & 0 deletions examples/llmagent_with_model_retry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# LLM Agent 模型重试示例

本示例演示如何在模型构造时传入 `ModelRetryConfig`,让业务代码不用自己实现重试逻辑;当 LLM 请求遇到限流、超时、网络波动等瞬时错误时,SDK 会自动重试。

## 关键特性

- **按需开启重试**:只有显式传入 `ModelRetryConfig` 的模型才会启用 SDK 托管重试。
- **一套配置,多种模型可用**:同一个 `ModelRetryConfig` 可以传给 OpenAI、Anthropic 等模型实现,统一控制重试行为。
- **只重试临时问题**:限流、超时、服务端内部错误、连接异常会在次数限制内重试。
- **避免重复输出内容**:流式输出已经产生内容后如果再失败,错误会直接透出,不会重试并重复输出内容。
- **优先使用服务端等待时间**:默认会读取 `Retry-After` / `retry-after-ms`,有服务端等待时间时优先使用。

## Agent 层级结构说明

本例是单 Agent 示例,重试配置绑定在模型上:

```text
weather_retry_agent (LlmAgent)
├── model: OpenAIModel(..., model_retry_config=ModelRetryConfig(...))
├── tool: get_weather_report(city)
└── runner: 无自定义重试逻辑
```

关键文件:

- [examples/llmagent_with_model_retry/agent/agent.py](./agent/agent.py):创建模型并注入 `ModelRetryConfig`
- [examples/llmagent_with_model_retry/agent/config.py](./agent/config.py):读取模型连接与重试环境变量
- [examples/llmagent_with_model_retry/agent/tools.py](./agent/tools.py):天气工具实现
- [examples/llmagent_with_model_retry/agent/prompts.py](./agent/prompts.py):提示词
- [examples/llmagent_with_model_retry/run_agent.py](./run_agent.py):运行入口,展示业务层无需手写重试

## 关键代码解释

### 1) 创建重试配置

`agent/config.py` 从环境变量构造:

```python
from trpc_agent_sdk.configs import ExponentialBackoffConfig
from trpc_agent_sdk.configs import ModelRetryConfig

ModelRetryConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个配置加一下解释说明

num_retries=2,
backoff=ExponentialBackoffConfig(
initial_backoff=1.0,
max_backoff=8.0,
multiplier=2.0,
jitter=True,
respect_retry_after=True,
),
)
```

### 2) 注入模型

`agent/agent.py` 将配置传给模型构造器:

```python
OpenAIModel(
model_name=model_name,
api_key=api_key,
base_url=base_url,
model_retry_config=retry_config,
)
```

### 3) Runner 不需要重试逻辑

`run_agent.py` 仍然只调用:

```python
async for event in runner.run_async(...):
...
```

如果模型调用在产出内容前遇到可重试错误,SDK 会按 `ModelRetryConfig` 自动重试。

## 会重试和不会重试的场景

### 会重试

- `429` 限流
- `408` / `409` 超时或模型服务锁等待超时
- `5xx` 服务端内部错误
- 超时异常
- 连接或传输异常

### 不会重试

- `400` 错误请求
- `401` / `403` 认证或权限错误
- 未识别错误类别
- 重试次数已耗尽
- 流式输出已经产生内容后才发生的错误

## 环境与运行

### 环境要求

- Python 3.10+

### 安装步骤

```bash
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/llmagent_with_model_retry/.env](./.env) 中配置(或通过 `export` 设置):

```bash
# 必填:模型连接配置
TRPC_AGENT_API_KEY=<your-api-key>
TRPC_AGENT_BASE_URL=<openai-compatible-base-url>
TRPC_AGENT_MODEL_NAME=<model-name>

# 可选:模型重试配置;不设置时使用示例默认值
TRPC_AGENT_MODEL_RETRY_NUM_RETRIES=2
TRPC_AGENT_MODEL_RETRY_INITIAL_BACKOFF=1.0
TRPC_AGENT_MODEL_RETRY_MAX_BACKOFF=8.0
TRPC_AGENT_MODEL_RETRY_BACKOFF_MULTIPLIER=2.0
TRPC_AGENT_MODEL_RETRY_JITTER=true
TRPC_AGENT_MODEL_RETRY_RESPECT_RETRY_AFTER=true
```

### 运行命令

```bash
cd examples/llmagent_with_model_retry
python3 run_agent.py
```

## 运行结果示例

```text
Model retry enabled: {'num_retries': 2, 'rules': {'retryable_error_codes': ['408', '409', '429', '500', '502', '503', '504'], 'non_retryable_error_codes': ['400', '401', '403'], 'retryable_exception_class_name_parts': ['Timeout', 'Connection', 'Transport']}, 'backoff': {'type': 'exponential', 'initial_backoff': 1.0, 'max_backoff': 8.0, 'multiplier': 2.0, 'jitter': True, 'respect_retry_after': True}}
Session ID: fdb9e370...
SDK-managed retry is configured on the model; no retry loop is needed in this runner.
User: What's the current weather in Beijing?
Assistant:
Invoke Tool: get_weather_report({'city': 'Beijing'})
Tool Result: {'temperature': '25°C', 'condition': 'Sunny', 'humidity': '60%'}

# 当模型服务返回可重试错误时,SDK 会在模型层自动重试:
[WARNING] Model call failed (category=rate_limit); retrying in 0.46s (attempt 1/2).
```

## 适用场景建议

- 在模型服务限流,或其他瞬时错误时自动重试
- 需要结合服务端 `Retry-After` 控制退避等待时间。
Empty file.
43 changes: 43 additions & 0 deletions examples/llmagent_with_model_retry/agent/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
#
# Copyright (C) 2026 Tencent. All rights reserved.
#
# tRPC-Agent-Python is licensed under Apache-2.0.
"""Agent module for the model retry example."""

from trpc_agent_sdk.agents import LlmAgent
from trpc_agent_sdk.models import LLMModel
from trpc_agent_sdk.models import OpenAIModel
from trpc_agent_sdk.tools import FunctionTool

from .config import get_model_config
from .config import get_model_retry_config
from .prompts import INSTRUCTION
from .tools import get_weather_report


def _create_model() -> LLMModel:
"""Create an OpenAI-compatible model with SDK-managed retry enabled."""
api_key, base_url, model_name = get_model_config()
retry_config = get_model_retry_config()
print(f"Model retry enabled: {retry_config.model_dump()}")
return OpenAIModel(
model_name=model_name,
api_key=api_key,
base_url=base_url,
model_retry_config=retry_config,
)


def create_agent() -> LlmAgent:
"""Create a weather agent that uses model-level retry."""
return LlmAgent(
name="weather_retry_agent",
description="A weather assistant with SDK-managed model retry enabled.",
model=_create_model(),
instruction=INSTRUCTION,
tools=[FunctionTool(get_weather_report)],
)


root_agent = create_agent()
57 changes: 57 additions & 0 deletions examples/llmagent_with_model_retry/agent/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
#
# Copyright (C) 2026 Tencent. All rights reserved.
#
# tRPC-Agent-Python is licensed under Apache-2.0.
"""Configuration helpers for the model retry example."""

import os

from trpc_agent_sdk.configs import ExponentialBackoffConfig
from trpc_agent_sdk.configs import ModelRetryConfig


def _get_bool(name: str, default: bool) -> bool:
value = os.getenv(name)
if value is None or value == "":
return default
return value.strip().lower() in {"1", "true", "yes", "y", "on"}


def _get_float(name: str, default: float) -> float:
value = os.getenv(name)
if value is None or value == "":
return default
return float(value)


def _get_int(name: str, default: int) -> int:
value = os.getenv(name)
if value is None or value == "":
return default
return int(value)


def get_model_config() -> tuple[str, str, str]:
"""Get model connection settings from environment variables."""
api_key = os.getenv("TRPC_AGENT_API_KEY", "")
base_url = os.getenv("TRPC_AGENT_BASE_URL", "")
model_name = os.getenv("TRPC_AGENT_MODEL_NAME", "")
if not api_key or not base_url or not model_name:
raise ValueError("TRPC_AGENT_API_KEY, TRPC_AGENT_BASE_URL, and "
"TRPC_AGENT_MODEL_NAME must be set in environment variables")
return api_key, base_url, model_name


def get_model_retry_config() -> ModelRetryConfig:
"""Build the opt-in SDK-managed model retry configuration."""
return ModelRetryConfig(
num_retries=_get_int("TRPC_AGENT_MODEL_RETRY_NUM_RETRIES", 2),
backoff=ExponentialBackoffConfig(
initial_backoff=_get_float("TRPC_AGENT_MODEL_RETRY_INITIAL_BACKOFF", 1.0),
max_backoff=_get_float("TRPC_AGENT_MODEL_RETRY_MAX_BACKOFF", 8.0),
multiplier=_get_float("TRPC_AGENT_MODEL_RETRY_BACKOFF_MULTIPLIER", 2.0),
jitter=_get_bool("TRPC_AGENT_MODEL_RETRY_JITTER", True),
respect_retry_after=_get_bool("TRPC_AGENT_MODEL_RETRY_RESPECT_RETRY_AFTER", True),
),
)
13 changes: 13 additions & 0 deletions examples/llmagent_with_model_retry/agent/prompts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
#
# Copyright (C) 2026 Tencent. All rights reserved.
#
# tRPC-Agent-Python is licensed under Apache-2.0.
"""Prompts for the model retry example agent."""

INSTRUCTION = """You are a practical weather assistant.
When the user asks for weather, identify the city and call get_weather_report.
If the city is missing, ask one short clarification question.
After receiving tool results, summarize the weather clearly and mention the retry configuration only if the user asks about reliability.
"""
40 changes: 40 additions & 0 deletions examples/llmagent_with_model_retry/agent/tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
#
# Copyright (C) 2026 Tencent. All rights reserved.
#
# tRPC-Agent-Python is licensed under Apache-2.0.
"""Tools for the model retry example agent."""


def get_weather_report(city: str) -> dict:
"""Get weather information for the specified city."""
weather_data = {
"Beijing": {
"temperature": "25°C",
"condition": "Sunny",
"humidity": "60%",
},
"Shanghai": {
"temperature": "28°C",
"condition": "Cloudy",
"humidity": "70%",
},
"Guangzhou": {
"temperature": "32°C",
"condition": "Thunderstorm",
"humidity": "85%",
},
"Shenzhen": {
"temperature": "30°C",
"condition": "Light rain",
"humidity": "78%",
},
}
return weather_data.get(
city,
{
"temperature": "Unknown",
"condition": "Data not available",
"humidity": "Unknown",
},
)
Loading
Loading