mirror of
https://github.com/langgenius/dify-docs.git
synced 2026-07-22 12:25:45 -04:00
438 lines
18 KiB
Plaintext
438 lines
18 KiB
Plaintext
---
|
|
dimensions:
|
|
type:
|
|
primary: implementation
|
|
detail: high
|
|
level: intermediate
|
|
standard_title: Agent
|
|
language: ja
|
|
title: Agent
|
|
description: このドキュメントでは、DifyのAgent戦略プラグインの開発プロセスについて詳しく説明します。ManifestファイルへのAgent戦略フィールドの追加、Agentプロバイダーの定義、Agent戦略を実装するためのコアステップが含まれます。パラメータの取得、モデルの呼び出し、ツールの呼び出し、ログの生成と管理に関する完全なサンプルコードも詳細に解説しています。
|
|
---
|
|
|
|
Agent戦略は、標準の入力内容と出力形式を定義する拡張可能なテンプレートです。具体的なAgent戦略インターフェースの機能コードを開発することで、CoT(思考の連鎖)/ ToT(思考の木)/ GoT(思考のグラフ)/ BoT(思考の骨格)など、さまざまなAgent戦略を実現し、[Sementic Kernel](https://learn.microsoft.com/en-us/semantic-kernel/overview/) のような複雑な戦略を実装できます。
|
|
|
|
### Manifest内へのフィールド追加
|
|
|
|
プラグインにAgent戦略を追加するには、`manifest.yaml`ファイル内に`plugins.agent_strategies`フィールドを新たに追加し、Agentプロバイダーも定義する必要があります。サンプルコードは以下の通りです。
|
|
|
|
```yaml
|
|
version: 0.0.2
|
|
type: plugin
|
|
author: "langgenius"
|
|
name: "agent"
|
|
plugins:
|
|
agent_strategies:
|
|
- "provider/agent.yaml"
|
|
```
|
|
|
|
ここでは、`manifest`ファイル内の一部の無関係なフィールドは省略されています。Manifestの詳細な形式については、[マニフェストファイルによるプラグイン情報の定義](/plugin-dev-ja/0411-plugin-info-by-manifest)ドキュメントを参照してください。
|
|
|
|
### Agentプロバイダーの定義
|
|
|
|
次に、`agent.yaml`ファイルを新規作成し、基本的なAgentプロバイダー情報を入力する必要があります。
|
|
|
|
```yaml
|
|
identity:
|
|
author: langgenius
|
|
name: agent
|
|
label:
|
|
en_US: Agent
|
|
zh_Hans: Agent
|
|
pt_BR: Agent
|
|
description:
|
|
en_US: Agent
|
|
zh_Hans: Agent
|
|
pt_BR: Agent
|
|
icon: icon.svg
|
|
strategies:
|
|
- strategies/function_calling.yaml
|
|
```
|
|
|
|
主にいくつかの記述的な基本情報を含み、現在のプロバイダーがどの戦略を含むかを指定します。上記のサンプルコードでは、最も基本的な`function_calling.yaml`戦略ファイルのみが指定されています。
|
|
|
|
### Agent戦略の定義と実装
|
|
|
|
#### 定義
|
|
|
|
次に、Agent戦略を実現できるコードを定義する必要があります。`function_calling.yaml`ファイルを新規作成します:
|
|
|
|
```yaml
|
|
identity:
|
|
name: function_calling
|
|
author: Dify
|
|
label:
|
|
en_US: FunctionCalling
|
|
zh_Hans: FunctionCalling
|
|
pt_BR: FunctionCalling
|
|
description:
|
|
en_US: Function Calling is a basic strategy for agent, model will use the tools provided to perform the task.
|
|
zh_Hans: Function Callingは基本的なAgent戦略であり、モデルは提供されたツールを使用してタスクを実行します。
|
|
pt_BR: Function Calling is a basic strategy for agent, model will use the tools provided to perform the task.
|
|
parameters:
|
|
- name: model
|
|
type: model-selector
|
|
scope: tool-call&llm
|
|
required: true
|
|
label:
|
|
en_US: Model
|
|
zh_Hans: モデル
|
|
pt_BR: Model
|
|
- name: tools
|
|
type: array[tools]
|
|
required: true
|
|
label:
|
|
en_US: Tools list
|
|
zh_Hans: ツールリスト
|
|
pt_BR: Tools list
|
|
- name: query
|
|
type: string
|
|
required: true
|
|
label:
|
|
en_US: Query
|
|
zh_Hans: ユーザーの質問
|
|
pt_BR: Query
|
|
- name: max_iterations
|
|
type: number
|
|
required: false
|
|
default: 5
|
|
label:
|
|
en_US: Max Iterations
|
|
zh_Hans: 最大反復回数
|
|
pt_BR: Max Iterations
|
|
max: 50
|
|
min: 1
|
|
extra:
|
|
python:
|
|
source: strategies/function_calling.py
|
|
```
|
|
|
|
コード形式は[`Tool`標準形式](tool.md)に似ており、`model`、`tools`、`query`、`max_iterations`など合計4つのパラメータを定義し、最も基本的なAgent戦略の実装を容易にします。このコードの意味は、ユーザーがモデルと使用するツールを選択し、最大反復回数を設定し、最終的にqueryを渡してAgentの実行を開始できるようにすることです。
|
|
|
|
#### 機能実装コードの作成
|
|
|
|
**パラメータの取得**
|
|
|
|
上記で定義された4つのパラメータに基づき、`model`タイプのパラメータは`model-selector`であり、`tool`タイプのパラメータは特殊な`array[tools]`です。パラメータで取得された形式は、SDKに組み込まれている`AgentModelConfig`と`list[ToolEntity]`を使用して変換できます。
|
|
|
|
```python
|
|
from dify_plugin.interfaces.agent import AgentModelConfig, AgentStrategy, ToolEntity
|
|
|
|
class FunctionCallingParams(BaseModel):
|
|
query: str
|
|
model: AgentModelConfig
|
|
tools: list[ToolEntity] | None
|
|
maximum_iterations: int = 3
|
|
|
|
class FunctionCallingAgentStrategy(AgentStrategy):
|
|
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
|
|
"""
|
|
Run FunctionCall agent application
|
|
"""
|
|
fc_params = FunctionCallingParams(**parameters)
|
|
```
|
|
|
|
**モデルの呼び出し**
|
|
|
|
指定されたモデルの呼び出しは、Agentプラグインに不可欠な機能です。SDK内の`session.model.invoke()`関数を使用してモデルを呼び出します。`model`から必要な入力パラメータを取得できます。
|
|
|
|
`invoke model`のメソッドシグネチャのサンプルコード:
|
|
|
|
```python
|
|
def invoke(
|
|
self,
|
|
model_config: LLMModelConfig,
|
|
prompt_messages: list[PromptMessage],
|
|
tools: list[PromptMessageTool] | None = None,
|
|
stop: list[str] | None = None,
|
|
stream: bool = True,
|
|
) -> Generator[LLMResultChunk, None, None] | LLMResult:
|
|
```
|
|
|
|
モデル情報`model_config`、プロンプト情報`prompt_messages`、およびツール情報`tools`を渡す必要があります。
|
|
|
|
そのうち`prompt_messages`パラメータは以下のサンプルコードを参照して呼び出すことができますが、`tool_messages`は一定の変換が必要です。
|
|
|
|
`invoke model`の使用方法のサンプルコードを参照してください:
|
|
|
|
```python
|
|
from collections.abc import Generator
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel
|
|
|
|
from dify_plugin.entities.agent import AgentInvokeMessage
|
|
from dify_plugin.entities.model.llm import LLMModelConfig
|
|
from dify_plugin.entities.model.message import (
|
|
PromptMessageTool,
|
|
SystemPromptMessage,
|
|
UserPromptMessage,
|
|
)
|
|
from dify_plugin.entities.tool import ToolParameter
|
|
from dify_plugin.interfaces.agent import AgentModelConfig, AgentStrategy, ToolEntity
|
|
|
|
class FunctionCallingParams(BaseModel):
|
|
query: str
|
|
instruction: str | None
|
|
model: AgentModelConfig
|
|
tools: list[ToolEntity] | None
|
|
maximum_iterations: int = 3
|
|
|
|
class FunctionCallingAgentStrategy(AgentStrategy):
|
|
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
|
|
"""
|
|
Run FunctionCall agent application
|
|
"""
|
|
# init params
|
|
fc_params = FunctionCallingParams(**parameters)
|
|
query = fc_params.query
|
|
model = fc_params.model
|
|
stop = fc_params.model.completion_params.get("stop", []) if fc_params.model.completion_params else []
|
|
prompt_messages = [
|
|
SystemPromptMessage(content="あなたのシステムプロンプトメッセージ"),
|
|
UserPromptMessage(content=query),
|
|
]
|
|
tools = fc_params.tools
|
|
prompt_messages_tools = self._init_prompt_tools(tools)
|
|
|
|
# invoke llm
|
|
chunks = self.session.model.llm.invoke(
|
|
model_config=LLMModelConfig(**model.model_dump(mode="json")),
|
|
prompt_messages=prompt_messages,
|
|
stream=True,
|
|
stop=stop,
|
|
tools=prompt_messages_tools,
|
|
)
|
|
|
|
def _init_prompt_tools(self, tools: list[ToolEntity] | None) -> list[PromptMessageTool]:
|
|
"""
|
|
Init tools
|
|
"""
|
|
|
|
prompt_messages_tools = []
|
|
for tool in tools or []:
|
|
try:
|
|
prompt_tool = self._convert_tool_to_prompt_message_tool(tool)
|
|
except Exception:
|
|
# APIツールは削除された可能性があります
|
|
continue
|
|
|
|
# save prompt tool
|
|
prompt_messages_tools.append(prompt_tool)
|
|
|
|
return prompt_messages_tools
|
|
|
|
def _convert_tool_to_prompt_message_tool(self, tool: ToolEntity) -> PromptMessageTool:
|
|
"""
|
|
convert tool to prompt message tool
|
|
"""
|
|
message_tool = PromptMessageTool(
|
|
name=tool.identity.name,
|
|
description=tool.description.llm if tool.description else "",
|
|
parameters={
|
|
"type": "object",
|
|
"properties": {},
|
|
"required": [],
|
|
},
|
|
)
|
|
|
|
parameters = tool.parameters
|
|
for parameter in parameters:
|
|
if parameter.form != ToolParameter.ToolParameterForm.LLM:
|
|
continue
|
|
|
|
parameter_type = parameter.type
|
|
if parameter.type in {
|
|
ToolParameter.ToolParameterType.FILE,
|
|
ToolParameter.ToolParameterType.FILES,
|
|
}:
|
|
continue
|
|
enum = []
|
|
if parameter.type == ToolParameter.ToolParameterType.SELECT:
|
|
enum = [option.value for option in parameter.options] if parameter.options else []
|
|
|
|
message_tool.parameters["properties"][parameter.name] = {
|
|
"type": parameter_type,
|
|
"description": parameter.llm_description or "",
|
|
}
|
|
|
|
if len(enum) > 0:
|
|
message_tool.parameters["properties"][parameter.name]["enum"] = enum
|
|
|
|
if parameter.required:
|
|
message_tool.parameters["required"].append(parameter.name)
|
|
|
|
return message_tool
|
|
|
|
```
|
|
|
|
**ツールの呼び出し**
|
|
|
|
ツールの呼び出しもAgentプラグインに不可欠な機能です。`self.session.tool.invoke()`を使用して呼び出すことができます。`invoke tool`のメソッドシグネチャのサンプルコード:
|
|
|
|
```python
|
|
def invoke(
|
|
self,
|
|
provider_type: ToolProviderType,
|
|
provider: str,
|
|
tool_name: str,
|
|
parameters: dict[str, Any],
|
|
) -> Generator[ToolInvokeMessage, None, None]
|
|
```
|
|
|
|
必須パラメータは`provider_type`、`provider`、`tool_name`、`parameters`です。そのうち`tool_name`と`parameters`は、Function CallingではLLMによって生成されることがよくあります。`invoke tool`の使用例コード:
|
|
|
|
```python
|
|
from dify_plugin.entities.tool import ToolProviderType
|
|
|
|
class FunctionCallingAgentStrategy(AgentStrategy):
|
|
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
|
|
"""
|
|
Run FunctionCall agent application
|
|
"""
|
|
fc_params = FunctionCallingParams(**parameters)
|
|
|
|
# tool_call_name and tool_call_args parameter is obtained from the output of LLM
|
|
tool_instances = {tool.identity.name: tool for tool in fc_params.tools} if fc_params.tools else {}
|
|
tool_instance = tool_instances[tool_call_name]
|
|
tool_invoke_responses = self.session.tool.invoke(
|
|
provider_type=ToolProviderType.BUILT_IN,
|
|
provider=tool_instance.identity.provider,
|
|
tool_name=tool_instance.identity.name,
|
|
# デフォルト値を追加
|
|
parameters={**tool_instance.runtime_parameters, **tool_call_args},
|
|
)
|
|
```
|
|
|
|
`self.session.tool.invoke()`関数の出力はGeneratorであり、同様にストリーミング解析が必要であることを意味します。
|
|
|
|
解析方法については、以下の関数を参照してください:
|
|
|
|
```python
|
|
import json
|
|
from collections.abc import Generator
|
|
from typing import cast
|
|
|
|
from dify_plugin.entities.agent import AgentInvokeMessage
|
|
from dify_plugin.entities.tool import ToolInvokeMessage
|
|
|
|
def parse_invoke_response(tool_invoke_responses: Generator[AgentInvokeMessage]) -> str:
|
|
result = ""
|
|
for response in tool_invoke_responses:
|
|
if response.type == ToolInvokeMessage.MessageType.TEXT:
|
|
result += cast(ToolInvokeMessage.TextMessage, response.message).text
|
|
elif response.type == ToolInvokeMessage.MessageType.LINK:
|
|
result += (
|
|
f"結果リンク: {cast(ToolInvokeMessage.TextMessage, response.message).text}。"
|
|
+ " ユーザーに確認するよう伝えてください。"
|
|
)
|
|
elif response.type in {
|
|
ToolInvokeMessage.MessageType.IMAGE_LINK,
|
|
ToolInvokeMessage.MessageType.IMAGE,
|
|
}:
|
|
result += (
|
|
"画像は既に作成されユーザーに送信済みです。"
|
|
+ "作成する必要はありません。ユーザーに今すぐ確認するよう伝えてください。"
|
|
)
|
|
elif response.type == ToolInvokeMessage.MessageType.JSON:
|
|
text = json.dumps(cast(ToolInvokeMessage.JsonMessage, response.message).json_object, ensure_ascii=False)
|
|
result += f"ツール応答: {text}。"
|
|
else:
|
|
result += f"ツール応答: {response.message!r}。"
|
|
return result
|
|
```
|
|
|
|
#### Log
|
|
|
|
Agentの思考プロセスを確認したい場合、正常に返されたメッセージを確認する以外に、専用のインターフェースを使用してAgent全体の思考プロセスをツリー構造で表示することもできます。
|
|
|
|
**ログの作成**
|
|
|
|
* このインターフェースは`AgentLogMessage`を作成して返します。このMessageはログ内のツリーのノードを表します。
|
|
* `parent`が渡された場合、そのノードは親ノードを持つことを示します。
|
|
* ステータスはデフォルトで"Success"(成功)です。ただし、タスクの実行プロセスをよりよく表示したい場合は、まずステータスを"start"に設定して「実行中」のログを表示し、タスク完了後にそのログのステータスを"Success"に更新することができます。これにより、ユーザーはタスクの開始から完了までの全プロセスを明確に確認できます。
|
|
* `label`は、最終的にユーザーにログのタイトルを表示するために使用されます。
|
|
|
|
```python
|
|
def create_log_message(
|
|
self,
|
|
label: str,
|
|
data: Mapping[str, Any],
|
|
status: AgentInvokeMessage.LogMessage.LogStatus = AgentInvokeMessage.LogMessage.LogStatus.SUCCESS,
|
|
parent: AgentInvokeMessage | None = None,
|
|
) -> AgentInvokeMessage
|
|
```
|
|
|
|
**ログの完了**
|
|
|
|
前のステップで開始ステータスとして`start`状態を選択した場合、ログ完了インターフェースを使用してステータスを変更できます。
|
|
|
|
```python
|
|
def finish_log_message(
|
|
self,
|
|
log: AgentInvokeMessage,
|
|
status: AgentInvokeMessage.LogMessage.LogStatus = AgentInvokeMessage.LogMessage.LogStatus.SUCCESS,
|
|
error: Optional[str] = None,
|
|
) -> AgentInvokeMessage
|
|
```
|
|
|
|
**インスタンス**
|
|
|
|
この例では、単純な2ステップの実行プロセスを示しています。まず「思考中」のステータスログを出力し、次に実際のタスク処理を完了します。
|
|
|
|
```python
|
|
class FunctionCallingAgentStrategy(AgentStrategy):
|
|
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
|
|
thinking_log = self.create_log_message(
|
|
data={
|
|
"Query": parameters.get("query"),
|
|
},
|
|
label="思考中",
|
|
status=AgentInvokeMessage.LogMessage.LogStatus.START,
|
|
)
|
|
|
|
yield thinking_log
|
|
|
|
llm_response = self.session.model.llm.invoke(
|
|
model_config=LLMModelConfig(
|
|
provider="openai",
|
|
model="gpt-4o-mini",
|
|
mode="chat",
|
|
completion_params={},
|
|
),
|
|
prompt_messages=[
|
|
SystemPromptMessage(content="あなたは役立つアシスタントです"),
|
|
UserPromptMessage(content=parameters.get("query")),
|
|
],
|
|
stream=False,
|
|
tools=[],
|
|
)
|
|
|
|
thinking_log = self.finish_log_message(
|
|
log=thinking_log,
|
|
)
|
|
|
|
yield thinking_log
|
|
|
|
yield self.create_text_message(text=llm_response.message.content)
|
|
```
|
|
|
|
## 関連リソース
|
|
|
|
- [プラグイン開発の基本概念](/plugin-dev-ja/0111-getting-started-dify-plugin) - プラグイン開発の全体的なアーキテクチャを理解する
|
|
- [Agent戦略プラグイン開発例](/plugin-dev-ja/9433-agent-strategy-plugin) - 実際のAgent戦略プラグイン開発例
|
|
- [マニフェストファイルによるプラグイン情報の定義](/plugin-dev-ja/0411-plugin-info-by-manifest) - Manifestファイルの詳細な形式を理解する
|
|
- [モデルの逆呼び出し](/plugin-dev-ja/9242-reverse-invocation-model) - プラットフォーム内のモデル機能を呼び出す方法を理解する
|
|
- [ツールの逆呼び出し](/plugin-dev-ja/9242-reverse-invocation-tool) - 他のプラグインを呼び出す方法を理解する
|
|
|
|
{/*
|
|
Contributing Section
|
|
DO NOT edit this section!
|
|
It will be automatically generated by the script.
|
|
*/}
|
|
|
|
---
|
|
|
|
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/plugin-dev-ja/9232-agent.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
|
|