mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-11-05 07:12:02 +08:00
docs: add ja docs
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# コンポーネントの追加
|
||||
|
||||
プラグインは、LangBotにさまざまな機能を提供する1つ以上のコンポーネントで構成されています。現在サポートされているコンポーネントタイプには次のものがあります:
|
||||
|
||||
- イベントリスナー(EventListener): パイプライン実行中のイベントをリッスンし、コンテキストやパイプラインを変更します。
|
||||
- コマンド(Command): `!`(または他の設定されたプレフィックス)で始まるユーザーコマンドメッセージによってトリガーされます。
|
||||
- ツール(Tool): LangBotの組み込みLocal Agentの実行中にLLMによって呼び出されます。
|
||||
- ナレッジリトリーバー(KnowledgeRetriever): LangBotに外部ナレッジベース検索機能を提供し、さまざまなRAGシステムとの統合をサポートします。
|
||||
|
||||
## コンポーネントの追加
|
||||
|
||||
プラグインディレクトリでコマンドを実行します:
|
||||
|
||||
```bash
|
||||
lbp comp <component_type>
|
||||
```
|
||||
|
||||
例えば、イベントリスナーを追加する場合:
|
||||
|
||||
```bash
|
||||
lbp comp EventListener
|
||||
```
|
||||
|
||||
プロンプトに従って、コンポーネント設定(ある場合)を入力します。
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > lbp comp EventListener
|
||||
Generating component EventListener...
|
||||
Component EventListener generated successfully.
|
||||
組件 EventListener 生成成功。
|
||||
➜ HelloPlugin >
|
||||
```
|
||||
|
||||
:::info
|
||||
CLIはプラグインディレクトリに`components`ディレクトリを生成し、その中に対応するコンポーネントディレクトリを作成します。
|
||||
|
||||
```
|
||||
.
|
||||
├── assets
|
||||
│ └── icon.svg
|
||||
├── components
|
||||
│ ├── __init__.py
|
||||
│ └── event_listener
|
||||
│ ├── __init__.py
|
||||
│ ├── default.py
|
||||
│ └── default.yaml
|
||||
├── main.py
|
||||
├── manifest.yaml
|
||||
├── README.md
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
同時に、プラグインの`manifest.yaml`にコンポーネント検出設定が追加されます:
|
||||
|
||||
```yaml
|
||||
...
|
||||
components:
|
||||
EventListener:
|
||||
fromDirs:
|
||||
- path: components/event_listener/
|
||||
...
|
||||
```
|
||||
コンポーネントを削除するには、対応する情報を手動で削除できます。
|
||||
:::
|
||||
|
||||
## コンポーネントタイプ
|
||||
|
||||
各コンポーネントの詳細な使用方法については、次を参照してください:
|
||||
|
||||
- [EventListener](./event-listener.md)
|
||||
- [Command](./command.md)
|
||||
- [Tool](./tool.md)
|
||||
- [KnowledgeRetriever](./knowledge-retriever.md)
|
||||
@@ -0,0 +1,212 @@
|
||||
# コンポーネント: Command
|
||||
|
||||
Commandコンポーネントは、`!`(または他の設定されたプレフィックス)で始まるユーザーコマンドメッセージによってトリガーされます。`!help`コマンドをトリガーする例を次に示します:
|
||||
|
||||
<img width="600" src="/assets/image/zh/plugin/dev/components/command_use.png" />
|
||||
|
||||
## Commandコンポーネントの追加
|
||||
|
||||
1つのプラグインには任意の数のコマンドを含めることができます。プラグインディレクトリでコマンド`lbp comp Command`を実行し、プロンプトに従ってコマンド設定を入力します。
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > lbp comp Command
|
||||
Generating component Command...
|
||||
Command name: info
|
||||
Command description: Show information of the query
|
||||
Component Command generated successfully.
|
||||
組件 Command 生成成功。
|
||||
```
|
||||
|
||||
これにより、`components/commands/`ディレクトリに`info.yaml`と`info.py`ファイルが生成されます。`.yaml`ファイルは`!info`コマンドの基本情報を定義し、`.py`ファイルはコマンドハンドラです:
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > tree
|
||||
...
|
||||
├── components
|
||||
│ ├── __init__.py
|
||||
│ ├── commands
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── info.py
|
||||
│ │ └── info.yaml
|
||||
...
|
||||
```
|
||||
|
||||
## マニフェストファイル: Commandコンポーネント
|
||||
|
||||
```yaml
|
||||
apiVersion: v1 # 変更しないでください
|
||||
kind: Command # 変更しないでください
|
||||
metadata:
|
||||
name: info # コマンド名、ユーザーは!infoでこのコマンドをトリガーします
|
||||
label: # コマンド表示名、LangBot UIに表示、多言語対応
|
||||
en_US: Info
|
||||
zh_Hans: Info
|
||||
description: # コマンド説明、LangBot UIに表示、多言語対応。オプション。
|
||||
en_US: 'Show information of the query'
|
||||
zh_Hans: '発送此次消息的詳細信息'
|
||||
spec:
|
||||
execution:
|
||||
python:
|
||||
path: info.py # コマンドハンドラ、変更しないでください
|
||||
attr: Info # コマンドハンドラクラス名、info.pyのクラス名と一致
|
||||
```
|
||||
|
||||
## プラグイン処理
|
||||
|
||||
以下のコードがデフォルトで生成されます(components/command/<command_name>.py)。`Info`クラスの`initialize`メソッドでサブコマンド処理ロジックを登録して実装する必要があります。
|
||||
|
||||
```python
|
||||
# Auto generated by LangBot Plugin SDK.
|
||||
# Please refer to https://docs.langbot.app/en/plugin/dev/tutor.html for more details.
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, AsyncGenerator
|
||||
|
||||
from langbot_plugin.api.definition.components.command.command import Command, Subcommand
|
||||
from langbot_plugin.api.entities.builtin.command.context import ExecuteContext, CommandReturn
|
||||
|
||||
|
||||
class Info(Command):
|
||||
|
||||
async def initialize(self):
|
||||
await super().initialize()
|
||||
|
||||
"Fill with your code here"
|
||||
```
|
||||
|
||||
サブコマンドの追加:
|
||||
|
||||
```python
|
||||
...
|
||||
class Info(Command):
|
||||
|
||||
async def initialize(self):
|
||||
await super().initialize()
|
||||
|
||||
@self.subcommand(
|
||||
name="", # 空文字列はルートコマンドを表す
|
||||
help="Show information of the query", # コマンドヘルプ情報
|
||||
usage="info", # コマンド使用例、コマンドヘルプに表示
|
||||
aliases=["i"], # コマンドエイリアス
|
||||
)
|
||||
async def send(self, context: ExecuteContext) -> AsyncGenerator[CommandReturn, None]:
|
||||
print(context)
|
||||
|
||||
reply_text = f"Query ID: {context.query_id}\n"
|
||||
reply_text += f"command: {context.command}\n"
|
||||
reply_text += f"command_text: {context.command_text}\n"
|
||||
reply_text += f"params: {context.params}\n"
|
||||
reply_text += f"crt_params: {context.crt_params}\n"
|
||||
reply_text += f"privilege: {context.privilege}\n"
|
||||
reply_text += f"session: {context.session.launcher_type.value}_{context.session.launcher_id}\n"
|
||||
|
||||
yield CommandReturn(
|
||||
text=reply_text,
|
||||
)
|
||||
|
||||
@self.subcommand(
|
||||
name="field",
|
||||
help="Show information of the field",
|
||||
usage="info field",
|
||||
aliases=["f"],
|
||||
)
|
||||
async def field(self, context: ExecuteContext) -> AsyncGenerator[CommandReturn, None]:
|
||||
print(context)
|
||||
|
||||
field_name = context.crt_params[0]
|
||||
field_value = getattr(context, field_name)
|
||||
|
||||
yield CommandReturn(
|
||||
text=f"{field_name}: {field_value}",
|
||||
)
|
||||
```
|
||||
|
||||
このコードでは、`@self.subcommand`デコレータを通じて`send`関数がサブコマンドとして登録され、コマンドコンテキスト(ExecuteContext)情報を出力し、それを返信メッセージに連結します。
|
||||
|
||||
### サブコマンド登録
|
||||
|
||||
`name`はサブコマンド名です。空のままにすると、メインコマンドを処理することを意味します。空でない場合、2番目のパラメータをコマンドとして照合します。例えば:
|
||||
|
||||
- `!info`は、name=""のサブコマンドに一致
|
||||
- `!info field`は、name="field"のサブコマンドに一致
|
||||
- `!info field value`は、name="field"のサブコマンドに一致し、`value`がサブコマンドパラメータ
|
||||
- 特に、`name="*"`は、一致しないすべての第1レベルサブコマンドに一致し、`info`の後の各セクションをパラメータとして渡します。例えば`!info 123`、`!info abc`。ユーザーの入力に応じて、`context.crt_params`から`['123']`または`['abc']`を取得できます。
|
||||
|
||||
サブコマンド関数では、`context`変数を通じてコマンドパラメータを読み取ることができます。
|
||||
|
||||
上記のコマンドの効果は画像に示されています:
|
||||
|
||||
<img width="600" src="/assets/image/zh/plugin/dev/components/info_command_demo.png" />
|
||||
|
||||
### コマンドコンテキスト
|
||||
|
||||
```python
|
||||
|
||||
class ExecuteContext(pydantic.BaseModel):
|
||||
"""単一コマンド実行コンテキスト"""
|
||||
|
||||
query_id: int
|
||||
"""リクエストID"""
|
||||
|
||||
session: provider_session.Session
|
||||
"""このメッセージのセッションオブジェクト"""
|
||||
|
||||
command_text: str
|
||||
"""完全なコマンドテキスト"""
|
||||
|
||||
command: str
|
||||
"""コマンド名"""
|
||||
|
||||
crt_command: str
|
||||
"""現在のコマンド
|
||||
|
||||
マルチレベルコマンドでは、crt_commandは現在のコマンド、commandはルートコマンド。
|
||||
例: !plugin on Webwlkr
|
||||
pluginを処理する場合、commandはplugin、crt_commandはplugin
|
||||
onを処理する場合、commandはplugin、crt_commandはon
|
||||
"""
|
||||
|
||||
params: list[str]
|
||||
"""コマンドパラメータ
|
||||
|
||||
コマンド全体をスペースで分割した後のパラメータリスト
|
||||
"""
|
||||
|
||||
crt_params: list[str]
|
||||
"""現在のコマンドパラメータ
|
||||
|
||||
マルチレベルコマンドでは、crt_paramsは現在のコマンドパラメータ、paramsはルートコマンドパラメータ。
|
||||
例: !plugin on Webwlkr
|
||||
pluginを処理する場合、paramsは['on', 'Webwlkr']、crt_paramsは['on', 'Webwlkr']
|
||||
onを処理する場合、paramsは['on', 'Webwlkr']、crt_paramsは['Webwlkr']
|
||||
"""
|
||||
|
||||
privilege: int
|
||||
"""セッション権限レベル"""
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### コマンド戻り値
|
||||
|
||||
コマンド戻り値(CommandReturn)は、現在テキスト、画像(image_url、画像リンク)、エラーの返却をサポートしています。
|
||||
|
||||
```python
|
||||
yield CommandReturn(
|
||||
text=reply_text,
|
||||
)
|
||||
|
||||
yield CommandReturn(
|
||||
image_url=image_url,
|
||||
)
|
||||
```
|
||||
|
||||
コマンド処理は複数のメッセージを返すことをサポートしているため、`yield`ステートメントを使用してメッセージを返してください。
|
||||
|
||||
具体的な戻り値については、`CommandReturn`の定義を参照してください: [langbot_plugin.api.entities.builtin.command.context.CommandReturn](https://github.com/langbot-app/langbot-plugin-sdk/tree/main/src/langbot_plugin/api/entities/builtin/command/context.py)
|
||||
|
||||
## 次のステップ
|
||||
|
||||
コマンド登録とコマンド実行の基本情報を学びました。次は:
|
||||
|
||||
- [プラグイン共通API](/en/plugin/dev/apis/common)を確認してください
|
||||
@@ -0,0 +1,101 @@
|
||||
# コンポーネント: イベントリスナー
|
||||
|
||||
LangBotのパイプラインは実行時にイベントを生成し、プラグインがフックして処理できるようにします。各プラグインは1つのイベントリスナー(components/event_listener/default.yaml)のみを持つことができますが、その中で任意の数のイベントを登録できます。
|
||||
|
||||
## イベントリスナーコンポーネントの追加
|
||||
|
||||
プラグインディレクトリでコマンド`lbp comp EventListener`を実行します。イベントリスナーコンポーネントの作成には設定は必要ありません。
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > lbp comp EventListener
|
||||
Generating component EventListener...
|
||||
Component EventListener generated successfully.
|
||||
組件 EventListener 生成成功。
|
||||
```
|
||||
|
||||
これにより、`components/event_listener/`ディレクトリに`default.yaml`と`default.py`ファイルが生成されます。`.yaml`ファイルはイベントリスナーの基本情報を定義し、`.py`ファイルはイベントリスナーハンドラです:
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > tree
|
||||
...
|
||||
├── components
|
||||
│ ├── __init__.py
|
||||
│ └── event_listener
|
||||
│ ├── __init__.py
|
||||
│ ├── default.py
|
||||
│ └── default.yaml
|
||||
...
|
||||
```
|
||||
|
||||
## マニフェストファイル: イベントリスナー
|
||||
|
||||
各プラグインは1つのイベントリスナーのみを持つことができるため、マニフェストファイルでの変更は必要ありません。
|
||||
|
||||
## プラグイン処理
|
||||
|
||||
以下のコードがデフォルトで生成されます(components/event_listener/default.py)。`DefaultEventListener`クラスの`initialize`メソッドでイベント処理ロジックを登録して実装する必要があります。
|
||||
|
||||
```python
|
||||
# Auto generated by LangBot Plugin SDK.
|
||||
# Please refer to https://docs.langbot.app/en/plugin/dev/tutor.html for more details.
|
||||
from __future__ import annotations
|
||||
|
||||
from langbot_plugin.api.definition.components.common.event_listener import EventListener
|
||||
from langbot_plugin.api.entities import events, context
|
||||
|
||||
|
||||
class DefaultEventListener(EventListener):
|
||||
|
||||
async def initialize(self):
|
||||
await super().initialize()
|
||||
|
||||
"Fill with your code here"
|
||||
```
|
||||
|
||||
特定のイベントのリスナーを追加:
|
||||
|
||||
```python
|
||||
...
|
||||
class DefaultEventListener(EventListener):
|
||||
|
||||
async def initialize(self):
|
||||
await super().initialize()
|
||||
|
||||
@self.handler(events.PersonMessageReceived)
|
||||
async def handler(event_context: context.EventContext):
|
||||
print("Hello LangBot Plugin!")
|
||||
print(event_context)
|
||||
|
||||
await event_context.reply(
|
||||
platform_message.MessageChain([
|
||||
platform_message.Plain(text=f"Hello from Nahida Plugin!"),
|
||||
])
|
||||
)
|
||||
```
|
||||
|
||||
このコードは、`PersonMessageReceived`(プライベートチャットからのメッセージを受信)イベントのリスナーを登録し、イベントがトリガーされたときにイベントコンテキスト(EventContext)情報を出力し、イベントコンテキストAPIを呼び出してメッセージで返信します。
|
||||
|
||||
EventContextはこのイベントトリガーの共通コンテキスト情報を保存し、EventContext.eventはPersonMessageReceived(または他の対応するイベントタイプ)のオブジェクトで、イベントの詳細情報を保存します。
|
||||
|
||||
```python
|
||||
# EventContext定義の概要
|
||||
class EventContext(pydantic.BaseModel):
|
||||
"""イベントコンテキスト、このイベント実行の情報を保存"""
|
||||
...
|
||||
|
||||
event: pydantic.SerializeAsAny[BaseEventModel]
|
||||
"""イベントオブジェクト、具体的な型はハンドラ登録時に指定された型、events.pyで見つけることができます"""
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
## イベント登録
|
||||
|
||||
イベント登録は`@self.handler`デコレータを通じて実装され、デコレータのパラメータはイベントタイプです。監視可能なすべてのイベントは`langbot_plugin.api.entities.builtin.events`で定義されています。
|
||||
|
||||
## 次のステップ
|
||||
|
||||
イベントリスナーの基本情報を学びました。次は:
|
||||
|
||||
- ドキュメント[パイプラインイベント](/en/plugin/dev/apis/pipeline-events)で`監視可能なイベントのリスト`と`イベントコンテキストAPI`を確認してください
|
||||
- [プラグイン共通API](/en/plugin/dev/apis/common)を確認してください
|
||||
@@ -0,0 +1,264 @@
|
||||
# コンポーネント: ナレッジリトリーバー
|
||||
|
||||
ナレッジリトリーバーコンポーネントにより、プラグインはLangBotに外部ナレッジベース検索機能を提供できます。ユーザーがLangBotで外部ナレッジベースを作成する際、プラグインが提供するナレッジリトリーバーを選択してナレッジを検索できます。
|
||||
|
||||
<img width="600" src="/assets/image/zh/plugin/dev/components/knowledge_retriever_use.png" />
|
||||
|
||||
## ナレッジリトリーバーコンポーネントの追加
|
||||
|
||||
1つのプラグインには任意の数のナレッジリトリーバーを追加できます。プラグインディレクトリでコマンド`lbp comp KnowledgeRetriever`を実行し、プロンプトに従ってナレッジリトリーバーの設定を入力します。
|
||||
|
||||
```bash
|
||||
➜ FastGPTRetriever > lbp comp KnowledgeRetriever
|
||||
Generating component KnowledgeRetriever...
|
||||
KnowledgeRetriever name: fastgpt
|
||||
KnowledgeRetriever description: Retrieve knowledge from FastGPT knowledge bases
|
||||
Component KnowledgeRetriever generated successfully.
|
||||
```
|
||||
|
||||
これにより、`components/knowledge_retriever/`ディレクトリに`fastgpt.yaml`と`fastgpt.py`ファイルが生成されます。`.yaml`ファイルはナレッジリトリーバーの基本情報と設定パラメータを定義し、`.py`ファイルはこのリトリーバーのハンドラです:
|
||||
|
||||
```bash
|
||||
➜ FastGPTRetriever > tree
|
||||
...
|
||||
├── components
|
||||
│ ├── __init__.py
|
||||
│ └── knowledge_retriever
|
||||
│ ├── __init__.py
|
||||
│ ├── fastgpt.py
|
||||
│ └── fastgpt.yaml
|
||||
...
|
||||
```
|
||||
|
||||
## マニフェストファイル: ナレッジリトリーバー
|
||||
|
||||
```yaml
|
||||
apiVersion: v1 # 変更しないでください
|
||||
kind: KnowledgeRetriever # 変更しないでください
|
||||
metadata:
|
||||
name: fastgpt # ナレッジリトリーバー名、このリトリーバーを識別するために使用
|
||||
label:
|
||||
en_US: FastGPT Knowledge Base # リトリーバー表示名、LangBotのUIに表示、多言語対応
|
||||
zh_Hans: FastGPT 知識庫
|
||||
ja_JP: FastGPT ナレッジベース
|
||||
description:
|
||||
en_US: 'Retrieve knowledge from FastGPT knowledge bases' # リトリーバー説明、LangBotのUIに表示、多言語対応。オプション
|
||||
zh_Hans: '従 FastGPT 知識庫中検索知識'
|
||||
ja_JP: 'FastGPT ナレッジベースから知識を取得'
|
||||
icon: assets/icon.svg # リトリーバーアイコン、外部ナレッジベース設定ページに表示
|
||||
spec:
|
||||
config: # リトリーバー設定パラメータ、ユーザーは外部ナレッジベース作成時にこれらのパラメータを入力する必要があります
|
||||
- name: api_base_url # パラメータ名
|
||||
type: string # パラメータタイプ: string、number、boolean、select
|
||||
label:
|
||||
en_US: API Base URL
|
||||
zh_Hans: API 基礎地址
|
||||
ja_JP: API ベース URL
|
||||
description:
|
||||
en_US: 'Base URL for FastGPT API'
|
||||
zh_Hans: 'FastGPT API 基礎地址'
|
||||
ja_JP: 'FastGPT API ベース URL'
|
||||
default: 'http://localhost:3000' # デフォルトパラメータ値
|
||||
required: true # 必須かどうか
|
||||
- name: api_key
|
||||
type: string
|
||||
label:
|
||||
en_US: FastGPT API Key
|
||||
zh_Hans: FastGPT API Key
|
||||
ja_JP: FastGPT API キー
|
||||
description:
|
||||
en_US: 'API key from your FastGPT instance'
|
||||
zh_Hans: '従您的 FastGPT 実例獲取的 API Key'
|
||||
ja_JP: 'FastGPT インスタンスから取得した API Key'
|
||||
default: ''
|
||||
required: true
|
||||
- name: search_mode # select型パラメータの例
|
||||
type: select
|
||||
label:
|
||||
en_US: Search Mode
|
||||
zh_Hans: 搜索模式
|
||||
ja_JP: 検索モード
|
||||
description:
|
||||
en_US: 'The search method to use'
|
||||
zh_Hans: '使用的搜索方法'
|
||||
ja_JP: '使用する検索方法'
|
||||
default: 'embedding'
|
||||
options: # select型パラメータはオプションリストを定義する必要があります
|
||||
- name: 'embedding'
|
||||
label:
|
||||
en_US: 'Embedding Search'
|
||||
zh_Hans: '向量搜索'
|
||||
ja_JP: '埋め込み検索'
|
||||
- name: 'fullTextRecall'
|
||||
label:
|
||||
en_US: 'Full-Text Recall'
|
||||
zh_Hans: '全文検索'
|
||||
ja_JP: '全文検索'
|
||||
- name: using_rerank # boolean型パラメータの例
|
||||
type: boolean
|
||||
label:
|
||||
en_US: Use Re-ranking
|
||||
zh_Hans: 使用重排序
|
||||
ja_JP: リランキングを使用
|
||||
description:
|
||||
en_US: 'Whether to use re-ranking'
|
||||
zh_Hans: '是否使用重排序'
|
||||
ja_JP: 'リランキングを使用するかどうか'
|
||||
default: false
|
||||
required: false
|
||||
execution:
|
||||
python:
|
||||
path: fastgpt.py # リトリーバーハンドラ、変更しないでください
|
||||
attr: FastGPT # リトリーバーハンドラのクラス名、fastgpt.pyのクラス名と一致
|
||||
```
|
||||
|
||||
設定項目フォーマットのリファレンスについては、[プラグインマニフェスト設定フォーマット](/en/plugin/dev/basic-info)を参照してください。
|
||||
|
||||
## プラグインハンドラ
|
||||
|
||||
以下のコードがデフォルトで生成されます(components/knowledge_retriever/<retriever_name>.py)。`FastGPT`クラスの`retrieve`メソッドでナレッジ検索ロジックを実装する必要があります。完全なコードは[langbot-plugin-demo](https://github.com/langbot-app/langbot-plugin-demo)で見つけることができます。
|
||||
|
||||
```python
|
||||
# Auto generated by LangBot Plugin SDK.
|
||||
# Please refer to https://docs.langbot.app/en/plugin/dev/tutor.html for more details.
|
||||
...
|
||||
|
||||
class FastGPT(KnowledgeRetriever):
|
||||
|
||||
async def retrieve(self, context: RetrievalContext) -> list[RetrievalResultEntry]:
|
||||
"""FastGPTナレッジベースからナレッジを検索"""
|
||||
|
||||
# 1. 設定パラメータを取得
|
||||
api_base_url = self.config.get('api_base_url', 'http://localhost:3000')
|
||||
api_key = self.config.get('api_key')
|
||||
dataset_id = self.config.get('dataset_id')
|
||||
search_mode = self.config.get('search_mode', 'embedding')
|
||||
using_rerank = self.config.get('using_rerank', False)
|
||||
|
||||
# 2. パラメータ検証
|
||||
if not api_key or not dataset_id:
|
||||
logger.error("Missing required configuration: api_key or dataset_id")
|
||||
return []
|
||||
|
||||
# 3. APIリクエストを構築
|
||||
url = f"{api_base_url.rstrip('/')}/api/core/dataset/searchTest"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
payload = {
|
||||
"datasetId": dataset_id,
|
||||
"text": context.query, # RetrievalContextからクエリテキストを取得
|
||||
"searchMode": search_mode,
|
||||
"usingReRank": using_rerank,
|
||||
}
|
||||
|
||||
try:
|
||||
# 4. 外部APIを呼び出す
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(url, json=payload, headers=headers, timeout=30.0)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
# 5. レスポンスを解析してRetrievalResultEntryに変換
|
||||
results = []
|
||||
for record in result.get('data', []):
|
||||
# メインデータと補助データをコンテンツとして結合
|
||||
content_text = '\n'.join([
|
||||
record.get('q', ''),
|
||||
record.get('a', '')
|
||||
]).strip()
|
||||
|
||||
# 検索結果エントリを作成
|
||||
entry = RetrievalResultEntry(
|
||||
id=record.get('id', ''),
|
||||
content=[ContentElement.from_text(content_text)],
|
||||
metadata={
|
||||
'dataset_id': record.get('datasetId', ''),
|
||||
'source_name': record.get('sourceName', ''),
|
||||
'score': record.get('score', 0.0),
|
||||
},
|
||||
# 類似度スコアを距離に変換(スコアが高いほど距離が小さい)
|
||||
distance=1.0 - float(record.get('score', 0.0)),
|
||||
)
|
||||
results.append(entry)
|
||||
|
||||
logger.info(f"Retrieved {len(results)} chunks from FastGPT dataset {dataset_id}")
|
||||
return results
|
||||
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(f"HTTP error from FastGPT API: {e.response.status_code} - {e.response.text}")
|
||||
return []
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f"Request error when calling FastGPT API: {str(e)}")
|
||||
return []
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
logger.error(f"Unexpected error during retrieval: {str(e)}")
|
||||
return []
|
||||
```
|
||||
|
||||
### 検索コンテキスト
|
||||
|
||||
`RetrievalContext`にはこの検索のコンテキスト情報が含まれます:
|
||||
|
||||
```python
|
||||
class RetrievalContext(pydantic.BaseModel):
|
||||
"""ナレッジ検索コンテキスト"""
|
||||
|
||||
query: str
|
||||
"""クエリテキスト、ユーザーの検索質問"""
|
||||
```
|
||||
|
||||
### 検索結果
|
||||
|
||||
検索結果は`RetrievalResultEntry`オブジェクトのリストに変換する必要があり、各オブジェクトは検索されたナレッジチャンクを表します:
|
||||
|
||||
```python
|
||||
class RetrievalResultEntry(pydantic.BaseModel):
|
||||
"""単一検索結果エントリ"""
|
||||
|
||||
id: str
|
||||
"""結果ID、このエントリを一意に識別"""
|
||||
|
||||
content: list[ContentElement]
|
||||
"""結果コンテンツ、ContentElement.from_text()を使用してテキストコンテンツを作成"""
|
||||
|
||||
metadata: dict[str, Any]
|
||||
"""結果メタデータ、ソース、スコアなど、任意のキーと値のペアを含めることができます"""
|
||||
|
||||
distance: float
|
||||
"""距離スコア、クエリとの関連性を示します(小さいほど関連性が高い)
|
||||
通常は1.0 - similarity_scoreとして計算されます"""
|
||||
```
|
||||
|
||||
### 設定パラメータの取得
|
||||
|
||||
`self.config.get(パラメータ名, デフォルト値)`を使用して、ユーザーが設定したパラメータ値を取得します:
|
||||
|
||||
```python
|
||||
# 文字列パラメータを取得
|
||||
api_base_url = self.config.get('api_base_url', 'http://localhost:3000')
|
||||
|
||||
# 数値パラメータを取得
|
||||
limit = self.config.get('limit', 5000)
|
||||
similarity = self.config.get('similarity', 0.0)
|
||||
|
||||
# ブールパラメータを取得
|
||||
using_rerank = self.config.get('using_rerank', False)
|
||||
|
||||
# selectパラメータを取得
|
||||
search_mode = self.config.get('search_mode', 'embedding')
|
||||
```
|
||||
|
||||
## リトリーバーのテスト
|
||||
|
||||
作成後、プラグインディレクトリでコマンド`lbp run`を実行してデバッグを開始します。その後、LangBotで:
|
||||
|
||||
1. 「ナレッジベース」ページに移動
|
||||
2. 外部ナレッジベースを追加
|
||||
3. プラグインが提供するナレッジリトリーバーを選択し、設定を入力
|
||||
|
||||
<img width="600" src="/assets/image/zh/plugin/dev/components/knowledge_retriever_config.png" />
|
||||
|
||||
保存後、LangBotパイプラインでこのナレッジベースを選択できます。
|
||||
@@ -0,0 +1,174 @@
|
||||
# コンポーネント: Tool
|
||||
|
||||
LangBotの組み込みLocal Agentは、実行中にツールを呼び出して外部世界と対話します。現在、プラグインとMCPの両方を通じてツールを追加することがサポートされています。
|
||||
|
||||
## Toolコンポーネントの追加
|
||||
|
||||
1つのプラグインには任意の数のツールを含めることができます。プラグインディレクトリでコマンド`lbp comp Tool`を実行し、プロンプトに従ってツール設定を入力します。
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > lbp comp Tool
|
||||
Generating component Tool...
|
||||
Tool name: get_weather_alerts
|
||||
Tool description: Get weather alerts for a US state.
|
||||
Component Tool generated successfully.
|
||||
組件 Tool 生成成功。
|
||||
```
|
||||
|
||||
これにより、`components/tools/`ディレクトリに`get_weather_alerts.yaml`と`get_weather_alerts.py`ファイルが生成されます。`.yaml`ファイルはツールの基本情報を定義し、`.py`ファイルはツールハンドラです:
|
||||
|
||||
```bash
|
||||
➜ HelloPlugin > tree
|
||||
...
|
||||
├── components
|
||||
│ ├── __init__.py
|
||||
│ └── tools
|
||||
│ ├── __init__.py
|
||||
│ ├── get_weather_alerts.py
|
||||
│ └── get_weather_alerts.yaml
|
||||
...
|
||||
```
|
||||
|
||||
## マニフェストファイル: Tool
|
||||
|
||||
```yaml
|
||||
apiVersion: v1 # 変更しないでください
|
||||
kind: Tool # 変更しないでください
|
||||
metadata:
|
||||
name: get_weather_alerts # ツール名、LLM認識用
|
||||
label:
|
||||
en_US: GetWeatherAlerts # ツール表示名、LangBot UIに表示、多言語対応
|
||||
zh_Hans: GetWeatherAlerts
|
||||
description:
|
||||
en_US: 'Get weather alerts for a US state.' # ツール説明、LangBot UIに表示、多言語対応。オプション
|
||||
zh_Hans: '獲取美国某个州的天気預警'
|
||||
spec:
|
||||
parameters: [] # ツールパラメータ、会話コンテキストに基づいてLLMが生成する値
|
||||
llm_prompt: 'Get weather alerts for a US state.' # ツールプロンプト、LLMがこのツールを呼び出すかどうかを判断するため
|
||||
execution:
|
||||
python:
|
||||
path: get_weather_alerts.py # ツールハンドラ、変更しないでください
|
||||
attr: GetWeatherAlerts # ツールハンドラクラス名、get_weather_alerts.pyのクラス名と一致
|
||||
```
|
||||
|
||||
## プラグイン処理
|
||||
|
||||
以下のコードがデフォルトで生成されます(components/tools/<tool_name>.py)。`GetWeatherAlerts`クラスの`call`メソッドでこのツールの呼び出しと戻り値のロジックを実装する必要があります。
|
||||
|
||||
```python
|
||||
# Auto generated by LangBot Plugin SDK.
|
||||
# Please refer to https://docs.langbot.app/en/plugin/dev/tutor.html for more details.
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from langbot_plugin.api.definition.components.tool.tool import Tool
|
||||
from langbot_plugin.api.entities.builtin.provider import session as provider_session
|
||||
|
||||
|
||||
class GetWeatherAlerts(Tool):
|
||||
|
||||
async def call(self, params: dict[str, Any], session: provider_session.Session, query_id: int) -> str:
|
||||
"""Fill your tool code here"""
|
||||
return {}
|
||||
```
|
||||
|
||||
`call`メソッドでこのツールを実装します:
|
||||
|
||||
:::info
|
||||
天気検索ツールの例は、MCPの[サーバー作成例](https://modelcontextprotocol.io/quickstart/server)から来ています。
|
||||
:::
|
||||
|
||||
```python
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from langbot_plugin.api.definition.components.tool.tool import Tool
|
||||
from langbot_plugin.api.entities.builtin.provider import session as provider_session
|
||||
import httpx
|
||||
|
||||
# 定数
|
||||
NWS_API_BASE = "https://api.weather.gov"
|
||||
USER_AGENT = "weather-app/1.0"
|
||||
|
||||
|
||||
async def make_nws_request(url: str) -> dict[str, Any] | None:
|
||||
"""適切なエラー処理を使用してNWS APIにリクエストを行う。"""
|
||||
headers = {
|
||||
"User-Agent": USER_AGENT,
|
||||
"Accept": "application/geo+json"
|
||||
}
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url, headers=headers, timeout=30.0)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def format_alert(feature: dict) -> str:
|
||||
"""アラート機能を読みやすい文字列にフォーマットする。"""
|
||||
props = feature["properties"]
|
||||
return f"""
|
||||
Event: {props.get('event', 'Unknown')}
|
||||
Area: {props.get('areaDesc', 'Unknown')}
|
||||
Severity: {props.get('severity', 'Unknown')}
|
||||
Description: {props.get('description', 'No description available')}
|
||||
Instructions: {props.get('instruction', 'No specific instructions provided')}
|
||||
"""
|
||||
|
||||
class GetWeatherAlerts(Tool):
|
||||
|
||||
async def call(self, params: dict[str, Any], session: provider_session.Session, query_id: int) -> str:
|
||||
"""Fill your tool code here"""
|
||||
state = params.get("state", "CA")
|
||||
|
||||
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
|
||||
data = await make_nws_request(url)
|
||||
|
||||
if not data or "features" not in data:
|
||||
return "Unable to fetch alerts or no alerts found."
|
||||
|
||||
if not data["features"]:
|
||||
return "No active alerts for this state."
|
||||
|
||||
alerts = [format_alert(feature) for feature in data["features"]]
|
||||
return "\n---\n".join(alerts)
|
||||
```
|
||||
|
||||
このツールでは、`params`から`state`パラメータを取得し、NWS APIを呼び出してその州の天気アラートを取得する必要があるため、マニフェストファイルの`parameters`で`state`パラメータを定義する必要があります。
|
||||
|
||||
`parameters`フォーマットは[JSON Schema](https://json-schema.org/docs)に従い、[OpenAI Function Calling機能](https://platform.openai.com/docs/guides/function-calling#defining-functions)でサポートされており、そのルートタイプは`type: object`に固定されています。`properties`にパラメータを追加し、`required`に必須パラメータの説明を追加してください。
|
||||
|
||||
```yaml
|
||||
...
|
||||
spec:
|
||||
parameters:
|
||||
type: object # 変更しないでください
|
||||
properties: # 変更しないでください、ここにパラメータを追加
|
||||
state:
|
||||
type: string
|
||||
description: 'Two-letter US state code (e.g. CA, NY)'
|
||||
required: # ここに必須パラメータの説明を追加
|
||||
- state
|
||||
...
|
||||
```
|
||||
|
||||
このツールは`httpx`ライブラリも使用しているため、プラグインディレクトリの`requirements.txt`に`httpx`依存関係を追加する必要があります。
|
||||
|
||||
```txt
|
||||
# HelloPlugin/requirements.txt
|
||||
langbot-plugin # デフォルトで既に存在
|
||||
httpx
|
||||
```
|
||||
|
||||
次に、プラグインディレクトリでコマンド`lbp run`を実行してデバッグを開始します。LangBotでツール呼び出しをサポートするモデルを設定し、対応するパイプラインでそのモデルの使用を選択してこのツールを使用します。
|
||||
|
||||
<img width="600" src="/assets/image/zh/plugin/dev/components/tool_use_in_chat.png" />
|
||||
|
||||
## 次のステップ
|
||||
|
||||
ツールの基本的な使い方を学びました。次は:
|
||||
|
||||
- [プラグイン共通API](/en/plugin/dev/apis/common)を確認してください
|
||||
Reference in New Issue
Block a user