mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
docs: Clarify and expand the LLM tool registration guidance in the AI plugin documentation (#8178)
* docs(zh/ai): fix misleading tool registration guide and add warnings * docs(en/ai): add tool registration section with deprecation warnings
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user