【踩坑】用Coze订制一只专属AI小秘😘

1. 引言

🤔 上节《用Coze扣子轻松搭个Bot,从此告别"标题党"》提到了 信息流,让我想起了另一个需求:

希望每天早上起床洗漱时,能够看到订制过的聚合信息:天气、待办、热搜、深圳地铁微博等~

🥰 就好像有一个 专属秘书 跟我汇报工作一样,之前的实现思路:

搞个云服务器跑爬虫脚本,定时爬数据保存数据库里中,写个查数据的接口,最后写个App调接口拉下数据。

😏 把 Coze的官方文档 的官方文档完整看完,感jio 完全可以搭个Bot来实现我的需求,几个关键的要素:

  • 数据库:支持用户通过自然语言来增删改查数据库,不过一个Bot目前只能创建一张表。
  • 知识库 :感觉能当 静态配置文件 使用,AI可以从这里读取一些固化数据,比如存一些要比如存要爬取url列表。
  • 大模型 :感觉它最大的作用就是 理解用户意图 ,将它理解到的意图和处理逻辑相匹配,然后调用对应的 插件或工作流,执行任务后输出返回。
  • 节点和插件 :本质上都是 API接口调用的封装 ,如果平台提供的插件不够用或不好用,可以自己找个 API接口 (第三方或自己实现) 封装个 自定义插件。配置起来也很简单:配个API的url、请求头和输入输出参数就完事了。
  • 代码 :上节提到过代码在一个异步的main()函数中执行,入参Args,返回值是Output。笔者就在想,能不能在上面写 爬虫代码 😏?先试了下支持 import 导包,接着依次试了下导入常见的Python抓包库如urllib、requests、aiohttp_requests 等都提示找不到库,正当我一筹莫展的时候,我发现了下方的 尝试AI Ctrl + I,直接用AI生成下代码看看?

😶 喔吼,提供了 request_async 库来模拟请求,接着又试了下其它库,如bs4、pypeteer都提示找不到库,看来 只支持模拟请求不支持自动化爬取 ,数据解析的话,估计只能写 正则 来提取了。

🥰 关于Coze提供的 "积木" 都里了然于心了,接下来具体实践下,猜猜坑~

2. 数据库

2.1. 新建Bot

新建一个Bot,AI生成的Logo太Low了,直接用 剪映的Dreamina 生成一张妹子图,感觉跟小秘的身份更贴切~

创建完,随手写个简单提示词:

😑 试了下,发现颜文字和emoji表情不会同时出现,em...读者更喜欢哪种呢?

😋 感觉颜文字更卡哇伊一些?接着试下Coze提供的数据库玩法~

2.2. 建表

编排 页找到 记忆-数据库

点击+号,可以直接 自定义表格 ,也可以 使用模板 然后在二次编辑:

接着随手定义了四个字段 (配置项信息要谨慎填写哦!它会用于LLM意图理解):

创建后,下方可以看到 新建的表,点击右侧的两个小图标可以对表进行编辑或删除。

2.3. 增删改查

表建完,接着试试跟Bot聊天实现表的增删改查,数据可能有些错误,没关系,后面通过添加约束来提高准确性,先录几条待办吧:

Bot提示已经记录了,我们点下右上角的 已存数据库,看看数据是否真的入库:

接着试试查:

然后是改 (2333,说修改成功,实际是没有改到的,因为task_time字段不等,哈哈哈😄):

最后在试试删:

单删和全删都是可以的,😂 不过因为没有添加 约束,执行过程不太靠谱,等下写个专门处理待办的工作流。

2.4. 骚操作:一表多用

🤭 前面说了一个Bot只能建一个表,工作流那里也只能使用 记忆库 结点,但在我们的场景中,需要存储多种类型的数据。比如我们这里,除了存储待办外,还需要存储想查询天气的城市信息?咋办?添加一个 代表数据类型的字段 就完事了,把前面建的表删掉,然后新建一个保存用户提交记录的表:

通过这个 record_type 来区分,提示词那里稍微改改:

接着录点数据试试:

bash 复制代码
待办:周四下午1点去小白家里吃饭
录入城市:深圳市南山区
录入城市:广州市白云区、上海市黄浦区
待办:大年三十晚上7点看饺子包春晚
待办:明早五点起来收拾行李回家,记得带身份证

打开数据库,可以看到数据都正确录入了:

接着试试通过对话的方式分别查看录入的信息:

可以,数据库的玩法就体验到这里,接着开始完善具体实现细节~

3. 完善提示

🤡 我本来想用 工作流 来单独处理待办的,却发现并不支持操作数据库,只会给我返回没啥用的 SQL语句😂

又折腾了一下代码节点,也不支持操作数据库,em... 看来只能在 人设与回复逻辑 那里操作数据库了,可玩性骤减啊... 先写出 判定用户意图执行对应操作的提示词

😑 花了几个小时,反复测试和修改提示词,em...语雀大模型的误判率还挺高,难顶,最终的提示词:

勉强能答对,拆分好技能,接着一个个完善~

3.1. 待办处理

😑 这里把我整麻了,太不稳定了,我的提示词:

然后经常出错、失败和不符合预期的输出结果:

  • 没有生成raw_sql字段:Failed: missing parameter: raw_sql
  • raw_sql 没包含 record_create_time 字段:一直报 参数校验未通过,年前会默认生成,今天怎么瞎搞都不行,无奈只能将这个字段改为非必填。
  • 不稳定的输出结果,约束输出格式完全没用,少返回数据等等...

反复调整提示词还是dio样,还不支持手动调 ts-TableMemory 插件执行特定sql,无奈只能放弃待办了...

3.2. 天气查询

😑 和上面同样的问题,数据库操作插件太不靠谱了,我的提示词:

😑 问天气,直接跳过第一步ts-TableMemory查数据库,去调墨迹天气插件,传参不是北京就是上海,醉了

😞 难道一次只能调用一个插件?唉,放弃数据库了,改用 知识库 写死几个城市试试,虽然和我们的初衷违背:每个用户动态关注想关注城市的天气信息 ┓( ´∀` )┏。新建一个知识库:

依次点击 新增单元文本格式自定义下一步输入单元名创建分段

工作流支持 知识库 节点,直接创建一个工作流:

新建一个 知识库节点,做下简单配置:

试运行,看下输出结果:

可以,知识库里配置的城市信息都拿到了,接着添加一个 墨迹天气 的插件,点击 批处理,参数值设置为知识库的outputList:

city 字段设置为item1里的值:

运行看看:

得嘞,天气信息都获取到了😄,这里直接把省市区都塞到city字段里了,正确传参应该是 拆分省市区 来传对应参数的。所以需要对 知识库 的城市信息做下处理,提取下省市区,思路有两,一一实现下😆

3.2.1. Python正则代码提取省市区

无它,写个 正则 提取即可,随手搜个 省市区/县/镇/乡/村提取正则表达式 就好了,新建 代码 节点,写出提取代码:

python 复制代码
import re

# 匹配省市区的正则
pattern = re.compile(r'(?P<province>[^省]+省|自治区|直辖市)(?P<city>[^市]+市|自治州)(?P<county>[^县]+县|[^区]+区|[^市]+市|[^旗]+旗|自治县)?(?P<other>.*)', re.S)

async def main(args: Args) -> Output:
    params = args.params
    result_list = []
    address_list = params["inputList"]
    # 遍历地址,提取省市区
    for address in address_list:
        match = pattern.search(address['output'])
        if match:
            result_dict = {}
            province = match.group('province')
            city = match.group('city')
            county = match.group('county')
            other = match.group('other')
            if province:
                result_dict['province'] = province
            if city:
                result_dict['city'] = city
            if county:
                result_dict['county'] = county            
            result_list.append(result_dict)
    ret: Output = {
        "outputList": result_list,
    }
    return ret

添加输入参数,运行看下输出:

接着要配置下输出值中 子项的数据类型 ,否则后面会 索引不到子级字段!!!你不配置就会介样:

配置下:

然后调下天气插件的输入参数:

阔以,天气都获取到了,代码的方式跑通了,接着试试大模型~

3.2.2. 利用大模型提取省市区

🤭 这就简单了,直接写提示词,让它帮我们提取下省市区,然后塞到对应字段中:

这里有一点要注意,大模型的返回值不支持 Object类型和Array<Object>类型 (灰色不给选),所以这里得拆分成三个String数组输出。

😛当然,也可以指定输出结果为 固定格式的Json ,然后接个 代码节点,解析Json字符串作为入参,生成Array 输出。

天气插件配置下入参:

运行结果和 代码节点 一致,简单对比下两种方式的特点:

  • 代码提取:提取速度快(0.063s),硬编码只支持处理简单和标准的地址格式,支持返回Object类型的数据。
  • 大模型提取:提取速度较慢(4s),支持处理复杂和非标准的地址格式,不支持返回Object类型的数据。

3.2.3. 格式化输出结果

加个代码节点,格式化下天气的输出结果:

python 复制代码
async def main(args: Args) -> Output:
    params = args.params
    weather_infos = params['weather_infos']
    city_infos = params['city_infos']
    output = ""
    for index, weather_info in enumerate(weather_infos):
        city_info = city_infos[index]
        weather_dict = weather_info["data"]
        # 判空避免获取不到天气数据奔溃
        if weather_dict:
            weather_data = weather_info["data"][0]
            output += "- 【{}{}】{} - {}~{}°C".format(city_info["city"],city_info["county"], weather_data["condition"], weather_data["temp_low"], weather_data["temp_high"])
            if index != len(weather_infos) - 1:
                output += "\n"
    ret: Output = {
        "output": output,
    }
    return ret

搞点输入运行下看看:

最后跟 结束节点 串起来,试运行看看:

ok,查询天气信息的工作流就到这里,发布 下工作流,然后编排提示词那里,指定使用此工作流:

接着在 预览和调试 处,随手输入一个 天气

🥳 可以,是想要的效果,巴适得很~

3.3. 新闻热点

然后是新闻热点,同样整个工作流:

点击插件,搜下 新闻 ,只发现一个 头条新闻 插件,添加下,发现只支持传递一个 关键词 参数:

运行下看看:

我期望的是这样的热点新闻:

结果改了好几个关键词 (如: 头条热榜) 都不行,数据也只有4-5条,而且有些新闻是很早之前的,这哪里是新闻,这是 旧闻 吧 ****🐶

🤔 自带 新闻插件 不给力,可以换个思路:用 搜索插件 搜索,然后用 网页信息提取插件 进行内容提取,最终整合下信息。😳 平台目前支持两个搜索插件:必应搜索头条搜索 。主要参数都差不多:新闻关键词(必填)搜索条数偏移。另外,头条搜索包含两个插件工具:

  • search :搜索用户询问的内容,比必应多了个search_id 参数用于分页加载更多。
  • browse:从url链接获取正文信息,参数:url、prompt(有关url链接内容的问题)。

两个插件都用上,搜索关键词 实时热点新闻,运行看看输出结果,对比下搜索结果:

必应搜索 直接返回了各种 带热搜的站点头条搜索 返回的结则有些咋,比如这个搜索结果大部分跟《热搜》这部电影有关。🤔 权衡之下还是决定用必应,然后这样玩:

  • 代码节点:获取站点url(做下去重),返回url列表;
  • url页面内容读取插件:批处理获取下热点新闻的内容;
  • 代码节点:使用split('\n')将content字段分割成多条新闻;
  • 大模型:批处理生成热点新闻的概要列表返回。

然后就是创建对应的节点:

3.3.1. 提取站点url的代码节点

就提取热搜站点的url保存到列表中返回,顺带用set()做下简单去重:

python 复制代码
async def main(args: Args) -> Output:
    params = args.params
    news_input = params["input"]
    url_list = []
    for news in news_input:
        url_list.append(news["url"])
    # 顺带用set做下去重    
    ret: Output = {
        "urlList": list(set(url_list)),
    }
    return ret

3.3.2. 插件提取页面热搜内容

这里用的 头条搜索的search插件 ,相比起 Link Reader插件 速度更快,毕竟这里要执行 批处理

3.3.3. 分割新闻标题的代码节点

就是用split('\n')对content的内容进行分割,拆成一个字符串数组返回:

python 复制代码
async def main(args: Args) -> Output:
    params = args.params
    output_list = params["content"]
    news_list = []
    for output in output_list:
        news_list.extend(output["data"]["content"].split('\n'))
    ret: Output = {
        "newsList": news_list,
    }
    return ret

运行输出结果:

可以看到新闻标题还是粘连在一起了,而且拼接格式不太确定,所以没法直接 硬编码 的方式进行提取,试下用 大模型 节点来提取一波~

3.3.4. 提取新闻标题的大模型结点

简单写下提取新闻标题的 提示词,并对输出结果添加约束,以保证输出结果符合我们的预期:

但是得出的输出结果:

难道是输入内容太长了,消耗了太多Token:

后面我又删减了一些,还是不行,我又试着把输入和提示词复制到另一个国产AI上:

😄 2333,直接就结束对话,大概率是触发了某些 敏感词违禁词,试下丢GPT4上瞅瞅:

果然,后面反复尝试,发现是几个 人名 导致的,所以前面的代码节点还需要对相关字符串做下 替换。新闻条数也得做下限制,不然会报其它的错误,调整完后的运行结果:

可以,发布下工作流,改下提示词:

发送 新闻热点 看看:

勉强算是拿到了新闻热点了,最后完善下消息汇总吧~

3.4. 信息汇总

😑 em...这一步的设想就是将多种数据组合到一起返回,待办就不掺和了,就调下天气和新闻吧,写下提示词:

发送 看看:

┓( ´∀` )┏ 行吧,人设和回复逻辑 这里 只会调用一个插件或工作流,这个AI小秘就暂且搞到这吧,仅仅依靠平台提供的插件,很难达到我们的预期,很多功能需要自己写插件实现...

😏 对了年前偶然发现Coze支持把Bot发布到 豆包 上了:

😆 啧啧,选个温柔御姐的声线,听着AI小秘汇报,体验直接拉满!😁 不过,具体要审核多久不知道,过年前提交的 Bot-标题党滚粗 还处于 审核中。虽然别人搜不到你的Bot,但你自个是可以偷着乐的哈~

4. 小结

😐 磕磕碰碰,勉强把AI小秘给堆完了,尽管和我们的期望大相径庭,但

捋一捋期间遇到的问题吧,当然,也可能是我的使用姿势不对导致的,欢迎评论区指出:

  • 数据库
    • 一个Bot只支持一个数据库表
    • 不能在工作流中操作数据库 ,大模型和代码节点都不行,你只能在 人设与回复逻辑 那里通过 自然语言 让AI理解,然后由它 自动生成sql 并调用 ts-TableMemory.tableExecute 插件对数据库进行增删改查,整个过程你是没法干预的。
    • 数据库表设计得稍稍复杂点,经常会出现:没生成raw_sql字段字段遗漏导致参数校验不通过返回条数和查询结果数量不一致 等问题。
    • ts-TableMemory.tableExecute 插件是没开放的,没法自己手写sql操作数据库表。
  • 自带插件
    • 批处理+试运行 ,容易报错,且报错意义不明:RPCError [调用HTTP接口失败,插件调用失败],感觉是做了 接口防刷 触发的报错。😳 但文档或者插件描述也没说调用频次限制啥的..
  • 云雀大模型
    • 时不时抽风,报错啥提示也没,有时会返回一个莫名其妙的输出,即便你加了约束。
  • 没提供用户唯一标识获取方法
    • 想自定义插件,不知道怎么做用户关联
  • 节点折叠
    • 节点很多的时候,操作起来不太方便,如果能支持整个折叠就好了,比如就剩下:节点图标+节点名称。

🤡 以上就是我在搭Bot期间遇到的问题,em... 可能我上来就定位错了,想弄一个 功能大而全的Bot 。只是现在的扣子更适合 实现单一功能的Bot,等以后支持API输出了,再来完善这个AI小秘吧🤖~

BotID:7331752198227116068

相关推荐
我算是程序猿26 分钟前
用AI做电子萌宠,快速涨粉变现
人工智能·stable diffusion·aigc
哪 吒1 小时前
吊打ChatGPT4o!大学生如何用上原版O1辅助论文写作(附论文教程)
人工智能·ai·自然语言处理·chatgpt·aigc
龙的爹23333 小时前
论文翻译 | Generated Knowledge Prompting for Commonsense Reasoning
人工智能·gpt·机器学习·语言模型·自然语言处理·nlp·prompt
龙的爹23333 小时前
论文翻译 | Model-tuning Via Prompts Makes NLP Models Adversarially Robust
人工智能·gpt·语言模型·自然语言处理·nlp·prompt
AI绘画君4 小时前
Stable Diffusion绘画 | AI 图片智能扩充,超越PS扩图的AI扩图功能(附安装包)
人工智能·ai作画·stable diffusion·aigc·ai绘画·ai扩图
乔代码嘚7 小时前
AI2.0时代,普通小白如何通过AI月入30万
人工智能·stable diffusion·aigc
玄奕子7 小时前
GPT对话知识库——在STM32的平台下,通过SPI读取和写入Flash的步骤。
stm32·单片机·gpt·嵌入式·嵌入式驱动
XiaoLiuLB8 小时前
ChatGPT Canvas:交互式对话编辑器
人工智能·自然语言处理·chatgpt·编辑器·aigc
龙的爹23331 天前
论文翻译 | LLaMA-Adapter :具有零初始化注意的语言模型的有效微调
人工智能·gpt·语言模型·自然语言处理·nlp·prompt·llama
罗曼蒂克在消亡1 天前
github项目——gpt-pilot自动创建应用
gpt·github·github项目