my-add-function-calling

用一个最小的加法工具示例理解 Function Calling 的两轮调用流程与宿主执行职责。

#type / howto #status / growing

[!info] related notes

my-add-function-calling

目标

写一个自己的 add 函数, 让 codex 调用

步骤

实现 add

import json
from openai import OpenAI

client = OpenAI()

def add(a: float, b: float) -> float:
    return a + b

tools = [
    {
        "type": "function",
        "name": "add",
        "description": "Add two numbers and return the sum.",
        "strict": True,
        "parameters": {
            "type": "object",
            "properties": {
                "a": {
                    "type": "number",
                    "description": "The first number"
                },
                "b": {
                    "type": "number",
                    "description": "The second number"
                }
            },
            "required": ["a", "b"],
            "additionalProperties": False
        }
    }
]

# 第一次请求:让模型决定要不要调用 add
response = client.responses.create(
    model="gpt-5",
    input="请帮我计算 12.5 + 7.3",
    tools=tools,
)

# 把第一轮输出先存起来
input_items = response.output

# 找到模型发出的 function_call
for item in response.output:
    if item.type == "function_call" and item.name == "add":
        args = json.loads(item.arguments)

        result = add(
            a=float(args["a"]),
            b=float(args["b"])
        )

        # 把工具执行结果回传给模型
        input_items.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps({"result": result})
        })

# 第二次请求:让模型基于工具结果生成最终自然语言回复
final_response = client.responses.create(
    model="gpt-5",
    input=input_items,
    tools=tools,
)

print(final_response.output_text)

ai 给了我如上示例,主要的工具是 add 函数,然后直接模拟了一次对话。
可以注意到是:

  1. 通过运行时(外壳)来发起请求(传入可用 function),
  2. 并根据 ai 响应来执行对应的 function,
  3. 把函数结果再一起发给 ai
  4. 得到最终结果

[!importance] 重点 要用 function calling,必须有一层你控制的运行时。它不一定是很重的“agent 框架”,也可以只是几十行 Python/Node 的小外壳。

想法

当前的网页聊天中应该就是一个 app 壳,设想一个查询天气的流程:

  1. 用户:xx地方明天的气温
  2. 聊天应用 携带问题和可用工具 把请求发送给 LLM
  3. LLM 判断需要使用 “天气查询工具”,让 应用 传入 xx 参数给 “天气查询工具” 来调用这个工具
  4. 应用 调用后,把 结果 发送给 LLM
  5. LLM 返回最终结果 xx地方气温是 yy, 应用看到是最终结果,返回给用户

function 管理问题

这个应用如果应用很广,比如聊天应用,会需要成千上万的 function 吧,查天气,查网页,读文件等等。现在是怎么处理的

回答:

通常不会把成千上万个 function 每轮都直接塞给模型。

原因有两个:

  • token 会很贵
  • 工具越多,模型越难选,误选率也会上升

OpenAI 现在给出的方向其实很明确:除了普通 function calling,还支持 built-in toolsremote MCP servers,以及 tool search。其中 tool search 的作用就是 按需延迟加载工具定义,官方原文是 “load deferred tool definitions at runtime”,并且说它可以 “dynamically load relevant tools into the model’s context to optimize token usage”。

所以现实里一般会这样管:

A. 分层,不是平铺

先做一层路由,只把当前任务相关的工具集交给模型。
比如:

  • 浏览类任务:web_search, fetch_url, summarize_page
  • 本地文件类任务:read_file, write_file, list_dir
  • 运维类任务:run_test, deploy_preview, check_logs

而不是把所有业务工具一次性全给。

B. 能用内建工具,就别自己重复造

OpenAI 的 Responses/Tools 体系本身就支持一批内建能力,例如 web search、file search、computer use 等;模型页也会标注某个模型支持哪些工具。比如 GPT-5.4/5.4 mini 支持 Functions、Web search、File search、Computer use,GPT-5.4 nano 还列出了 MCP。

如果工具很多,更适合把它们组织成:

  • 若干个 MCP server
  • 若干个 domain registry
  • 或者 tool search 的延迟加载体系

这样模型不是“面对 3000 个函数”,而是“面对几个能力入口,再逐步展开”。

D. 需要更强控制时,用 Agents SDK / 自己的 orchestration

官方 Agents SDK 文档明确说:当 你的服务器拥有 orchestration、tool execution、state、approvals 时,SDK 路线更合适;它也适合你需要直接控制 tools、MCP servers 和 runtime behavior 的场景。

一句话总结这题:

不是“一个大应用 = 一个巨型 functions 列表”,而是“一个运行时 + 分层工具注册 + 按需暴露”。

现在的 agent 的读文件、写文件等是利用function calling 吗

创建于 2026/4/16 更新于 2026/5/27