refc:重构插件api,补全文档,合并expressor和replyer,分离reply和sender,新log浏览器

This commit is contained in:
SengokuCola
2025-06-19 20:20:34 +08:00
parent 7e05ede846
commit ab28b94e33
63 changed files with 5285 additions and 8316 deletions

View File

@@ -23,27 +23,28 @@ Action采用**两层决策机制**来优化性能和决策质量:
#### 激活类型说明
| 激活类型 | 说明 | 使用场景 |
|---------|-----|---------|
| `NEVER` | 从不激活Action对麦麦不可见 | 临时禁用某个Action |
| `ALWAYS` | 永远激活Action总是在麦麦的候选池中 | 核心功能,如回复、表情 |
| `LLM_JUDGE` | 通过LLM智能判断当前情境是否需要激活此Action | 需要智能判断的复杂场景 |
| `RANDOM` | 基于随机概率决定是否激活 | 增加行为随机性的功能 |
| `KEYWORD` | 当检测到特定关键词时激活 | 明确触发条件的功能 |
| 激活类型 | 说明 | 使用场景 |
| ------------- | ------------------------------------------- | ------------------------ |
| `NEVER` | 从不激活Action对麦麦不可见 | 临时禁用某个Action |
| `ALWAYS` | 永远激活Action总是在麦麦的候选池中 | 核心功能,如回复、不回复 |
| `LLM_JUDGE` | 通过LLM智能判断当前情境是否需要激活此Action | 需要智能判断的复杂场景 |
| `RANDOM` | 基于随机概率决定是否激活 | 增加行为随机性的功能 |
| `KEYWORD` | 当检测到特定关键词时激活 | 明确触发条件的功能 |
#### 聊天模式控制
| 模式 | 说明 |
|-----|-----|
| `ChatMode.FOCUS` | 仅在专注聊天模式下可激活 |
| 模式 | 说明 |
| ------------------- | ------------------------ |
| `ChatMode.FOCUS` | 仅在专注聊天模式下可激活 |
| `ChatMode.NORMAL` | 仅在普通聊天模式下可激活 |
| `ChatMode.ALL` | 所有模式下都可激活 |
| `ChatMode.ALL` | 所有模式下都可激活 |
### 第二层使用决策Usage Decision
**在Action被激活后使用条件决定麦麦什么时候会"选择"使用这个Action**
这一层由以下因素综合决定:
- `action_require`使用场景描述帮助LLM判断何时选择
- `action_parameters`所需参数影响Action的可执行性
- 当前聊天上下文和麦麦的决策逻辑
@@ -58,7 +59,7 @@ class EmojiAction(BaseAction):
focus_activation_type = ActionActivationType.RANDOM # 专注模式下随机激活
normal_activation_type = ActionActivationType.KEYWORD # 普通模式下关键词激活
activation_keywords = ["表情", "emoji", "😊"]
# 第二层:使用决策
action_require = [
"表达情绪时可以选择使用",
@@ -68,12 +69,14 @@ class EmojiAction(BaseAction):
```
**决策流程**
1. **第一层激活判断**
- 普通模式:只有当用户消息包含"表情"、"emoji"或"😊"时,麦麦才"知道"可以使用这个Action
- 专注模式:随机激活,有概率让麦麦"看到"这个Action
2. **第二层使用决策**
- 即使Action被激活麦麦还会根据`action_require`中的条件判断是否真正选择使用
- 即使Action被激活麦麦还会根据 `action_require`中的条件判断是否真正选择使用
- 例如:如果刚刚已经发过表情,根据"不要连续发送多个表情"的要求麦麦可能不会选择这个Action
## 📋 Action必须项清单
@@ -125,38 +128,147 @@ action_require = [
associated_types = ["text", "emoji", "image"]
```
### 4. 动作记录必须项
### 4. 新API导入必须项
每个 Action 在执行完成后,**必须**使用 `store_action_info` 记录动作信息。这是非常重要的,因为
1. **记忆连续性**:让麦麦记住自己执行过的动作,避免重复执行
2. **上下文理解**:帮助麦麦理解自己的行为历史,做出更合理的决策
3. **行为追踪**:便于后续查询和分析麦麦的行为模式
使用新插件系统时必须导入所需的API模块
```python
async def execute(self) -> Tuple[bool, Optional[str]]:
# 导入新API模块
from src.plugin_system.apis import generator_api, send_api, emoji_api
# 如果需要使用其他API
from src.plugin_system.apis import llm_api, database_api, message_api
```
### 5. 动作记录必须项
每个 Action 在执行完成后,**必须**使用 `store_action_info` 记录动作信息:
```python
async def execute(self) -> Tuple[bool, str]:
# ... 执行动作的代码 ...
if success:
# 存储动作信息
await self.api.store_action_info(
# 存储动作信息 - 使用新API格式
await self.store_action_info(
action_build_into_prompt=True, # 让麦麦知道这个动作
action_prompt_display=f"执行了xxx动作参数{param}", # 动作描述
action_done=True, # 动作是否完成
thinking_id=self.thinking_id, # 关联的思考ID
action_data={ # 动作的详细数据
"param1": value1,
"param2": value2
}
)
return True, "动作执行成功"
```
> ⚠️ **重要提示**如果不记录动作信息,可能会导致以下问题:
> - 麦麦不知道自己执行过什么动作,可能会重复执行
> - 无法追踪动作历史,影响后续决策
> - 在长对话中失去上下文连续性
> - 无法进行行为分析和优化
> ⚠️ **重要提示**新API格式中不再需要手动传递 `thinking_id` 等参数BaseAction会自动处理。
## 🚀 新API使用指南
### 📨 消息发送API
新的消息发送API更加简洁自动处理群聊/私聊逻辑:
```python
class MessageAction(BaseAction):
async def execute(self) -> Tuple[bool, str]:
# 发送文本消息 - 自动判断群聊/私聊
await self.send_text("Hello World!")
# 发送表情包
emoji_base64 = await emoji_api.get_by_description("开心")
if emoji_base64:
await self.send_emoji(emoji_base64)
# 发送图片
await self.send_image(image_base64)
# 发送自定义类型消息
await self.send_custom("video", video_data, typing=True)
return True, "消息发送完成"
```
### 🤖 智能生成API (replyer_1)
使用replyer_1生成个性化内容
```python
class SmartReplyAction(BaseAction):
async def execute(self) -> Tuple[bool, str]:
# 构建生成参数
reply_data = {
"text": "请生成一个友好的回复",
"style": "casual",
"topic": "日常聊天",
"replyer_name": "replyer_1" # 指定使用replyer_1
}
# 使用generator_api生成回复
success, reply_set = await generator_api.generate_reply(
chat_stream=self.chat_stream,
action_data=reply_data,
platform=self.platform,
chat_id=self.chat_id,
is_group=self.is_group
)
if success and reply_set:
# 提取并发送文本回复
for reply_type, reply_content in reply_set:
if reply_type == "text":
await self.send_text(reply_content)
elif reply_type == "emoji":
await self.send_emoji(reply_content)
# 记录动作
await self.store_action_info(
action_build_into_prompt=True,
action_prompt_display=f"使用replyer_1生成了智能回复",
action_done=True
)
return True, "智能回复生成成功"
else:
return False, "回复生成失败"
```
### ⚙️ 配置访问API
使用便捷的配置访问方法:
```python
class ConfigurableAction(BaseAction):
async def execute(self) -> Tuple[bool, str]:
# 获取插件配置 - 支持嵌套键访问
enable_feature = self.get_config("features.enable_smart_mode", False)
max_length = self.get_config("limits.max_text_length", 200)
style = self.get_config("behavior.response_style", "friendly")
if enable_feature:
# 启用高级功能
pass
return True, "配置获取成功"
```
### 📊 数据库API
使用新的数据库API存储和查询数据
```python
class DataAction(BaseAction):
async def execute(self) -> Tuple[bool, str]:
# 使用database_api
from src.plugin_system.apis import database_api
# 存储数据
await database_api.store_action_info(
chat_stream=self.chat_stream,
action_name=self.action_name,
action_data=self.action_data,
# ... 其他参数
)
return True, "数据存储完成"
```
## 🔧 激活类型详解
@@ -168,10 +280,34 @@ async def execute(self) -> Tuple[bool, Optional[str]]:
class GreetingAction(BaseAction):
focus_activation_type = ActionActivationType.KEYWORD
normal_activation_type = ActionActivationType.KEYWORD
# 关键词配置
activation_keywords = ["你好", "hello", "hi", "嗨"]
keyword_case_sensitive = False # 不区分大小写
async def execute(self) -> Tuple[bool, str]:
# 可选使用replyer_1生成个性化问候
if self.get_config("greeting.use_smart_reply", False):
greeting_data = {
"text": "生成一个友好的问候语",
"replyer_name": "replyer_1"
}
success, reply_set = await generator_api.generate_reply(
chat_stream=self.chat_stream,
action_data=greeting_data
)
if success:
for reply_type, content in reply_set:
if reply_type == "text":
await self.send_text(content)
break
return True, "发送智能问候"
# 传统问候方式
await self.send_text("你好!很高兴见到你!")
return True, "发送问候"
```
### LLM_JUDGE激活
@@ -182,16 +318,38 @@ class GreetingAction(BaseAction):
class HelpAction(BaseAction):
focus_activation_type = ActionActivationType.LLM_JUDGE
normal_activation_type = ActionActivationType.LLM_JUDGE
# LLM判断提示词
llm_judge_prompt = """
判定是否需要使用帮助动作的条件:
1. 用户表达了困惑或需要帮助
2. 用户提出了问题但没有得到满意答案
3. 对话中出现了技术术语或复杂概念
请回答"是"或"否"。
"""
async def execute(self) -> Tuple[bool, str]:
# 使用replyer_1生成帮助内容
help_data = {
"text": "用户需要帮助,请提供适当的帮助信息",
"help_type": self.action_data.get("help_type", "general"),
"replyer_name": "replyer_1"
}
success, reply_set = await generator_api.generate_reply(
chat_stream=self.chat_stream,
action_data=help_data
)
if success:
for reply_type, content in reply_set:
if reply_type == "text":
await self.send_text(content)
return True, "提供了帮助"
else:
await self.send_text("我来帮助你!有什么问题吗?")
return True, "提供了默认帮助"
```
### RANDOM激活
@@ -202,466 +360,210 @@ class HelpAction(BaseAction):
class SurpriseAction(BaseAction):
focus_activation_type = ActionActivationType.RANDOM
normal_activation_type = ActionActivationType.RANDOM
# 随机激活概率
random_activation_probability = 0.1 # 10%概率激活
```
### ALWAYS/NEVER激活
```python
class CoreAction(BaseAction):
focus_activation_type = ActionActivationType.ALWAYS # 总是激活
normal_activation_type = ActionActivationType.NEVER # 在普通模式下禁用
```
## 🎨 完整Action示例
### 智能问候Action
```python
from src.plugin_system import BaseAction, ActionActivationType, ChatMode
class SmartGreetingAction(BaseAction):
"""智能问候Action - 展示关键词激活的完整示例"""
# ===== 激活控制必须项 =====
focus_activation_type = ActionActivationType.KEYWORD
normal_activation_type = ActionActivationType.KEYWORD
mode_enable = ChatMode.ALL
parallel_action = False
# ===== 基本信息必须项 =====
action_name = "smart_greeting"
action_description = "智能问候系统,基于关键词触发,支持个性化问候消息"
# 关键词配置
activation_keywords = ["你好", "hello", "hi", "嗨", "问候", "早上好", "晚上好"]
keyword_case_sensitive = False
# ===== 功能定义必须项 =====
action_parameters = {
"username": "要问候的用户名(可选)",
"greeting_style": "问候风格casual(随意)、formal(正式)、friendly(友好)"
}
action_require = [
"用户发送包含问候词汇的消息时使用",
"检测到新用户加入时使用",
"响应友好交流需求时使用",
"避免在短时间内重复问候同一用户"
]
associated_types = ["text", "emoji"]
async def execute(self) -> Tuple[bool, str]:
"""执行智能问候"""
# 获取参数
username = self.action_data.get("username", "")
greeting_style = self.action_data.get("greeting_style", "casual")
# 根据风格生成问候消息
if greeting_style == "formal":
message = f"您好{username}!很荣幸为您服务!"
emoji = "🙏"
elif greeting_style == "friendly":
message = f"你好{username}!欢迎来到这里,希望我们能成为好朋友!"
emoji = "😊"
else: # casual
message = f"嗨{username}!很开心见到你~"
emoji = "👋"
# 发送消息
await self.send_text(message)
await self.send_type("emoji", emoji)
return True, f"向{username or '用户'}发送了{greeting_style}风格的问候"
import random
surprises = ["🎉", "✨", "🌟", "💝", "🎈"]
selected = random.choice(surprises)
await self.send_emoji(selected)
return True, f"发送了惊喜表情: {selected}"
```
### 智能禁言Action
## 💡 完整示例
以下是一个真实的群管理禁言Action示例展示了LLM判断、参数验证、配置管理等高级功能
### 智能聊天Action
```python
from typing import Optional
import random
from src.plugin_system.base.base_action import BaseAction
from src.plugin_system.base.component_types import ActionActivationType, ChatMode
from src.plugin_system.apis import generator_api, emoji_api
class MuteAction(BaseAction):
"""智能禁言Action - 基于LLM智能判断是否需要禁言"""
# ===== 激活控制必须项 =====
focus_activation_type = ActionActivationType.LLM_JUDGE # Focus模式使用LLM判定
normal_activation_type = ActionActivationType.KEYWORD # Normal模式使用关键词
class IntelligentChatAction(BaseAction):
"""智能聊天Action - 展示新API的完整用法"""
# 激活设置
focus_activation_type = ActionActivationType.ALWAYS
normal_activation_type = ActionActivationType.LLM_JUDGE
mode_enable = ChatMode.ALL
parallel_action = False
# ===== 基本信息必须项 =====
action_name = "mute"
action_description = "智能禁言系统基于LLM判断是否需要禁言"
# ===== 激活配置 =====
# 关键词设置用于Normal模式
activation_keywords = ["禁言", "mute", "ban", "silence"]
keyword_case_sensitive = False
# LLM判定提示词用于Focus模式
llm_judge_prompt = """
判定是否需要使用禁言动作的严格条件:
使用禁言的情况:
1. 用户发送明显违规内容(色情、暴力、政治敏感等)
2. 恶意刷屏或垃圾信息轰炸
3. 用户主动明确要求被禁言("禁言我"等)
4. 严重违反群规的行为
5. 恶意攻击他人或群组管理
绝对不要使用的情况:
1. 正常聊天和交流
2. 情绪化表达但无恶意
3. 开玩笑或调侃,除非过分
4. 单纯的意见分歧或争论
"""
# ===== 功能定义必须项 =====
action_parameters = {
"target": "禁言对象,必填,输入你要禁言的对象的名字,请仔细思考不要弄错禁言对象",
"duration": "禁言时长,必填,输入你要禁言的时长(秒),单位为秒,必须为数字",
"reason": "禁言理由,可选",
}
action_require = [
"当有人违反了公序良俗的内容",
"当有人刷屏时使用",
"当有人发了擦边,或者色情内容时使用",
"当有人要求禁言自己时使用",
"如果某人已经被禁言了,就不要再次禁言了,除非你想追加时间!!",
]
associated_types = ["text", "command"]
async def execute(self) -> Tuple[bool, Optional[str]]:
"""执行智能禁言判定"""
# 获取参数
target = self.action_data.get("target")
duration = self.action_data.get("duration")
reason = self.action_data.get("reason", "违反群规")
# 参数验证
if not target:
await self.send_text("没有指定禁言对象呢~")
return False, "禁言目标不能为空"
if not duration:
await self.send_text("没有指定禁言时长呢~")
return False, "禁言时长不能为空"
# 获取时长限制配置
min_duration = self.api.get_config("mute.min_duration", 60)
max_duration = self.api.get_config("mute.max_duration", 2592000)
# 验证时长格式并转换
try:
duration_int = int(duration)
if duration_int <= 0:
await self.send_text("禁言时长必须是正数哦~")
return False, "禁言时长必须大于0"
# 限制禁言时长范围
if duration_int < min_duration:
duration_int = min_duration
elif duration_int > max_duration:
duration_int = max_duration
except (ValueError, TypeError):
await self.send_text("禁言时长必须是数字哦~")
return False, f"禁言时长格式无效: {duration}"
# 获取用户ID
try:
platform, user_id = await self.api.get_user_id_by_person_name(target)
except Exception as e:
await self.send_text("查找用户信息时出现问题~")
return False, f"查找用户ID时出错: {e}"
if not user_id:
await self.send_text(f"找不到 {target} 这个人呢~")
return False, f"未找到用户 {target} 的ID"
# 格式化时长显示
time_str = self._format_duration(duration_int)
# 获取模板化消息
message = self._get_template_message(target, time_str, reason)
await self.send_message_by_expressor(message)
# 发送群聊禁言命令
success = await self.send_command(
command_name="GROUP_BAN",
args={"qq_id": str(user_id), "duration": str(duration_int)},
display_message=f"禁言了 {target} {time_str}",
)
if success:
return True, f"成功禁言 {target},时长 {time_str}"
else:
await self.send_text("执行禁言动作失败")
return False, "发送禁言命令失败"
def _get_template_message(self, target: str, duration_str: str, reason: str) -> str:
"""获取模板化的禁言消息"""
templates = self.api.get_config(
"mute.templates",
[
"好的,禁言 {target} {duration},理由:{reason}",
"收到,对 {target} 执行禁言 {duration},因为{reason}",
"明白了,禁言 {target} {duration},原因是{reason}",
"哇哈哈哈哈哈,已禁言 {target} {duration},理由:{reason}",
],
)
template = random.choice(templates)
return template.format(target=target, duration=duration_str, reason=reason)
def _format_duration(self, seconds: int) -> str:
"""将秒数格式化为可读的时间字符串"""
if seconds < 60:
return f"{seconds}秒"
elif seconds < 3600:
minutes = seconds // 60
remaining_seconds = seconds % 60
if remaining_seconds > 0:
return f"{minutes}{remaining_seconds}秒"
else:
return f"{minutes}分钟"
else:
hours = seconds // 3600
remaining_minutes = (seconds % 3600) // 60
if remaining_minutes > 0:
return f"{hours}小时{remaining_minutes}分钟"
else:
return f"{hours}小时"
```
**关键特性说明**
1. **🎯 双模式激活**Focus模式使用LLM_JUDGE更谨慎Normal模式使用KEYWORD快速响应
2. **🧠 严格的LLM判定**详细提示词指导LLM何时应该/不应该使用禁言,避免误判
3. **✅ 完善的参数验证**验证必需参数、数值转换、用户ID查找等多重验证
4. **⚙️ 配置驱动**:时长限制、消息模板等都可通过配置文件自定义
5. **😊 友好的用户反馈**:错误提示清晰、随机化消息模板、时长格式化显示
6. **🛡️ 安全措施**:严格权限控制、防误操作验证、完整错误处理
### 智能助手Action
```python
class IntelligentHelpAction(BaseAction):
"""智能助手Action - 展示LLM判断激活的完整示例"""
# ===== 激活控制必须项 =====
focus_activation_type = ActionActivationType.LLM_JUDGE
normal_activation_type = ActionActivationType.RANDOM
mode_enable = ChatMode.ALL
parallel_action = True
# ===== 基本信息必须项 =====
action_name = "intelligent_help"
action_description = "智能助手,主动提供帮助和建议"
# 基本信息
action_name = "intelligent_chat"
action_description = "使用replyer_1进行智能聊天回复支持表情包和个性化回复"
# LLM判断提示词
llm_judge_prompt = """
是否需要提供智能帮助的条件
1. 用户表达了困惑或需要帮助
2. 对话中出现了技术问题
3. 用户寻求解决方案或建议
4. 适合提供额外信息的场合
不要使用的情况:
1. 用户明确表示不需要帮助
2. 对话进行得很顺利
3. 刚刚已经提供过帮助
是否需要进行智能聊天回复
1. 用户提出了有趣的话题
2. 需要更加个性化的回复
3. 适合发送表情包的情况
请回答"是"或"否"。
"""
# 随机激活概率
random_activation_probability = 0.15
# ===== 功能定义必须项 =====
# 功能定义
action_parameters = {
"help_type": "帮助类型explanation(解释)、suggestion(建议)、guidance(指导)",
"topic": "帮助主题或用户关心的问题",
"urgency": "紧急程度low(低)、medium(中)、high(高)"
"topic": "聊天话题",
"mood": "当前氛围happy/sad/excited/calm",
"include_emoji": "是否包含表情包true/false"
}
action_require = [
"用户表达困惑或寻求帮助时使用",
"检测到用户遇到技术问题时使用",
"对话中出现知识盲点时主动提供帮助",
"避免过度频繁地提供帮助,要恰到好处"
"需要更个性化回复时使用",
"聊天氛围适合发送表情时使用",
"避免在正式场合使用"
]
associated_types = ["text", "emoji"]
async def execute(self) -> Tuple[bool, str]:
"""执行智能帮助"""
# 获取参数
help_type = self.action_data.get("help_type", "suggestion")
topic = self.action_data.get("topic", "")
urgency = self.action_data.get("urgency", "medium")
# 根据帮助类型和紧急程度生成消息
if help_type == "explanation":
message = f"关于{topic},让我来为你解释一下..."
elif help_type == "guidance":
message = f"在{topic}方面,我可以为你提供一些指导..."
else: # suggestion
message = f"针对{topic},我建议你可以尝试以下方法..."
# 根据紧急程度调整表情
if urgency == "high":
emoji = "🚨"
elif urgency == "low":
emoji = "💡"
topic = self.action_data.get("topic", "日常聊天")
mood = self.action_data.get("mood", "happy")
include_emoji = self.action_data.get("include_emoji", "true") == "true"
# 构建智能回复数据
chat_data = {
"text": f"请针对{topic}话题进行回复,当前氛围是{mood}",
"topic": topic,
"mood": mood,
"style": "conversational",
"replyer_name": "replyer_1" # 使用replyer_1
}
# 生成智能回复
success, reply_set = await generator_api.generate_reply(
chat_stream=self.chat_stream,
action_data=chat_data,
platform=self.platform,
chat_id=self.chat_id,
is_group=self.is_group
)
reply_sent = False
if success and reply_set:
# 发送生成的回复
for reply_type, content in reply_set:
if reply_type == "text":
await self.send_text(content)
reply_sent = True
elif reply_type == "emoji":
await self.send_emoji(content)
# 如果配置允许且生成失败,发送表情包
if include_emoji and not reply_sent:
emoji_result = await emoji_api.get_by_description(mood)
if emoji_result:
emoji_base64, emoji_desc, matched_emotion = emoji_result
await self.send_emoji(emoji_base64)
reply_sent = True
# 记录动作执行
if reply_sent:
await self.store_action_info(
action_build_into_prompt=True,
action_prompt_display=f"进行了智能聊天回复,话题:{topic},氛围:{mood}",
action_done=True
)
return True, f"完成智能聊天回复:{topic}"
else:
emoji = "🤔"
# 发送帮助消息
await self.send_text(message)
await self.send_type("emoji", emoji)
return True, f"提供了{help_type}类型的帮助,主题:{topic}"
return False, "智能回复生成失败"
```
## 📊 性能优化建议
## 🛠️ 调试技巧
### 1. 合理使用激活类型
- **ALWAYS**: 仅用于核心功能
- **LLM_JUDGE**: 适度使用避免过多LLM调用
- **KEYWORD**: 优选,性能最好
- **RANDOM**: 控制概率,避免过于频繁
### 2. 优化execute方法
### 开发调试Action
```python
async def execute(self) -> Tuple[bool, str]:
try:
# 快速参数验证
if not self._validate_parameters():
return False, "参数验证失败"
# 核心逻辑
result = await self._core_logic()
# 成功返回
return True, "执行成功"
except Exception as e:
logger.error(f"{self.log_prefix} 执行失败: {e}")
return False, f"执行失败: {str(e)}"
class DebugAction(BaseAction):
"""调试Action - 展示如何调试新API"""
focus_activation_type = ActionActivationType.KEYWORD
normal_activation_type = ActionActivationType.KEYWORD
activation_keywords = ["debug", "调试"]
mode_enable = ChatMode.ALL
parallel_action = True
action_name = "debug_helper"
action_description = "调试助手,显示当前状态信息"
action_parameters = {}
action_require = ["需要调试信息时使用"]
associated_types = ["text"]
async def execute(self) -> Tuple[bool, str]:
# 收集调试信息
debug_info = {
"聊天类型": "群聊" if self.is_group else "私聊",
"平台": self.platform,
"目标ID": self.target_id,
"用户ID": self.user_id,
"用户昵称": self.user_nickname,
"动作数据": self.action_data,
}
if self.is_group:
debug_info.update({
"群ID": self.group_id,
"群名": self.group_name,
})
# 格式化调试信息
info_lines = ["🔍 调试信息:"]
for key, value in debug_info.items():
info_lines.append(f" • {key}: {value}")
debug_text = "\n".join(info_lines)
# 发送调试信息
await self.send_text(debug_text)
# 测试配置获取
test_config = self.get_config("debug.verbose", True)
if test_config:
await self.send_text(f"配置测试: debug.verbose = {test_config}")
return True, "调试信息已发送"
```
### 3. 合理设置并行执行
## 📚 最佳实践
```python
# 轻量级Action可以并行
parallel_action = True # 如:发送表情、记录日志
1. **总是导入所需的API模块**
# 重要Action应该独占
parallel_action = False # 如:回复消息、状态切换
```
```python
from src.plugin_system.apis import generator_api, send_api, emoji_api
```
2. **在生成内容时指定replyer_1**
## 🐛 调试技巧
```python
action_data = {
"text": "生成内容的请求",
"replyer_name": "replyer_1"
}
```
3. **使用便捷发送方法**
### 1. 日志记录
```python
await self.send_text("文本") # 自动处理群聊/私聊
await self.send_emoji(emoji_base64)
```
4. **合理使用配置**
```python
from src.common.logger import get_logger
```python
enable_feature = self.get_config("section.key", default_value)
```
5. **总是记录动作信息**
logger = get_logger("my_action")
```python
await self.store_action_info(
action_build_into_prompt=True,
action_prompt_display="动作描述",
action_done=True
)
```
async def execute(self) -> Tuple[bool, str]:
logger.info(f"{self.log_prefix} 开始执行: {self.reasoning}")
logger.debug(f"{self.log_prefix} 参数: {self.action_data}")
# 执行逻辑...
logger.info(f"{self.log_prefix} 执行完成")
```
### 2. 激活状态检查
```python
# 在execute方法中检查激活原因
def _debug_activation(self):
logger.debug(f"激活类型: Focus={self.focus_activation_type}, Normal={self.normal_activation_type}")
logger.debug(f"当前模式: {self.api.get_chat_mode()}")
logger.debug(f"激活原因: {self.reasoning}")
```
### 3. 参数验证
```python
def _validate_parameters(self) -> bool:
required_params = ["param1", "param2"]
for param in required_params:
if param not in self.action_data:
logger.warning(f"{self.log_prefix} 缺少必需参数: {param}")
return False
return True
```
## 🎯 最佳实践
### 1. 清晰的Action命名
- 使用描述性的类名:`SmartGreetingAction` 而不是 `Action1`
- action_name要简洁明确`"smart_greeting"` 而不是 `"action_1"`
### 2. 完整的文档字符串
```python
class MyAction(BaseAction):
"""
我的Action - 一句话描述功能
详细描述Action的用途、激活条件、执行逻辑等。
激活条件:
- Focus模式关键词激活
- Normal模式LLM判断激活
执行逻辑:
1. 验证参数
2. 生成响应
3. 发送消息
"""
```
### 3. 错误处理
```python
async def execute(self) -> Tuple[bool, str]:
try:
# 主要逻辑
pass
except ValueError as e:
await self.send_text("参数错误,请检查输入")
return False, f"参数错误: {e}"
except Exception as e:
await self.send_text("操作失败,请稍后重试")
return False, f"执行失败: {e}"
```
### 4. 配置驱动
```python
# 从配置文件读取设置
enable_feature = self.api.get_config("my_action.enable_feature", True)
max_retries = self.api.get_config("my_action.max_retries", 3)
```
---
🎉 **现在你已经掌握了Action组件开发的完整知识继续学习 [Command组件详解](command-components.md) 来了解命令开发。**
通过使用新的API格式Action的开发变得更加简洁和强大