倾旋的博客

倾旋的博客

现阶段在进行有效性验证/攻击模拟相关的安全研究工作,我的博客会记录一些我的学习过程和部分安全技术研究成果。

04 Jun 2024

使用Coze平台对Github Star项目进行分析推送

👾实现思路

Coze有个版本,分别面向海外和国内,这里我使用海外版本

域名模型备注
coze.comGPT4o\GPT3.5\GPT4\Gemini 1.5 Pro..海外魔法
coze.cn字节云雀国内

这里不多介绍Coze平台的基本功能了,请移步官方文档:Coze - Coze 文档中心

整体实现思路如下:

  • 编写一个能够读取我自己Github Star项目的插件
  • 编写一个能够向知识星球推送文字的插件
  • 创建工作流,方便后续其他Bot调用
  • 创建一个Bot,编写Prompt,导入上述插件进行调试
  • 设置自定义交互的按钮来修改变量,增加易用性

🔧编写访问Github API的插件

为了实现能够将Github的Star项目输入给AI,首先需要编写一个插件,这个插件用于访问Github API接口:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
import os

# 获取Github访问令牌
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
headers = {
    'Authorization': f'token {GITHUB_TOKEN}'
}

def get_starred_repos(username):
    url = f'https://api.github.com/users/{username}/starred'
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        return []

def main():
    username = 'your-github-username'
    starred_repos = get_starred_repos(username)
    for repo in starred_repos:
        print(f"项目名称: {repo['name']}")
        print(f"项目描述: {repo['description']}")
        print(f"项目地址: {repo['html_url']}")
        print(f"Star数量: {repo['stargazers_count']}")
        print('---')

if __name__ == '__main__':
    main()

以上是我用Prompt AI生成的示例代码,这个示例代码确实能直接拿来使用,但是还需要按照实际情况调整输入输出参数,在Coze平台中每一个插件都可以通过Metadata设定输入参数以及输入参数的数据类型,同样的也有输出参数以及输出参数的数据类型。

0

1

我在Metadata设定了这个插件输入、输出的数据格式,输入参数分别是:

参数名称参数描述
token用于访问Github API接口的Access Token
limit用于设定要取得多少个Star项目

输出参数分别是:

参数名称参数描述
description项目描述
url项目链接
stargazers_count项目Star数量
topics项目主题

但通过requests 访问API接口还是不够优雅,我找到了PyGithub这个库,对Github API封装很好,在插件依赖中直接引入了:

2

最终的插件代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from runtime import Args
from typings.GetGithubStarredRepos.GetGithubStarredRepos import Input, Output
"""
Each file needs to export a function named `handler`. This function is the entrance to the Tool.

Parameters:
args: parameters of the entry function.
args.input - input parameters, you can get test input value by args.input.xxx.
args.logger - logger instance used to print logs, injected by runtime.

Remember to fill in input/output in Metadata, it helps LLM to recognize and use tool.

Return:
The return data of the function, which should match the declared output parameters.
"""
from github import Github
# https://pygithub.readthedocs.io/en/stable/introduction.html
# Authentication is defined via github.Auth
from github import Auth

def handler(args: Args[Input])->Output:
    print(args.input.username)
    limit = args.input.limit
    token = args.input.token
    count = 0
    # using an access token
    auth = Auth.Token(token)

    # First create a Github instance:
    # Public Web Github
    g = Github(auth=auth)

    repos  = list()
    # repo_info = {'url':'', 'description': '', 'stargazers_count': 0, 'topics': ''}
    # https://docs.github.com/zh/rest/activity/starring?apiVersion=2022-11-28#list-repositories-starred-by-the-authenticated-user--parameters
    starred_repos = g.get_user().get_starred()
    # Then play with your Github objects:
    for starred_repos in g.get_user().get_starred():
        print("Got > " + str(count))
        # repo_info['description'] = starred_repos.description
        # repo_info['url'] = starred_repos.owner.url
        # repo_info['stargazers_count'] = starred_repos.stargazers_count
        # repo_info['topics'] = ",".join(starred_repos.topics)
        repo_info = {
            'url': starred_repos.owner.html_url,
            'description': starred_repos.description,
            'stargazers_count': starred_repos.stargazers_count,
            'topics': ",".join(starred_repos.topics)
        }
        repos.append(repo_info)
        args.logger.info(repo_info)
        # 如果不限制,则读取全部
        if limit == 0:
            continue
        count = count + 1
        if limit == count:
            break
        # To close connections after use
    g.close()
    args.logger.info(repos)
    return {"repos": repos}

在Coze平台上可以直接对插件进行测试,在Output Value日志栏目中可以看到返回的数据结构:

3

至此一个获取Github Star项目的插件就做好了。

📔编写发送知识星球帖子的插件

由于知识星球没有提供API接口,因此我使用浏览器开发者工具查看了一下请求规律,编写了如下代码:

参数参数说明
cookie知识星球Cookie
group_id知识星球的ID
content帖子内容
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from runtime import Args
from typings.send_topic.send_topic import Input, Output
import requests
import json

def post_topics(cookie, group_id, content):
    url = f'https://api.zsxq.com/v2/groups/{group_id}/topics'
    headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Content-Type': 'application/json',
        'Cookie': cookie,
        'Dnt': '1',
        'Origin': 'https://wx.zsxq.com',
        'Priority': 'u=1, i',
        'Referer': 'https://wx.zsxq.com/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0',
        'X-Version': '2.57.0'
    }
    data = {
        'req_data': {
            'type': 'topic',
            'text': content,
            'image_ids': [],
            'file_ids': [],
            'mentioned_user_ids': []
        }
    }

    response = requests.post(url, headers=headers, json=data)
    response_json = response.json()
    return response_json
"""
Each file needs to export a function named `handler`. This function is the entrance to the Tool.

Parameters:
args: parameters of the entry function.
args.input - input parameters, you can get test input value by args.input.xxx.
args.logger - logger instance used to print logs, injected by runtime.

Remember to fill in input/output in Metadata, it helps LLM to recognize and use tool.

Return:
The return data of the function, which should match the declared output parameters.
"""
def handler(args: Args[Input])->Output:
    cookie = args.input.cookie
    group_id = args.input.group_id
    content = args.input.content
    result = post_topics(cookie, group_id, content)
    return {'succeeded': result['succeeded']}

这个插件返回的比较简单,如果成功就返回True,失败就返回False。

4

🔄创建工作流

工作流支持通过可视化的方式,对插件、大语言模型、代码块等功能进行组合,从而实现复杂、稳定的业务流程编排,例如旅行规划、报告分析等。当目标任务场景包含较多的步骤,且对输出结果的准确性、格式有严格要求时,适合配置工作流来实现。

在工作流中可以引入多种模块:

节点名称描述
LLM大语言模型节点,该节点支持选择不同的 AI 模型处理文本生成任务。
Code代码节点。通过 IDE 编写代码处理输入参数,并返回输出值。
Knowledge知识库节点。根据输入参数从关联知识库中召回数据,并返回。
Conditionif-else 逻辑节点。满足设置条件则运行 if 分支,否则运行 else 分支。
Variable变量节点。用于读取和写入 Bot 中的变量。
Plugins插件节点,能够调用Plugins Store中的所有插件

5

这里我以获取Github Star项目的工作流为例,首先每个Workflow都有一个起始节点和结束节点,结束节点可以设置返回值。

在整个工作流内,上一个节点的输入输出变量可以被下一个节点引用:

6

  • Batch processing : 可以并发执行,如果要处理一批线性的输入(例如数组),可以调用这个方式去执行。

7

🤖创建一个面向用户的Bot

Coze 利用大型语言模型极大地简化了 Bot 的搭建过程。 在充分利用大语言模型优势的同时,Coze 还支持用户通过知识库、工作流等功能来配置 Bot 如何响应用户查询,以保证 Bot 符合预期。

你可以使用 Coze 提供的以下功能,定制你的 AI Bot:

  • 人设与提示词

设定 Bot 的身份及其目标和技能,例如产品问答助手、新闻播报员、翻译助理等等。Bot 的人设和提示词决定了 Bot 如何与你的用户进行互动。

  • 插件

通过 API 连接集成各种平台和服务,扩展 Bot 能力。Coze 平台内置丰富的插件供你直接调用,你也可以创建自定义插件,将你所需要的 API 集成在 Coze 内作为插件来使用。

  • 工作流

一种用于规划和实现复杂功能逻辑的工具。你可以通过拖拽不同的任务节点来设计复杂的多步骤任务,提升 Bot 处理复杂任务的效率。

  • 记忆库

Coze 的记忆库功能可以保留和理解对话细节,并支持添加外部知识库给模型补充知识,使 Bot 与用户的互动更加有针对性和个性化。你可以通过以下方式来存储和管理外部知识。

  • 知识库:支持上传本地或线上内容,然后将这些内容分割成知识分片,通过语义匹配给模型补充知识。
  • 变量:通过 key-value 的形式来记录变量值。例如记录用户的某一偏好。
  • 数据库:用来存储和管理结构化数据,并支持用户通过自然语言方式对数据库中的数据进行增删改查。
  • 多发布渠道

Coze 支持将搭建的 Bot 发布到各种社交应用中,让你的 Bot 服务更多的用户。

  • 其他定制化功能

    • 定时任务:你可以为 Bot 添加定时任务,预定的时间条件下自动触发 Bot 向用户发送消息。
    • 开场白:设置 Bot 对话的开场语,让用户快速了解 Bot 的功能。例如 我是一个旅行助手 Bot,我能帮助你计划行程和查找旅行信息。
    • 用户问题建议:Bot 每次响应用户问题后,系统会根据上下文自动提供三个相关的问题建议给用户使用。
    • 音色:为 Bot 选择与用户交流使用的语言和语调。

    8


以上内容引用自:Coze - Coze 文档中心

创建完插件、Workflow,就可以将Workflow导入到Bot中了,再写上Prompt就基本完成了。这里贴一下我的Prompt(写的比较烂,有很大优化空间):

1
2
3
4
5
6
7
8
# 角色
您是一位专精于整理和推送数据的AI助理。

## 技能
### 技能一:浏览Github星标项目
- 利用search_users_star流程来收集用户在Github上的Starred项目信息。

当用户需要查询Github Starred 数据时,AI助理会运用search_users_star工作流收集Github Starred项目信息并存储到{{github_repository}}中,然后按以下格式输出,内容不需要截断:

早安,新的一天开始了!这些是我为您找到的令人瞩目的Github项目: <search_users_star工作流结果>

1
2
3

### 技能二:可以将<search_users_star工作流结果>发送到知识星球
- 利用send_message_to_topic流程将{{github_repository}} 中的数据发送到知识星球,按照如下格式:

你好!这些是我为您找到的令人瞩目的Github项目: <search_users_star工作流结果>

:) 由 GPT-4o 模型驱动

1
2
3
4
5

## 约束条件
- 仅可透过search_users_star工作流获取Github的相关信息。
- 不论何种情况下,都不能暴露或让用户查阅变量的具体数值。
- 用户只能设定变量的数值,不允许进行其他的操作活动。

说到Database,我在这个Bot中尝试使用了一下,确实非常好用,可以用提示词控制Bot把结果按照Database结构保存起来,例如Bot获得前10个Github项目就保存起来了:

9

👍设置自定义交互按钮

自定义交互按钮其实就是ShortCut,可以让用户按照设置好的表单填写信息,然后发送给Bot

由于前面编写的Workflow需要一些Token、Cookie之类的信息,我就创建了几个变量用于保存这些信息,并且防止Prompt注入,限制了用户不能查看变量的值。

10

11

最终实现效果:

12

13

总结

Coze平台有点像是一个在线版的LangChain,比起之前使用代码去定制自己的Agent,通过平台一站式解决就很丝滑,并且能够多个Workflow进行联动,通过Trigger还能够设置定时任务(定时推送,这个本文还没有实现),总之能够极大的方便日常工作和生活,不过还是不建议在上面使用较为隐私的信息。