667 lines
22 KiB
Markdown
667 lines
22 KiB
Markdown
# ⚡ Action组件详解
|
||
|
||
## 📖 什么是Action
|
||
|
||
Action是给麦麦在回复之外提供额外功能的智能组件,**由麦麦的决策系统自主选择是否使用**,具有随机性和拟人化的调用特点。Action不是直接响应用户命令,而是让麦麦根据聊天情境智能地选择合适的动作,使其行为更加自然和真实。
|
||
|
||
### 🎯 Action的特点
|
||
|
||
- 🧠 **智能激活**:麦麦根据多种条件智能判断是否使用
|
||
- 🎲 **随机性**:增加行为的不可预测性,更接近真人交流
|
||
- 🤖 **拟人化**:让麦麦的回应更自然、更有个性
|
||
- 🔄 **情境感知**:基于聊天上下文做出合适的反应
|
||
|
||
## 🎯 两层决策机制
|
||
|
||
Action采用**两层决策机制**来优化性能和决策质量:
|
||
|
||
### 第一层:激活控制(Activation Control)
|
||
|
||
**激活决定麦麦是否"知道"这个Action的存在**,即这个Action是否进入决策候选池。**不被激活的Action麦麦永远不会选择**。
|
||
|
||
> 🎯 **设计目的**:在加载许多插件的时候降低LLM决策压力,避免让麦麦在过多的选项中纠结。
|
||
|
||
#### 激活类型说明
|
||
|
||
| 激活类型 | 说明 | 使用场景 |
|
||
|---------|-----|---------|
|
||
| `NEVER` | 从不激活,Action对麦麦不可见 | 临时禁用某个Action |
|
||
| `ALWAYS` | 永远激活,Action总是在麦麦的候选池中 | 核心功能,如回复、表情 |
|
||
| `LLM_JUDGE` | 通过LLM智能判断当前情境是否需要激活此Action | 需要智能判断的复杂场景 |
|
||
| `RANDOM` | 基于随机概率决定是否激活 | 增加行为随机性的功能 |
|
||
| `KEYWORD` | 当检测到特定关键词时激活 | 明确触发条件的功能 |
|
||
|
||
#### 聊天模式控制
|
||
|
||
| 模式 | 说明 |
|
||
|-----|-----|
|
||
| `ChatMode.FOCUS` | 仅在专注聊天模式下可激活 |
|
||
| `ChatMode.NORMAL` | 仅在普通聊天模式下可激活 |
|
||
| `ChatMode.ALL` | 所有模式下都可激活 |
|
||
|
||
### 第二层:使用决策(Usage Decision)
|
||
|
||
**在Action被激活后,使用条件决定麦麦什么时候会"选择"使用这个Action**。
|
||
|
||
这一层由以下因素综合决定:
|
||
- `action_require`:使用场景描述,帮助LLM判断何时选择
|
||
- `action_parameters`:所需参数,影响Action的可执行性
|
||
- 当前聊天上下文和麦麦的决策逻辑
|
||
|
||
### 🎬 决策流程示例
|
||
|
||
假设有一个"发送表情"Action:
|
||
|
||
```python
|
||
class EmojiAction(BaseAction):
|
||
# 第一层:激活控制
|
||
focus_activation_type = ActionActivationType.RANDOM # 专注模式下随机激活
|
||
normal_activation_type = ActionActivationType.KEYWORD # 普通模式下关键词激活
|
||
activation_keywords = ["表情", "emoji", "😊"]
|
||
|
||
# 第二层:使用决策
|
||
action_require = [
|
||
"表达情绪时可以选择使用",
|
||
"增加聊天趣味性",
|
||
"不要连续发送多个表情"
|
||
]
|
||
```
|
||
|
||
**决策流程**:
|
||
1. **第一层激活判断**:
|
||
- 普通模式:只有当用户消息包含"表情"、"emoji"或"😊"时,麦麦才"知道"可以使用这个Action
|
||
- 专注模式:随机激活,有概率让麦麦"看到"这个Action
|
||
|
||
2. **第二层使用决策**:
|
||
- 即使Action被激活,麦麦还会根据`action_require`中的条件判断是否真正选择使用
|
||
- 例如:如果刚刚已经发过表情,根据"不要连续发送多个表情"的要求,麦麦可能不会选择这个Action
|
||
|
||
## 📋 Action必须项清单
|
||
|
||
每个Action类都**必须**包含以下属性:
|
||
|
||
### 1. 激活控制必须项
|
||
|
||
```python
|
||
# 专注模式下的激活类型
|
||
focus_activation_type = ActionActivationType.LLM_JUDGE
|
||
|
||
# 普通模式下的激活类型
|
||
normal_activation_type = ActionActivationType.KEYWORD
|
||
|
||
# 启用的聊天模式
|
||
mode_enable = ChatMode.ALL
|
||
|
||
# 是否允许与其他Action并行执行
|
||
parallel_action = False
|
||
```
|
||
|
||
### 2. 基本信息必须项
|
||
|
||
```python
|
||
# Action的唯一标识名称
|
||
action_name = "my_action"
|
||
|
||
# Action的功能描述
|
||
action_description = "描述这个Action的具体功能和用途"
|
||
```
|
||
|
||
### 3. 功能定义必须项
|
||
|
||
```python
|
||
# Action参数定义 - 告诉LLM执行时需要什么参数
|
||
action_parameters = {
|
||
"param1": "参数1的说明",
|
||
"param2": "参数2的说明"
|
||
}
|
||
|
||
# Action使用场景描述 - 帮助LLM判断何时"选择"使用
|
||
action_require = [
|
||
"使用场景描述1",
|
||
"使用场景描述2"
|
||
]
|
||
|
||
# 关联的消息类型 - 说明Action能处理什么类型的内容
|
||
associated_types = ["text", "emoji", "image"]
|
||
```
|
||
|
||
### 4. 动作记录必须项
|
||
|
||
每个 Action 在执行完成后,**必须**使用 `store_action_info` 记录动作信息。这是非常重要的,因为:
|
||
|
||
1. **记忆连续性**:让麦麦记住自己执行过的动作,避免重复执行
|
||
2. **上下文理解**:帮助麦麦理解自己的行为历史,做出更合理的决策
|
||
3. **行为追踪**:便于后续查询和分析麦麦的行为模式
|
||
|
||
```python
|
||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||
# ... 执行动作的代码 ...
|
||
|
||
if success:
|
||
# 存储动作信息
|
||
await self.api.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, "动作执行成功"
|
||
```
|
||
|
||
> ⚠️ **重要提示**:如果不记录动作信息,可能会导致以下问题:
|
||
> - 麦麦不知道自己执行过什么动作,可能会重复执行
|
||
> - 无法追踪动作历史,影响后续决策
|
||
> - 在长对话中失去上下文连续性
|
||
> - 无法进行行为分析和优化
|
||
|
||
## 🔧 激活类型详解
|
||
|
||
### KEYWORD激活
|
||
|
||
当检测到特定关键词时激活Action:
|
||
|
||
```python
|
||
class GreetingAction(BaseAction):
|
||
focus_activation_type = ActionActivationType.KEYWORD
|
||
normal_activation_type = ActionActivationType.KEYWORD
|
||
|
||
# 关键词配置
|
||
activation_keywords = ["你好", "hello", "hi", "嗨"]
|
||
keyword_case_sensitive = False # 不区分大小写
|
||
```
|
||
|
||
### LLM_JUDGE激活
|
||
|
||
通过LLM智能判断是否激活:
|
||
|
||
```python
|
||
class HelpAction(BaseAction):
|
||
focus_activation_type = ActionActivationType.LLM_JUDGE
|
||
normal_activation_type = ActionActivationType.LLM_JUDGE
|
||
|
||
# LLM判断提示词
|
||
llm_judge_prompt = """
|
||
判定是否需要使用帮助动作的条件:
|
||
1. 用户表达了困惑或需要帮助
|
||
2. 用户提出了问题但没有得到满意答案
|
||
3. 对话中出现了技术术语或复杂概念
|
||
|
||
请回答"是"或"否"。
|
||
"""
|
||
```
|
||
|
||
### RANDOM激活
|
||
|
||
基于随机概率激活:
|
||
|
||
```python
|
||
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}风格的问候"
|
||
```
|
||
|
||
### 智能禁言Action
|
||
|
||
以下是一个真实的群管理禁言Action示例,展示了LLM判断、参数验证、配置管理等高级功能:
|
||
|
||
```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
|
||
|
||
class MuteAction(BaseAction):
|
||
"""智能禁言Action - 基于LLM智能判断是否需要禁言"""
|
||
|
||
# ===== 激活控制必须项 =====
|
||
focus_activation_type = ActionActivationType.LLM_JUDGE # Focus模式使用LLM判定
|
||
normal_activation_type = ActionActivationType.KEYWORD # Normal模式使用关键词
|
||
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 = "智能助手,主动提供帮助和建议"
|
||
|
||
# LLM判断提示词
|
||
llm_judge_prompt = """
|
||
判定是否需要提供智能帮助的条件:
|
||
1. 用户表达了困惑或需要帮助
|
||
2. 对话中出现了技术问题
|
||
3. 用户寻求解决方案或建议
|
||
4. 适合提供额外信息的场合
|
||
|
||
不要使用的情况:
|
||
1. 用户明确表示不需要帮助
|
||
2. 对话进行得很顺利
|
||
3. 刚刚已经提供过帮助
|
||
|
||
请回答"是"或"否"。
|
||
"""
|
||
|
||
# 随机激活概率
|
||
random_activation_probability = 0.15
|
||
|
||
# ===== 功能定义必须项 =====
|
||
action_parameters = {
|
||
"help_type": "帮助类型:explanation(解释)、suggestion(建议)、guidance(指导)",
|
||
"topic": "帮助主题或用户关心的问题",
|
||
"urgency": "紧急程度:low(低)、medium(中)、high(高)"
|
||
}
|
||
|
||
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 = "💡"
|
||
else:
|
||
emoji = "🤔"
|
||
|
||
# 发送帮助消息
|
||
await self.send_text(message)
|
||
await self.send_type("emoji", emoji)
|
||
|
||
return True, f"提供了{help_type}类型的帮助,主题:{topic}"
|
||
```
|
||
|
||
## 📊 性能优化建议
|
||
|
||
### 1. 合理使用激活类型
|
||
|
||
- **ALWAYS**: 仅用于核心功能
|
||
- **LLM_JUDGE**: 适度使用,避免过多LLM调用
|
||
- **KEYWORD**: 优选,性能最好
|
||
- **RANDOM**: 控制概率,避免过于频繁
|
||
|
||
### 2. 优化execute方法
|
||
|
||
```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)}"
|
||
```
|
||
|
||
### 3. 合理设置并行执行
|
||
|
||
```python
|
||
# 轻量级Action可以并行
|
||
parallel_action = True # 如:发送表情、记录日志
|
||
|
||
# 重要Action应该独占
|
||
parallel_action = False # 如:回复消息、状态切换
|
||
```
|
||
|
||
## 🐛 调试技巧
|
||
|
||
### 1. 日志记录
|
||
|
||
```python
|
||
from src.common.logger import get_logger
|
||
|
||
logger = get_logger("my_action")
|
||
|
||
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) 来了解命令开发。** |