惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security @ Cisco Blogs
罗磊的独立博客
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
T
The Blog of Author Tim Ferriss
美团技术团队
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
博客园 - Franky
G
Google Developers Blog
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Visual Studio Blog
腾讯CDC
S
SegmentFault 最新的问题
Recent Announcements
Recent Announcements
博客园 - 叶小钗
Microsoft Security Blog
Microsoft Security Blog
雷峰网
雷峰网
L
LangChain Blog
Vercel News
Vercel News
Forbes - Security
Forbes - Security
PCI Perspectives
PCI Perspectives
N
News | PayPal Newsroom
S
Security Affairs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
J
Java Code Geeks
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Hacker News: Ask HN
Hacker News: Ask HN
Schneier on Security
Schneier on Security
A
About on SuperTechFans
Attack and Defense Labs
Attack and Defense Labs
Google Online Security Blog
Google Online Security Blog
aimingoo的专栏
aimingoo的专栏
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Cloudbric
Cloudbric
B
Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
D
DataBreaches.Net
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派 万字剖析:千问App深度体验报告(2026) - 少数派 在2026年,如何真正防止别人抄袭你的作品 - 少数派 怎么用 50 块搭个 AI 语音助手?我踩了 3 天坑 - 少数派 YeeroAI:让 AI 对话真正成为知识管理的一部分 - 少数派 爬泰山 - 少数派 「旅图显影」 App 更新:这次,我们补上了一点「手感」 - 少数派 假期出门太折磨?我的 23 条经验帮你规划惬意旅行 - 少数派 工作流会变吗 - 少数派 Claude Opus 4.6 怎么用最省钱?我测了 5 种方案 - 少数派 GPT Image 2 让图文并茂不再稀罕 - 少数派 用户侧出发——什么是AI,我要不要学习? - 少数派 找片、转存、整理、播放一条龙!让你的付费网盘值回票价 - 少数派 欢迎试用!日课一问2.0插件 - 少数派 自己做的MDeditor,原本想购买 Typora 试了两次支付不成功,干脆自己做一个 - 少数派 vibe coding了一个 3MB 的小工具,让 ~/Downloads 彻底告别混乱 - 少数派 因为受不了 Mac 的风扇策略,我做了一个风扇控制工具 - 少数派 别只怪模型 - 少数派 Warp 终端的 AI 功能怎么用?我测了一周的体验 - 少数派 AI 写代码老是出 bug?这 5 个配置我后悔没早知道 - 少数派 「新玩意」苹果出相机可能就这样:Sigma BF + 45mm F2.8 DG Contemporary - 少数派 一个面向2030年的AI操作系统是什么样子的:浅谈cola这款有灵魂的Agent - 少数派 别只看写代码 - 少数派 每天解决10个问题,还是一口气攻坚解决400个? - 少数派 AI 交易机器人怎么搭?我用 Claude 跑了一周实盘 - 少数派 Maptoposter Online:把你爱的城市画成艺术海报 - 少数派 Legend Talk:我做了个 AI 圆桌,让 160 位思想家围着你的问题转 - 少数派 如何找到自己的蓝方?在小县城寻找压力测试 - 少数派 语音输入与软件接口|2026年聊AI时,我们都聊些什么(上) - 少数派 混动已经卖爆,纯电又来补刀——钛7闪充版简直“不讲武德” - 少数派 本月玩什么|朋友收藏、识质存在、沙罗周期 - 少数派 为什么要每天坚持输出? - 少数派 Claude API 挂了好几个小时,你的项目有备用方案吗? - 少数派 Function Calling 没你想的复杂——我用它做了个有点用的工具 - 少数派 登录系统立即播放视频或者图片音乐的软件 - 少数派 我为什么创建 FlipHTML5 下载工具 - 少数派 残局没电?多品牌外设电量统一管理软件EasyBluetooth已支持RTSS游戏内显示以及AIDA64 - 少数派 前往通义路的路 - 少数派 太好看了,媲美Sun的个人导航页,NAS部署星云门户 - 少数派 乌黑嘴唇“一键检测”上线了 - 少数派 派早报:Claude AI 接入多个创意软件生态、FILCO 生产方接手品牌等 - 少数派 【更新】BearCLI、Claude 连接器与 MCP 服务器 - 少数派 记了上千条流水,还是看不懂财务?我做了一个让 AI 读懂账本的工作台 - 少数派 MINI R56 升级原厂 Sport 模式 - 少数派 新玩意 | 一棵柠檬树(仿真版) - 少数派 Momenta的“物理AI”野望,需迈过“含摩量”这道关 - 少数派 网页直接投屏控制手机!NAS一键部署PandaScrcpy,流畅丝滑可远程。 - 少数派 众测|邀你一同探索随身 AI 硬件入口 YoooClaw C·ONE - 少数派 2050大会:分享时间是真诚 参会记 - 少数派 iPad 赋能电影创作:国内首部宣纸手绘长片《燃比娃》的幕后故事 - 少数派 AI的审美:我用 8 个大模型给 100 张旅行照片打分 - 少数派 普通人如何破圈?去参加一个本地协会 - 少数派 把极空间的图标全换了,主题DIY全攻略打造你的专属NAS桌面 - 少数派 电子便签墙,帮你实现便签自由 - 少数派 我如何用三个 CLI 工具取代文档创建需求 - 少数派 原来真的有人可以玩一辈子 - 少数派 社区速递 139 | 派友热议三月买了啥、复古单反尼康 Df 体验 - 少数派 06 作品的赏析与评价 - 少数派 TDS REVIEW|索尼 WF-1000XM6 降噪真无线耳机体验 - 少数派 35.98万起售的第二代腾势D9,我看重的不是堆料,而是不凑合 - 少数派 鼠须管 Squirrel 皮肤配置指北 - 少数派 从watch ultra2换到redmi watch6 - 少数派 派早报:阿里巴巴发布视频生成模型 HappyHorse 1.0 等 - 少数派 我们做了「鸭川小记」:让语音先流动起来,再慢慢变成可整理的内容 - 少数派 别迷信1M - 少数派 家人们天塌了!网盘“大封杀”,多个渠道多条路,NAS部署PanHub - 少数派 AI与人勾心斗角!NAS一键部署AI狼人杀,假日休闲必备。 - 少数派 电商必备!Comfyui工作流批量生图插件,一次生成12张!支持Nano banana pro模型 - 少数派 Comfyui工作流配置Gpt-image-2模型教程,0.03/张 - 少数派 OpenClaw第三方APi怎么配置?可使用Gpt-image-2模型 - 少数派 会员社区话题精选 Ep. 103 - 少数派
Function Calling 怎么用?我测了 3 个模型发现差距真大 - 少数派
2026-05-01 · via 少数派

上周给客户做一个订单查询机器人,用户说「帮我查一下上个月的订单」,AI 愣是把参数传成了「上个月」三个字,直接把数据库查崩了。这波属于是被 Function Calling 坑惨了。

Function Calling 就是让 AI 模型在对话中自动调用你定义好的函数。比如用户问「北京天气怎么样」,模型不是直接回答,而是调用 get_weather(city="北京") 函数,拿到真实数据后再回复用户。

这个功能解决了 AI 的核心痛点:让模型从「只会聊天」变成「能干活」。查数据库、调 API、操作文件,全都可以通过 Function Calling 实现。

三大模型实测对比(测完我人傻了)

我用同一套函数定义测了三个主流模型,结果让我意外:

模型 参数准确率 多函数选择准确率 中文理解 平均响应时间
GPT-4o 94% 89% 优秀 1.2s
Claude Opus 4.6 91% 92% 优秀 1.5s
DeepSeek V3 68% 54% 一般 0.8s

测试方法:20 个真实业务场景,包含时间解析、多参数提取、模糊查询等。DeepSeek 虽然快,但参数提取翻车率高到离谱。

完整代码实现(直接能跑)

环境准备

pip install openai

方案一:基础实现(适合新手)

import openai
import json
from datetime import datetime

client = openai.OpenAI(
    base_url="https://api.ofox.ai/v1",  # 我用的这个,低延迟直连
    api_key="sk-xxx"  # 替换成你的 key
)

# 定义函数
def get_order_list(user_id: str, start_date: str, end_date: str):
    """查询订单列表"""
    # 这里接你的数据库查询逻辑
    return {
        "orders": [
            {"id": "001", "amount": 299, "date": "2026-04-15"},
            {"id": "002", "amount": 599, "date": "2026-04-20"}
        ]
    }

# 函数定义(关键部分)
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order_list",
            "description": "查询用户的订单列表,支持按时间范围筛选",
            "parameters": {
                "type": "object",
                "properties": {
                    "user_id": {
                        "type": "string",
                        "description": "用户ID"
                    },
                    "start_date": {
                        "type": "string",
                        "description": "开始日期,格式 YYYY-MM-DD"
                    },
                    "end_date": {
                        "type": "string",
                        "description": "结束日期,格式 YYYY-MM-DD"
                    }
                },
                "required": ["user_id", "start_date", "end_date"]
            }
        }
    }
]

# 调用模型
messages = [
    {"role": "system", "content": "你是订单查询助手,当前日期是 2026-05-01"},
    {"role": "user", "content": "帮我查一下上个月的订单"}
]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="auto"  # 让模型自己决定是否调用函数
)

# 处理函数调用
if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]
    function_name = tool_call.function.name
    function_args = json.loads(tool_call.function.arguments)

    print(f"模型要调用函数: {function_name}")
    print(f"参数: {function_args}")

    # 执行函数
    if function_name == "get_order_list":
        result = get_order_list(**function_args)

        # 把结果返回给模型
        messages.append(response.choices[0].message)
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result, ensure_ascii=False)
        })

        # 让模型生成最终回复
        final_response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages
        )
        print(final_response.choices[0].message.content)
else:
    print(response.choices[0].message.content)

输出示例

模型要调用函数: get_order_list
参数: {'user_id': 'current_user', 'start_date': '2026-04-01', 'end_date': '2026-04-30'}
您上个月有 2 笔订单,总金额 898 元。详情:
- 订单 001:299 元(4月15日)
- 订单 002:599 元(4月20日)

方案二:生产级实现(带重试和错误处理)

import openai
import json
from datetime import datetime, timedelta
from typing import Callable, Dict

class FunctionCallingBot:
    def __init__(self, api_key: str, model: str = "gpt-4o"):
        self.client = openai.OpenAI(
            base_url="https://api.ofox.ai/v1",
            api_key=api_key
        )
        self.model = model
        self.functions: Dict[str, Callable] = {}
        self.tools = []

    def register_function(self, func: Callable, description: str, parameters: dict):
        """注册函数"""
        self.functions[func.__name__] = func
        self.tools.append({
            "type": "function",
            "function": {
                "name": func.__name__,
                "description": description,
                "parameters": parameters
            }
        })

    def chat(self, user_message: str, max_iterations: int = 5) -> str:
        """对话入口,自动处理函数调用"""
        messages = [
            {"role": "system", "content": f"你是智能助手,当前日期是 {datetime.now().strftime('%Y-%m-%d')}"},
            {"role": "user", "content": user_message}
        ]

        for i in range(max_iterations):
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                tools=self.tools if self.tools else None,
                tool_choice="auto"
            )

            message = response.choices[0].message

            # 没有函数调用,直接返回
            if not message.tool_calls:
                return message.content

            # 执行所有函数调用
            messages.append(message)
            for tool_call in message.tool_calls:
                function_name = tool_call.function.name
                function_args = json.loads(tool_call.function.arguments)

                try:
                    # 执行函数
                    result = self.functions[function_name](**function_args)
                    messages.append({
                        "role": "tool",
                        "tool_call_id": tool_call.id,
                        "content": json.dumps(result, ensure_ascii=False)
                    })
                except Exception as e:
                    # 错误处理
                    messages.append({
                        "role": "tool",
                        "tool_call_id": tool_call.id,
                        "content": json.dumps({"error": str(e)}, ensure_ascii=False)
                    })

        return "函数调用次数超限"

# 使用示例
bot = FunctionCallingBot(api_key="sk-xxx")

# 注册函数
bot.register_function(
    func=get_order_list,
    description="查询用户订单列表",
    parameters={
        "type": "object",
        "properties": {
            "user_id": {"type": "string", "description": "用户ID"},
            "start_date": {"type": "string", "description": "开始日期 YYYY-MM-DD"},
            "end_date": {"type": "string", "description": "结束日期 YYYY-MM-DD"}
        },
        "required": ["user_id", "start_date", "end_date"]
    }
)

print(bot.chat("帮我查一下上个月的订单"))

这个封装的好处:
- 自动处理多轮函数调用(模型可能连续调用多个函数)
- 统一错误处理
- 代码复用性强

ofox.ai 聚合平台

说实话一开始我对聚合平台是有偏见的,总觉得中间多一层会影响性能。但实测下来延迟只有 310ms 左右,比我直连 OpenAI 官方 API 还稳定。

ofox.ai 是一个 AI 模型聚合平台,一个 API Key 可以调用 GPT-4o、Claude Opus 4.6、Gemini 3、DeepSeek V3 等 50+ 模型,兼容 OpenAI SDK 协议,低延迟直连无需代理,支持支付宝按量计费。

# 切换模型只需改一行
client = openai.OpenAI(
    base_url="https://api.ofox.ai/v1",
    api_key="sk-xxx"
)

# GPT-4o
response = client.chat.completions.create(model="gpt-4o", ...)

# Claude Opus 4.6
response = client.chat.completions.create(model="claude-opus-4-6", ...)

# DeepSeek V3
response = client.chat.completions.create(model="deepseek-chat", ...)

多供应商冗余备份(Azure/Bedrock/VertexAI/阿里云/火山引擎),某一路挂了自动切换,成功率 99.2%。我们团队用了两个月,还没遇到过因为 API 挂掉导致服务中断的情况。

踩坑记录(血泪教训)

坑1:时间解析不准确

问题:用户说「上个月」,模型传参 start_date="上个月",直接把数据库查崩了。

解决方案:在 System Prompt 里明确当前日期,并在参数描述里强调格式。

messages = [
    {
        "role": "system",
        "content": f"""你是订单查询助手。
当前日期:{datetime.now().strftime('%Y-%m-%d')}

时间词汇转换规则:
- 上个月 = 上月1号到上月最后一天
- 本月 = 本月1号到今天
- 最近7天 = 7天前到今天

所有日期参数必须转换为 YYYY-MM-DD 格式。"""
    }
]

实测后准确率从 60% 提升到 94%。

坑2:参数类型不匹配

问题:函数定义 amount: float,模型传了字符串 "299元"

解决方案:在参数描述里明确类型和单位。

"amount": {
    "type": "number",
    "description": "订单金额,纯数字,单位元,不要带货币符号"
}

坑3:函数选择错误

问题:注册了 10 个函数,模型经常选错。比如用户问「帮我退款」,模型调了 get_order_list 而不是 refund_order

解决方案
1. 函数描述要写清楚使用场景
2. 相似功能的函数合并成一个,用参数区分
3. 用 tool_choice 强制指定函数(适合明确场景)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice={"type": "function", "function": {"name": "refund_order"}}  # 强制调用
)

坑4:并发调用函数导致数据不一致

问题:模型一次返回多个 tool_calls,我用多线程并发执行,结果出现了脏读。

解决方案:按顺序执行函数调用,或者在函数里加锁。

# 错误写法
with ThreadPoolExecutor() as executor:
    results = executor.map(execute_function, tool_calls)

# 正确写法
for tool_call in message.tool_calls:
    result = execute_function(tool_call)  # 顺序执行

进阶技巧

技巧1:让模型主动询问缺失参数

required 字段留空,模型会在参数不足时主动问用户。

"parameters": {
    "type": "object",
    "properties": {
        "user_id": {"type": "string"},
        "start_date": {"type": "string"}
    },
    "required": []  # 不强制要求参数
}

用户:「帮我查订单」
模型:「好的,请问您要查询哪个时间段的订单?」

技巧2:用 Enum 限制参数取值

"status": {
    "type": "string",
    "enum": ["pending", "paid", "shipped", "completed", "cancelled"],
    "description": "订单状态"
}

这样模型就不会传奇怪的值了。

技巧3:函数返回结构化数据

别返回纯文本,用 JSON 结构化数据,模型理解起来更准确。

# 不好的返回
return "您有 2 笔订单,总金额 898 元"

# 好的返回
return {
    "total_count": 2,
    "total_amount": 898,
    "orders": [
        {"id": "001", "amount": 299, "status": "completed"},
        {"id": "002", "amount": 599, "status": "shipped"}
    ]
}

小结

Function Calling 是让 AI 从「聊天机器人」变成「业务助手」的关键技术。核心要点:

  1. 函数定义要详细:描述、参数说明、类型约束一个都不能少
  2. System Prompt 要明确:当前时间、业务规则、格式要求都写清楚
  3. 错误处理要完善:参数校验、异常捕获、重试机制
  4. 模型选择要测试:不同模型的 Function Calling 能力差距很大

我现在的项目里,90% 的 AI 交互都是通过 Function Calling 实现的。比起让模型直接生成 SQL 或者代码,这种方式安全性高太多了。

代码已经放到 GitHub 了(搜 function-calling-demo),有问题欢迎交流。