安爸-超级家庭

Dify中的Agent策略插件开发例子:以Function Calling为例

安爸 发布于

本文使用Dify v1.0.0-beta.1版本。Agent 策略插件能够帮助 LLM 执行推理或决策逻辑,包括工具选择、调用和结果处理,以更加自动化的方式处理问题。Dify官方实现的Agent策略插件包括Function CallingReason+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_messagefinish_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,触发后续处理。
  • 执行工具调用
    • 遍历每个工具调用,生成工具调用日志。
    • 通过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_callingRound1-GPT-4o Thought

{   "output": "",   "tool_input": "{\"current_time\": {}}",   "tool_name": "current_time" }

Agent策略function_callingRound1-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_callingRound1输出:

{   "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_callingRound2-GPT-4o Thought

{   "output": "当前时间是2025年2月5日,23:26。",   "tool_input": "",   "tool_name": "" }

Agent策略function_callingRound2输出:

{   "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工程化)

Dify中的Agent策略插件开发例子:以Function Calling为例最先出现在每时AI


扫描二维码,在手机上阅读