flutter实现Function Call
根据Function Call实现用大模型来调用方法。以下实现用操作空调。
一、选用大模型
阿里云百炼:筛选具有Function Call能力的模型
讯飞星火大模型:Spark 4.0Ultra、Max现已支持system、Function Call功能
二、代码实现(通义千问3-Max)
import 'dart:convert';import 'package:dio/dio.dart';class FunctionCallService {static const String _tag = "FunctionCallService";static final FunctionCallService instance = FunctionCallService._();FunctionCallService._();factory FunctionCallService.getInstance() {return instance;}final List<Map<String, dynamic>> tools = [{"type": "function","function": {"name": "controlAirConditioner","description": "打开空调并设置参数","parameters": {"type": "object","properties": {"action": {"type": "bool", "description": "打开或关闭"},"room": {"type": "string", "description": "空调所在房间"},"name": {"type": "string", "description": "空调名称"},"temperature": {"type": "number", "description": "目标温度 (16-45摄氏度)"},"mode": {"type": "string","description": "运行模式","enum": ["cool", "heat", "fan", "dry", "auto"]},"fan_speed": {"type": "string","description": "风速","enum": ["low", "medium", "high", "auto"]}},"required": ["name"]},}}];final apiUrl ="https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";// apiKey获取地址:https://bailian.console.aliyun.com/?spm=a2ty02.30268951.0.0.21ae74a17iekVZ&tab=model#/api-keyfinal apiKey = "sk-xxx";final model = "qwen3-max";Future<String> controlAirConditioner({required bool action,String? room,String? name,double? temperature,String? mode,String? fanSpeed}) async {// 实际操作return '操作成功';}final Dio _dio = Dio();void handleFunctionCall() async {var messages = [];messages.add({'role': "system","content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息。"});messages.add({"role": "user", "content": "打开客厅空调到38度"});print('$_tag 开始调用模型');Response response = await _dio.post(apiUrl,data: {'model': model, 'messages': messages, 'tools': tools},options: Options(headers: {'Authorization': 'Bearer $apiKey'},));print('$_tag 第一次调用模型的请求参数:$messages');print('$_tag 第一次调用模型的回答结果:${response.data['choices'][0]['message']}');messages.add(response.data['choices'][0]['message']);parseFunctionCall(response.data['choices'][0]['message']['tool_calls'][0]['function'],messages);}void parseFunctionCall(Map toolCall, List messages) async {if (toolCall['name'] == 'controlAirConditioner') {var arguments = toolCall['arguments'];var args = jsonDecode(arguments);var content = await controlAirConditioner(action: args['action'],room: args['room'],name: args['name'],mode: args['mode'],fanSpeed: args['fan_speed'],temperature: args['temperature'] != null? double.parse(args['temperature'].toString()): null);messages.add({'role': 'tool', 'content': content});Response response = await _dio.post(apiUrl,data: {'model': model, 'messages': messages, 'tools': tools},options: Options(headers: {'Authorization': 'Bearer $apiKey'},));print('$_tag 第二次调用模型的请求参数:$messages');print('$_tag 第二次调用模型的回答结果:${response.data['choices'][0]['message']}');}}
}
📌 运行结果
I/flutter (23387): FunctionCallService 开始调用模型
I/flutter (23387): FunctionCallService 第一次调用模型的请求参数:[{role: system, content: 不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息。}, {role: user, content: 打开客厅空调到38度}]
I/flutter (23387): FunctionCallService 第一次调用模型的回答结果:{content: , role: assistant, tool_calls: [{function: {arguments: {"name": "客厅空调", "temperature": 38, "action": true}, name: controlAirConditioner}, id: call_58b2365bdd4e4d9da6f65fb1, index: 0, type: function}]}
I/flutter (23387): FunctionCallService 第二次调用模型的请求参数:[{role: system, content: 不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息。}, {role: user, content: 打开客厅空调到38度}, {content: , role: assistant, tool_calls: [{function: {arguments: {"name": "客厅空调", "temperature": 38, "action": true}, name: controlAirConditioner}, id: call_58b2365bdd4e4d9da6f65fb1, index: 0, type: function}]}, {role: tool, content: 操作成功}]
I/flutter (23387): FunctionCallService 第二次调用模型的回答结果:{content: 客厅空调已成功打开,并设置温度为38度。, role: assistant}