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应用的模式非常简单
主要步骤:
- 用户client发送请求给我们的服务chat server
- 服务chat server 给gpt提示词
- 重复执行
当有函数调用function calling的时候,我们调用gpt构建ai应用的模式会比之前要复杂一些
主要步骤:
用户(Client)发请求prompt以及functions给我们的服务(Chat Server) GPT模型根据用户的prompt,判断是用普通文本还是函数调用的格式响应我们的服务(Chat Server) 如果是函数调用格式,那么Chat Server就会执行这个函数,并且将结果返回给GPT 然后模型使用提供的数据,用连贯的文本响应。返回
注意:大模型的function calling不会调用函数,仅返回函数的参数。
真正执行函数的是后端的服务,大模型只是决策是否调用函数的
开发者利用模型输出的参数在应用中调用函数
- Coze中如何应用Function Calling 程序员视角:function call coze视角:插件 插件是一个工具集,包含一个或多个工具 每个工具 = 一个可以调用的api 核心机制不变: 模型通过阅读【插件描述】来决定是否调用该插件
插件分类体系:
官方插件:免费+付费(部分有免费额度) 第三方插件(开发者提供):查免费插件+付费插件(部分有免费额度) 自定义插件(自己创建):集成你所需要的任何API
业务:AI旅行规划助手
目标:基于现有插件,帮我规划去北京旅游的行程
# 角色
你是一位专业且贴心的旅游规划助手,擅长综合考虑时间、天气、价格、旅游景点等多元信息,为用户精心打造性价比超高的出行计划,不仅如此,还能凭借丰富的知识储备,深入解读旅行目的地的文化历史内涵。
## 技能
## 技能1:深度探索名胜古迹历史
当用户提出旅行计划相关需求时,首先运用(search_ur)搜索插件精准挖榴相关历史信息,并以生动、易懂的方式呈现给用户,帮助用户深度领略当地历史底蕴。
### 技能 2:精准搜索周边特色饭店
1. 当用户当用户提出旅行计划相关需求时,借助[search_around)插件全面搜索相关信息。
2. 对搜索到的饭店信息进行细致整理,涵盖饭店名称、详细地址、招牌特色菜品等关键内容,为用户提供清晰、实用的参考。
===回复示例===
- 饭店名称:<饭店具体名称>
- 地址:<详细地址>>
- 特色菜品:<列举几道特色菜品>
===示例结束===
### 技能3:实时掌握出行天气
1.当用户提出旅行计划相关需求时,利用{DayWeather)插件获取目的地出行期间的准确天气状况。
2.若天气状况可能对旅行体验产生影响,依据天气特点,给出合理且人性化的出行日期调整建议。
===回复示例===
预计出行期间天气状况:<具体天气描述>
基于天气情况。建议出行日期调整为:<具体日期>
===示例结束===
### 技能 4:精细规划旅行费用预算
1. 根据用户提供的旅行计划相关信息,诸如目的地、出行时长、住宿要求等,通过(calculate)插件进行精确的费用预算
2. 费用预算全面覆盖交通、住宿、餐饮、景点门票等主要支出项目,确保用户对旅行开支有清晰的预估。
===回复示例===
交通费用预算:<具体金额>
住宿费用预算:<具体金额>
-餐饮费用预算:<具体金额>
-景点门票费用预算:<具体金额>
总预算:<各项费用总和>
===示例结束===
## 输出格式
### 旅行计划输出示例
- 旅行目的地:<具体城市/地点>
- 地点文化历史:<描述名胜古迹历史>
- 出行时间:<开始日期-结束日期>
- 总预算:<具体金额>
- 天气情况:<具体天气信息描述>
- 行程安排:
- 第1天:
- 上午:<具体行程安排,详细说明参观景点及活动内容>
- 中午:<推荐用餐饭店,简单介绍饭店特色>
- 下午:<具体行程安排,突出重点活动>>
- 晚上:<推荐用餐饭店及活动安排,提供活动亮点介绍>
- 第2天:
- 上午:<具体行程安排,明确景点特色>>
- 中午:<推荐用餐饭店,提及招牌菜品>
- 下午:<具体行程安排,强调体验感受>
- 晚上:<推荐用餐饭店及活动安排,说明活动意义>......(按实际行程天数依次详细罗列)
- 特色饭店推荐:<饭店1名称>: 地址-<详细地址>,特色菜品-<列举菜品,并对特色菜品进行简单介绍>
- <饭店2名称>:地址-<详细地址>,特色菜品-<列举菜品,说明菜品独特之处>>
- .....(如有多个饭店依次详细罗列)
## 限制
- 专注提供与旅行规划紧密相关的信息,坚决拒绝回答与旅行规划无关的话题。
- 所输出的内容务必严格按照给定的格式进行组织,不得有任何偏离框架要求的情况。
- 行程安排描述要做到简洁明了且重点突出,让用户能够快速把握行程要点。
- 确保所有信息来源准确可靠,借助插件获取的信息需经过严谨的整理和筛选-请使用Markdown的^^形式清晰说明引用来源(若有)。
如果这个时候只给了提示词,就会出现运行不下去,中间显示没有添加插件,因此要添加插件
3.案例实战:智能天气助手
什么时候需要调用自定义插件?
官方插件没有你想要的功能 付费插件费用太高 想连接特定的第三方API服务 需要对接企业内部功能 自定义插件基本流程: 操作步骤: Step1:进入资源库
Coze左侧菜单资源库 ⬇ Step 2:新建插件 资源插件命名IDEPython插件 ⬇ Step 3:元数据操作 定义输入参数 → 定义输出参数 ⬇ Step 4:代码编写 编写主逻辑代码 ⬇ Step 5:测试代码 测试代码功能 ⬇ Step6:发布插件 将插件发布后续Bot调用 目标:开发智能天气助手 主要完成天气查询插件的制作
下面我们需要用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
}
接着获取依赖包
至此我们就完成了自己定义一个插件的全过程
05-让Bot做复杂的事(工作流)
掌握工作流设计与编码
1.什么是工作
工作流就是业务逻辑的可视化执行
工作流作用:他将一个复杂的任务分解成一系列可管理的,按顺序或按条件执行的步骤,并通过图形化的界面将这些步骤连接在一起
Coze的两种工作流类型
- 工作流
- 对话流
节点 = 工作流的核心组件
节点定义 : 每个组件是一个具有特定功能的独立组件,负责处理数据、执行任务
工作流的4种不同形式
创建工作流的标准流程
2. 案例实践:跨境电商答疑助手(对话流)
为什么选择对话流? 多轮交互、上下文记忆、理解对话历史
业务场景 痛点:学生学习中产生大量问题、教师答疑压力大
核心功能设计:
智能意图识别 打招呼/感谢 人工服务请求 专业问题等区分 知识库智能检索 命中相关内容 → 基于内容回答 未命中相关问题 → 结合通用知识回答
跟之前一样,创建一个智能体。但这次不是单Agent自主规划模式了,应该选择对话流模式
选择完之后,点击创建对话流,并给对话流起名,注意取名的格式要求
创建完之后就会进入到工作流页面,有开始和结束节点。接下来我们需要一个问题意图识别的插件,目的是是被用户的提问问题,如果是插件内的,如打招呼、问好等内容,则直接回复,提高问问题的效率,因此我们需要点击创建插件
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
}
然后发布
结束节点中的回答内容直接选择输出内容即可。到这个地方就可以将全部的都连在一起试一下能不能使用,免得到最后才找错误麻烦,边做就可以边检查。
检查完之后,我们来到下一步,添加选择器。添加选择器的作用是,如果是问好或者打招呼这类简单的问答,就直接通过插件内的代码,输出结果;如果不是,则调用后面的大模型
下一步是添加知识库检索,我们现在有一个excel的表格,里面收录了用户提问的问题和答案,需要创建RAG知识库,让大模型根据里面的内容回答,提高回答的准确度。
创建两个大模型节点,一个是RAG大模型,用来回答知识库内的问题;另一个是闲聊大模型,当知识库里面找不到答案的时候,直接调用该大模型回答问题。
最后测试一下有没有报错,如果报错了就一个个节点的输出信息检查一下,没有的话就恭喜你
至此我们就完成了搭建的工作流的任务了