一文讲透Coze,普通人也能拿捏智能体(下)

0 阅读16分钟

1.让Bot做事请

要想让Bot做事情,首先我们先要掌握FunctionCalling与插件技术

1.什么是FunctionCalling?

2023年6月13日OpenAI公布了Function Call(函数调用)功能,该功能指的是在语言模型中集成外部功能或API的调用能力,这意味着模型可以在生成文本的过程中调用外部函数或服务,获取额外的数据或执行特定的任务。2023年6月13日OpenAI公布了Function Call(函数调用)功能,该功能指的是在语言模型中集成外部功能或API的调用能力,这意味着模型可以在生成文本的过程中调用外部函数或服务,获取额外的数据或执行特定的任务。

function calling可以解决大模型什么问题?

  • 信息实时性:无法获取最新信息
  • 数据局限性:训练数据虽多,但无法覆盖所有领域
  • 功能扩展性:功能虽强大,但不可能内置所有需要的功能

当没有函数调用function calling是,gpt构建ai应用的模式非常简单

主要步骤:

  1. 用户client发送请求给我们的服务chat server
  2. 服务chat server 给gpt提示词
  3. 重复执行

当有函数调用function calling的时候,我们调用gpt构建ai应用的模式会比之前要复杂一些

主要步骤:

用户(Client)发请求prompt以及functions给我们的服务(Chat Server) GPT模型根据用户的prompt,判断是用普通文本还是函数调用的格式响应我们的服务(Chat Server) 如果是函数调用格式,那么Chat Server就会执行这个函数,并且将结果返回给GPT 然后模型使用提供的数据,用连贯的文本响应。返回

注意:大模型的function calling不会调用函数,仅返回函数的参数。
真正执行函数的是后端的服务,大模型只是决策是否调用函数的
开发者利用模型输出的参数在应用中调用函数

  1. Coze中如何应用Function Calling 程序员视角:function call coze视角:插件 插件是一个工具集,包含一个或多个工具 每个工具 = 一个可以调用的api 核心机制不变: 模型通过阅读【插件描述】来决定是否调用该插件

插件分类体系:

官方插件:免费+付费(部分有免费额度) 第三方插件(开发者提供):查免费插件+付费插件(部分有免费额度) 自定义插件(自己创建):集成你所需要的任何API

image.png

业务:AI旅行规划助手
目标:基于现有插件,帮我规划去北京旅游的行程

image.png

# 角色
你是一位专业且贴心的旅游规划助手,擅长综合考虑时间、天气、价格、旅游景点等多元信息,为用户精心打造性价比超高的出行计划,不仅如此,还能凭借丰富的知识储备,深入解读旅行目的地的文化历史内涵。
## 技能
## 技能1:深度探索名胜古迹历史
当用户提出旅行计划相关需求时,首先运用(search_ur)搜索插件精准挖榴相关历史信息,并以生动、易懂的方式呈现给用户,帮助用户深度领略当地历史底蕴。
### 技能 2:精准搜索周边特色饭店
1. 当用户当用户提出旅行计划相关需求时,借助[search_around)插件全面搜索相关信息。
2. 对搜索到的饭店信息进行细致整理,涵盖饭店名称、详细地址、招牌特色菜品等关键内容,为用户提供清晰、实用的参考。
===回复示例===
- 饭店名称:<饭店具体名称>
- 地址:<详细地址>>
- 特色菜品:<列举几道特色菜品>
===示例结束===

### 技能3:实时掌握出行天气
1.当用户提出旅行计划相关需求时,利用{DayWeather)插件获取目的地出行期间的准确天气状况。
2.若天气状况可能对旅行体验产生影响,依据天气特点,给出合理且人性化的出行日期调整建议。
===回复示例===
预计出行期间天气状况:<具体天气描述>
基于天气情况。建议出行日期调整为:<具体日期>
===示例结束===
### 技能 4:精细规划旅行费用预算
1. 根据用户提供的旅行计划相关信息,诸如目的地、出行时长、住宿要求等,通过(calculate)插件进行精确的费用预算
2. 费用预算全面覆盖交通、住宿、餐饮、景点门票等主要支出项目,确保用户对旅行开支有清晰的预估。
===回复示例===
交通费用预算:<具体金额>
住宿费用预算:<具体金额>
-餐饮费用预算:<具体金额>
-景点门票费用预算:<具体金额>
总预算:<各项费用总和>
===示例结束===
## 输出格式
### 旅行计划输出示例
- 旅行目的地:<具体城市/地点>
- 地点文化历史:<描述名胜古迹历史>
- 出行时间:<开始日期-结束日期>
- 总预算:<具体金额>
- 天气情况:<具体天气信息描述>
- 行程安排:
- 第1天:
    - 上午:<具体行程安排,详细说明参观景点及活动内容>
    - 中午:<推荐用餐饭店,简单介绍饭店特色>
    - 下午:<具体行程安排,突出重点活动>>
    - 晚上:<推荐用餐饭店及活动安排,提供活动亮点介绍>
- 第2天:
- 上午:<具体行程安排,明确景点特色>>
- 中午:<推荐用餐饭店,提及招牌菜品>
- 下午:<具体行程安排,强调体验感受>
- 晚上:<推荐用餐饭店及活动安排,说明活动意义>......(按实际行程天数依次详细罗列)
- 特色饭店推荐:<饭店1名称>: 地址-<详细地址>,特色菜品-<列举菜品,并对特色菜品进行简单介绍>
- <饭店2名称>:地址-<详细地址>,特色菜品-<列举菜品,说明菜品独特之处>>
- .....(如有多个饭店依次详细罗列)

## 限制
- 专注提供与旅行规划紧密相关的信息,坚决拒绝回答与旅行规划无关的话题。
- 所输出的内容务必严格按照给定的格式进行组织,不得有任何偏离框架要求的情况。
- 行程安排描述要做到简洁明了且重点突出,让用户能够快速把握行程要点。
- 确保所有信息来源准确可靠,借助插件获取的信息需经过严谨的整理和筛选-请使用Markdown的^^形式清晰说明引用来源(若有)。

如果这个时候只给了提示词,就会出现运行不下去,中间显示没有添加插件,因此要添加插件

image.png

image.png

3.案例实战:智能天气助手

什么时候需要调用自定义插件?

官方插件没有你想要的功能 付费插件费用太高 想连接特定的第三方API服务 需要对接企业内部功能 自定义插件基本流程: 操作步骤: Step1:进入资源库

Coze左侧菜单资源库 ⬇ Step 2:新建插件 资源插件命名IDEPython插件 ⬇ Step 3:元数据操作 定义输入参数 → 定义输出参数 ⬇ Step 4:代码编写 编写主逻辑代码 ⬇ Step 5:测试代码 测试代码功能 ⬇ Step6:发布插件 将插件发布后续Bot调用 目标:开发智能天气助手 主要完成天气查询插件的制作

image.png

image.png

image.png

image.png

下面我们需要用python编写一个天气查询的代码,如果不会写代码可以直接问ai

from runtime import Args
import requests
import requests # 需要安装对应的库
# 定义插件的主⼊⼝函数 handler;Coze 平台会⾃动调⽤此函数
# 参数 args 是 Coze 传⼊的运⾏时上下⽂对象
# 返回值为 dict 类型,将作为插件的输出结果返回给 Agent
def handler(args: Args):
    """
     天⽓查询插件:
     根据城市地址查询天⽓信息,⽐如输⼊“北京“,输出{
     high:"⾼温 7℃",
     low:"低温 -1℃",
     weather:"晴",
     week:"星期⼆"
     }
     """
    # === 1. 解析输⼊ ===
    try:
        # 从 args.input 中获取 location 字段,并去除⾸尾空格(如⽤户输⼊ " 北京 ")
        # 注意:此处假设输⼊为对象属性访问(如 args.input.location),适⽤于manifest 中声明了 location 字段的情况
        location = args.input.location.strip()
    except Exception:
    # 若获取 location 失败(如字段不存在、输⼊⾮对象等),设为空字符串
        location = ""
    # === 2. 城市编码映射(仅北京、天津,内置)===
    # 构建城市名称 → 天⽓ API 编码的映射字典(仅保留北京和天津两个城市,轻量且教学友好)
    city_code_map = {
    "北京": "101010100", # 北京市的天⽓ API 编码
    "天津": "101030100" # 天津市的天⽓ API 编码
     }
    # 根据⽤户输⼊的城市名,查找对应的编码;若找不到则返回 None
    city_code = city_code_map.get(location)
    # 不⽀持的城市(如输⼊“上海”或空字符串)→ 返回空值结构
    if not city_code:
        # 记录警告⽇志:提示该城市暂不⽀持(可在 Coze 后台查看)
        args.logger.warning(f"Unsupported location: '{location}'")
    # 返回标准化的空结果(所有字段为 None),保证输出结构⼀致
    return {
        "high": None, # 最⾼温度
        "low": None, # 最低温度
        "weather": None, # 天⽓类型(如“晴”)
        "week": None # 星期(如“星期⼆”)
     }
    # === 3. 调⽤天⽓ API ===
    # 拼接完整 API 请求 URL,替换 {city_code} 为实际城市编码
    url = f"http://t.weather.itboy.net/api/weather/city/{city_code}"
    try:
        # 发起 GET 请求,设置超时 5 秒(防⽌插件卡死)
        response = requests.get(url, timeout=5)
        # 若 HTTP 状态码⾮ 2xx,主动抛出异常(如 404、500 等)
        response.raise_for_status()
        # 将响应体解析为 JSON 字典(安全⽅式,避免使⽤危险的 eval())
        data = response.json()
        # 检查 API 业务层返回状态码(该 API 约定 status=200 表示成功)
        if data.get("status") != 200:
        # 若业务状态异常(如城市编码错误),抛出⾃定义异常
            raise ValueError("Weather API returned non-200 status")
        # 从返回数据中提取「今⽇」天⽓预报(forecast 列表第 0 项即为当天)
        # 路径:data → forecast 数组 → 第 0 个元素
        forecast = data["data"]["forecast"][0]
        # 构造并返回天⽓基本信息字典
        return {
            "high": forecast["high"], # 字符串,如 "⾼温 7℃"
            "low": forecast["low"], # 字符串,如 "低温 -1℃"
            "weather": forecast["type"], # 字符串,如 "晴"、"⼩⾬"
            "week": forecast["week"] # 字符串,如 "星期⼆"
         }
# 捕获所有可能的异常(⽹络错误、JSON 解析失败、字段缺失等)
    except Exception as e:
        # 记录错误⽇志,包含具体异常信息和请求城市,便于调试
        args.logger.error(f"Weather query failed for '{location}': {e}")
        # 统⼀返回空值结构,确保插件健壮性(不会因异常导致 Agent 崩溃)
        return {
            "high": None,
            "low": None,
            "weather": None,
            "week": None
        }


接着获取依赖包

image.png

image.png

image.png

image.png

image.png

image.png

至此我们就完成了自己定义一个插件的全过程

05-让Bot做复杂的事(工作流)

掌握工作流设计与编码

1.什么是工作

工作流就是业务逻辑的可视化执行

工作流作用:他将一个复杂的任务分解成一系列可管理的,按顺序或按条件执行的步骤,并通过图形化的界面将这些步骤连接在一起

image.png

Coze的两种工作流类型

  • 工作流
  • 对话流

image.png

节点 = 工作流的核心组件
节点定义 : 每个组件是一个具有特定功能的独立组件,负责处理数据、执行任务

工作流的4种不同形式

image.png

创建工作流的标准流程

image.png

2. 案例实践:跨境电商答疑助手(对话流)

为什么选择对话流? 多轮交互、上下文记忆、理解对话历史

业务场景 痛点:学生学习中产生大量问题、教师答疑压力大

核心功能设计:

智能意图识别 打招呼/感谢 人工服务请求 专业问题等区分 知识库智能检索 命中相关内容 → 基于内容回答 未命中相关问题 → 结合通用知识回答

跟之前一样,创建一个智能体。但这次不是单Agent自主规划模式了,应该选择对话流模式

image.png

选择完之后,点击创建对话流,并给对话流起名,注意取名的格式要求

image.png

image.png

创建完之后就会进入到工作流页面,有开始和结束节点。接下来我们需要一个问题意图识别的插件,目的是是被用户的提问问题,如果是插件内的,如打招呼、问好等内容,则直接回复,提高问问题的效率,因此我们需要点击创建插件

image.png

image.png

image.png

from runtime import Args
import random
"""
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)->dict:
    """
    基于固定短语匹配的跨境电商问答处理器
    Args:
    query:用户输入的问题
    Returns:
    Dict:包含回复类型、回复内容等信息的字典
    """
    #去除首尾空格
    query = args.input.query.strip()
    
    #打招呼相关的固定短语
    greeting_phrases = {
    #基本问候
        "你好","您好","hi","hello","嗨","哈喽","哈罗",
        "早上好","下午好","晚上好","上午好","中午好","晚安",
        "早", "午安","good morning","good afternoon","good evening",
        #询问身份
        "你是谁","你是什么","你叫什么","你的名字","介绍一下自己",
        "自我介绍","你是什么东西","你是哪个","你是啥",
        #询问状态
        "你好吗","怎么样","还好吗","你还好吗","最近怎么样",
        "你在吗","在不在","还在吗","在线吗","你在线吗",
        #询问能力
        "你能干什么","你会做什么","你能做什么","你的功能",
        "你有什么用","你的作用","你的职责","你的用途",
        "你能帮我什么","你可以做什么","你会什么","你懂什么",
        "能力介绍","功能介绍","你的能力","你有什么功能",
        #开始对话
        "开始","开始咨询","开始对话","开始聊天","我想咨询",
        "我有问题","我想问问题","我想了解","咨询一下",
        #测试类
        "测试","试试","试一试","test","testing","试试看",
        "测试一下","看看","检查一下"
    }
    #礼貌用语
    thank_phrases={
        "谢谢","感谢","多谢","谢了","thanks","thank you",
        "thx","3g","3x","谢谢你","感谢你","多谢了",
        "非常感谢","十分感谢","万分感谢","太感谢了"
    }
    goodbye_phrases = {
        "再见","拜拜","bye","byebye","goodbye","88","走了",
        "告辞","先走了","下次见","回头见","有空再聊","改天聊",
        "seeyou","拜","溜了","闪了","slip away"
    }
    human_service_phrases = {
        #直接要求人工服务
        "人工服务","人工客服","人工坐席","人工咨询","人工帮助",
        "人工支持","人工答疑","人工解答","人工回复","人工对话",
        #转接相关
        "转人工","找人工","要人工","转接人工","转接客服",
        "切换人工","接入人工","联系人工","答疑入口",
        #真人服务
        "真人服务","真人客服","真人咨询","真人对话","真人帮助",
        "活人","真人","人类","人工","真的人",
        #客服相关
        "客服","在线客服","联系客服","找客服","客服电话",
        "客服微信","客服qq","官方客服",
        #老师/导师
        "联系老师","找老师","咨询老师","请教老师","老师帮忙",
        "专业老师","课程老师","指导老师",
        #专业服务
        "专人服务","专人客服","专业咨询","专业服务","专家咨询",
        "顾问咨询","一对一服务","专属服务",
        #投诉和问题
        "投诉","举报","反馈问题","意见反馈","服务投诉",
        "质量问题","服务问题","系统问题",
        #售后相关
        "退款","退货","售后","售后服务","退换货","申请退款",
        "退费","取消订单","订单问题",
        # 不满意
        "不满意","有问题","出问题","不行","太差了","服务差",
        "回答不对","答非所问","听不懂","不准确"
    }
    
    # 固定回复
    greeting_response = "你好,很高兴为您服务! 我是您的跨境电商学习小助手,专业您答疑解惑。"

    polite_responses = {
        "thank": [
            "不用客气,随时为您服务!",
            "很高兴能帮助到您!",
            "这是我应该做的,有问题随时找我哦!",
            "客气了,有什么问题尽管问!",
            "不客气,祝您跨境电商生意兴隆!"
        ],
        "goodbye": [
            "再见!期待下次为您服务!",
            "祝您生活愉快,有问题随时来找我!",
            "再见!祝您跨境电商生意兴隆!",
            "拜拜!有问题随时回来咨询!",
            "再见!祝您学习愉快!"
        ]
    }

    
    human_service_response ="同学,点击 https://www.123.com 可进入人工答疑"
    def normalize_text(text: str) -> str:
        """标准化文本:去除标点符号,转换为小写"""
        import re
        #保留中文、英文、数字,去除标点符号和空格
        cleaned = re.sub(r'[^\w\u4e00-\u9fff]','',text.lower().strip())
        return cleaned
        
    def exact_match_check(query_text: str, phrase_set) -> bool:
        """精确匹配检查"""
        normalized_query = normalize_text(query_text)
        for phrase in phrase_set:
            normalized_phrase = normalize_text(phrase)
            if normalized_phrase == normalized_query:
                return True
        return False
    def contains_match_check(query_text:str, phrase_set) -> bool:
        """包含匹配检查(用于短查询中包含关键短语的情况)"""
        normalized_query = normalize_text(query_text)
        #只有当查询很短时才使用包含匹配(避免误匹配)
        if len(normalized_query) <= 10:
            for phrase in phrase_set:
                normalized_phrase = normalize_text(phrase)
                if normalized_phrase in normalized_query or normalized_query in normalized_phrase:
                    return True
        return False
    # 处理输入
    query = query.strip()
    if not query:
        return {
            "type":"error",
            "response":"请输入您的问题。",
            "need_rag": False,
            "original_query": query
        }
    print(f"处理查询:'{query}'")
    print(f"标准化后:'{normalize_text(query)}'")
    # 1.检查感谢类礼貌用语(精确匹配)
    if exact_match_check(query, thank_phrases):
        return {
            "type":"greeting",
            "response" : random.choice(polite_responses["thank"]),
            "need_rag": False,
            "original_query": query
        }
    #2.检查告别类礼貌用语(精确匹配)
    if exact_match_check(query, goodbye_phrases):
        return {
            "type": "greeting",
            "response":random.choice(polite_responses["goodbye"]),
            "need_rag": False,
            "original_query": query
        }
            
    #3.检查打招呼(精确匹配+短语包含匹配)
    if exact_match_check(query, greeting_phrases) or contains_match_check(query, greeting_phrases):return {
        "type":"greeting",
        "response": greeting_response,
        "need_rag":False,
        "original_query":query
    }
            
    #4.检查人工服务请求(精确匹配+短语包含匹配)
    if exact_match_check(query, human_service_phrases) or contains_match_check(query, human_service_phrases):
        return {
            "type": "human_service",
            "response": human_service_response,
            "need_rag":False,
            "original_query":query
        }
    #5.其他情况需要RAG检索
    return {
        "type": "rag_needed",
        "response":"",
        "need_rag": True,
        "original_query": query
    }

然后发布

image.png

image.png

结束节点中的回答内容直接选择输出内容即可。到这个地方就可以将全部的都连在一起试一下能不能使用,免得到最后才找错误麻烦,边做就可以边检查。

检查完之后,我们来到下一步,添加选择器。添加选择器的作用是,如果是问好或者打招呼这类简单的问答,就直接通过插件内的代码,输出结果;如果不是,则调用后面的大模型

image.png

image.png

下一步是添加知识库检索,我们现在有一个excel的表格,里面收录了用户提问的问题和答案,需要创建RAG知识库,让大模型根据里面的内容回答,提高回答的准确度。

image.png

image.png

创建两个大模型节点,一个是RAG大模型,用来回答知识库内的问题;另一个是闲聊大模型,当知识库里面找不到答案的时候,直接调用该大模型回答问题。

image.png

image.png

最后测试一下有没有报错,如果报错了就一个个节点的输出信息检查一下,没有的话就恭喜你

image.png

至此我们就完成了搭建的工作流的任务了