307 lines
8.7 KiB
Markdown
307 lines
8.7 KiB
Markdown
---
|
||
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] - 基础会话协议 |