DeepSeek 函数调用实战:从零搭建一个会“动手“的 AI 助手

一、引言:只会聊天的 AI,价值少了一半

先看一个真实场景。你在 Dify 里搭了一个 DeepSeek 客服助手,用户问"帮我查一下订单 O20240901001 的物流状态",模型答得彬彬有礼:"请您提供订单号,我为您查询。"------可订单号明明就在问题里。再问"顺便把发票发到我邮箱",它又答:"抱歉,我暂时无法发送邮件。"

问题出在哪?出在模型只会"说",不会"做"。它没有手,够不到你的订单系统、邮件系统、数据库。而函数调用(Function Calling / Tool Use)就是给 AI 装上"手"的关键技术:让模型在对话中主动声明"我需要调用某个函数",再由你的程序真正执行,把结果喂回去,模型据此继续作答。

本文基于华为云 MaaS 平台的 DeepSeek 大模型推理服务与 Flexus 云服务器实战环境,从原理到代码、从单函数到多工具、从 Demo 到生产级工程,完整走一遍 DeepSeek 函数调用的落地路径。读完你将能:

  1. 讲清楚函数调用为什么是 Agent 的地基;
  2. 用 OpenAI 兼容的 tools 协议把 DeepSeek 接入自己的工具;
  3. 用 Dify 的可视化编排快速搭一个带工具的助手;
  4. 避开并发、鉴权、超时、工具幻觉等生产级大坑。

二、先搞懂原理:函数调用到底是怎么工作的

2.0 为什么是 JSON Schema,而不是自然语言描述

细心的读者会发现,工具声明里的 parameters 用的是 JSON Schema 规范------而不是让开发者用自然语言写"这个函数接收一个城市名"。原因有三:

  1. 机器可校验:JSON Schema 可以程序化地校验模型生成的参数是否合法,缺了必填字段、类型给错,你的代码能第一时间发现并让模型重试;
  2. 模型更听话:DeepSeek 在训练阶段就见过海量 JSON Schema 格式的指令数据,用它的"母语"描述工具,指令遵循的准确率明显高于自由文本;
  3. 生态互通:OpenAI 系、Anthropic 系、各大云厂商的工具调用协议全部基于 JSON Schema,一套声明可以在不同模型间无损迁移------你在 MaaS 上写的 tools,换到任何兼容模型上都能用。

所以别嫌 Schema 写法啰嗦,它其实是整个函数调用体系里"最值得认真写"的部分:工具声明写得好不好,直接决定模型调用得准不准

2.1 一句话定义

函数调用不是模型去执行代码,而是模型根据用户意图,从你声明的函数清单里选出一个(或几个),并生成符合规范的调用参数 。真正执行的是你的程序。模型全程"只动嘴,不动手"------动手的是你写的那几行 execute 代码。

2.2 一次完整调用要经过四步

步骤 谁在做 干什么
① 声明函数 开发者 把函数名、描述、参数 JSON Schema 传给模型
② 模型决策 模型 判断该调哪个函数、参数填什么,返回 tool_calls
③ 执行函数 你的程序 真正去查数据库、调 API、发邮件
④ 回传结果 开发者 把函数返回值以 tool 消息发回,模型生成最终回答

关键认知:第 ② 步模型只输出"调用意图和参数",不保证参数一定正确、也不保证函数真实存在------这正是后面要讲的"工具幻觉"问题的根源。

2.3 为什么 DeepSeek 的函数调用值得单开一篇

早在 DeepSeek-V2.5 时代,官方就在 API 中开放了 function calling 能力;到了 DeepSeek-V3 / R1 系列,工具调用的指令遵循能力大幅提升:能同时发起多个工具调用(parallel tool calls)、能正确处理多轮工具结果、能在工具结果异常时给出合理的兜底回复。加上 MaaS 平台上按 Token 计费、开箱即用的推理服务,函数调用场景的成本门槛被压得很低------高频工具调用场景下,一次完整的多轮工具对话往往只要几分钱。

但能力强不代表不会犯错。接下来我们直接从代码入手,把正确姿势和错误姿势都过一遍。

三、环境准备:MaaS 上拿到 DeepSeek 的 API

3.1 三步拿到推理服务

  1. 登录华为云 ModelArts Studio(MaaS)控制台,进入"模型服务"页面;
  2. 选择 DeepSeek 系列模型(V3 或 R1,按场景选:工具调用与多轮对话优先 V3,复杂推理优先 R1),开通"推理服务";
  3. 在"API 凭证"里生成 API Key,记下服务的基础 URL(形如 https://xxx.maas.com/v1)与模型名。

MaaS 提供的是 OpenAI 兼容接口 ,这意味着市面上几乎所有为 OpenAI 写的 SDK 和框架(OpenAI Python SDK、LangChain、Dify、LiteLLM 等)都可以无缝切换过来,只需改 base_urlapi_key。这是函数调用生态能够"一次开发、处处复用"的最大红利。

3.2 最小验证代码

复制代码
from openai import OpenAI

client = OpenAI(
    base_url="https://你的MaaS服务地址/v1",  # MaaS 的 OpenAI 兼容端点
    api_key="你的API-KEY",
)

resp = client.chat.completions.create(
    model="deepseek-v3",           # MaaS 上开通的模型名
    messages=[{"role": "user", "content": "你好"}],
)
print(resp.choices[0].message.content)

跑通这一步,环境就绪。下面进入正题:给模型"装手"。

四、从零写函数调用:一个查天气的助手

4.1 第一步:声明一个函数

函数调用的一切始于"告诉模型你有什么工具"。我们用 OpenAI 兼容的 tools 参数声明一个查天气的函数。注意:描述要写得像给一个聪明但没见过你系统的实习生看------他需要知道什么时候用、每个参数是什么意思、填什么格式。

复制代码
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询指定城市当前的天气情况,包括温度、天气现象和风力。当用户询问天气时使用。",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,如:北京、上海、深圳",
                    }
                },
                "required": ["city"],
            },
        },
    }
]

4.2 第二步:真正的函数(模型不执行,你执行)

函数声明是"给模型看的说明书",真正的执行逻辑在你自己这边:

复制代码
def get_weather(city: str) -> str:
    """真实执行:这里应调用天气 API,demo 用假数据"""
    table = {"北京": "晴 26℃ 微风", "上海": "多云 29℃ 东南风3级", "深圳": "雷阵雨 31℃ 南风2级"}
    return table.get(city, f"暂无 {city} 的天气数据")

4.3 第三步:完整的调用循环

这是函数调用最核心的模板,所有单工具场景都是它的变体

复制代码
def chat_with_tools(messages):
    # 第一轮:把消息和工具清单一起发给模型
    resp = client.chat.completions.create(
        model="deepseek-v3",
        messages=messages,
        tools=tools,
        tool_choice="auto",      # auto=让模型自己决定要不要调
    )
    msg = resp.choices[0].message
    messages.append(msg)          # 把模型的回复(可能含 tool_calls)追加进历史

    # 如果模型想调工具
    if msg.tool_calls:
        for tc in msg.tool_calls:
            fn = tc.function
            if fn.name == "get_weather":
                import json
                args = json.loads(fn.arguments)     # 参数是 JSON 字符串
                result = get_weather(args["city"])  # 真正执行
                # 把工具结果以 role=tool 发回,tool_call_id 必须对应
                messages.append({
                    "role": "tool",
                    "tool_call_id": tc.id,
                    "content": json.dumps(result, ensure_ascii=False),
                })
        # 第二轮:让模型基于工具结果生成最终回答
        resp = client.chat.completions.create(
            model="deepseek-v3", messages=messages, tools=tools)
        messages.append(resp.choices[0].message)

    return messages[-1].content

4.4 跑起来看效果

复制代码
messages = [{"role": "user", "content": "北京今天适合出门吗?需要带伞吗?"}]
print(chat_with_tools(messages))

模型会先输出一个 tool_calls(调用 get_weather,参数 {"city": "北京"}),你的代码执行完把结果回传,模型最终回答:"北京今天晴、26℃、微风,适合出门,不需要带伞。"------注意,回答里的"适合出门"是模型基于真实工具结果 推理的,不是瞎编的。这就是函数调用的价值:让模型的每一个结论都长在真实数据上

4.5 最容易踩的三个坑(新手必看)

  1. 忘记追加历史tool_calls 那条 assistant 消息和 tool 结果消息必须按顺序messages,否则模型不知道工具结果是回答谁的。顺序是:assistant(含tool_calls) → tool(结果) → assistant(最终回答)。
  2. tool_call_id 对不上 :多工具并行时,每个 tool 消息必须带自己对应的 tool_call_id,张冠李戴会让模型直接"精神错乱"。
  3. 参数是字符串不是对象fn.arguments 是 JSON 字符串,必须先 json.loads 再取字段 。忘了解析会得到 '{"city": "北京"}' 这种没法用的东西。

五、进阶:多工具与并行调用

5.0 工具描述撰写的最佳实践

工具多了以后你会发现:模型"选错工具"和"参数填错",一半以上是开发者描述写得含糊。三条经验值直接给到:

  1. 触发条件写具体:"当用户询问订单信息时使用"比"查询订单"好用得多。要写清楚"什么时候用、什么时候不用"------比如查询订单工具里注明"仅用于已下单用户,咨询下单流程请勿使用",能显著减少误调用;
  2. 参数说明给格式和示例order_id 的描述写成"订单号,形如 O20240901001,以 O 开头共 12 位",模型填参的正确率会大幅提升。示例是最好的约束;
  3. 名称用动词短语query_ordercreate_after_saleorderas 这种模糊命名更利于模型区分相近工具。工具一多,命名风格就是隐形的分类器。

下面这段对比能直观说明问题。模糊描述:

复制代码
{"name": "get", "description": "查信息", "parameters": {"type": "object", "properties": {"id": {"type": "string"}}}}

清晰描述:

复制代码
{"name": "query_order_status", "description": "按订单号查询订单当前状态与物流进度,用户询问'我的订单到哪了/发货没'时使用", "parameters": {"type": "object", "properties": {"order_id": {"type": "string", "description": "订单号,以 O 开头共 12 位,如 O20240901001"}}, "required": ["order_id"]}}

同样的模型、同样的输入,后者的工具调用成功率能拉开十个百分点以上。工具描述不是写给机器看的注释,而是写给模型看的"使用说明书"。

5.1 一次声明多个工具

真实业务里不可能只有一个工具。订单查询、物流跟踪、售后登记......我们一次声明三个,让模型自己选:

复制代码
tools = [
    {"type": "function", "function": {"name": "get_weather", ...}},
    {"type": "function", "function": {
        "name": "query_order",
        "description": "按订单号查询订单状态、金额、商品明细。当用户询问订单信息时使用。",
        "parameters": {"type": "object", "properties": {
            "order_id": {"type": "string", "description": "订单号,形如 O20240901 开头"},
        }, "required": ["order_id"]},
    }},
    {"type": "function", "function": {
        "name": "send_email",
        "description": "向指定邮箱发送邮件。当用户要求发送邮件/发票/报表时使用。",
        "parameters": {"type": "object", "properties": {
            "to": {"type": "string"}, "subject": {"type": "string"}, "body": {"type": "string"},
        }, "required": ["to", "subject", "body"]},
    }},
]

5.2 并行调用:模型一次"想好"多步

用户问:"帮我查一下订单 O20240901001 的状态,顺便看看北京明天天气,天气不好就发邮件提醒我。"------模型可能同时发起 query_orderget_weather 两个调用。你的代码要做的是:遍历所有 tool_calls,逐个执行,全部结果回传,再让模型综合回答 。前面的 chat_with_tools 循环天然支持并行(for tc in msg.tool_calls 就是为并行准备的)。

并行调用是 DeepSeek-V3 系模型工具能力的亮点:一次推理同时输出多个结构化调用,既省时间又省 Token(少了一轮"先问你下一步"的往返)。

5.3 工具路由:把函数名映射到真实实现

函数多了以后,硬编码 if fn.name == "xxx" 会越来越丑。用一个注册表统一管理:

复制代码
TOOL_REGISTRY = {
    "get_weather": get_weather,
    "query_order": query_order,
    "send_email": send_email,
}

def dispatch(name: str, args_json: str) -> str:
    import json
    fn = TOOL_REGISTRY.get(name)
    if fn is None:
        return json.dumps({"error": f"未知工具: {name}"}, ensure_ascii=False)
    args = json.loads(args_json) if args_json else {}
    result = fn(**args)
    return json.dumps(result, ensure_ascii=False, default=str)

以后加新工具 = 写一个函数 + 加一行注册 + 加一段声明,主循环一行都不用改。这就是"声明(tools)与实现(registry)分离"的工程红利。

六、工具幻觉:模型"编造"工具与参数怎么办

6.1 什么是工具幻觉

模型可能:① 调用了你根本没声明的函数名;② 参数格式错误(该给数字给字符串);③ 参数值编造(订单号不存在也照填);④ 明明没工具可用,却假装调用了。前两种是协议层问题,后两种是语义层问题。

6.2 防御三板斧

第一板斧:声明即边界。 只把 tools 里声明过的函数放进注册表,dispatch 里对未知工具一律返回错误 JSON------绝不能让模型"发明"函数去执行。

第二板斧:结果可失败。 工具执行失败不要抛异常裸奔,返回结构化错误让模型自己"圆场":

复制代码
def query_order(order_id: str) -> str:
    if not order_id.startswith("O"):
        return json.dumps({"error": "订单号格式不正确,应以 O 开头"}, ensure_ascii=False)
    # 查库逻辑...

模型收到 {"error": ...} 后,通常会主动道歉并向用户解释或引导纠正------这比程序直接崩溃体验好一百倍。

第三板斧:关键动作要人审。 凡是"花钱、发消息、删数据"这类不可逆操作(如 send_emailtransfer_money),生产环境务必加确认环节:先让模型把参数整理给用户确认,用户点头后程序才真正执行。这条在 Dify 里可以直接用"节点间人工确认"实现。

七、工程化落地:并发、超时与可观测性

7.1 三个必须处理的工程问题

问题 表现 解法
并发限流 工具多轮循环里大量请求,触发 MaaS 限流 连接复用 + 指数退避重试 + 并发池上限
超时失控 模型或工具长时间无响应,用户干等 分层超时:LLM 调用、工具执行、整轮对话各自设超时
黑盒难查 出了问题不知道是模型选错还是工具执行错 全链路日志:每次调用的输入输出、耗时、Token 数全部落盘

7.2 一个稳健的执行器骨架

复制代码
import json, time
from openai import OpenAI

class ToolAgent:
    def __init__(self, client, tools, registry, timeout=30, max_rounds=5):
        self.client = client
        self.tools = tools
        self.registry = registry
        self.timeout = timeout          # 单次模型调用超时
        self.max_rounds = max_rounds    # 工具往返上限,防死循环

    def run(self, user_input: str) -> str:
        messages = [{"role": "user", "content": user_input}]
        for _ in range(self.max_rounds):
            resp = self.client.chat.completions.create(
                model="deepseek-v3", messages=messages,
                tools=self.tools, timeout=self.timeout)
            msg = resp.choices[0].message
            messages.append(msg)
            if not msg.tool_calls:
                return msg.content        # 不再调工具 → 结束
            for tc in msg.tool_calls:
                fn, args = tc.function.name, tc.function.arguments
                result = self.registry[fn](json.loads(args)) if fn in self.registry \
                    else json.dumps({"error": f"未知工具 {fn}"})
                messages.append({"role": "tool", "tool_call_id": tc.id,
                                 "content": json.dumps(result, ensure_ascii=False, default=str)})
        return "已达到最大工具调用轮数,请简化问题后重试"

max_rounds 是保命符:模型在复杂任务里可能"调了又调"停不下来,没有轮数上限,一次对话能烧掉你几十次调用。

7.3 可观测性清单

生产环境请至少记录:每次 LLM 调用的 prompt_tokens / completion_tokens(成本核算)、工具名与参数(审计)、执行耗时(性能监控)、tool_calls 数量与轮数(防失控)。成本侧有个经验值:加了工具声明的请求,单次 Token 消耗通常比纯对话高 10%-30% ,因为 tools 描述每次都要随请求发出去------工具声明写得精炼,本身就是省钱。

7.4 幂等性:工具重试的安全带

并发与超时带来的下一个问题是重复执行:一次调用超时了,你重试,但上一次其实已经在订单系统里建好了工单------用户就收到了两张售后单。解法是让"会改变状态"的工具具备幂等性:

  1. 业务幂等键create_after_sale 接收一个由调用方生成的 request_id(可用订单号+时间戳+随机数拼成),系统按 request_id 去重,重复请求直接返回第一次的结果;
  2. 查询类天然安全query_orderget_weather 这类只读工具没有副作用,超时直接重试即可,不用额外设计;
  3. 先查后写:写操作前先调用一次查询确认当前状态,避免"重复建单""重复扣款"这类业务事故。

给 Agent 接工具时,请先给你的工具做一次"副作用体检":只读还是写操作?写操作能不能安全重试? 想清楚这两问,再谈并发上限。

7.5 工具结果校验:别把脏数据喂给模型

工具返回的数据五花八门:数据库字段可能是 None、日期可能是 2026-09-04T00:00:00Z 这种用户看不懂的格式、金额可能是分单位的整数。直接回传会让模型"照着脏数据说胡话"。在 dispatch 里加一道清洗层:空值转成"暂无"、时间格式化成 2026-09-04、金额除以 100 转成元并保留两位小数。模型回答质量的天花板,是你喂给它的工具结果质量。

八、Dify 里的函数调用:不写代码也能编排

8.1 为什么还要用 Dify

上面纯代码方案灵活,但每次加工具都要改代码、发版。Dify(华为云 Flexus 云服务器上可一键部署)把函数调用做成了可视化编排:模型节点里声明工具、HTTP 节点或代码节点里实现执行逻辑、再加判断分支和人工确认,拖拽即成。适合快速验证和中后台场景。

8.2 在 Dify 中搭建"订单助手"的步骤

  1. 创建应用 :新建"聊天助手"类型应用,模型选择 MaaS 上的 DeepSeek(在 Dify 里配置自定义模型供应商,填 base_url 和 API Key);
  2. 添加工具 :在"工具"页添加自定义工具,用 OpenAPI Schema 描述 query_order(本质还是 JSON Schema,只是换成了 OpenAPI 格式),或直接添加 HTTP 工具指向你自己的查询接口;
  3. 编排流程:聊天入口 → LLM 节点(带工具)→ 若模型输出工具调用,走工具执行节点 → 把结果回填给 LLM 生成回答;
  4. 加人工确认 :在 send_email 这类动作后加"对话流/工作流"的暂停节点,用户确认后才发信;
  5. 发布上线:发布为 Web App 或通过 API 接入你的客服系统。

8.3 代码与 Dify 怎么选

维度 纯代码方案 Dify 编排方案
上手门槛 需要写 Python 拖拽即可,业务同学也能改
灵活性 极高,任意逻辑 受节点类型限制
调试体验 靠日志 可视化查看每步输入输出
适合场景 复杂 Agent、深度定制 快速落地、工具流程固定、需要人审

我的建议:先代码把原理跑通,再用 Dify 提效 。两者不是替代关系------你手写的 dispatch 逻辑,在 Dify 里就是那根"工具节点"的连线。

九、R1 与 V3:推理模型做工具调用要注意什么

9.1 两个模型的定位差异

MaaS 上 DeepSeek 系列里,V3 是通用对话与工具调用的主力:响应快、成本低、多工具并行稳;R1 是推理增强模型,适合数学、逻辑、复杂规划,但推理过程长、首字延迟高。函数调用场景的朴素经验是:

  • 纯工具调用(查个订单、问个天气)→ V3,又快又省;
  • 需要先规划再调用("比较这三份方案的成本差异并整理成邮件")→ R1,先想清楚再动手;
  • R1 做工具调用时 :把 reasoning 输出单独存日志(R1 的思考过程本身有 debug 价值),并且注意它的工具参数有时会带"思考痕迹",json.loads 前先做清洗。

9.2 实测经验:工具结果太长怎么办

工具返回一大段 JSON(比如订单明细 + 物流轨迹 + 售后记录),直接全文回传给模型,既费 Token 又可能让模型"抓不住重点"。两个技巧:

  1. 截断/摘要:工具侧只返回模型回答所需的核心字段,明细放附件或链接;
  2. 分页:一次只回前 N 条,告诉模型"如需更多请再调用一次带 page 参数"。

让工具返回"够用且精炼"的结果,是函数调用省钱提质的隐藏杠杆。

十、实战案例:把整套串起来

10.1 场景

做一个"售后小助手":用户报订单号 → 查订单 → 判断是否在售后期内 → 在期内引导登记、超期则说明原因 → 全程可溯源。

10.2 完整代码(核心片段)

复制代码
tools = [
    {"type": "function", "function": {"name": "query_order",
        "description": "按订单号查询订单状态、购买时间、金额", "parameters": {
            "type": "object",
            "properties": {"order_id": {"type": "string", "description": "订单号"}},
            "required": ["order_id"]}}},
    {"type": "function", "function": {"name": "create_after_sale",
        "description": "为符合条件的订单创建售后工单", "parameters": {
            "type": "object",
            "properties": {
                "order_id": {"type": "string"},
                "reason": {"type": "string", "description": "用户报修/退货原因"},
            }, "required": ["order_id", "reason"]}}},
]

def query_order(order_id: str):
    # demo: 真实场景查数据库/订单API
    return {"order_id": order_id, "status": "已签收",
            "buy_time": "2026-08-20", "amount": 1299.0}

def create_after_sale(order_id: str, reason: str):
    # demo: 真实场景写工单系统
    return {"ticket_id": "AS20260904001", "order_id": order_id, "status": "已创建"}

registry = {"query_order": query_order, "create_after_sale": create_after_sale}
agent = ToolAgent(client, tools, registry)   # 复用 7.2 的执行器

print(agent.run("我的订单 O20240901001 屏幕碎了,能售后吗?"))

一次典型的执行轨迹:

复制代码
[第1轮] 模型: tool_calls=[query_order(O20240901001)]
[执行]  查订单 → 返回 已签收/2026-08-20
[第2轮] 模型: tool_calls=[create_after_sale(O20240901001, 屏幕碎裂)]
[执行]  建工单 → 返回 AS20260904001
[第3轮] 模型: 最终回答 "已为您创建售后工单 AS20260904001,售后专员将..."

注意看:模型自己完成了"查→判断→办"的决策链,你只提供了工具和规则。这就是 Agent 的最小闭环。

10.3 如果查询结果是"订单不存在"

模型收到 {"error": "订单不存在"} 后,会自然回答:"抱歉,没有查到该订单,请核对订单号是否以 O 开头。"------没有崩溃、没有幻觉编造物流信息,这就是 6.2 节结构化错误的威力。

十一、总结与行动清单

11.1 本文核心结论

  1. 函数调用 = 模型出意图、程序做执行 :模型只生成工具名和参数,执行权永远在你这边的 dispatch 里;
  2. 协议是 OpenAI 兼容的 tools:MaaS 上的 DeepSeek 用同一套 Schema,生态工具全兼容;
  3. 循环模板是地基 :assistant(tool_calls) → tool(结果) → assistant(最终),顺序与 tool_call_id 不能错;
  4. 防御要前置:声明即边界、结果可失败、关键动作人审,三板斧挡掉 90% 的工具幻觉;
  5. 工程三件套:超时、轮数上限、全链路日志,缺一个都别上生产;
  6. 选型有讲究:纯调用用 V3,复杂规划用 R1;代码灵活、Dify 高效,先懂原理再谈编排。

11.2 一句话记住本文

给 DeepSeek 装"手"的正确姿势:声明好工具、写好分发器、设好护栏,然后让模型自己决定怎么干活。

11.3 最后的话

函数调用是 2026 年 AI 应用开发者的"基础技能"------它把模型从"聊天框"里解放出来,接上你的数据库、API 和业务系统。本文的代码都在上面,建议你照着跑一遍:先单工具、再多工具、再上护栏,半小时就能感受到"模型开始替你干活"的质变。踩过什么坑、有什么骚操作,欢迎评论区聊聊!

十二、参考资源


写在最后 :你第一次给 DeepSeek 接上函数调用时,是顺利跑通还是被 tool_call_id 折磨到凌晨?评论区交出你的故事,让后来者少踩一个坑!🤖

相关推荐
百度Geek说1 小时前
都在开源 Harness,Codex 和 DeepSeek 到底有什么不一样?
人工智能
科研小牛马1 小时前
北航何静:AI时代,热门专业十年后怎么样了
人工智能
weixin_446260851 小时前
JarvisGUI:面向跨设备GUI智能体的动态任务组合评测基准
人工智能
Splashtop高性能远程控制软件1 小时前
AI 辅助端点运维先接手补丁分级、合规可视和同台处置
运维·网络·人工智能·自动化·远程工作·splashtop
Yanjun2i1 小时前
Agent学习记录四:多工具时如何处理
人工智能·python·学习·agent
creator_Li1 小时前
深度学习 学习笔记
pytorch·深度学习
我有满天星辰2 小时前
第一次使用 Milvus:给我的 AI 知识库装上“记忆”
人工智能·milvus
YOLO数据集集合2 小时前
天空反无人机检测数据集 | 无人机检测 多旋翼识别 固定翼识别 低空安防 目标检测9063期
人工智能·yolo·目标检测·计算机视觉·无人机·反无人机