GLM-4-9B-Chat-1M开发者案例:用Function Call集成数据库与API工具链

GLM-4-9B-Chat-1M开发者案例:用Function Call集成数据库与API工具链 GLM-4-9B-Chat-1M开发者案例用Function Call集成数据库与API工具链1. 引言当大模型学会“动手”想象一下你正在开发一个智能客服系统。用户问“帮我查一下订单12345的最新状态然后发一封邮件给客户告诉他预计明天送达。” 传统做法是先写代码连接数据库查询订单再调用邮件API发送通知整个过程至少需要几十行代码还得处理各种异常。但现在你只需要对大模型说一句话它就能自动完成这两件事。这不是科幻而是GLM-4-9B-Chat-1M的Function Call函数调用功能带来的真实能力。GLM-4-9B-Chat-1M是智谱AI推出的新一代开源对话模型它最吸引开发者的特性之一就是支持自定义工具调用。这意味着模型不仅能聊天还能“动手”操作外部系统——查询数据库、调用API、执行代码几乎无所不能。更重要的是它支持1M的上下文长度相当于约200万中文字符。你可以把整个项目的文档、API手册、数据库结构都喂给它让它真正理解你的业务环境。本文将带你深入实践看看如何用GLM-4-9B-Chat-1M的Function Call功能构建一个能连接数据库和API的智能助手。我会从基础概念讲起一步步带你实现完整的工具链集成最后分享几个实用的开发技巧。2. 理解Function Call大模型的“手和脚”2.1 什么是Function Call简单来说Function Call就是让大模型学会使用工具。就像你给一个聪明的助手配上了操作各种设备的权限——它能听懂你的指令然后自己去操作数据库、调用接口、执行脚本。传统的大模型只能“动嘴”现在它能“动手”了。这个转变的意义有多大我举个例子你就明白了。没有Function Call时你问“北京今天天气怎么样”模型回答“我无法获取实时天气信息因为我的知识截止到2024年7月。”有Function Call时你问“北京今天天气怎么样”模型思考“用户需要实时天气信息我应该调用天气查询API。”模型调用get_weather(city北京)API返回{city: 北京, weather: 晴, temp: 25°C}模型回答“北京今天晴天气温25°C。”看到了吗从“无能为力”到“主动解决”这就是Function Call的魔力。2.2 GLM-4-9B-Chat-1M的独特优势为什么选择GLM-4-9B-Chat-1M来实现这个功能它有以下几个杀手锏1M超长上下文这是目前开源模型中顶级的上下文长度。意味着你可以把整个数据库的schema表结构描述放进去把几十个API的接口文档放进去把业务逻辑的详细说明放进去 模型能记住所有这些信息做出更准确的判断。多语言支持支持26种语言包括日语、韩语、德语等。如果你的系统需要服务国际用户这个特性非常实用。开源免费作为开源模型你可以自由部署、修改、商用没有使用限制和费用担忧。性能强劲在语义理解、数学推理、代码生成等方面都表现出色特别是在长文本任务上从官方的大海捞针实验数据看准确率很高。3. 环境准备快速部署GLM-4-9B-Chat-1M3.1 使用vLLM一键部署vLLM是一个高性能的推理引擎专门为大语言模型优化。用vLLM部署GLM-4-9B-Chat-1M就像给跑车装上专业赛道轮胎——又快又稳。如果你使用的是CSDN星图镜像部署已经完成了。只需要验证一下服务是否正常# 查看模型服务日志 cat /root/workspace/llm.log看到类似下面的输出就说明模型已经加载成功正在等待你的调用INFO: Started server process [1234] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:80003.2 通过Chainlit快速测试Chainlit是一个专门为LLM应用设计的UI框架可以快速搭建聊天界面。镜像中已经集成了Chainlit打开就能用。在浏览器中访问Chainlit界面简单问几个问题确认模型能正常响应你你好介绍一下你自己 GLM我是GLM-4-9B-Chat一个由智谱AI开发的大语言模型...如果能看到正常的对话回复说明基础环境已经就绪。接下来我们要给这个“聪明的脑袋”装上“能干的双手”。4. 实战开始构建数据库查询工具4.1 设计工具函数我们先从最简单的开始——让模型能查询数据库。假设我们有一个电商系统的订单表结构如下# 模拟的订单数据库实际项目中连接真实数据库 orders_database [ {order_id: 12345, customer: 张三, status: 已发货, amount: 299.00}, {order_id: 12346, customer: 李四, status: 待付款, amount: 599.00}, {order_id: 12347, customer: 王五, status: 已完成, amount: 1299.00}, ] # 工具函数查询订单状态 def query_order_status(order_id: str): 根据订单ID查询订单状态 参数 order_id: 订单编号 返回 订单信息字典包含客户、状态、金额等信息 for order in orders_database: if order[order_id] order_id: return order return {error: 订单不存在}这个函数很简单就是根据订单ID在“数据库”里查找。注意函数的文档字符串docstring要写清楚模型会根据这个描述来决定什么时候调用这个函数。4.2 定义工具描述模型需要知道每个工具能做什么、怎么用。我们需要用JSON格式描述工具tools [ { type: function, function: { name: query_order_status, description: 根据订单ID查询订单的详细信息包括客户姓名、订单状态、订单金额等, parameters: { type: object, properties: { order_id: { type: string, description: 订单编号如12345 } }, required: [order_id] } } } ]关键点name函数名要和实际函数名一致description用自然语言描述函数功能越详细越好parameters定义参数的类型和说明4.3 让模型学会使用工具现在我们把工具交给模型看看它怎么用import requests import json # 模型API地址假设部署在本地8000端口 API_URL http://localhost:8000/v1/chat/completions def chat_with_tools(user_message, tools): 与支持工具调用的模型对话 headers { Content-Type: application/json } data { model: glm-4-9b-chat-1m, messages: [ {role: user, content: user_message} ], tools: tools, tool_choice: auto # 让模型自己决定是否调用工具 } response requests.post(API_URL, headersheaders, jsondata) return response.json() # 测试一下 user_query 帮我查一下订单12345的状态 response chat_with_tools(user_query, tools) print(json.dumps(response, indent2, ensure_asciiFalse))模型的回复会包含一个特殊的结构告诉你它想调用哪个工具、参数是什么{ choices: [{ message: { role: assistant, content: null, tool_calls: [{ id: call_001, type: function, function: { name: query_order_status, arguments: {\order_id\: \12345\} } }] } }] }看到没有模型自己分析出需要调用query_order_status函数并且正确提取了参数order_id为12345。4.4 执行工具调用并继续对话模型说它要调用工具我们就帮它调用然后把结果返回给它def execute_tool_call(tool_call): 执行工具调用 function_name tool_call[function][name] arguments json.loads(tool_call[function][arguments]) if function_name query_order_status: result query_order_status(arguments[order_id]) return result else: return {error: f未知工具: {function_name}} # 完整的对话流程 def full_conversation(user_message): # 第一轮模型决定调用工具 response1 chat_with_tools(user_message, tools) tool_call response1[choices][0][message][tool_calls][0] # 执行工具 tool_result execute_tool_call(tool_call) # 第二轮把工具结果返回给模型让它生成最终回复 messages [ {role: user, content: user_message}, {role: assistant, content: None, tool_calls: [tool_call]}, {role: tool, content: json.dumps(tool_result), tool_call_id: tool_call[id]} ] data { model: glm-4-9b-chat-1m, messages: messages, tools: tools } response2 requests.post(API_URL, headersheaders, jsondata) final_reply response2[choices][0][message][content] return final_reply # 完整测试 result full_conversation(帮我查一下订单12345的状态) print(f模型最终回复{result})输出会是这样的模型最终回复订单12345的详细信息如下 - 客户张三 - 状态已发货 - 金额299.00元太棒了我们刚刚完成了一个完整的工具调用流程。模型不仅能理解用户意图还能自动选择正确的工具获取数据后生成友好的回复。5. 扩展能力集成API工具链5.1 添加更多工具函数单一的工具不够用我们来构建一个完整的工具链。除了查询数据库我们还可以让模型调用外部API。import smtplib from email.mime.text import MIMEText # 工具1数据库查询刚才已经实现了 def query_order_status(order_id: str): # ... 同上 ... # 工具2发送邮件通知 def send_email_notification(to_email: str, subject: str, content: str): 发送邮件通知 参数 to_email: 收件人邮箱 subject: 邮件主题 content: 邮件内容 # 这里简化了邮件发送逻辑实际项目中需要配置SMTP msg MIMEText(content, plain, utf-8) msg[Subject] subject msg[From] noreplyexample.com msg[To] to_email # 模拟发送成功 print(f[模拟] 发送邮件给 {to_email}) print(f主题{subject}) print(f内容{content}) return {status: success, message: 邮件发送成功} # 工具3获取天气信息 def get_weather(city: str): 获取城市天气信息 参数 city: 城市名称 # 模拟调用天气API weather_data { 北京: {weather: 晴, temp: 25°C, humidity: 40%}, 上海: {weather: 多云, temp: 28°C, humidity: 65%}, 广州: {weather: 阵雨, temp: 30°C, humidity: 85%}, } if city in weather_data: return weather_data[city] else: return {error: 暂不支持该城市}5.2 更新工具描述把所有工具的描述都提供给模型tools [ { type: function, function: { name: query_order_status, description: 根据订单ID查询订单的详细信息包括客户姓名、订单状态、订单金额等, parameters: { type: object, properties: { order_id: {type: string, description: 订单编号} }, required: [order_id] } } }, { type: function, function: { name: send_email_notification, description: 发送邮件通知给指定收件人, parameters: { type: object, properties: { to_email: {type: string, description: 收件人邮箱地址}, subject: {type: string, description: 邮件主题}, content: {type: string, description: 邮件正文内容} }, required: [to_email, subject, content] } } }, { type: function, function: { name: get_weather, description: 获取指定城市的天气信息包括天气状况、温度、湿度等, parameters: { type: object, properties: { city: {type: string, description: 城市名称如北京、上海} }, required: [city] } } } ]5.3 处理多个工具调用有时候用户的一个请求可能需要调用多个工具。比如“查一下订单12345的状态如果是已发货就发邮件通知客户。”模型可以智能地规划工具调用顺序def handle_complex_query(user_message): 处理可能需要多个工具调用的复杂查询 # 第一轮对话 response1 chat_with_tools(user_message, tools) message response1[choices][0][message] all_results [] # 如果有工具调用 if tool_calls in message and message[tool_calls]: messages [{role: user, content: user_message}] # 执行所有工具调用 for tool_call in message[tool_calls]: # 执行工具 tool_result execute_tool_call(tool_call) all_results.append(tool_result) # 添加到消息历史 messages.append({ role: assistant, content: None, tool_calls: [tool_call] }) messages.append({ role: tool, content: json.dumps(tool_result), tool_call_id: tool_call[id] }) # 最后让模型生成总结回复 data { model: glm-4-9b-chat-1m, messages: messages, tools: tools } response2 requests.post(API_URL, headersheaders, jsondata) final_reply response2[choices][0][message][content] return final_reply, all_results # 如果不需要工具调用直接返回回复 else: return message[content], [] # 测试复杂查询 query 先查一下订单12345的状态然后告诉我北京的天气 reply, results handle_complex_query(query) print(f用户查询{query}) print(f工具调用结果{results}) print(f模型回复{reply})模型会先调用query_order_status查订单再调用get_weather查天气最后生成一个综合回复。6. 高级技巧提升工具调用效果6.1 给模型更多上下文信息1M的上下文长度是我们的巨大优势。我们可以把业务规则、数据库schema、API文档都放进去# 在系统提示词中加入业务上下文 system_prompt 你是一个电商客服助手可以帮用户查询订单、发送通知、查询天气等。 数据库表结构 1. orders表存储订单信息 - order_id: 订单编号字符串 - customer: 客户姓名字符串 - status: 订单状态待付款/已付款/已发货/已完成 - amount: 订单金额浮点数 业务规则 1. 只有状态为已发货的订单才需要发送物流通知 2. 发送邮件时主题格式为[电商系统] {具体事项} 3. 天气查询支持国内主要城市 请根据用户请求选择合适的工具帮助用户解决问题。 # 在对话时加入系统提示 messages [ {role: system, content: system_prompt}, {role: user, content: user_message} ]6.2 处理模糊查询用户可能不会给出精确的信息比如“查一下我昨天的订单。” 这时候我们需要教模型如何追问# 添加一个工具查询用户最近订单 def query_recent_orders(customer_name: str, days: int 1): 查询用户最近N天的订单 # 模拟实现 pass # 在系统提示中加入指导 system_prompt 如果用户查询信息不完整请主动询问缺少的信息 1. 查询订单时需要订单编号或客户姓名 2. 发送邮件时需要收件人邮箱 3. 查询天气时需要城市名称 不要假设用户提供了所有必要信息必要时进行确认。 6.3 错误处理和降级方案工具调用可能失败我们需要教模型如何处理异常def execute_tool_call_with_fallback(tool_call): 执行工具调用带有错误处理和降级方案 try: result execute_tool_call(tool_call) # 如果工具返回错误 if error in result: return { status: error, message: f工具调用失败{result[error]}, suggestion: 请检查输入参数是否正确或联系管理员 } return {status: success, data: result} except Exception as e: # 异常处理 return { status: error, message: f系统错误{str(e)}, suggestion: 请稍后重试或使用其他方式查询 } # 在系统提示中告诉模型如何应对错误 system_prompt 工具调用可能失败如果遇到错误 1. 首先向用户道歉 2. 说明出现了什么问题 3. 提供替代方案或建议 4. 询问是否需要其他帮助 7. 完整示例智能客服助手让我们把所有内容整合起来构建一个完整的智能客服助手import json import requests from typing import List, Dict class SmartCustomerService: 智能客服助手 def __init__(self, api_url: str http://localhost:8000/v1/chat/completions): self.api_url api_url self.headers {Content-Type: application/json} # 定义所有可用工具 self.tools self._define_tools() # 系统提示词充分利用1M上下文 self.system_prompt self._create_system_prompt() def _define_tools(self) - List[Dict]: 定义所有工具 return [ { type: function, function: { name: query_order, description: 查询订单信息支持按订单ID、客户姓名、日期范围查询, parameters: { type: object, properties: { order_id: {type: string, description: 订单编号}, customer_name: {type: string, description: 客户姓名}, start_date: {type: string, description: 开始日期格式YYYY-MM-DD}, end_date: {type: string, description: 结束日期格式YYYY-MM-DD} } } } }, { type: function, function: { name: send_notification, description: 发送通知支持邮件、短信、站内信, parameters: { type: object, properties: { type: {type: string, enum: [email, sms, message], description: 通知类型}, recipient: {type: string, description: 接收人}, title: {type: string, description: 通知标题}, content: {type: string, description: 通知内容} }, required: [type, recipient, content] } } }, { type: function, function: { name: check_inventory, description: 检查商品库存, parameters: { type: object, properties: { product_id: {type: string, description: 商品ID}, product_name: {type: string, description: 商品名称} } } } } ] def _create_system_prompt(self) - str: 创建系统提示词 return 你是一个专业的电商客服助手拥有以下能力 1. 订单管理查询订单状态、物流信息、支付状态 2. 客户服务发送通知、处理咨询、解决问题 3. 商品查询检查库存、查询价格、推荐商品 业务规则 - 订单状态包括待付款、已付款、已发货、已完成、已取消 - 发货后24小时内更新物流信息 - 仅向已付款订单发送发货通知 - 库存少于10件时提示补货 请根据用户需求选择合适的工具提供帮助。如果信息不完整请主动询问。 def _call_tool(self, tool_name: str, arguments: Dict) - Dict: 实际调用工具 # 这里简化实现实际项目中连接真实服务 if tool_name query_order: return self._mock_query_order(arguments) elif tool_name send_notification: return self._mock_send_notification(arguments) elif tool_name check_inventory: return self._mock_check_inventory(arguments) else: return {error: f未知工具: {tool_name}} def _mock_query_order(self, args: Dict) - Dict: 模拟订单查询 # 简化实现 return { order_id: args.get(order_id, 12345), status: 已发货, customer: 张三, amount: 299.00, shipping_info: 快递公司顺丰运单号SF123456789 } def process_query(self, user_query: str) - str: 处理用户查询 # 准备消息 messages [ {role: system, content: self.system_prompt}, {role: user, content: user_query} ] # 第一轮获取模型回复可能包含工具调用 data { model: glm-4-9b-chat-1m, messages: messages, tools: self.tools, tool_choice: auto } response requests.post(self.api_url, headersself.headers, jsondata) result response.json() message result[choices][0][message] # 如果没有工具调用直接返回 if tool_calls not in message or not message[tool_calls]: return message[content] # 执行所有工具调用 tool_messages [] for tool_call in message[tool_calls]: tool_name tool_call[function][name] tool_args json.loads(tool_call[function][arguments]) # 执行工具 tool_result self._call_tool(tool_name, tool_args) # 记录工具调用和结果 tool_messages.extend([ { role: assistant, content: None, tool_calls: [tool_call] }, { role: tool, content: json.dumps(tool_result), tool_call_id: tool_call[id] } ]) # 第二轮把工具结果给模型生成最终回复 all_messages messages tool_messages data[messages] all_messages final_response requests.post(self.api_url, headersself.headers, jsondata) final_result final_response.json() return final_result[choices][0][message][content] # 使用示例 if __name__ __main__: assistant SmartCustomerService() # 测试各种查询 test_queries [ 帮我查一下订单12345的物流信息, 商品ABC还有库存吗, 通知客户张三他的订单已经发货了, 我昨天下的订单都发货了吗 ] for query in test_queries: print(f\n用户{query}) response assistant.process_query(query) print(f助手{response})这个完整的示例展示了如何定义多个工具函数创建详细的系统提示词处理工具调用链生成自然流畅的回复8. 总结8.1 核心价值回顾通过这个实践案例我们看到了GLM-4-9B-Chat-1M的Function Call功能如何改变开发方式从被动回答到主动执行模型不再只是回答问题而是能主动调用工具完成任务。降低开发门槛你不需要为每个功能都写一套复杂的逻辑只需要定义好工具函数模型就能智能调用。充分利用长上下文1M的上下文长度让你可以把完整的业务文档、API说明、数据库结构都提供给模型让它真正理解你的系统。灵活扩展工具链可以随时扩展添加新的数据库查询、API调用、业务逻辑模型都能快速适应。8.2 实际应用建议在实际项目中应用这个方案时我有几个建议从小处开始不要一开始就构建复杂的工具链。先从1-2个核心工具开始验证可行性再逐步扩展。详细描述工具工具函数的描述要尽可能详细准确。模型完全依赖这些描述来决定是否调用、如何调用。做好错误处理工具调用可能失败网络可能超时参数可能错误。要在代码层面做好异常处理并教模型如何应对。监控和优化记录模型的工具调用决策分析哪些调用成功、哪些失败不断优化工具描述和系统提示。安全第一工具调用涉及实际操作要特别注意权限控制。不要让模型能调用危险的操作如删除数据、修改配置等。8.3 未来展望Function Call只是开始。随着大模型能力的提升我们可以期待更智能的工具选择模型不仅能调用单个工具还能规划复杂的工具调用序列。动态工具发现系统运行时动态注册新工具模型自动学习使用。多模态工具结合图像识别、语音处理等多模态能力处理更复杂的任务。自主学习和优化模型根据使用反馈自动优化工具调用策略。GLM-4-9B-Chat-1M的1M上下文和强大的Function Call能力为我们打开了智能应用开发的新大门。现在你可以让模型真正成为你的智能助手而不仅仅是一个聊天伙伴。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。