The True Starting Point of Migration: More Than Just Changing an Endpoint
When you see a model version upgrade announcement stating "XX API has been deprecated, please migrate to the new SDK," your first reaction is to replace the request URL and parameter names. But for Function Calling, this idea is precisely the biggest source of migration failure.
The core of Function Calling Migration is not API address change, but the paradigm shift of the tool calling mechanism. In the old Chat Completions API for OpenAI, functions are defined with the functions parameter, and the model returns the function_call object; In the new Responses API or Assistants API, tool definitions, call context, and state management are unified into the tools parameter, and tool_choice, parallel function calls, and stricter output format constraints are introduced.
A real-life case: A development team directly copied 20 function definitions from the old API to the new API and found that the model frequently returned "invalid tool calls" errors. After investigation, it was found that the new API requires the description field for each tool to explicitly specify parameter dependencies (e.g., "Please ensure user ID is obtained before calling this function"), which the old API did not enforce.
The Most Prone Failure: Implicit Context Loss
The most hidden pitfall in migration is context state loss. In the old API, developers were used to piecing the intermediate results of function calls back into the messages array, allowing the model to naturally sense history. However, in the Agent loop of a new API (for example, using the run + tool_outputs pattern), the tool's execution results must be returned strictly according to the thread or step structure. If the format is incorrect, the model ignores all previous tool outputs, causing the Agent workflow to be interrupted.
Specific error scenarios:
- In a multi-step toolchain, you first call
search_databaseto return 10 records, then callformat_resultsto request a table generation based on the previous step's result. However, in the new API, if you insert the output ofsearch_databasein a non-standard way intotool_outputs, the model will consider the step failed and skipformat_results. - Solution: Strictly follow the SDK's
submit_tool_outputsinterface, ensuring each output comes with a correspondingtool_call_id, and the output content does not exceed the model's context limit (usually 4096 tokens).

Step 1: Tool Definition of audit and Refactoring
If you want to implement migration now, the first step is not to change the code, but to perform tool-defined audit:
- List all existing functions: including names, parameters, and return formats. Be sure to mark functions that depend on the output of prerequisite tools (for example, "generate chart" depends on the results of "query data").
- Split by granularity: The new API recommends that each tool do only one thing. Common "universal functions" in older APIs (such as
execute_anything) had to be split into single responsibility functions, otherwise the model would easily become confusing. - Override description: Each tool's description must include preconditions, output format, and typical call scenarios. For example:
- Old:
"获取天气数据" - New:
"根据城市名获取当前天气。需要先调用 check_city_exists 确认城市有效。返回 JSON 格式:{temperature, humidity, condition}"
- Old:
- Add error handling tools: Define a
report_errortool specifically for handling exceptions that the model cannot handle, avoiding loop calls.
After completing the audit, create a new Agent test script in the development environment and use the new API's client.responses.create or client.beta.threads.runs.create to verify each tool call one by one.

Practical Path: A Simple Migration Case
Suppose you have an old API code:
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": "北京天气如何?"}],
functions=[{
"name": "get_weather",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}}
}]
)
迁移至新 API(OpenAI Python SDK v1.x+):
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4o",
input=[{"role": "user", "content": "北京天气如何?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}},
"description": "根据城市名获取天气。参数 city 必须是中国城市的中文名称。"
}
}]
)
注意新 API 使用了 input 而非 messages,且 tools 数组内每个工具需要显式 type 和更详细的 description。
Future Direction: From Function Calling to Agent Loops
Understanding the logic behind migration is actually preparing for more complex Agent workflows. Once you master tool definition, context management, and error recovery, you can move on to advanced topics like multi-tool orchestration, memory management, andMCPprotocol integration.
If you want to transition from an ordinary developer to an Agent engineer, the next step in this content should be to enter more systematic original paid articles or courses.

No comments yet. Be the first to share your thoughts.