diff --git a/docs/en/dev/star/guides/ai.md b/docs/en/dev/star/guides/ai.md index 8e09da134..cf7914bca 100644 --- a/docs/en/dev/star/guides/ai.md +++ b/docs/en/dev/star/guides/ai.md @@ -1,4 +1,3 @@ - # AI AstrBot provides built-in support for multiple Large Language Model (LLM) providers and offers a unified interface, making it convenient for plugin developers to access various LLM services. @@ -67,6 +66,58 @@ class BilibiliTool(FunctionTool[AstrAgentContext]): return "1. Video Title: How to Use AstrBot\nVideo Link: xxxxxx" ``` +## Registering Tools with AstrBot + +Once a Tool is defined, if you want it to be automatically invoked during user conversations, register it in your plugin's `__init__` method: + +```py +class MyPlugin(Star): + def __init__(self, context: Context): + super().__init__(context) + # >= v4.5.1: + self.context.add_llm_tools(BilibiliTool(), SecondTool(), ...) + + # < v4.5.1: + tool_mgr = self.context.provider_manager.llm_tools + tool_mgr.func_list.append(BilibiliTool()) +``` + +> [!WARNING] +> `context.register_llm_tool()` is deprecated. Do not use it in new plugins. +> +> If you must use it for legacy compatibility, `func_args` must be a **list of dicts** in this format: +> ```py +> func_args = [{"type": "string", "name": "arg_name", "description": "..."}, ...] +> ``` +> Passing a list of strings or any other format will raise `AttributeError: 'str' object has no attribute 'pop'`. + +### Registering Tools via Decorator + +Alternatively, you can use the `@filter.llm_tool` decorator to define and register a tool in one step. Make sure to follow the exact format below, including the docstring — AstrBot parses the docstring to generate the parameter schema: + +```py{3,4,5,6,7} +@filter.llm_tool(name="get_weather") # If name is omitted, the function name is used +async def get_weather(self, event: AstrMessageEvent, location: str) -> MessageEventResult: + '''Get weather information. + + Args: + location(string): The location to query + ''' + resp = self.get_weather_from_api(location) + yield event.plain_result("Weather: " + resp) +``` + +In `location(string): The location to query`, `location` is the parameter name, `string` is the type, and the remainder is the description. + +Supported types: `string`, `number`, `object`, `boolean`, `array`. Since v4.5.7, array subtypes are supported, e.g. `array[string]`. + +> [!WARNING] +> **The `Args:` block is required and must be formatted correctly.** +> +> The `@filter.llm_tool` decorator generates the parameter schema by parsing the function's docstring — it does **not** read Python type annotations. If the docstring is missing an `Args:` block, or the format does not follow `param_name(type): description`, the generated schema will be empty. Any arguments passed by the LLM will be silently dropped, causing the function to fail with a missing-argument error. +> +> Additionally, passing `parameters=...` directly to the decorator is **not supported** and will be silently ignored. If you need manual control over the schema, use the `@dataclass` + `add_llm_tools()` approach above. + ## Invoking Agents > [!TIP] diff --git a/docs/zh/dev/star/guides/ai.md b/docs/zh/dev/star/guides/ai.md index 71b867efd..ceba128ea 100644 --- a/docs/zh/dev/star/guides/ai.md +++ b/docs/zh/dev/star/guides/ai.md @@ -81,9 +81,18 @@ class MyPlugin(Star): tool_mgr.func_list.append(BilibiliTool()) ``` +> [!WARNING] +> `context.register_llm_tool()` 已被弃用,请勿在新插件中使用。 +> +> 如需通过该方法注册(旧插件兼容),`func_args` 必须是 **字典列表**,格式为: +> ```py +> func_args = [{"type": "string", "name": "arg_name", "description": "参数描述"}, ...] +> ``` +> 传入字符串列表或其他格式会导致 `AttributeError: 'str' object has no attribute 'pop'`。 + ### 通过装饰器定义 Tool 和注册 Tool -除了上述的通过 `@dataclass` 定义 Tool 的方式之外,你也可以使用装饰器的方式注册 tool 到 AstrBot。如果请务必按照以下格式编写一个工具(包括函数注释,AstrBot 会解析该函数注释,请务必将注释格式写对) +除了上述的通过 `@dataclass` 定义 Tool 的方式之外,你也可以使用装饰器的方式注册 tool 到 AstrBot。请务必按照以下格式编写一个工具(包括函数注释,AstrBot 会解析该函数注释,请务必将注释格式写对): ```py{3,4,5,6,7} @filter.llm_tool(name="get_weather") # 如果 name 不填,将使用函数名 @@ -101,6 +110,13 @@ async def get_weather(self, event: AstrMessageEvent, location: str) -> MessageEv 支持的参数类型有 `string`, `number`, `object`, `boolean`, `array`。在 v4.5.7 之后,支持对 `array` 类型参数指定子类型,例如 `array[string]`。 +> [!WARNING] +> **`Args:` 段是必须的,且格式不能写错。** +> +> `@filter.llm_tool` 装饰器通过解析函数的 docstring 来生成工具的参数 schema,**不会**读取函数签名中的类型注解。如果 docstring 缺少 `Args:` 段,或格式不符合 `参数名(类型): 描述` 的规范,框架生成的参数 schema 将为空,LLM 传入的参数会被静默丢弃,最终导致函数因缺少参数而报错。 +> +> 此外,装饰器**不支持**通过 `parameters=...` 显式传入参数 schema,该写法会被忽略。如需手动控制 schema,请使用上方的 `@dataclass` + `add_llm_tools()` 方式。 + ## 调用 Agent > [!TIP]