1. 目标:让AI能查询天气,通过Function Calling调用天气工具。在昨天的基础上学习
2.实现逻辑:提示词写清晰
csharp
commonClass.SetSystemPrompt("查询指定城市的天气信息。用户询问天气时必须调用此函数获取准确数据");
天气工具:
csharp
public static object GetWeatherTool()
{
return new
{
type = "function",
function = new
{
name = "get_weather",
description = "查询指定城市的天气信息。用户询问天气时必须调用此函数获取准确数据。",
parameters = new
{
type = "object",
properties = new
{
city = new
{
type = "string",
description = "城市名称,例如:北京、上海、广州、深圳"
}
},
required = new[] { "city" }
}
}
};
}
主要实现代码
csharp
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using NCalc;
namespace ConsoleApp1.Common
{
public class CommonHelper
{
private readonly HttpClient _httpClient = new HttpClient();
private const string AMAP_KEY = "这里写你的天气 高德 天气应用Key";
/// <summary>
/// 执行本地工具
/// </summary>
public async Task<string> ExecuteTool(string toolName, string arguments)
{
switch (toolName)
{
case "get_current_time":
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
case "calculator": //计算器
return CalculateExpression(arguments);
case "get_weather": //天气
return await GetWeather(arguments);
// 未来可以添加更多工具
default:
return $"未知工具: {toolName}";
}
}
private string CalculateExpression(string arguments)
{
try
{
// 解析参数
var doc = JsonDocument.Parse(arguments);
string expression = doc.RootElement.GetProperty("expression").GetString();
// 替换中文符号和空格
expression = expression.Replace("×", "*")
.Replace("÷", "/")
.Replace(" ", "");
// 使用DataTable计算
var table = new DataTable();
var result = table.Compute(expression, "");
return result.ToString();
}
catch (Exception ex)
{
return $"计算错误: {ex.Message}";
}
}
private async Task<string> GetWeather(string city)
{
try
{
// 1. 地理编码:城市名 → adcode
string geoUrl = $"https://restapi.amap.com/v3/geocode/geo?address={city}&key={AMAP_KEY}";
var geoResponse = await _httpClient.GetStringAsync(geoUrl);
var geoDoc = JsonDocument.Parse(geoResponse);
var adcode = geoDoc.RootElement
.GetProperty("geocodes")[0]
.GetProperty("adcode")
.GetString();
// 2. 查询天气
string weatherUrl = $"https://restapi.amap.com/v3/weather/weatherInfo?city={adcode}&key={AMAP_KEY}";
var weatherResponse = await _httpClient.GetStringAsync(weatherUrl);
var weatherDoc = JsonDocument.Parse(weatherResponse);
var live = weatherDoc.RootElement.GetProperty("lives")[0];
string weather = live.GetProperty("weather").GetString();
string temperature = live.GetProperty("temperature").GetString();
string wind = live.GetProperty("windpower").GetString();
return $"{city}:{weather},{temperature}°C,风力{wind}级";
}
catch (Exception ex)
{
return $"获取真实天气失败: {ex.Message}";
}
}
}
}
混合调用:
csharp
public static async Task Day()
{
try
{
Console.WriteLine($"-------------天气工具测试-------------\r\n");
CommonClass commonClass = new CommonClass();
//commonClass.SetSystemPrompt("查询指定城市的天气信息。用户询问天气时必须调用此函数获取准确数据");
// 设置系统提示
commonClass.SetSystemPrompt(@"你是一个智能助手。
- 当用户询问时间时,调用 get_current_time
- 当用户询问数学计算时,调用 calculator
- 当用户询问天气时,调用 get_weather
- 如果是闲聊,直接回答,不需要调用工具");
// 定义工具(天气 + 时间 + 计算器,多工具协同)
//var tools = new object[] { CommonClass.GetCurrentTimeTool(), CommonClass.GetCalculatorTool(), CommonClass.GetWeatherTool() }; //
object[] tools = commonClass.GetAllTools(); //获取所有工具(统一注册)
Console.WriteLine("用户:现在几点了?");
var reply = await commonClass.CallAPIWithTools("现在几点了?", tools);
Console.WriteLine($"AI:{reply}\n");
// 测试1:查询北京天气
//Console.WriteLine("用户:西安今天天气怎么样?");
//var reply1 = await commonClass.CallAPIWithTools("西安今天天气怎么样?", tools);
//Console.WriteLine($"AI回答:{reply1}\n");
// ===== 测试5:混合意图 =====
Console.WriteLine("【测试:混合意图】");
Console.WriteLine("用户:北京天气怎么样?现在几点了?");
var reply5 = await commonClass.CallAPIWithTools("北京天气怎么样?现在几点了?", tools);
Console.WriteLine($"AI:{reply5}\n");
Console.WriteLine("用户:西安美食推荐?");
var reply1 = await commonClass.CallAPIWithTools("西安美食推荐?", tools);
Console.WriteLine($"AI回答:{reply1}\n");
}
catch (Exception ex)
{
Console.WriteLine($"异常:{ex.Message}");
}
}
主要设置:请求体的tool_choice设置auto
csharp
//请求体 第1次请求:带tools参数
var requestBody = new
{
model = "qwen-turbo",
messages = _history, //MessagesIn
tools = tools,
tool_choice = "auto", //让AI自动决定是否调用工具
stream = false
};
- 注册高德天气应用步骤:调用高德天气,需注册高德应用天气,申请Key。申请步骤详解:
【1】注册/登录高德开放平台:访问高德开放平台官网,如果没有账号,先点击"注册"完成开发者注册;已有账号则直接登录。
【2】进入控制台创建应用:登录后进入"控制台",在左侧菜单找到"应用管理" -> "我的应用"。点击右上角的"创建新应用",给你的应用起个名字(比如"我的AI助手"),选择好应用类型,然后提交。
【3】添加Key并选择"Web服务":进入刚创建的应用,点击"添加Key"。在弹出的对话框里,最关键的步骤是服务平台一定要选择"Web服务"(不是Web端JS API)。之后填好Key名称,勾选同意条款,提交就可以了。
【4】获取你的Key:添加成功后,你就能在应用详情里看到生成的Key字符串了,复制保存好就行。
⚠️ 避坑小贴士
别选错平台:申请时,服务平台务必选"Web服务"。选错了类型(比如选成iOS/Android SDK),调用天气接口时就会报"INVALID_USER_KEY"这个错。
注意每日调用限额:个人认证的开发者账号,天气接口每日免费调用限额是5,000次。学习和个人项目完全够用,注意别超限就行。