Dify中的Agent策略插件开发例子:以Function Calling为例
本文使用Dify v1.0.0-beta.1版本。Agent 策略插件能够帮助 LLM 执行推理或决策逻辑,包括工具选择、调用和结果处理,以更加自动化的方式处理问题。Dify官方实现的Agent策略插件包括Function Calling和Reason+ReAct(Reason+Act)。本文重点介绍Function Calling具体实现。
一.初始化插件模板
1.初始化Agent插件模板
运行以下命令,初始化 Agent 插件开发模板。如下所示:



2.填写或选择配置信息
按照页面提示,填写或选择对应信息。如下所示:


3.Agent插件模板代码结构
初始化插件模板后将生成一个代码文件夹,包含插件开发过程中所需的完整资源。熟悉 Agent 策略插件的整体代码结构有助于插件的开发过程。插件的功能代码集中在 strategies/ 目录内。

二.开发插件功能
Agent 策略插件的开发主要围绕以下两个文件展开:
- 插件声明文件:
strategies/function_calling.yaml - 插件功能代码:
strategies/function_calling.py
1.定义参数
要创建一个Agent插件,首先需要在 strategies/function_calling.yaml 文件中定义插件所需的参数。这些参数决定了插件的核心功能,比如调用 LLM 模型和使用工具的能力。
官方建议优先配置以下五个基础参数:
- model:指定要调用的大语言模型(LLM),如 GPT-4o、DeepSeek-V3 等。
- tools:定义插件可以使用的工具列表,增强插件功能。
- instruction:提供初始的系统提示消息内容,帮助模型理解和执行任务。
- query:设置与模型交互的提示词或输入内容。
- maximum_iterations:限制插件执行的最大迭代次数,避免过度计算。
完成参数配置后,插件将在自动生成相应的设置的使用页面,方便进行直观、便捷的调整和使用。

2.获取参数并执行
接下来需要先在 strategies/function_calling.py 文件内定义 Agent 参数类供后续使用。校验传入参数,如下所示:
`from dify_plugin.entities.agent import AgentInvokeMessage
from dify_plugin.interfaces.agent import AgentModelConfig, AgentStrategy, ToolEntity
from pydantic import BaseModel
class FunctionCallingParams(BaseModel):
query: str
instruction: str | None
model: AgentModelConfig
tools: list[ToolEntity] | None
maximum_iterations: int = 3
`
获取参数后,执行具体的业务逻辑,如下所示:
`class FunctionCallingAgentStrategy(AgentStrategy):
def init(self, session):
super().init(session)
self.query = ""
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
"""
Run FunctionCall agent application
"""
fc_params = FunctionCallingParams(**parameters)
......
`
3.调用模型
在 Agent 策略插件中,调用模型是核心执行逻辑之一。可以通过 SDK 提供的 session.model.llm.invoke() 方法高效地调用 LLM 模型,实现文本生成、对话处理等功能。
def invoke( self, model_config: LLMModelConfig | dict, 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:工具信息(Function Calling 相关)
- stop:停止符
- stream:是否支持流式输出
这样就实现了以下功能:用户输入指令后,Agent 策略插件会自动调用 LLM,根据生成结果构建并传递工具调用所需的参数,使模型能够灵活调度已接入的工具,高效完成复杂任务。

4.调用工具
填写工具参数后,需赋予 Agent 策略插件实际调用工具的能力。可以通过 SDK 中的session.tool.invoke() 函数进行工具调用。构造参数如下所示:
- provider_type:提供商类型
- provider:提供商
- tool_name:工具名称
- parameters:输入参数
def invoke( self, provider_type: ToolProviderType, provider: str, tool_name: str, parameters: dict[str, Any], ) -> Generator[ToolInvokeMessage, None, None]: """ Invoke tool """ return self._backwards_invoke( InvokeType.Tool, ToolInvokeMessage, { "tool_type": provider_type.value, "provider": provider, "tool": tool_name, "tool_parameters": parameters, }, )
若希望通过 LLM 直接生成参数完成工具调用,可参考以下工具调用的示例代码:
tool_instances = ( {tool.identity.name: tool for tool in params.tools} if params.tools else {} ) for tool_call_id, tool_call_name, tool_call_args in tool_calls: tool_instance = tool_instances[tool_call_name] 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}, )
实现这部分功能代码后,Agent策略插件将具备自动Function Calling的能力,比如自动获取当前时间。如下所示:

5.日志创建
在 Agent 策略插件中,通常需要执行多轮操作才能完成复杂任务。记录每轮操作的执行结果对于开发者来说非常重要,有助于追踪 Agent 的执行过程、分析每一步的决策依据,从而更好地评估和优化策略效果。
为了实现这一功能,可以利用 SDK 中的 create_log_message 和 finish_log_message 方法记录日志。这种方式不仅可以在模型调用前后实时记录操作状态,还能帮助开发者快速定位问题。
日志创建具体使用场景示例,如下所示:
- 在模型调用之前,记录一条”开始调用模型”的日志,帮助开发者明确任务执行进度。
- 在模型调用成功后,记录一条”调用成功”的日志,方便追踪模型响应的完整性。
model_log = self.create_log_message( label=f"{params.model.model} Thought", data={}, metadata={"start_at": model_started_at, "provider": params.model.provider}, status=ToolInvokeMessage.LogMessage.LogStatus.START, ) yield model_log self.session.model.llm.invoke(...) yield self.finish_log_message( log=model_log, data={ "output": response, "tool_name": tool_call_names, "tool_input": tool_call_inputs, }, metadata={ "started_at": model_started_at, "finished_at": time.perf_counter(), "elapsed_time": time.perf_counter() - model_started_at, "provider": params.model.provider, }, )
设置完成后,工作流日志将输出执行结果,如下所示:

三.调试、打包和发布插件
1.调试插件
首先将插件运行起来,如下所示:


然后就可以看到带有DEBUGGING PLUGIN标识的function_calling插件,如下所示:


2.打包和发布插件
具体操作不再赘述,详细参考文献[4]。
四.FunctionCallingAgentStrategy类的方法
1.类的方法总结
| 方法名称 | 方法功能解析 | 输入参数及解释 | 输出参数及解释 |
|---|---|---|---|
| __init__ | 初始化FunctionCallingAgentStrategy类 | session : 会话对象 | 无 |
| _invoke | 运行 FunctionCall 代理应用程序 | parameters : 参数字典 | Generator[AgentInvokeMessage] : 代理调用消息生成器 |
| check_tool_calls | 检查 LLM 结果块中是否有工具调用 | llm_result_chunk : LLM 结果块 | bool : 是否有工具调用 |
| check_blocking_tool_calls | 检查 LLM 结果中是否有阻塞工具调用 | llm_result : LLM 结果 | bool : 是否有阻塞工具调用 |
| extract_tool_calls | 从 LLM 结果块中提取工具调用 | llm_result_chunk : LLM 结果块 | list[tuple[str, str, dict[str, Any]]] : 工具调用列表 |
| extract_blocking_tool_calls | 从 LLM 结果中提取阻塞工具调用 | llm_result : LLM 结果 | list[tuple[str, str, dict[str, Any]]] : 阻塞工具调用列表 |
| _init_system_message | 初始化系统消息 | prompt_template : 提示模板prompt_messages: 提示消息列表 | list[PromptMessage] : 提示消息列表 |
| _organize_user_query | 组织用户查询 | query : 查询字符串prompt_messages: 提示消息列表 | list[PromptMessage] : 提示消息列表 |
| _clear_user_prompt_image_messages | 清除用户提示中的图像消息 | prompt_messages : 提示消息列表 | list[PromptMessage] : 提示消息列表 |
| _organize_prompt_messages | 组织提示消息 | current_thoughts : 当前思路列表history_prompt_messages: 历史提示消息列表 | list[PromptMessage] : 提示消息列表 |
2._invoke()执行过程
FunctionCallingAgentStrategy类中的_invoke方法是一个核心方法,用于实现基于大语言模型(LLM)的多轮工具调用代理策略。以下是该方法的详细执行过程分析:
2.1 参数解析与初始化
- 输入参数:接收字典参数并转换为
FunctionCallingParams对象,包含:query: 用户原始查询instruction: 系统级指令(可选)model: 模型配置(如模型名称、供应商、参数等)tools: 可用工具列表(每个工具包含名称、参数、供应商等信息)maximum_iterations: 最大迭代轮次(默认3次)
- 初始化:
- 初始化迭代步数
iteration_step和最大迭代步数max_iteration_steps。 current_thoughts: 存储每轮的模型响应和工具调用结果。function_call_state: 标记是否仍需工具调用。- 初始化LLM使用量
llm_usage和最终答案final_answer。 - 构建初始系统提示消息(
SystemPromptMessage)。 - 将工具列表转换为字典格式,便于后续通过工具名称快速查找。
- 转换工具信息为模型需要的格式(
prompt_messages_tools),用于告知LLM可用工具。 - 初始化关键变量:
- 初始化迭代步数
2.2 多轮迭代处理
通过while循环进行多轮处理,直到无工具调用或达到最大轮次。
(1)单轮初始化
- 生成本轮开始的日志消息(
round_log)。 - 若为最后一轮,清空工具列表,强制模型生成最终回答。
- 组织当前提示消息(
prompt_messages):- 合并历史消息、用户查询和当前思考。
- 首次迭代后,清理用户消息中的图片内容(仅保留文本占位符)。
(2)调用LLM模型
- 调整模型的
max_tokens参数,确保不超过模型限制。 - 流式处理(
stream=True):- 逐块处理响应(
LLMResultChunk),实时检测工具调用。 - 收集响应内容(
response)和工具调用信息(tool_calls)。
- 逐块处理响应(
- 非流式处理:
- 直接处理完整响应(
LLMResult),提取工具调用和内容。
- 直接处理完整响应(
- 记录资源使用情况(
llm_usage)。
(3)工具调用处理
- 提取工具调用:
- 解析LLM响应中的工具调用信息(
tool_call_id,tool_call_name,tool_call_args)。 - 若存在工具调用,设置
function_call_state=True,触发后续处理。
- 解析LLM响应中的工具调用信息(
- 执行工具调用:
- 遍历每个工具调用,生成工具调用日志。
- 通过
session.tool.invoke实际调用工具,处理可能的多种返回类型(文本、链接、图片等)。 - 收集工具结果,构建
ToolPromptMessage并添加到current_thoughts,供下轮使用。
(4)本轮收尾
- 更新提示消息中的工具信息(如参数变化)。
- 生成本轮结束日志,包含响应内容、工具结果、耗时和资源消耗。
2.3 最终结果与资源统计
- 当所有迭代完成,生成包含总资源消耗的JSON消息:
total_price: 累计费用。currency: 费用单位。total_tokens: 总令牌数。
3.关键辅助方法
check_tool_calls/check_blocking_tool_calls: 检测响应中是否存在工具调用。extract_tool_calls/extract_blocking_tool_calls: 从响应中提取工具调用细节。_init_system_message: 确保系统消息存在于提示中。_organize_user_query: 将用户查询添加到提示消息。_clear_user_prompt_image_messages: 清理用户消息中的图片内容(避免多轮迭代中的冗余)。
4.异常与边界处理
- 工具不存在:返回错误信息,避免流程中断。
- JSON解析错误:使用
ensure_ascii=False处理非ASCII字符。 - 资源统计:累计每轮的令牌数和费用,确保最终结果准确。
5.流程示意图
通过这种多轮迭代策略,FunctionCallingAgentStrategy能够动态结合LLM的推理能力和外部工具的执行,逐步解决复杂任务,同时记录详细的执行日志和资源消耗,适合需要多步交互的应用场景。
五.可能遇到的问题
1.Failed to transform agent message
因为dify-plugin-daemon源码跑在WSL2中,前端和后端源码跑在宿主机中,导致无法访问宿主机的5001端口。具体报错,如下所示:


解决方案是在WSL Settings中,设置网络模式为Mirrored,打开主机地址环回,如下所示:

六.Chatflow中的Agent执行过程
1.event流

`data: {"event": "workflow_started", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "workflow_id": "98838bd9-e2a3-4c73-abf8-1d1f1327e9dd", "sequence_number": 77, "inputs": {"sys.query": "\u73b0\u5728\u51e0\u70b9\u4e86", "sys.files": [], "sys.conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "sys.user_id": "b3d39b0d-f73f-40fe-b406-e3035c755d11", "sys.dialogue_count": 0, "sys.app_id": "bd18d1d5-8b35-4126-810a-a35748e8ef77", "sys.workflow_id": "98838bd9-e2a3-4c73-abf8-1d1f1327e9dd", "sys.workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a"}, "created_at": 1738740364}}
data: {"event": "node_started", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "0ac54d2e-437a-4517-9405-12cf701d3078", "node_id": "1738648646598", "node_type": "start", "title": "\u5f00\u59cb", "index": 1, "predecessor_node_id": null, "inputs": null, "created_at": 1738740364, "extras": {}, "parallel_id": null, "parallel_start_node_id": null, "parent_parallel_id": null, "parent_parallel_start_node_id": null, "iteration_id": null, "parallel_run_id": null}}
data: {"event": "node_finished", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "0ac54d2e-437a-4517-9405-12cf701d3078", "node_id": "1738648646598", "node_type": "start", "title": "\u5f00\u59cb", "index": 1, "predecessor_node_id": null, "inputs": {"sys.query": "\u73b0\u5728\u51e0\u70b9\u4e86", "sys.files": [], "sys.conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "sys.user_id": "b3d39b0d-f73f-40fe-b406-e3035c755d11", "sys.dialogue_count": 0, "sys.app_id": "bd18d1d5-8b35-4126-810a-a35748e8ef77", "sys.workflow_id": "98838bd9-e2a3-4c73-abf8-1d1f1327e9dd", "sys.workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a"}, "process_data": null, "outputs": {"sys.query": "\u73b0\u5728\u51e0\u70b9\u4e86", "sys.files": [], "sys.conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "sys.user_id": "b3d39b0d-f73f-40fe-b406-e3035c755d11", "sys.dialogue_count": 0, "sys.app_id": "bd18d1d5-8b35-4126-810a-a35748e8ef77", "sys.workflow_id": "98838bd9-e2a3-4c73-abf8-1d1f1327e9dd", "sys.workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a"}, "status": "succeeded", "error": null, "elapsed_time": 0.034015, "execution_metadata": null, "created_at": 1738740364, "finished_at": 1738740364, "files": [], "parallel_id": null, "parallel_start_node_id": null, "parent_parallel_id": null, "parent_parallel_start_node_id": null, "iteration_id": null}}
data: {"event": "node_started", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "5b98263f-55d0-495a-a712-e11d815b6507", "node_id": "1738648773789", "node_type": "agent", "title": "Agent", "index": 2, "predecessor_node_id": "1738648646598", "inputs": null, "created_at": 1738740364, "extras": {}, "parallel_id": null, "parallel_start_node_id": null, "parent_parallel_id": null, "parent_parallel_start_node_id": null, "iteration_id": null, "parallel_run_id": null}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "label": "ROUND 1", "parent_id": null, "error": null, "status": "start", "data": {}, "metadata": {"started_at": 50773.5850235}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "ade7e662-7116-42a0-b16a-7f79d11177e9", "label": "gpt-4o Thought", "parent_id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "error": null, "status": "start", "data": {}, "metadata": {"provider": "langgenius/openai/openai", "start_at": 50773.5855136, "icon": "1bd032bb73218a5d141b80cab71112cc555b607783553a90933015b7a69a5c24.svg"}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "ade7e662-7116-42a0-b16a-7f79d11177e9", "label": "gpt-4o Thought", "parent_id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "error": null, "status": "success", "data": {"output": "", "tool_input": "{\"current_time\": {}}", "tool_name": "current_time"}, "metadata": {"currency": "USD", "elapsed_time": 2.4041311999972095, "finished_at": 50775.9896446, "provider": "langgenius/openai/openai", "started_at": 50773.5855136, "total_price": "0.00038", "total_tokens": 56, "icon": "1bd032bb73218a5d141b80cab71112cc555b607783553a90933015b7a69a5c24.svg"}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "8b0ba084-8cf4-4726-b02e-c21b1dd973a4", "label": "CALL current_time", "parent_id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "error": null, "status": "start", "data": {}, "metadata": {"provider": "time", "started_at": 50775.9900423, "icon": "http://127.0.0.1:5001/console/api/workspaces/current/tool-provider/builtin/time/icon"}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "8b0ba084-8cf4-4726-b02e-c21b1dd973a4", "label": "CALL current_time", "parent_id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "error": null, "status": "success", "data": {"output": {"meta": {"error": "", "time_cost": 0, "tool_config": {}}, "tool_call_id": "current_time", "tool_call_name": "current_time", "tool_response": "2025-02-05 23:26:06"}}, "metadata": {"elapsed_time": 0.036891399999149144, "finished_at": 50776.0269327, "provider": "time", "started_at": 50775.9900415, "icon": "http://127.0.0.1:5001/console/api/workspaces/current/tool-provider/builtin/time/icon"}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "label": "ROUND 1", "parent_id": null, "error": null, "status": "success", "data": {"output": {"llm_response": {"message": {"text": "2025-02-05 23:26:06"}, "meta": null, "type": "text"}, "tool_responses": [{"meta": {"error": "", "time_cost": 0, "tool_config": {}}, "tool_call_id": "current_time", "tool_call_name": "current_time", "tool_response": "2025-02-05 23:26:06"}]}}, "metadata": {"currency": "USD", "elapsed_time": 2.4422672999935457, "finished_at": 50776.0272907, "started_at": 50773.5850235, "total_price": "0.00038", "total_tokens": 56}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "9f74dd7e-a936-4366-876f-323e8fd229cf", "label": "ROUND 2", "parent_id": null, "error": null, "status": "start", "data": {}, "metadata": {"started_at": 50776.0274993}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "293b1f6a-afd7-4a1a-8253-815a5e9bcef0", "label": "gpt-4o Thought", "parent_id": "9f74dd7e-a936-4366-876f-323e8fd229cf", "error": null, "status": "start", "data": {}, "metadata": {"provider": "langgenius/openai/openai", "start_at": 50776.0280168, "icon": "1bd032bb73218a5d141b80cab71112cc555b607783553a90933015b7a69a5c24.svg"}}}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u5f53\u524d", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u65f6\u95f4", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u662f", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "202", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "5", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u5e74", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "2", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u6708", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "5", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u65e5", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\uff0c", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "23", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": ":", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "26", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "message", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "answer": "\u3002", "from_variable_selector": ["1738648773789", "text"]}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "293b1f6a-afd7-4a1a-8253-815a5e9bcef0", "label": "gpt-4o Thought", "parent_id": "9f74dd7e-a936-4366-876f-323e8fd229cf", "error": null, "status": "success", "data": {"output": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002", "tool_input": "", "tool_name": ""}, "metadata": {"currency": "USD", "elapsed_time": 2.759766099996341, "finished_at": 50778.7877826, "provider": "langgenius/openai/openai", "started_at": 50776.0280168, "total_price": "0.000575", "total_tokens": 83, "icon": "1bd032bb73218a5d141b80cab71112cc555b607783553a90933015b7a69a5c24.svg"}}}
data: {"event": "agent_log", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "data": {"node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "id": "9f74dd7e-a936-4366-876f-323e8fd229cf", "label": "ROUND 2", "parent_id": null, "error": null, "status": "success", "data": {"output": {"llm_response": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002", "tool_responses": []}}, "metadata": {"currency": "USD", "elapsed_time": 2.7609248000007938, "finished_at": 50778.7884238, "started_at": 50776.0274993, "total_price": "0.000575", "total_tokens": 83}}}
data: {"event": "node_finished", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "5b98263f-55d0-495a-a712-e11d815b6507", "node_id": "1738648773789", "node_type": "agent", "title": "Agent", "index": 2, "predecessor_node_id": "1738648646598", "inputs": {"model": {"provider": "langgenius/openai/openai", "model": "gpt-4o", "model_type": "llm", "mode": "chat", "type": "model-selector", "completion_params": {"temperature": 0.2, "top_p": 0.75, "presence_penalty": 0.5, "frequency_penalty": 0.5}}, "tools": [{"provider_name": "time", "tool_name": "current_time", "parameters": {"format": "%Y-%m-%d %H:%M:%S", "timezone": "Asia/Shanghai"}, "enabled": true, "extra": {"description": "\u83b7\u53d6\u5f53\u524d\u65f6\u95f4"}}], "instruction": "\u83b7\u53d6\u5f53\u524d\u65f6\u95f4", "query": "\u73b0\u5728\u51e0\u70b9\u4e86", "maximum_iterations": "3"}, "process_data": null, "outputs": {"text": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002", "files": [], "json": [{}]}, "status": "succeeded", "error": null, "elapsed_time": 5.74197, "execution_metadata": {"currency": "USD", "total_price": "0.000955", "total_tokens": 139, "tool_info": {"icon": "bf12203a5037a1b84c2d8c60a0627e50bedea89cf3f7722b794384aa497d10dc.svg", "agent_strategy": "function_calling"}, "agent_log": [{"id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "label": "ROUND 1", "node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "parent_id": null, "error": null, "status": "success", "data": {"output": {"llm_response": {"message": {"text": "2025-02-05 23:26:06"}, "meta": null, "type": "text"}, "tool_responses": [{"meta": {"error": "", "time_cost": 0, "tool_config": {}}, "tool_call_id": "current_time", "tool_call_name": "current_time", "tool_response": "2025-02-05 23:26:06"}]}}, "metadata": {"currency": "USD", "elapsed_time": 2.4422672999935457, "finished_at": 50776.0272907, "started_at": 50773.5850235, "total_price": "0.00038", "total_tokens": 56}}, {"id": "ade7e662-7116-42a0-b16a-7f79d11177e9", "label": "gpt-4o Thought", "node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "parent_id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "error": null, "status": "success", "data": {"output": "", "tool_input": "{\"current_time\": {}}", "tool_name": "current_time"}, "metadata": {"currency": "USD", "elapsed_time": 2.4041311999972095, "finished_at": 50775.9896446, "provider": "langgenius/openai/openai", "started_at": 50773.5855136, "total_price": "0.00038", "total_tokens": 56, "icon": "1bd032bb73218a5d141b80cab71112cc555b607783553a90933015b7a69a5c24.svg"}}, {"id": "8b0ba084-8cf4-4726-b02e-c21b1dd973a4", "label": "CALL current_time", "node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "parent_id": "7f40692f-d6cb-404d-aee7-9cdbd75c7b60", "error": null, "status": "success", "data": {"output": {"meta": {"error": "", "time_cost": 0, "tool_config": {}}, "tool_call_id": "current_time", "tool_call_name": "current_time", "tool_response": "2025-02-05 23:26:06"}}, "metadata": {"elapsed_time": 0.036891399999149144, "finished_at": 50776.0269327, "provider": "time", "started_at": 50775.9900415, "icon": "http://127.0.0.1:5001/console/api/workspaces/current/tool-provider/builtin/time/icon"}}, {"id": "9f74dd7e-a936-4366-876f-323e8fd229cf", "label": "ROUND 2", "node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "parent_id": null, "error": null, "status": "success", "data": {"output": {"llm_response": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002", "tool_responses": []}}, "metadata": {"currency": "USD", "elapsed_time": 2.7609248000007938, "finished_at": 50778.7884238, "started_at": 50776.0274993, "total_price": "0.000575", "total_tokens": 83}}, {"id": "293b1f6a-afd7-4a1a-8253-815a5e9bcef0", "label": "gpt-4o Thought", "node_execution_id": "ecb47f2e-7256-4189-af30-b81157d72845", "parent_id": "9f74dd7e-a936-4366-876f-323e8fd229cf", "error": null, "status": "success", "data": {"output": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002", "tool_input": "", "tool_name": ""}, "metadata": {"currency": "USD", "elapsed_time": 2.759766099996341, "finished_at": 50778.7877826, "provider": "langgenius/openai/openai", "started_at": 50776.0280168, "total_price": "0.000575", "total_tokens": 83, "icon": "1bd032bb73218a5d141b80cab71112cc555b607783553a90933015b7a69a5c24.svg"}}]}, "created_at": 1738740364, "finished_at": 1738740370, "files": [], "parallel_id": null, "parallel_start_node_id": null, "parent_parallel_id": null, "parent_parallel_start_node_id": null, "iteration_id": null}}
data: {"event": "node_started", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "341a0507-45b3-4348-9174-606e7a82a162", "node_id": "answer", "node_type": "answer", "title": "\u76f4\u63a5\u56de\u590d", "index": 3, "predecessor_node_id": "1738648773789", "inputs": null, "created_at": 1738740370, "extras": {}, "parallel_id": null, "parallel_start_node_id": null, "parent_parallel_id": null, "parent_parallel_start_node_id": null, "iteration_id": null, "parallel_run_id": null}}
data: {"event": "node_finished", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "341a0507-45b3-4348-9174-606e7a82a162", "node_id": "answer", "node_type": "answer", "title": "\u76f4\u63a5\u56de\u590d", "index": 3, "predecessor_node_id": "1738648773789", "inputs": null, "process_data": null, "outputs": {"answer": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002", "files": []}, "status": "succeeded", "error": null, "elapsed_time": 0.026624, "execution_metadata": null, "created_at": 1738740370, "finished_at": 1738740370, "files": [], "parallel_id": null, "parallel_start_node_id": null, "parent_parallel_id": null, "parent_parallel_start_node_id": null, "iteration_id": null}}
data: {"event": "workflow_finished", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "workflow_run_id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "data": {"id": "ef93b6c1-4219-40e1-9253-e247ad188a3a", "workflow_id": "98838bd9-e2a3-4c73-abf8-1d1f1327e9dd", "sequence_number": 77, "status": "succeeded", "outputs": {"answer": "\u5f53\u524d\u65f6\u95f4\u662f2025\u5e742\u67085\u65e5\uff0c23:26\u3002"}, "error": null, "elapsed_time": 5.7938042000023415, "total_tokens": 139, "total_steps": 3, "created_by": {"id": "b3d39b0d-f73f-40fe-b406-e3035c755d11", "name": "ai408", "email": "913292836@qq.com"}, "created_at": 1738740364, "finished_at": 1738740370, "exceptions_count": 0, "files": []}}
data: {"event": "message_end", "conversation_id": "c64faf26-0f38-4267-ba63-1392997e3319", "message_id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "created_at": 1738740364, "task_id": "1934b64d-e761-4a14-961b-a0f25bc9eb24", "id": "c9a6f7ac-6814-49ce-bce1-7aaea3230603", "metadata": {"usage": {"prompt_tokens": 0, "prompt_unit_price": "0.0", "prompt_price_unit": "0.0", "prompt_price": "0.0", "completion_tokens": 0, "completion_unit_price": "0.0", "completion_price_unit": "0.0", "completion_price": "0.0", "total_tokens": 0, "total_price": "0.0", "currency": "USD", "latency": 0.0}}, "files": []}
`
2.Agent节点输入和输出

Agent节点输入,如下所示:
{ "model": { "provider": "langgenius/openai/openai", "model": "gpt-4o", "model_type": "llm", "mode": "chat", "type": "model-selector", "completion_params": { "temperature": 0.2, "top_p": 0.75, "presence_penalty": 0.5, "frequency_penalty": 0.5 } }, "tools": [ { "provider_name": "time", "tool_name": "current_time", "parameters": { "format": "%Y-%m-%d %H:%M:%S", "timezone": "Asia/Shanghai" }, "enabled": true, "extra": { "description": "获取当前时间" } } ], "instruction": "获取当前时间", "query": "现在几点了", "maximum_iterations": "3" }
Agent节点输出,如下所示:
{ "text": "当前时间是2025年2月5日,23:26。", "files": [], "json": [ {} ] }
3.Agent策略function_calling的Round1

Agent策略function_calling的Round1-GPT-4o Thought:
{ "output": "", "tool_input": "{\"current_time\": {}}", "tool_name": "current_time" }
Agent策略function_calling的Round1-CALL current_time:
{ "output": { "meta": { "error": "", "time_cost": 0, "tool_config": {} }, "tool_call_id": "current_time", "tool_call_name": "current_time", "tool_response": "2025-02-05 23:26:06" } }

Agent策略function_calling的Round1输出:
{ "output": { "llm_response": { "message": { "text": "2025-02-05 23:26:06" }, "meta": null, "type": "text" }, "tool_responses": [ { "meta": { "error": "", "time_cost": 0, "tool_config": {} }, "tool_call_id": "current_time", "tool_call_name": "current_time", "tool_response": "2025-02-05 23:26:06" } ] } }
4.Agent策略function_calling的Round2

Agent策略function_calling的Round2-GPT-4o Thought:
{ "output": "当前时间是2025年2月5日,23:26。", "tool_input": "", "tool_name": "" }

Agent策略function_calling的Round2输出:
{ "output": { "llm_response": "当前时间是2025年2月5日,23:26。", "tool_responses": [] } }
参考文献
[1] Agent策略插件:https://docs.dify.ai/zh-hans/plugins/quick-start/develop-plugins/agent-strategy
[2] https://github.com/langgenius/dify-official-plugins/tree/main/agent-strategies/cot\_agent/strategies
[3] Dify Agent策略:https://marketplace.dify.ai/plugins/langgenius/agent
[4] Dify中的GoogleSearch工具插件开发例子:https://z0yrmerhgi8.feishu.cn/wiki/Ib15wh1rSi8mWckvWROckoT2n6g
[5] Dify中的Agent策略插件开发例子:以Function Calling为例(原文链接):https://z0yrmerhgi8.feishu.cn/wiki/SjUuwiRk6imo4Dkn4BBcZoCOn1f
(文:NLP工程化)