Files
2026-07-13 12:39:17 +08:00

307 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
search:
exclude: true
---
# 高级 SQLite 会话
`AdvancedSQLiteSession` 是基础 `SQLiteSession` 的增强版本,提供高级对话管理能力,包括对话分支、详细的使用情况分析以及结构化对话查询。
## 功能
- **对话分支**:从任意用户消息创建替代对话路径
- **使用情况追踪**:按轮次提供详细的 token 使用情况分析,并包含完整的 JSON 明细
- **结构化查询**:按轮次获取对话、工具使用统计等
- **分支管理**:独立的分支切换与管理
- **消息结构元数据**:跟踪消息类型、工具使用情况和对话流程
## 快速开始
```python
from agents import Agent, Runner
from agents.extensions.memory import AdvancedSQLiteSession
# Create agent
agent = Agent(
name="Assistant",
instructions="Reply very concisely.",
)
# Create an advanced session
session = AdvancedSQLiteSession(
session_id="conversation_123",
db_path="conversations.db",
create_tables=True
)
# First conversation turn
result = await Runner.run(
agent,
"What city is the Golden Gate Bridge in?",
session=session
)
print(result.final_output) # "San Francisco"
# IMPORTANT: Store usage data
await session.store_run_usage(result)
# Continue conversation
result = await Runner.run(
agent,
"What state is it in?",
session=session
)
print(result.final_output) # "California"
await session.store_run_usage(result)
```
## 初始化
```python
from agents.extensions.memory import AdvancedSQLiteSession
# Basic initialization
session = AdvancedSQLiteSession(
session_id="my_conversation",
create_tables=True # Auto-create advanced tables
)
# With persistent storage
session = AdvancedSQLiteSession(
session_id="user_123",
db_path="path/to/conversations.db",
create_tables=True
)
# With custom logger
import logging
logger = logging.getLogger("my_app")
session = AdvancedSQLiteSession(
session_id="session_456",
create_tables=True,
logger=logger
)
```
### 参数
- `session_id` (str):对话会话的唯一标识符
- `db_path` (str | Path)SQLite 数据库文件路径。默认为 `:memory:`,用于内存存储
- `create_tables` (bool):是否自动创建高级表。默认为 `False`
- `logger` (logging.Logger | None):用于会话的自定义日志记录器。默认为模块日志记录器
## 使用情况追踪
AdvancedSQLiteSession 通过按对话轮次存储 token 使用情况数据,提供详细的使用情况分析。**这完全依赖于在每次智能体运行后调用 `store_run_usage` 方法。**
### 使用情况数据存储
```python
# After each agent run, store the usage data
result = await Runner.run(agent, "Hello", session=session)
await session.store_run_usage(result)
# This stores:
# - Total tokens used
# - Input/output token breakdown
# - Request count
# - Detailed JSON token information (if available)
```
### 使用情况统计检索
```python
# Get session-level usage (all branches)
session_usage = await session.get_session_usage()
if session_usage:
print(f"Total requests: {session_usage['requests']}")
print(f"Total tokens: {session_usage['total_tokens']}")
print(f"Input tokens: {session_usage['input_tokens']}")
print(f"Output tokens: {session_usage['output_tokens']}")
print(f"Total turns: {session_usage['total_turns']}")
# Get usage for specific branch
branch_usage = await session.get_session_usage(branch_id="main")
# Get usage by turn
turn_usage = await session.get_turn_usage()
for turn_data in turn_usage:
print(f"Turn {turn_data['user_turn_number']}: {turn_data['total_tokens']} tokens")
if turn_data['input_tokens_details']:
print(f" Input details: {turn_data['input_tokens_details']}")
if turn_data['output_tokens_details']:
print(f" Output details: {turn_data['output_tokens_details']}")
# Get usage for specific turn
turn_2_usage = await session.get_turn_usage(user_turn_number=2)
```
## 对话分支
AdvancedSQLiteSession 的关键功能之一是能够从任意用户消息创建对话分支,从而让你探索替代的对话路径。
### 分支创建
```python
# Get available turns for branching
turns = await session.get_conversation_turns()
for turn in turns:
print(f"Turn {turn['turn']}: {turn['content']}")
print(f"Can branch: {turn['can_branch']}")
# Create a branch from turn 2
branch_id = await session.create_branch_from_turn(2)
print(f"Created branch: {branch_id}")
# Create a branch with custom name
branch_id = await session.create_branch_from_turn(
2,
branch_name="alternative_path"
)
# Create branch by searching for content
branch_id = await session.create_branch_from_content(
"weather",
branch_name="weather_focus"
)
```
### 分支管理
```python
# List all branches
branches = await session.list_branches()
for branch in branches:
current = " (current)" if branch["is_current"] else ""
print(f"{branch['branch_id']}: {branch['user_turns']} turns, {branch['message_count']} messages{current}")
# Switch between branches
await session.switch_to_branch("main")
await session.switch_to_branch(branch_id)
# Delete a branch
await session.delete_branch(branch_id, force=True) # force=True allows deleting current branch
```
### 分支工作流示例
```python
# Original conversation
result = await Runner.run(agent, "What's the capital of France?", session=session)
await session.store_run_usage(result)
result = await Runner.run(agent, "What's the weather like there?", session=session)
await session.store_run_usage(result)
# Create branch from turn 2 (weather question)
branch_id = await session.create_branch_from_turn(2, "weather_focus")
# Continue in new branch with different question
result = await Runner.run(
agent,
"What are the main tourist attractions in Paris?",
session=session
)
await session.store_run_usage(result)
# Switch back to main branch
await session.switch_to_branch("main")
# Continue original conversation
result = await Runner.run(
agent,
"How expensive is it to visit?",
session=session
)
await session.store_run_usage(result)
```
## 结构化查询
AdvancedSQLiteSession 提供了多种方法,用于分析对话结构和内容。
### 对话分析
```python
# Get conversation organized by turns
conversation_by_turns = await session.get_conversation_by_turns()
for turn_num, items in conversation_by_turns.items():
print(f"Turn {turn_num}: {len(items)} items")
for item in items:
if item["tool_name"]:
print(f" - {item['type']} (tool: {item['tool_name']})")
else:
print(f" - {item['type']}")
# Get tool usage statistics
tool_usage = await session.get_tool_usage()
for tool_name, count, turn in tool_usage:
print(f"{tool_name}: used {count} times in turn {turn}")
# Find turns by content
matching_turns = await session.find_turns_by_content("weather")
for turn in matching_turns:
print(f"Turn {turn['turn']}: {turn['content']}")
```
### 消息结构
会话会自动跟踪消息结构,包括:
- 消息类型(用户、assistant、tool_call 等)
- 工具调用的工具名称
- 轮次编号和序列号
- 分支关联
- 时间戳
## 数据库架构
AdvancedSQLiteSession 在基础 SQLite 架构之上扩展了两个额外的表:
### message_structure 表
```sql
CREATE TABLE message_structure (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
message_id INTEGER NOT NULL,
branch_id TEXT NOT NULL DEFAULT 'main',
message_type TEXT NOT NULL,
sequence_number INTEGER NOT NULL,
user_turn_number INTEGER,
branch_turn_number INTEGER,
tool_name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE,
FOREIGN KEY (message_id) REFERENCES agent_messages(id) ON DELETE CASCADE
);
```
### turn_usage 表
```sql
CREATE TABLE turn_usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
branch_id TEXT NOT NULL DEFAULT 'main',
user_turn_number INTEGER NOT NULL,
requests INTEGER DEFAULT 0,
input_tokens INTEGER DEFAULT 0,
output_tokens INTEGER DEFAULT 0,
total_tokens INTEGER DEFAULT 0,
input_tokens_details JSON,
output_tokens_details JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE,
UNIQUE(session_id, branch_id, user_turn_number)
);
```
## 完整示例
查看[完整示例](https://github.com/openai/openai-agents-python/tree/main/examples/memory/advanced_sqlite_session_example.py),全面了解所有功能。
## API 参考
- [`AdvancedSQLiteSession`][agents.extensions.memory.advanced_sqlite_session.AdvancedSQLiteSession] - 主类
- [`Session`][agents.memory.session.Session] - 基础会话协议