Page cover image

6.4 Agent Best Practices02-Url

本小节主要介绍使用如何的使用Dify 上的URL 控件调用外部的第三方的脚本

https://dify101.com/market/exa-ai-dify-ai-beginner-friendly-http-node-tutorial

今天的工程的任务是,根据用户提出的问题的,使用的AI搜索引擎去寻找一些网页,形成相关的摘要,并且把摘要以优美的形式展示出来,这个任务的就简单地完成了。

整体的思路,首先是使用开始控件输入搜索的相关的信息,使用大模型优化输入的相关的问题,使用的API 的http 请求处理脚本的,找到关联问题信息之中输出的网址,将网址进行MARKDOWN 的格式化处理,处理完成之后,再次使用API 搜索关联内容的关键信息highlight,将highlight 输出,使用的大模型进行总结规划,根据归纳的信息,进行模板化处理并且输出。

这个就是这个应用主要的思路。

看到一个很好的API文档怎么简单快速的接入到dify 之中,这样可以快速创建应用,这是很关键的内容

https://exa.ai/

1.0 使用这个EXA 搜索服务

这里首先使用的是API KEY

如何在使用过程之中使用Python 语言进行转换以及转JSON的一些相关的技巧性的内容,这样的可以快速构建相关的应用的过程。

API key : de89010b-b235-471f-8cfe-171a6e06391b

首先我们要研究下EXA 的API 文档,一般来说我们在研究文档时候的,首先需要知道的输入格式,输出格式,以及输出内容的JSON的格式由那些服务

我们发现请求的格式很简单的,仅需要传入的api_key 就可以发起请求,然后就由相关的节点的内容的输出,在先关的节点内容输出之后的就可以解析内容

"curl"这种类型的文档通常指的是用cURL命令行工具展示如何与API交互的示例。cURL(客户端URL库)是一个命令行工具,用于通过URL语法来传输数据,支持多种协议,包括HTTP、HTTPS等。以下是cURL在API文档中的常见用法和特性:

  1. 交互性:cURL命令提供了一种简单而直接的方式来演示如何向API发送请求。这对于开发者测试API非常有用,因为他们可以直接在命令行中运行这些命令。

  2. 完整性:cURL命令通常包含所有需要的请求信息,包括HTTP方法(如GET, POST, PUT, DELETE等)、头部信息(如Content-Type, Authorization等)、请求体数据(如果适用)、以及URL参数。

  3. 易于理解

    • HTTP方法:比如 curl -X POST 表示POST请求。

    • URL:目标API的完整路径。

    • 头信息:例如,-H "Authorization: Bearer token" 用于身份验证。

    • 数据:如果需要发送数据,可以使用 -d 选项,例如 -d '{"key":"value"}'。

简单来说就是一个使用的python 库文件,一个是没有使用Python库文件。

这里我们还需要关注下,在API 使用过程之中使用获取内容的api 的组件信息

2.0 以下是各个节点的创建的过程

2.1第一个节点

我们这里注意使用的是chatbot 的工作流,因为只有chatbot 的工作流才有系统内置的sys.dialogue_count 的选项内容存在。

使用prompt 进行重写,主要的原因就是的用户在相关的提问的时候,提出来的问题不是很具体,或者说提出来的问题比较杂乱无章,这个时候就可以进行相应的重写的操作。

2.2 第二个节点:

请在不改变原始意图的情况下重新表述用户的问题,使其更加具体。

2.3节点三 获取时间的内容及格式

from datetime import datetime, timedelta

def main(arg1: str) -> dict:
    end_date = datetime.now()
    start_date = end_date - timedelta(days=60)
    
    end_formatted = end_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
    start_formatted = start_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
    
    return {
        "startPublishedDate": start_formatted,
        "endPublishedDate": end_formatted
    }

这是一段由python 写的定义的脚本代码,注意主要是为了获取时间的,使用的main 进行主函数的定义的,在此定义的基础下输出未来搜索的开始时间以及结束的时间。

  • 函数声明:函数接受一个字符串类型的参数arg1,但在函数体内并没有使用这个参数。函数返回一个字典。

  • 日期计算

    • 使用datetime.now()获取当前的日期和时间,作为结束时间(end_date)。

    • 通过从结束时间减去60天来计算开始时间(start_date)。

  • 日期格式化

    • 这两个时间点(start_date和end_date)被格式化为ISO 8601标准的字符串格式(例如:"2024-10-27T02:03:00.000000Z"),这是一种通用的日期时间表示方法。

  • 返回值

    • 函数返回一个包含两个键值对的字典:

      • "startPublishedDate":格式化后的开始日期时间字符串。

      • "endPublishedDate":格式化后的结束日期时间字符串。

  • 目的:这个函数可能用于创建一个时间范围,以用于查询或处理在特定时间段内发生的事件或数据。

  • 注意

    • 虽然函数参数arg1被声明,但没有在函数中被使用,这可能是在某种上下文中预留的,或者是代码未完成的一部分。

    • main函数通常用作程序的入口点,但在这里它只是一个普通的函数,命名为main可能是为了与其他代码结构保持一致。

第三个节点,打包输入的JSON 的格式,根据之前我们研究的API 文档我们知道,输入的参数以及内容的格式,为了避免输入的内容的报错,我们这里打包输入的内容,转换成JSON的格式


import json

def main(arg1: str, startPublishedDate: str, endPublishedDate: str) -> dict:
    json_data = {
        "query": arg1,
        "type": "neural",
        "numResults": 6, 
        "includeDomains": ["dify.ai"],
        "startPublishedDate": startPublishedDate,
        "endPublishedDate":endPublishedDate,
        "contents": {
            "text": True,
            "highlights": {
                "numSentences": 7,
                "highlightsPerUrl": 3
            }
        }
    }
    
    return {
        "result": json.dumps(json_data)
    }
  • 构建一个搜索请求的JSON数据结构,可能用于某些搜索API或服务。

  • 它允许用户指定搜索的查询内容、时间范围,以及对搜索结果的显示方式(如文本内容是否包含,高亮显示设置等)进行定制。

  • 返回的JSON字符串可以被用于向API发送POST请求或用于其他需要JSON格式的地方。

同以上一样我们也需要打包下http 请求之后的输出的内容,这里是重点内容是要看下http 输出的内容的格式是什么。一般来说的我们会将输出的内容

import json

def main(input_data: str) -> dict:
    # Parse the input JSON
    data = json.loads(input_data)
    
    # Extract the results array and convert each item to a JSON string
    items = [json.dumps(item) for item in data.get('results', [])]
    
    # Calculate the number of items
    item_number = len(items)
    
    # Return a dictionary containing 'items' key and 'item_number' key
    return {
        "items": items,
        "item_number": item_number
    }

这样的我们的在后续进行循环操作处理,同样可以通过任何的动作进行优化的处理。

接下来是循环节点处理内容

这里注意的是循环节点是之前通过的http 服务之后,获的array 数组信息,这里需要对数组信息进行详细的处理的,查看数组的格式化内容,并进行处理。

适用于需要将 JSON 中的标题和链接转换为 Markdown 格式的场景。

处理

循环节点-使用API 获取节点信息,这里刚好使用之前的markdown 处理完成之后的 URL 作为输入的条件,同样使用的api节点的 http 的请求信息进行处理

总结内容让就比较简单了,使用基础的大模型的进行加载,加载之后,总结出相关内容

接下来处理的内容比较新,是使用一种新的语言模板对输出的内容的进行格式化的处理操作

https://docs.dify.ai/zh-hans/guides/workflow/node/template

模板节点允许你借助 Jinja2 这一强大的 Python 模板语言,在工作流内实现轻量、灵活的数据转换,适用于文本处理、JSON 转换等情景。例如灵活地格式化并合并来自前面步骤的变量,创建出单一的文本输出。这非常适合于将多个数据源的信息汇总成一个特定格式,满足后续步骤的需求。

Jinja2 使用场景

  • 动态内容生成:Jinja2 常用于 Flask 或 Django 框架中生成 HTML、XML 或其他格式的文本内容。在这个例子中,它可能用于创建一个项目列表页面或文档。

  • 模板继承与包含:虽然在这个片段中没有体现,Jinja2 支持模板继承和包含,这意味着这个模板可以是更大模板的一部分,或者可以被其他模板包含。

模板解析

  • 项目编号

    • NO.{{ index+1 }}:由于 index 可能从0开始,所以用 index+1 来确保编号从1开始。

  • Markdown 链接

    • 之前分析的 markdown_url 在这里被直接嵌入到文本中。这意味着在渲染时,这个变量应该已经包含了类似 标题 的内容。

  • 摘要

    • Summary: {{ summary }}:这里 summary 会被替换为具体的项目摘要。

  • 项目进度

    • {{ index+1 }}/{{ item_number }} 展示了当前项目在列表中的位置,以及总项目数。item_number 变量应该在模板外定义,可能是通过循环或其他逻辑计算得到的。

  • 分隔符

    • \n\n---\n\n 是纯文本,用来在项目之间提供视觉分隔。

本例子之中使用脚本的

NO.{{ index+1 }} {{ markdown_url }}
Summary: {{ summary }}
\\n\\n
{{ index+1 }}/{{ item_number }}
\\n\\n---\\n\\n

最后的进行调试,根据调试过程之中出现的问题,进行修正处理,做最后的完善

https://docs.dify.ai/zh-hans/guides/workflow/node/code

Last updated