最近在玩大模型 Function Calling(函数调用),正好拿阿里通义千问 + 高德天气 API 练了个手,做了一个 Streamlit 智能天气助手。你只需要用自然语言问一句“今天北京天气怎么样?”,大模型就会自动判断是否需要查天气,然后调用高德 API 拿到实时数据,最后组织成流畅的回答。

效果大概长这样:

text
用户:北京今天适合出门吗?
助手:北京今天晴,温度22℃,风力3级,湿度45%,非常适合户外活动。
下面就把实现思路、核心代码和使用方法分享给大家。

一、项目结构

text
weather_assistant/
├── app.py                 # 主程序(Streamlit UI + 逻辑)
├── requirements.txt      # 依赖
└── README.md


主要依赖:

streamlit – 快速构建 Web UI

dashscope – 阿里通义千问 SDK

requests – 调用高德 API

二、技术原理:什么是 Function Calling?


传统的大模型只能“动嘴”,问它天气它只能凭训练数据回答,无法获取实时信息。而 Function Calling 让模型可以“动手”——模型判断用户意图后,返回一个函数调用请求,我们执行这个函数(比如查天气),再把结果回传给模型,由模型生成最终回答。

流程如下:

text
用户提问 → 通义千问(判断需要查天气)→ 返回工具调用指令(get_weather)
→ 执行高德 API 获取真实天气 → 把结果传给模型 → 模型生成自然语言回答


三、核心代码解析


1. 高德天气查询函数


首先封装一个 get_weather(city),它做了两件事:

通过高德地理编码 API 把城市名转成 adcode

用 adcode 获取实时天气

def get_weather(city: str):
    # 1. 地理编码:城市 → adcode
    geo_url = f"https://restapi.amap.com/v3/geocode/geo?address={city}&output=JSON&key={AMAP_API_KEY}"
    geo_resp = requests.get(geo_url).json()
    adcode = geo_resp["geocodes"][0]["adcode"]

    # 2. 获取天气
    weather_url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={adcode}&key={AMAP_API_KEY}"
    weather_resp = requests.get(weather_url).json()
    live = weather_resp["lives"][0]
    weather_text = f"城市:{live['city']}\n天气:{live['weather']}\n温度:{live['temperature']}℃..."
    return live, weather_text


2. 定义工具(Tools)


告诉大模型它能调用哪些函数,以及函数参数是什么。

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的实时天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"}
                },
                "required": ["city"]
            }
        }
    }
]


3. 大模型调用 + 工具执行


核心函数 ask_weather_with_llm(user_query) 完整实现了两次模型调用:

# 第一次调用:带上 tools 参数
response = Generation.call(
    model="qwen-turbo",
    messages=messages,
    tools=tools,
    result_format="message"
)

model_message = response.output.choices[0].message

# 如果模型要求调用工具
if model_message.get("tool_calls"):
    tool_call = model_message["tool_calls"][0]
    func_name = tool_call["function"]["name"]
    func_args = json.loads(tool_call["function"]["arguments"])

    # 执行真正的天气查询
    weather_data, weather_text = available_functions[func_name](**func_args)

    # 将工具结果追加到对话历史
    messages.append(model_message)
    messages.append({
        "role": "tool",
        "tool_call_id": tool_call["id"],
        "content": weather_text
    })

    # 第二次调用:让模型基于真实天气生成回答
    second_response = Generation.call(
        model="qwen-plus",
        messages=messages,
        result_format="message"
    )
    final_reply = second_response.output.choices[0].message.get("content")
    return final_reply
else:
    # 不需要工具时直接返回
    return model_message.get("content")


4. Streamlit 界面
简单干净,一个输入框 + 按钮:

st.title("🌤️ 智能天气助手")
user_input = st.text_input("请输入您的问题")
if st.button("查询"):
    answer = ask_weather_with_llm(user_input)
    st.write(answer)
pip install streamlit dashscope requests


四、总结

通过这个项目可以看到,大模型 + 外部工具的组合可以轻松做出实用、交互自然的智能应用。Function Calling 把“理解意图”和“执行动作”解耦,开发者只需要定义好工具,剩下的事情交给模型。

你可以基于这个模板快速扩展其他功能,例如:

  • 接入新闻 API → 自动播报今日要闻

  • 接入邮件服务 → 让模型帮你写邮件并发送

  • 接入数据库 → 用自然语言查询业务数据

希望这篇文章能帮你快速上手大模型 Function Calling~

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐