Function Calling新手教程:从零开始掌握AI函数调用

2026-06-20阅读 0热度 0
ai

Day 2:Function Calling 详解|从暴力匹配到语义理解,手写Agent工具调用


开篇

上一篇笔记发布后24小时内获得270次浏览——对于一个刚开始记录学习过程的普通开发者而言,这个反馈超出了预期。

今天继续深入Agent实战。

昨天梳理了Agent的四大核心要素:对话历史、工具调用、Function Calling、规划能力。今天的目标是——将这四个概念串联,搭建一个可直接运行的实用工具

这个工具命名为「代码片段管理器」,核心功能是保存和检索常用代码片段,例如设计模式模板、工具方法等。


从“暴力匹配”入手

AI导师的建议很务实:先不要引入Function Calling,用最原始的字符串匹配写一版。只有亲手踩过坑,才能深刻理解Function Calling解决了什么问题。

于是第一版代码长这样:

class SnippetTools:
    def parse_intent(self, text):
        """字符串匹配判断用户想干什么"""
        if "保存" in text or "存" in text:
            return "sa ve"
        elif "搜索" in text or "找" in text or "查找" in text:
            return "search"
        elif "列表" in text or "看看" in text:
            return "list"
        elif "删除" in text:
            return "delete"
        else:
            return "chat"

运行效果对比如下:

用户输入识别结果
"保存一下这段代码" 识别为 sa ve
"存一下这段代码" 识别为 sa ve
"帮我留着这段代码" 识别失败,跑到chat去了

问题瞬间暴露:你永远无法穷举用户的所有表达方式

"留着"、"记一下"、"收起来"、"帮我存下"……每新增一种说法就必须追加一个关键词。这正是暴力匹配方案最致命的缺陷。


Function Calling 的本质

一句话概括:让大模型自主决策该调用哪个工具,开发者不再需要编写堆叠式if-else

对比两种方案的差异:

维度暴力匹配(字符串匹配)Function Calling
识别方式关键词匹配AI语义理解
灵活性低,必须使用固定说法高,支持多种自然语言表达
维护成本高,需要持续增加关键词低,AI自动理解意图
理解能力 换种说法即失效 任何说法均能理解

实现步骤

第一步:定义工具Schema

这是Function Calling的核心——通过JSON结构向AI声明可用的工具、每个工具的功能描述以及所需参数

TOOLS_SCHEMA = [
    {
        "type": "function",
        "function": {
            "name": "sa ve_snippet",
            "description": "保存一段代码片段到本地存储",  # 这句话很重要!
            "parameters": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "要保存的代码内容"
                    },
                    "language": {
                        "type": "string",
                        "description": "编程语言,如 python、ja va",
                        "enum": ["ja va", "python", "ja vascript"]
                    },
                    "tags": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "标签,如 ['单例模式', '创建型']"
                    }
                },
                "required": ["code", "language"]
            }
        }
    },
    # ... 还有 search_snippet、delete_snippet 等
]

关键要点:description 写得越详尽,AI的决策准确率就越高。

优秀案例

"description": "保存代码片段,参数包括代码内容、编程语言、标签和分类"

反面案例

"description": "保存"

第二步:调用LLM,传入工具定义

response = client.chat.completions.create(
    model="mimo-v2-flash",
    messages=conversation_history,
    tools=TOOLS_SCHEMA,    # 关键:传入工具定义
    tool_choice="auto"     # 让AI自动决定是否调用工具
)

第三步:处理LLM返回的工具调用

message = response.choices[0].message# LLM说:我要调用 sa ve_snippet
if message.tool_calls:
    for tool_call in message.tool_calls:
        tool_name = tool_call.function.name       # "sa ve_snippet"
        arguments = json.loads(tool_call.function.arguments)
        # arguments = {"code": "...", "language": "ja va", "tags": ["单例模式"]}        # 执行工具
        result = execute_tool(tool_name, arguments)        # 把结果告诉LLM,让它生成最终回复
        conversation_history.append({
            "role": "tool",
            "content": json.dumps(result)
        })

第四步:LLM生成最终回复

# 再调一次LLM,这次带上工具执行结果
final_response = client.chat.completions.create(
    model="mimo-v2-flash",
    messages=conversation_history
)print(final_response.choices[0].message.content)
# 输出:代码已保存!ID: 1,分类:设计模式,标签:单例模式、创建型

完整调用流程

时序图


运行效果

用户: "帮我存一下这段Ja va代码"
小助手: "好的,请把代码发给我"用户:
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}小助手: "代码已保存!
   - ID: 1
   - 语言: Ja va
   - 标签: 设计模式、单例模式
   - 文件: snippets.json"

无论是说“存一下”、“保存”、“帮我留着”还是“记下来”,LLM均能准确识别用户意图并触发相应工具。


今日核心要点

问题答案为什么需要
Function Calling是什么?让大模型自行判断调用哪个工具,无需手动编写if-else暴力穷举关键词不可持续
核心是什么?工具Schema——用JSON描述工具的能力和参数大模型必须知道可用工具列表
description重要吗?至关重要!描述越清晰,AI决策越精准AI靠description理解工具的用途
调用流程是怎样的?用户输入 → LLM分析 → 执行工具 → LLM生成回复完整的Agent交互闭环

常见疑问

Q1: Function Calling与普通API调用的区别是什么?

普通API调用是静态的:调用方在编码时已确定调用哪个接口。Function Calling则是动态的:LLM根据用户输入的语义,在运行时决定触发哪个工具。

Q2: 每个项目都需要单独编写工具Schema吗?

是的。每次向LLM发起请求时,必须传入tools参数,告诉LLM当前上下文中哪些工具可用。

Q3: 能否同时调用多个工具?

完全可以。LLM可以在一次响应中返回多个tool_calls,Agent会依次执行它们并将结果汇总返回。


明天预告

设计模式系列第一弹——单例模式

后续计划每天学习一个设计模式,并结合今天搭建的代码片段管理器,边学边存,积累一个完整的模式库。预计一个月内系统掌握23种常用设计模式。


系列文章

  • Day 1:Agent到底是什么?四个概念搞明白
  • Day 2:Function Calling到底是什么?跟着AI老师从笨办法开始写
  • Day 3:设计模式第一弹——单例模式(明天更新)
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策