428 lines
11 KiB
Markdown
428 lines
11 KiB
Markdown
|
|
# SubAgent系统使用指南
|
|||
|
|
|
|||
|
|
## 📚 概述
|
|||
|
|
|
|||
|
|
SubAgent是基于Agno框架构建的智能代理系统,为MedResearcher项目提供强大的AI功能。它支持多种LLM提供商,提供动态prompt构建、JSON结构化输出和零容错解析等核心功能。
|
|||
|
|
|
|||
|
|
## ✨ 核心特性
|
|||
|
|
|
|||
|
|
### 🤖 智能代理核心
|
|||
|
|
- **多提供商支持**: 阿里云(qwen)、DeepSeek、OpenAI等主流LLM服务
|
|||
|
|
- **动态Prompt**: 支持模板变量替换的灵活prompt构建系统
|
|||
|
|
- **结构化输出**: 基于Pydantic模型的JSON格式化响应
|
|||
|
|
- **零容错解析**: 多策略JSON解析,确保即使不完美输出也能解析
|
|||
|
|
|
|||
|
|
### 🔧 配置管理
|
|||
|
|
- **YAML配置**: 统一的配置文件管理,支持环境变量
|
|||
|
|
- **模型工厂**: 自动化的模型实例创建和参数管理
|
|||
|
|
- **灵活配置**: 支持运行时参数覆盖和动态配置
|
|||
|
|
|
|||
|
|
### 🛠 开发便利性
|
|||
|
|
- **类型安全**: 完整的类型提示支持
|
|||
|
|
- **异常处理**: 详细的错误信息和异常层级
|
|||
|
|
- **调试支持**: 内置日志和调试模式
|
|||
|
|
|
|||
|
|
## 🚀 快速开始
|
|||
|
|
|
|||
|
|
### 1. 基础设置
|
|||
|
|
|
|||
|
|
首先确保已安装依赖:
|
|||
|
|
```bash
|
|||
|
|
uv add agno pydantic pyyaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 配置LLM服务
|
|||
|
|
|
|||
|
|
在`src/config/llm_config.yaml`中配置你的LLM服务:
|
|||
|
|
```yaml
|
|||
|
|
aliyun:
|
|||
|
|
base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|||
|
|
api_key: "${DASHSCOPE_API_KEY}"
|
|||
|
|
models:
|
|||
|
|
qwen-max:
|
|||
|
|
class: "OpenAILike"
|
|||
|
|
params:
|
|||
|
|
id: "qwen-max"
|
|||
|
|
temperature: 0.3
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 设置环境变量
|
|||
|
|
|
|||
|
|
创建`.env`文件或设置环境变量:
|
|||
|
|
```bash
|
|||
|
|
export DASHSCOPE_API_KEY="your_api_key_here"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 创建你的第一个Agent
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from src.agent_system import SubAgent
|
|||
|
|
from pydantic import BaseModel, Field
|
|||
|
|
|
|||
|
|
# 定义响应模型
|
|||
|
|
class TaskResult(BaseModel):
|
|||
|
|
summary: str = Field(description="任务总结")
|
|||
|
|
confidence: float = Field(description="置信度", ge=0.0, le=1.0)
|
|||
|
|
|
|||
|
|
# 创建SubAgent
|
|||
|
|
agent = SubAgent(
|
|||
|
|
provider="aliyun",
|
|||
|
|
model_name="qwen-max",
|
|||
|
|
name="task_agent",
|
|||
|
|
instructions=["你是一个专业的任务处理专家"],
|
|||
|
|
prompt_template="请分析以下任务: {task_description}",
|
|||
|
|
response_model=TaskResult
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 执行任务
|
|||
|
|
result = agent.run(template_vars={"task_description": "数据分析项目"})
|
|||
|
|
print(f"总结: {result.summary}")
|
|||
|
|
print(f"置信度: {result.confidence}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📖 详细使用指南
|
|||
|
|
|
|||
|
|
### SubAgent核心类
|
|||
|
|
|
|||
|
|
#### 初始化参数
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
SubAgent(
|
|||
|
|
provider: str, # LLM提供商名称
|
|||
|
|
model_name: str, # 模型名称
|
|||
|
|
instructions: List[str], # 指令列表(可选)
|
|||
|
|
name: str, # Agent名称(可选)
|
|||
|
|
description: str, # Agent描述(可选)
|
|||
|
|
prompt_template: str, # 动态prompt模板(可选)
|
|||
|
|
response_model: BaseModel, # Pydantic响应模型(可选)
|
|||
|
|
config: Dict[str, Any], # 自定义配置(可选)
|
|||
|
|
**agent_kwargs # 传递给Agno Agent的额外参数
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 核心方法
|
|||
|
|
|
|||
|
|
##### 1. build_prompt() - 构建动态Prompt
|
|||
|
|
```python
|
|||
|
|
# 设置带变量的prompt模板
|
|||
|
|
agent.update_prompt_template("""
|
|||
|
|
请分析以下{data_type}数据:
|
|||
|
|
|
|||
|
|
数据内容: {data_content}
|
|||
|
|
分析目标: {analysis_goal}
|
|||
|
|
|
|||
|
|
请提供详细的分析结果。
|
|||
|
|
""")
|
|||
|
|
|
|||
|
|
# 构建具体prompt
|
|||
|
|
prompt = agent.build_prompt({
|
|||
|
|
"data_type": "销售",
|
|||
|
|
"data_content": "Q1销售数据...",
|
|||
|
|
"analysis_goal": "找出增长趋势"
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 2. run() - 执行推理
|
|||
|
|
```python
|
|||
|
|
# 方式1: 使用模板变量
|
|||
|
|
result = agent.run(template_vars={
|
|||
|
|
"input_text": "待分析的文本内容"
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
# 方式2: 直接提供prompt
|
|||
|
|
result = agent.run(prompt="请分析这段文本的情感倾向")
|
|||
|
|
|
|||
|
|
# 方式3: 带额外参数
|
|||
|
|
result = agent.run(
|
|||
|
|
template_vars={"data": "测试数据"},
|
|||
|
|
temperature=0.7,
|
|||
|
|
max_tokens=1000
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 3. get_model_info() - 获取模型信息
|
|||
|
|
```python
|
|||
|
|
info = agent.get_model_info()
|
|||
|
|
print(f"Agent名称: {info['name']}")
|
|||
|
|
print(f"提供商: {info['provider']}")
|
|||
|
|
print(f"模型: {info['model_name']}")
|
|||
|
|
print(f"是否有prompt模板: {info['has_prompt_template']}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Pydantic响应模型
|
|||
|
|
|
|||
|
|
#### 基础模型定义
|
|||
|
|
```python
|
|||
|
|
from pydantic import BaseModel, Field
|
|||
|
|
from typing import List, Optional
|
|||
|
|
|
|||
|
|
class AnalysisResult(BaseModel):
|
|||
|
|
"""分析结果模型"""
|
|||
|
|
|
|||
|
|
summary: str = Field(description="分析总结")
|
|||
|
|
key_points: List[str] = Field(description="关键要点列表")
|
|||
|
|
confidence: float = Field(description="置信度", ge=0.0, le=1.0)
|
|||
|
|
recommendations: Optional[List[str]] = Field(default=None, description="建议列表")
|
|||
|
|
|
|||
|
|
class Config:
|
|||
|
|
json_encoders = {
|
|||
|
|
float: lambda v: round(v, 3) if v is not None else None
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 复杂嵌套模型
|
|||
|
|
```python
|
|||
|
|
class DetailedItem(BaseModel):
|
|||
|
|
name: str = Field(description="项目名称")
|
|||
|
|
value: float = Field(description="数值")
|
|||
|
|
category: str = Field(description="分类")
|
|||
|
|
|
|||
|
|
class ComprehensiveResult(BaseModel):
|
|||
|
|
items: List[DetailedItem] = Field(description="详细项目列表")
|
|||
|
|
total_count: int = Field(description="总数量", ge=0)
|
|||
|
|
summary: str = Field(description="整体总结")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 配置管理详解
|
|||
|
|
|
|||
|
|
#### LLM配置文件结构 (llm_config.yaml)
|
|||
|
|
```yaml
|
|||
|
|
# 阿里云配置
|
|||
|
|
aliyun:
|
|||
|
|
base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|||
|
|
api_key: "${DASHSCOPE_API_KEY}"
|
|||
|
|
models:
|
|||
|
|
qwen-max:
|
|||
|
|
class: "OpenAILike"
|
|||
|
|
params:
|
|||
|
|
id: "qwen-max"
|
|||
|
|
temperature: 0.3
|
|||
|
|
max_tokens: 4000
|
|||
|
|
qwen-plus:
|
|||
|
|
class: "OpenAILike"
|
|||
|
|
params:
|
|||
|
|
id: "qwen-plus"
|
|||
|
|
temperature: 0.5
|
|||
|
|
|
|||
|
|
# DeepSeek配置
|
|||
|
|
deepseek:
|
|||
|
|
base_url: "https://api.deepseek.com/v1"
|
|||
|
|
api_key: "${DEEPSEEK_API_KEY}"
|
|||
|
|
models:
|
|||
|
|
deepseek-v3:
|
|||
|
|
class: "OpenAILike"
|
|||
|
|
params:
|
|||
|
|
id: "deepseek-chat"
|
|||
|
|
temperature: 0.3
|
|||
|
|
|
|||
|
|
# OpenAI配置
|
|||
|
|
openai:
|
|||
|
|
api_key: "${OPENAI_API_KEY}"
|
|||
|
|
models:
|
|||
|
|
gpt-4o:
|
|||
|
|
class: "OpenAIChat"
|
|||
|
|
params:
|
|||
|
|
model: "gpt-4o"
|
|||
|
|
temperature: 0.3
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 环境变量配置 (.env)
|
|||
|
|
```bash
|
|||
|
|
# 阿里云API密钥
|
|||
|
|
DASHSCOPE_API_KEY=sk-your-dashscope-key
|
|||
|
|
|
|||
|
|
# DeepSeek API密钥
|
|||
|
|
DEEPSEEK_API_KEY=sk-your-deepseek-key
|
|||
|
|
|
|||
|
|
# OpenAI API密钥
|
|||
|
|
OPENAI_API_KEY=sk-your-openai-key
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 便捷函数使用
|
|||
|
|
|
|||
|
|
#### create_json_agent() - 快速创建JSON Agent
|
|||
|
|
```python
|
|||
|
|
from src.agent_system import create_json_agent
|
|||
|
|
|
|||
|
|
# 快速创建支持JSON输出的Agent
|
|||
|
|
agent = create_json_agent(
|
|||
|
|
provider="aliyun",
|
|||
|
|
model_name="qwen-max",
|
|||
|
|
name="json_extractor",
|
|||
|
|
prompt_template="从以下文本提取信息: {text}",
|
|||
|
|
response_model="MyModel", # 可以是字符串或类
|
|||
|
|
instructions=["你是信息提取专家"]
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🎯 实际应用示例
|
|||
|
|
|
|||
|
|
### 示例1: 情感分析Agent
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from pydantic import BaseModel, Field
|
|||
|
|
from typing import Literal
|
|||
|
|
from src.agent_system import SubAgent
|
|||
|
|
|
|||
|
|
class SentimentResult(BaseModel):
|
|||
|
|
sentiment: Literal["positive", "negative", "neutral"] = Field(description="情感倾向")
|
|||
|
|
confidence: float = Field(description="置信度", ge=0.0, le=1.0)
|
|||
|
|
explanation: str = Field(description="分析说明")
|
|||
|
|
|
|||
|
|
sentiment_agent = SubAgent(
|
|||
|
|
provider="aliyun",
|
|||
|
|
model_name="qwen-max",
|
|||
|
|
name="sentiment_analyzer",
|
|||
|
|
instructions=[
|
|||
|
|
"你是专业的文本情感分析专家",
|
|||
|
|
"请准确识别文本的情感倾向",
|
|||
|
|
"提供详细的分析依据"
|
|||
|
|
],
|
|||
|
|
prompt_template="""
|
|||
|
|
请分析以下文本的情感倾向:
|
|||
|
|
|
|||
|
|
文本内容: {text}
|
|||
|
|
|
|||
|
|
请识别情感倾向(positive/negative/neutral)、置信度(0-1)和分析说明。
|
|||
|
|
""",
|
|||
|
|
response_model=SentimentResult
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 使用示例
|
|||
|
|
result = sentiment_agent.run(template_vars={
|
|||
|
|
"text": "这个产品质量很好,我非常满意!"
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
print(f"情感: {result.sentiment}")
|
|||
|
|
print(f"置信度: {result.confidence}")
|
|||
|
|
print(f"说明: {result.explanation}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 示例2: 数据提取Agent
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
class DataExtraction(BaseModel):
|
|||
|
|
extracted_data: Dict[str, Any] = Field(description="提取的数据")
|
|||
|
|
extraction_count: int = Field(description="提取项目数量")
|
|||
|
|
data_quality: Literal["high", "medium", "low"] = Field(description="数据质量评估")
|
|||
|
|
|
|||
|
|
extractor_agent = SubAgent(
|
|||
|
|
provider="aliyun",
|
|||
|
|
model_name="qwen-plus",
|
|||
|
|
name="data_extractor",
|
|||
|
|
instructions=[
|
|||
|
|
"你是数据提取专家",
|
|||
|
|
"从非结构化文本中提取结构化数据",
|
|||
|
|
"确保提取的数据准确完整"
|
|||
|
|
],
|
|||
|
|
prompt_template="""
|
|||
|
|
从以下{data_type}文档中提取关键数据:
|
|||
|
|
|
|||
|
|
文档内容:
|
|||
|
|
{document}
|
|||
|
|
|
|||
|
|
提取要求:
|
|||
|
|
{requirements}
|
|||
|
|
|
|||
|
|
请提取所有相关数据并评估数据质量。
|
|||
|
|
""",
|
|||
|
|
response_model=DataExtraction
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## ⚠️ 注意事项与最佳实践
|
|||
|
|
|
|||
|
|
### 1. 配置管理
|
|||
|
|
- **API密钥安全**: 始终使用环境变量存储API密钥,切勿在代码中硬编码
|
|||
|
|
- **配置验证**: 程序启动时验证配置文件完整性
|
|||
|
|
- **环境隔离**: 开发、测试、生产环境使用不同的配置文件
|
|||
|
|
|
|||
|
|
### 2. Prompt设计
|
|||
|
|
- **明确指令**: 提供清晰、具体的任务指令
|
|||
|
|
- **示例驱动**: 在prompt中包含输入输出示例
|
|||
|
|
- **结构化模板**: 使用结构化的prompt模板提高一致性
|
|||
|
|
|
|||
|
|
### 3. 错误处理
|
|||
|
|
- **异常捕获**: 对Agent调用进行适当的异常处理
|
|||
|
|
- **重试机制**: 对网络错误实现重试逻辑
|
|||
|
|
- **降级策略**: 准备备用模型或简化输出格式
|
|||
|
|
|
|||
|
|
### 4. 性能优化
|
|||
|
|
- **缓存机制**: 对相同输入实现结果缓存
|
|||
|
|
- **批处理**: 将多个小任务合并为大任务处理
|
|||
|
|
- **模型选择**: 根据任务复杂度选择合适的模型
|
|||
|
|
|
|||
|
|
## 🔧 故障排除
|
|||
|
|
|
|||
|
|
### 常见问题
|
|||
|
|
|
|||
|
|
#### 1. 配置文件不存在
|
|||
|
|
```
|
|||
|
|
错误: FileNotFoundError: LLM配置文件不存在
|
|||
|
|
解决: 确保 src/config/llm_config.yaml 文件存在且格式正确
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. API密钥未设置
|
|||
|
|
```
|
|||
|
|
错误: 环境变量 DASHSCOPE_API_KEY 未定义
|
|||
|
|
解决: 设置相应的环境变量或在.env文件中配置
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. JSON解析失败
|
|||
|
|
```
|
|||
|
|
错误: JSONParseError: 所有解析策略都失败了
|
|||
|
|
解决: 检查prompt设计,确保要求明确的JSON格式输出
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. 模型验证失败
|
|||
|
|
```
|
|||
|
|
错误: Pydantic模型验证失败
|
|||
|
|
解决: 检查响应模型定义与实际输出是否匹配
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 调试技巧
|
|||
|
|
|
|||
|
|
#### 启用调试模式
|
|||
|
|
```python
|
|||
|
|
agent = SubAgent(
|
|||
|
|
provider="aliyun",
|
|||
|
|
model_name="qwen-max",
|
|||
|
|
debug_mode=True, # 启用调试输出
|
|||
|
|
# ... 其他参数
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 查看生成的Prompt
|
|||
|
|
```python
|
|||
|
|
# 构建并查看最终的prompt
|
|||
|
|
prompt = agent.build_prompt({"key": "value"})
|
|||
|
|
print(f"生成的prompt: {prompt}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 捕获详细错误信息
|
|||
|
|
```python
|
|||
|
|
try:
|
|||
|
|
result = agent.run(template_vars={"text": "测试"})
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"错误类型: {type(e)}")
|
|||
|
|
print(f"错误信息: {e}")
|
|||
|
|
import traceback
|
|||
|
|
traceback.print_exc()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🚦 版本信息
|
|||
|
|
|
|||
|
|
- **当前版本**: 0.1.0
|
|||
|
|
- **依赖要求**:
|
|||
|
|
- Python >= 3.8
|
|||
|
|
- agno >= 0.1.0
|
|||
|
|
- pydantic >= 2.0.0
|
|||
|
|
- pyyaml >= 6.0.0
|
|||
|
|
|
|||
|
|
## 📞 支持与反馈
|
|||
|
|
|
|||
|
|
如遇到问题或有功能建议,请联系开发团队或提交issue。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*MedResearcher SubAgent系统 - 让AI更智能,让开发更简单* 🎉
|