Day 2:Function Calling 到底是什么?跟着AI老师从笨办法开始写

Day 2:Function Calling 到底是什么?跟着AI老师从笨办法开始写

本文是「AI Agent学习日记」系列第二篇。 一个"规划狂魔但想坚持"的程序员,用AI陪伴式学习AI。 老师:Hermes Agent(AI Agent)


前言

昨天发了第一篇笔记,一天时间270浏览。说实话有点意外,毕竟我就是个记录学习过程的小透明。

今天继续。

昨天学了Agent的四个核心概念(对话历史、工具调用、Function Calling、规划能力),今天的目标是:把这四个概念串起来,做一个真正能用的小工具

工具叫「代码片段管理器」------用来保存和搜索常用代码片段,比如设计模式模板、工具方法等。


从"笨办法"开始

AI老师说:先别急着用Function Calling,咱们用最笨的方式写一版,你才能理解Function Calling到底解决了什么问题。

于是第一版代码长这样:

python 复制代码
class SnippetTools:
    def parse_intent(self, text):
        """字符串匹配判断用户想干什么"""
        if "保存" in text or "存" in text:
            return "save"
        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"

运行效果对比:

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

问题来了:你永远穷举不完用户的所有说法

"留着"、"记一下"、"收起来"、"帮我存下"......每换一种说法,你就要加一个关键词。

这就是"笨办法"的致命缺陷。


Function Calling 是什么?

一句话:让AI自己决定调用哪个工具,不用你写if-else

对比一下:

维度 笨办法(字符串匹配) Function Calling
识别方式 关键词匹配 AI语义理解
灵活性 低,必须用固定说法 高,各种表达都行
维护成本 高,需要不断加关键词 低,AI自动理解
理解能力 ❌ 换个说法就废了 ✅ 怎么说都能理解

实现步骤

第一步:定义工具Schema

这是Function Calling的核心------用JSON告诉AI,你有哪些工具,每个工具干什么,需要什么参数

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

⚠️ 注意description 写得越清楚,AI判断越准确!

好例子

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

坏例子

json 复制代码
"description": "保存"

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

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

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

python 复制代码
message = response.choices[0].message

# LLM说:我要调用 save_snippet
if message.tool_calls:
    for tool_call in message.tool_calls:
        tool_name = tool_call.function.name       # "save_snippet"
        arguments = json.loads(tool_call.function.arguments)
        # arguments = {"code": "...", "language": "java", "tags": ["单例模式"]}

        # 执行工具
        result = execute_tool(tool_name, arguments)

        # 把结果告诉LLM,让它生成最终回复
        conversation_history.append({
            "role": "tool",
            "content": json.dumps(result)
        })

第四步:LLM生成最终回复

python 复制代码
# 再调一次LLM,这次带上工具执行结果
final_response = client.chat.completions.create(
    model="mimo-v2-flash",
    messages=conversation_history
)

print(final_response.choices[0].message.content)
# 输出:代码已保存!ID: 1,分类:设计模式,标签:单例模式、创建型

完整调用流程

时序图


运行效果

csharp 复制代码
用户: "帮我存一下这段Java代码"
小助手: "好的,请把代码发给我"

用户:
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

小助手: "代码已保存!
   - ID: 1
   - 语言: Java
   - 标签: 设计模式、单例模式
   - 文件: snippets.json"

不管是说"存一下"、"保存"、"帮我留着"、"记下来",LLM都能理解。


今日收获

问题 答案 为什么需要
Function Calling是什么? 让AI自己判断调用哪个工具,不用你写if-else 穷举关键词太累了
核心是什么? 工具Schema------用JSON描述工具的能力和参数 AI需要知道有什么工具可用
description重要吗? 非常重要!写得越清楚,AI判断越准确 AI靠description理解工具用途
调用流程是怎样的? 用户说话 → AI判断 → 执行工具 → AI生成回复 完整的Agent交互闭环

常见问题

Q1: Function Calling和普通API调用有什么区别?

普通API调用是固定的:调用方知道要调什么。Function Calling是动态的:AI根据用户说的话决定调什么。

Q2: 需要为每个项目都写工具Schema吗?

是的,每次调用LLM时都要传入tools参数,告诉LLM当前项目有哪些工具。

Q3: 可以同时调用多个工具吗?

可以!LLM可以一次返回多个tool_calls,Agent会依次执行。


明天预告

设计模式第一弹------单例模式

每天学一个设计模式,结合今天做的代码片段管理器,边学边存,学一个存一个。一个月下来,常用的23种设计模式就能过一遍。


系列文章

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

我是宸一,一个"规划狂魔但想坚持"的Java程序员。 正在用AI陪伴式学习AI,欢迎关注,一起进步。 老师:Hermes Agent(AI Agent)

相关推荐
程序员小崔日记1 小时前
十年后回头看,2026 年或许是程序员行业的转折点
人工智能·ai编程·claudecode
天蓝色的鱼鱼2 小时前
前端也能写 AI Agent?用 Vercel AI SDK 十分钟跑通你的第一个智能助手
前端·ai编程
DevUI团队2 小时前
接口即代码:一个Skill轻松搞定类型定义、接口调用、Mock与调试
前端·agent·ai编程
DevUI团队2 小时前
从截图到企业级前端页面:2个Skill,1次对话,10X效率开发符合设计/编码规范的页面
前端·agent·ai编程
猫头虎3 小时前
Cursor推出的Composer 2.5 是什么?从定向 RL 到合成数据,AI 编程智能体再进化
人工智能·开源·prompt·aigc·copilot·ai编程·composer
sweet丶3 小时前
iOS AI 编程环境配置:Agent、Skill、Rules、Hook、Command
ios·ai编程
winlife_4 小时前
让 AI 跑通“调跳跃手感“的完整闭环:funplay-unity-mcp 实战案例
人工智能·unity·游戏引擎·ai编程·mcp·游戏手感
EdenMa4 小时前
从飞书 PRD 到代码实现:我的AI编程workflow
openai·ai编程
wuhen_n4 小时前
LangChain 核心:Chain 链式调用实现复杂 AI 任务
前端·langchain·ai编程