Function Calling与智能Agent开发
# 课前问题解答
Qwen3-Coder-480B-A35B-Instruct模型介绍
- 参数特点:总参数480B,激活参数35B,采用MOE架构,激活参数不到总参数的十分之一
- 专业领域:主要擅长代码生成任务,在代理编码、代理测试等任务上表现优异,支持256K长上下文
- 对比优势:在开放模型中性能可与Claude Sonnet媲美,支持特别设计的函数调用格式
- 局限性:处理常识问答、作文等非代码任务能力相对较弱
Qwen3-235B-A22B-Instruct模型介绍
- 参数特点:总参数235B,激活参数22B,是相对通用的全能模型
- 能力提升:增强了256K长上下文理解能力,在指令执行、逻辑推理等方面有显著改进
- 版本差异:相比Qwen3-Coder,参数更少但更通用,适合非专业代码场景
激活参数的含义与MOE架构
- 激活参数解释:类比医院问诊,480B总参数相当于全院医生,35B激活参数相当于实际参与会诊的专家
- 动态路由:不同问题会激活不同参数子集,通过路由机制动态选择
- MOE特点:采用稀疏激活模式,相比稠密模型(Dense)更高效
- 部署要求:虽然推理时只需部分参数,但部署需要完整480B参数存储
向量数据库与数据表向量化
向量化策略:
少量表(1-2张):直接放入prompt
大量表(如10万张):需要向量化存储和检索
典型应用:
存储QA对(问题和答案向量)
数据表结构(DDL)通常作为prompt输入
性能考量:表结构向量化可能带来计算开销,需根据实际需求权衡
知识库管理与大模型运行
知识库组织:
按产品系列划分知识库
独立产品使用独立知识库
PDF处理:推荐使用MindView转换为Markdown格式
企业应用:产品手册问答系统可采用多知识库路由机制
# Function Calling
Function Calling在大模型中的作用是什么?
扩展模型能力大模型本身无法直接操作外部系统(如数据库、计算工具),但通过调用预设函数,可以完成:
实时数据获取(天气、股价、新闻)
复杂计算(数学运算、代码执行)
操作外部系统(发送邮件、控制智能设备)结构化输出模型可将用户自然语言请求转化为结构化参数,传递给函数。例如:
用户说“明天北京天气如何?”→模型调用get_weather(location="北京", date="2025-05-06")动态决策流程模型可根据上下文决定是否/何时调用函数,甚至链式调用多个函数(如先查天气,再推荐穿搭)。
# Function Calling与MCP的区别?
| 维度 | Function Calling | MCP |
|---|---|---|
| 定位 | 模型厂商私有接口(如OpenAI, Qwen) | 开放协议(类似HTTP/USB-C) |
| 扩展性 | 需为每个模型单独适配 | 一次开发,多模型兼容 |
| 复杂性 | 适合简单、单次调用任务 | 支持多轮对话、复杂上下文管理 |
| 生态依赖 | 依赖特定模型(如GPT-4) | 跨模型、跨平台(如Claude、Cursor) |
| 安全性 | 依赖云端API密钥 | 支持本地化数据控制 |
# 已经有了MCP还需要Function Calling么?
简单、原子化任务使用Function Calling会更方便
- 查询天气get_weather(city="北京")
- 计算数学公式calculate(expression="3+5")
- 发送单条通知send_email(to="user@example.com")
优势:
- 开发快捷:无需配置MCP Server,直接通过模型API调用预定义函数。
- 低延迟:单次请求-响应,无需协议层开销。
MCP可能成为主流,但Function Calling作为底层能力仍将存在
# CASE:天气调用(Function Calling)
import requests
from http import HTTPStatus
import dashscope
# 设置dashscope API key
dashscope.api_key = "sk-cd87191136be484d92f1ac53551440f1"
# 高德天气API的天气工具定义
# 这段代码定义了一个"工具说明书"
# 告诉 AI:"如果你需要查天气,可以用这个工具"
# 工具的名字叫 get_current_weather
# 需要一个参数 location(必填),还有一个可选参数 adcode
weather_tool = {
"type":"function",
"function":{
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters":{
"type": "Object",
"properties": {
"location": {
"type": "string",
"description": "The city name,e.g. 北京",
},
"adcode": {
"type": "string",
"description": "The city code, e.g. 110000 (北京)",
}
},
"required": ["location"]
}
}
}
def get_weather_from_gaode(location:str, adcode:str = None):
# 调用高德地图API查询天气
gaode_api_key = "681b65a915ffbcb806f8ec482b2fa638"
base_urk = "https://restapi.amap.com/v3/weather/weatherInfo"
params = {
"key": gaode_api_key,
"city": adcode if adcode else location,
"extensions": "base" # base:返回实况天气, all:返回预报天气
}
response = requests.get(base_urk, params=params)
print(response.json())
if response.status_code == 200:
return response.json()
else:
return {"error": f"Failed to get weather: {response.status_code}"}
def run_weather_query():
# 使用Qwen3 + 查询天气
messages = [
{"role": "system", "content": "你是一个智能助手,可以查询天气信息"},
{"role": "user", "content": "长沙现在天气怎么样?"}
]
response = dashscope.Generation.call(
model="qwen-turbo",
messages=messages,
tools=[weather_tool],
tool_choice="auto"
)
print(response)
if response.status_code == HTTPStatus.OK:
# 检查是否需要调用工具
if "tool_calls" in response.output.choices[0].message:
tool_call = response.output.choices[0].message.tool_calls[0]
if tool_call["function"]["name"] == "get_current_weather":
# 解析参数并调用高德API
import json
args = json.loads(tool_call["function"]["arguments"])
location = args.get("location", "北京")
adcode = args.get("adcode", None)
weather_data = get_weather_from_gaode(location, adcode)
print(f"查询结果:{weather_data}")
else:
print(response.output.choices[0].message.content)
else:
print(f"请求失败:{response.code}-{response.message}")
if __name__ == "__main__":
run_weather_query()
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
运行结果:

完整流程图:
用户:"长沙今天天气怎么样?"
↓
你的代码
↓
调用 Qwen 模型,传入工具定义
↓
Qwen 分析:"我需要调用 get_current_weather 工具"
↓
Qwen 返回:{"function": {"name": "get_current_weather", "arguments": "{\"location\": \"长沙\"}"}}
↓
你的代码解析参数,调用 get_weather_from_gaode("长沙")
↓
高德 API 返回天气数据:{"temperature": "16", "weather": "雾"}
↓
你的代码把这个结果再传回 Qwen(代码中还没实现这一步)
↓
Qwen 组织语言:"长沙今天雾,16度"
↓
把答案返回给用户
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
完整的第二轮调用应该为:
# 把AI回复的调用工具调用message加到对话历史
messages.append(response.output.choices[0].message)
# 把天气结果追加到对话历史
messages.append({
"role": "tool",
"name": "get_current_weather",
"content": str(weather_data) # 把天气数据转为字符串
})
# 再次调用 Qwen,让它生成最终答案
final_response = dashscope.Generation.call(
model="qwen-turbo",
messages=messages
)
print(final_response.output.choices[0].message.content)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17