在使用 DeepSeek 大模型进行应用开发时,很多同学会优先选择现成的 Agent 框架,例如 LangChain、LlamaIndex 等。然而在一些对性能敏感、或需要完全掌控逻辑的场景中,我们更希望 以最原生、最轻量的方式 直接实现工具调用(function calling)。

本文将结合一段可直接运行的 Python 代码,完整讲解如何使用 DeepSeek API 实现 原生的 Agent 工具调用,且完全不依赖任何框架。


🌟 最终效果预览

用户输入:

帮我查一下北京的天气

DeepSeek 根据 prompt 自动决定是否调用工具 → 发起工具调用 → 本地执行天气接口 → 将结果回传给模型 → 模型基于结果生成最终输出。这一全链路完全由我们手写实现。

最终你将获得一个真正意义上“原生、可控、可扩展”的 Agent 调用框架。


🧠 核心思路

原生实现工具调用的过程可以拆分为 4 步:

  1. 定义工具(functions 参数):告诉模型可用哪些函数。

  2. 让模型决定是否调用工具:设置 tool_choice="auto"

  3. 接收模型生成的 tool_call:解析调用的函数名和参数。

  4. 本地执行工具 → 将执行结果回传模型:实现类似 OpenAI function calling 的闭环。

这一模式适用于:

  • 自定义 Agent 系统

  • 需要对调用链路完全掌控的场景

  • 想做本地函数、数据库、互联网 API 调用的开发者


📌 完整示例代码讲解

下面是完整可运行的代码,包含天气查询函数、工具声明、模型调用、二次回传等完整链路。

import json

from openai import OpenAI
import os
import requests

client = OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com")

def get_weather(city: str, units: str = "metric") -> str:
    """
    查询指定城市的天气信息。
    """
    params = {
        "q": city,
        "appid": os.getenv("OPENWEATHER_API_KEY"),
        "units": units,
        "lang": "zh_cn"
    }
    try:
        response = requests.get("https://api.openweathermap.org/data/2.5/weather", params=params)
        response.raise_for_status()
        data = response.json()

        weather_info = {
            "城市": data.get("name"),
            "温度": data["main"].get("temp"),
            "体感温度": data["main"].get("feels_like"),
            "湿度": data["main"].get("humidity"),
            "气压": data["main"].get("pressure"),
            "天气": data["weather"][0].get("description"),
            "风速": data["wind"].get("speed"),
        }
        return str(weather_info)
    except requests.exceptions.RequestException as e:
        return f"查询失败:{str(e)}"


# 工具定义(function calling)
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询指定城市的天气信息,使用英文城市名称。",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"},
                    "units": {
                        "type": "string",
                        "enum": ["metric", "imperial"],
                        "default": "metric",
                    },
                },
                "required": ["city"],
            },
        },
    }
]

messages = [
    {"role": "system", "content": "You are a helpful assistant"},
    {"role": "user", "content": "帮我查一下北京的天气"},
]

# 第一次请求,由模型决定是否调用工具
resp = client.chat.completions.create(
    model="deepseek-chat",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

msg = resp.choices[0].message

# 模型触发工具调用
if msg.tool_calls:
    for tool_call in msg.tool_calls:
        if tool_call.function.name == "get_weather":
            args = json.loads(tool_call.function.arguments)
            result = get_weather(**args)

            messages.append(msg)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "name": "get_weather",
                "content": result,
            })

    # 第二次请求:将工具执行结果喂给模型
    final_resp = client.chat.completions.create(
        model="deepseek-chat",
        messages=messages,
    )
    print(final_resp.choices[0].message.content)
else:
    print(msg.content)

🔍 关键逻辑逐段解析

1. 定义工具

工具的功能、参数、类型严格遵循 JSON Schema。DeepSeek 会自动理解其结构。

"type": "function",
"function": { ... }

2. 发起第一次对话:让模型自行判断是否需要调用工具

tool_choice="auto"

模型会根据用户需求决定是否调用 get_weather

3. 处理模型返回的 tool_calls

如果模型决定调用:

if msg.tool_calls:
    ...

解析参数,真正执行 Python 函数。

4. 将工具执行结果回传模型

这是 function calling 的关键步骤:

messages.append({"role": "tool", "content": result})

模型收到后,会基于工具结果生成最终自然语言输出。


🛠️ 如何拓展更多工具?

你可以轻松扩展更多工具:

  • 数据库查询

  • 文件系统操作

  • 第三方 API

  • 本地知识库检索

  • 操控浏览器(Playwright)

只需要:

  1. 按 JSON Schema 描述参数

  2. 写一个 Python 函数

  3. 在 tools 数组里注册

就能被模型自动识别和调用。


🚀 实际生产可用吗?

答案是:完全可以

你可以基于文中逻辑搭建:

  • 企业内部 Agent 系统

  • 任务分解型助理

  • 数据分析问答系统

  • 智能客服

  • 工作流调度系统

优点:

  • 无额外框架依赖

  • 更高透明度与可控性

  • 可严格限制模型权限

  • 可监控所有函数调用


📦 示例项目建议结构

project/
├── tools/
│   ├── weather.py
│   └── database.py
├── core/
│   ├── agent.py
│   └── schema.py
├── main.py
└── README.md

这样你就能进一步搭建更复杂的 Agent 系统。


🎉 总结

本文手把手演示了一个完全原生、无任何框架依赖的 DeepSeek 工具调用实现示例。通过手写 JSON Schema + Tool Call 解析 + 二次对话,你可以构建一个高度可控的 Agent 框架。

如果你正准备做自己的 AI 应用、ChatOps、智能助手,这种方式会给你最自由的开发体验。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐