Files
Mofox-Core/docs/plugins/development-standards.md
2025-06-15 23:30:53 +08:00

10 KiB
Raw Blame History

📋 开发标准规范

🎯 概述

本文档定义了MaiBot插件开发的标准规范包括Action组件、Command组件和Tool组件的开发规范确保代码质量、可维护性和性能。

🧩 组件开发规范

Tool组件开发

工具基本要求

  • 继承 BaseTool 基类
  • 定义唯一的工具名称
  • 提供清晰的功能描述
  • 使用JSONSchema定义参数
  • 实现 execute 异步方法
  • 使用 register_tool() 注册

工具开发模板

from src.tools.tool_can_use.base_tool import BaseTool, register_tool

class MyTool(BaseTool):
    """工具类文档字符串"""
    
    name = "my_tool"
    description = "详细的工具功能描述告诉LLM这个工具的用途"
    
    parameters = {
        "type": "object",
        "properties": {
            "param": {
                "type": "string",
                "description": "参数详细描述"
            }
        },
        "required": ["param"]
    }
    
    async def execute(self, function_args, message_txt=""):
        """执行工具逻辑
        
        Args:
            function_args: 工具调用参数
            message_txt: 原始消息文本
            
        Returns:
            dict: 包含name和content字段的结果
        """
        # 实现工具功能逻辑
        result = "处理结果"
        
        return {
            "name": self.name,
            "content": result
        }

# 注册工具
register_tool(MyTool)

工具命名规范

  • 使用描述性的英文名称
  • 采用下划线命名法snake_case
  • 体现工具的核心功能
  • 避免过于简短或复杂的名称

示例

# ✅ 好的命名
name = "weather_query"        # 天气查询
name = "knowledge_search"     # 知识搜索
name = "stock_price_check"    # 股价检查

# ❌ 避免的命名
name = "tool1"               # 无意义
name = "wq"                  # 过于简短
name = "weather_and_news"    # 功能复杂

Action组件开发

Action必需字段检查表

激活控制字段

  • activation_type激活类型KEYWORD/LLM_JUDGE/RANDOM/ALWAYS/NEVER
  • activation_config:激活配置参数

基本信息字段

  • nameAction唯一标识名称
  • description:功能描述
  • usage_tip:使用提示

功能定义字段

  • func:执行函数
  • llm_function_tipsLLM调用提示

Action开发模板

from src.plugin_system.base_actions import BaseAction

class MyAction(BaseAction):
    """Action类文档字符串"""
    
    # 激活控制
    activation_type = "KEYWORD"  # 或 LLM_JUDGE/RANDOM/ALWAYS/NEVER
    activation_config = {
        "keywords": ["关键词1", "关键词2"],
        "priority": 1
    }
    
    # 基本信息
    name = "my_action"
    description = "Action功能描述"
    usage_tip = "使用场景和方法提示"
    
    # 功能定义
    func = "执行函数名"
    llm_function_tips = "告诉LLM何时以及如何使用这个Action"
    
    async def 执行函数名(self, message_txt, sender_name, chat_stream):
        """Action执行逻辑"""
        # 实现Action功能
        await chat_stream.send_message("执行结果")

激活类型使用规范

  • KEYWORD:适用于有明确关键词的功能,性能最优
  • LLM_JUDGE:适用于需要智能判断的复杂场景
  • RANDOM:适用于随机触发的功能
  • ALWAYS:适用于总是可用的基础功能
  • NEVER:适用于临时禁用的功能

Command组件开发

Command开发模板

from src.plugin_system.base_commands import BaseCommand

class MyCommand(BaseCommand):
    """Command类文档字符串"""
    
    # 命令基本信息
    command_name = "my_command"
    description = "命令功能描述"
    usage = "/my_command <参数> - 命令使用说明"
    
    # 匹配模式
    pattern = r"^/my_command\s+(.*)"
    
    async def execute(self, match, message_txt, sender_name, chat_stream):
        """Command执行逻辑"""
        params = match.group(1) if match.group(1) else ""
        
        # 实现命令功能
        await chat_stream.send_message(f"命令执行结果: {params}")

📝 代码结构标准

文件组织结构

plugins/my_plugin/
├── __init__.py          # 插件入口
├── plugin.py           # 插件主文件
├── config.toml         # 插件配置
├── actions/            # Action组件目录
│   ├── __init__.py
│   └── my_action.py
├── commands/           # Command组件目录
│   ├── __init__.py
│   └── my_command.py
├── utils/              # 工具函数目录
│   ├── __init__.py
│   └── helpers.py
└── README.md           # 插件说明文档

插件主文件模板

"""
插件名称My Plugin
插件描述:插件功能描述
作者:作者名称
版本1.0.0
"""

from src.plugin_system.plugin_interface import PluginInterface
from .actions.my_action import MyAction
from .commands.my_command import MyCommand

class MyPlugin(PluginInterface):
    """插件主类"""
    
    def get_action_info(self):
        """获取Action信息"""
        return [MyAction()]
    
    def get_command_info(self):
        """获取Command信息"""
        return [MyCommand()]

# 插件实例
plugin_instance = MyPlugin()

🔧 命名规范

类命名

  • Action类:使用 Action 后缀,如 GreetingAction
  • Command类:使用 Command 后缀,如 HelpCommand
  • Tool类:使用 Tool 后缀,如 WeatherTool
  • 插件类:使用 Plugin 后缀,如 ExamplePlugin

变量命名

  • 使用小写字母和下划线snake_case
  • 布尔变量使用 is_has_can_ 前缀
  • 常量使用全大写字母

函数命名

  • 使用小写字母和下划线snake_case
  • 异步函数不需要特殊前缀
  • 私有方法使用单下划线前缀

📊 性能优化规范

Action激活类型选择

  1. 首选KEYWORD:明确知道触发关键词时
  2. 谨慎使用LLM_JUDGE:仅在必须智能判断时使用
  3. 合理设置优先级避免过多高优先级Action

异步编程规范

  • 所有I/O操作必须使用异步
  • 避免在异步函数中使用阻塞操作
  • 合理使用 asyncio.gather() 并发执行

资源管理

  • 及时关闭文件、网络连接等资源
  • 使用上下文管理器(async with
  • 避免内存泄漏

🚨 错误处理规范

异常处理模板

async def my_function(self, message_txt, sender_name, chat_stream):
    """函数文档字符串"""
    try:
        # 核心逻辑
        result = await some_operation()
        
        # 成功处理
        await chat_stream.send_message(f"操作成功: {result}")
        
    except ValueError as e:
        # 具体异常处理
        await chat_stream.send_message(f"参数错误: {str(e)}")
        
    except Exception as e:
        # 通用异常处理
        await chat_stream.send_message(f"操作失败: {str(e)}")
        # 记录错误日志
        logger.error(f"Function my_function failed: {str(e)}")

错误信息规范

  • 使用用户友好的错误提示
  • 避免暴露系统内部信息
  • 提供解决建议或替代方案
  • 记录详细的错误日志

🧪 测试标准

单元测试模板

import unittest
import asyncio
from unittest.mock import Mock, AsyncMock
from plugins.my_plugin.actions.my_action import MyAction

class TestMyAction(unittest.TestCase):
    """MyAction测试类"""
    
    def setUp(self):
        """测试前准备"""
        self.action = MyAction()
        self.mock_chat_stream = AsyncMock()
    
    def test_action_properties(self):
        """测试Action属性"""
        self.assertEqual(self.action.name, "my_action")
        self.assertIsNotNone(self.action.description)
        self.assertIsNotNone(self.action.activation_type)
    
    async def test_action_execution(self):
        """测试Action执行"""
        await self.action.执行函数名("测试消息", "测试用户", self.mock_chat_stream)
        
        # 验证消息发送
        self.mock_chat_stream.send_message.assert_called()
    
    def test_action_execution_sync(self):
        """同步测试包装器"""
        asyncio.run(self.test_action_execution())

if __name__ == '__main__':
    unittest.main()

测试覆盖率要求

  • 核心功能必须有测试覆盖
  • 异常处理路径需要测试
  • 边界条件需要验证

📚 文档规范

代码文档

  • 所有类和函数必须有文档字符串
  • 使用Google风格的docstring
  • 包含参数说明和返回值说明

README文档模板

# 插件名称

## 📖 插件描述
简要描述插件的功能和用途

## ✨ 功能特性
- 功能1功能描述
- 功能2功能描述

## 🚀 快速开始
### 安装配置
1. 步骤1
2. 步骤2

### 使用方法
具体的使用说明和示例

## 📝 配置说明
配置文件的详细说明

## 🔧 开发信息
- 作者:作者名称
- 版本:版本号
- 许可证:许可证类型

🔍 代码审查清单

基础检查

  • 代码符合命名规范
  • 类和函数有完整文档字符串
  • 异常处理覆盖完整
  • 没有硬编码的配置信息

Action组件检查

  • 包含所有必需字段
  • 激活类型选择合理
  • LLM函数提示清晰
  • 执行函数实现正确

Command组件检查

  • 正则表达式模式正确
  • 参数提取和验证完整
  • 使用说明准确

Tool组件检查

  • 继承BaseTool基类
  • 参数定义遵循JSONSchema
  • 返回值格式正确
  • 工具已正确注册

性能检查

  • 避免不必要的LLM_JUDGE激活
  • 异步操作使用正确
  • 资源管理合理

安全检查

  • 输入参数验证
  • SQL注入防护
  • 敏感信息保护

🎯 最佳实践总结

设计原则

  1. 单一职责:每个组件专注单一功能
  2. 松耦合:减少组件间依赖
  3. 高内聚:相关功能聚合在一起
  4. 可扩展:易于添加新功能

性能优化

  1. 合理选择激活类型优先使用KEYWORD
  2. 避免阻塞操作:使用异步编程
  3. 缓存重复计算:提高响应速度
  4. 资源池化:复用连接和对象

用户体验

  1. 友好的错误提示:帮助用户理解问题
  2. 清晰的使用说明:降低学习成本
  3. 一致的交互方式:统一的命令格式
  4. 及时的反馈:让用户知道操作状态

🎉 遵循这些标准可以确保插件的质量、性能和用户体验!