🎉 New kimi k2.5 Multi-modal Model released! Now supports multimodal understanding and processing.
Docs
Getting Started Guide
Switch from OpenAI to Kimi API

Migrating from OpenAI to Kimi API

About API Compatibility

The Kimi API is compatible with OpenAI's interface specifications. You can use the Python (opens in a new tab) or NodeJS (opens in a new tab) SDKs provided by OpenAI to call and use the Kimi large language model. This means that if your application or service is developed based on OpenAI's models, you can seamlessly migrate to using the Kimi large language model by simply replacing the base_url and api_key with the configuration for the Kimi large language model. Here is an example of how to do this:

from openai import OpenAI
 
client = OpenAI(
    api_key="MOONSHOT_API_KEY", # <-- Replace MOONSHOT_API_KEY with the API Key you obtained from the Kimi Open Platform
    base_url="https://api.moonshot.ai/v1", # <-- Replace the base_url from https://api.openai.com/v1 to https://api.moonshot.ai/v1
)

We will do our best to ensure compatibility between the Kimi API and OpenAI. However, in some special cases, there may still be some differences and variations between the Kimi API and OpenAI (but this does not affect overall compatibility). We will detail the differences between the Kimi API and OpenAI and propose feasible migration solutions to help developers complete the migration process smoothly.

Here is a list of interfaces that are compatible with OpenAI:

  • /v1/chat/completions
  • /v1/files
  • /v1/files/{file_id}
  • /v1/files/{file_id}/content

Temperature and N Value

When using OpenAI's interface, you can set both temperature=0 and n>1, which means that in cases where the temperature value is 0, multiple different answers (i.e., choices) can be returned simultaneously.

However, in the Kimi API, when you set the temperature value to 0 or close to 0 (e.g., 0.001), we can only provide one answer (i.e., len(choices)=1). If you set temperature to 0 while using an n value greater than 1, we will return an "invalid request" error, specifically invalid_request_error.

Additionally, please note that the range of values for the temperature parameter in the Kimi API is [0, 1], while the range for the temperature parameter in OpenAI is [0, 2].

Migration Recommendation: For kimi-k2-turbo-preview, set temperature=0.6 for optimal results. For older models, 0.3 remains a safe default. If your business scenario requires setting temperature=0 to get more stable results from the Kimi large language model, please pay special attention to setting the n value to 1, or do not set the n value at all (in which case the default n=1 will be used as the request parameter, which is valid).

Usage Value in Stream Mode

When using OpenAI's chat.completions interface, in cases of streaming output (i.e., stream=True), the output result does not include usage information by default (including prompt_tokens/completion_tokens/total_tokens). OpenAI provides an additional parameter stream_options={"include_usage": True} to include usage information in the last data block of the response.

In the Kimi API, in addition to the stream_options={"include_usage": True} parameter, we also place usage information (including prompt_tokens/completion_tokens/total_tokens) in the end data block of each choice.

Migration Recommendation: In most cases, developers do not need to take any additional compatibility measures. If your business scenario requires tracking the usage information for each choice individually, you can access the choice.usage field. Note that among different choices, only the values of usage.completion_tokens and usage.total_tokens are different, while the values of usage.prompt_tokens are the same for all choices.

Deprecated function_call

In 2023, OpenAI introduced the functions parameter to enable function call functionality. After functional iteration, OpenAI later launched the tool call feature and marked the functions parameter as deprecated, which means that the functions parameter may be removed at any time in future API iterations.

The Kimi API fully supports the tool call feature. However, since functions has been deprecated, the Kimi API does not support using the functions parameter to execute function calls.

Migration Recommendation: If your application or service relies on tool calls, no additional compatibility measures are needed. If your application or service depends on the deprecated function call, we recommend migrating to tool calls. Tool calls expand the capabilities of function calls and support parallel function calls. For specific examples of tool calls, please refer to our tool call guide:

Using Kimi API for Tool Calls (tool_calls)

Here is an example of migrating from functions to tools:

We will present the code that needs to be modified in the form of comments, along with explanations, to help developers better understand how to perform the migration.

from typing import *
 
import json
import httpx
from openai import OpenAI
 
client = OpenAI(
    api_key="MOONSHOT_API_KEY",  # Replace MOONSHOT_API_KEY with the API Key you obtained from the Kimi Open Platform
    base_url="https://api.moonshot.ai/v1",
)
 
functions = [
    {
        "name": "search",  # The name of the function, please use English letters (uppercase and lowercase), numbers, plus hyphens and underscores as the function name
        "description": """ 
            Search for content on the internet using a search engine.
 
            Call this tool when your knowledge cannot answer the user's question or when the user requests you to perform an online search. Extract the content the user wants to search for from the conversation with the user and use it as the value of the query parameter.
            The search results include the title of the website, the website's address (URL), and a brief introduction to the website.
        """,  # Description of the function, write the specific function here and the usage scenario so that the Kimi large language model can correctly choose which functions to use
        "parameters": {  # Use the parameters field to define the parameters accepted by the function
            "type": "object",  # Always use type: object to make the Kimi large language model generate a JSON Object parameter
            "required": ["query"],  # Use the required field to tell the Kimi large language model which parameters are required
            "properties": {  # Properties contain the specific parameter definitions, and you can define multiple parameters
                "query": {  # Here, the key is the parameter name, and the value is the specific definition of the parameter
                    "type": "string",  # Use type to define the parameter type
                    "description": """
                        The content the user wants to search for, extract it from the user's question or chat context.
                    """  # Use description to describe the parameter so that the Kimi large language model can better generate the parameter
                }
            }
        }
    }
]
 
 
def search_impl(query: str) -> List[Dict[str, Any]]:
    """
    search_impl uses a search engine to search for query. Most mainstream search engines (such as Bing) provide API calls, and you can choose the one you like.
    You can call the search engine API of your choice and place the website title, website link, and website introduction information in a dict and return it.
 
    This is just a simple example, and you may need to write some authentication, validation, and parsing code.
    """
    r = httpx.get("https://your.search.api", params={"query": query})
    return r.json()
 
 
def search(arguments: Dict[str, Any]) -> Any:
    query = arguments["query"]
    result = search_impl(query)
    return {"result": result}
 
 
function_map = {
    "search": search,
}
 
# ==========================================================================================================================================================
# Tools are a superset of functions, so we can construct tools using the already defined functions. We loop through each function and create the corresponding tool format;
# At the same time, we also generate the corresponding tool_map.
# ==========================================================================================================================================================
 
tools = []
tool_map = {}
for function in functions:
    tool = {
        "type": "function",
        "function": function,
    }
    tools.append(tool)
    tool_map[function["name"]] = function_map[function["name"]]
 
messages = [
    {"role": "system",
     "content": "You are Kimi, an artificial intelligence assistant provided by Moonshot AI. You are more proficient in Chinese and English conversations. You provide users with safe, helpful, and accurate answers. You also refuse to answer any questions involving terrorism, racism, pornography, or violence. Moonshot AI is a proper noun and should not be translated into other languages."},
    {"role": "user", "content": "Please search the internet for Context Caching and tell me what it is."}  # The user asks Kimi to search online
]
 
finish_reason = None
 
# ==========================================================================================================================================================
# Here, we change the finish_reason value check from function_call to tool_calls
# ==========================================================================================================================================================
# while finish_reason is None or finish_reason == "function_call":
while finish_reason is None or finish_reason == "tool_calls":
    completion = client.chat.completions.create(
        model="kimi-k2.5",
        messages=messages,
        # ==========================================================================================================================================================
        # We no longer use the functions parameter, but instead use the tools parameter to enable tool calls
        # ==========================================================================================================================================================
        # function=functions,
        tools=tools,  # <-- We submit the defined tools to Kimi via the tools parameter
    )
    choice = completion.choices[0]
    finish_reason = choice.finish_reason
 
    # ==========================================================================================================================================================
    # Here, we replace the original function_call execution logic with the tool_calls execution logic;
    # Note that since there may be multiple tool_calls, we need to execute each one using a for loop.
    # ==========================================================================================================================================================
    # if finish_reason == "function_call":
    #   messages.append(choice.message)
    #   function_call_name = choice.message.function_call.name
    #   function_call_arguments = json.loads(choice.message.function_call.arguments)
    #   function_call = function_map[function_call_name]
    #   function_result = function_call(function_call_arguments)
    #   messages.append({
    #       "role": "function",
    #       "name": function_call_name,
    #       "content": json.dumps(function_result)
    #   })
 
    if finish_reason == "tool_calls":  # <-- Check if the response contains tool_calls
        messages.append(choice.message)  # <-- Add the assistant message from Kimi to the context for the next request
        for tool_call in choice.message.tool_calls:  # <-- Loop through each tool_call as there may be multiple
            tool_call_name = tool_call.function.name
            tool_call_arguments = json.loads(tool_call.function.arguments)  # <-- The arguments are serialized JSON, so we need to deserialize them
            tool_function = tool_map[tool_call_name]  # <-- Use tool_map to quickly find the function to execute
            tool_result = tool_function(tool_call_arguments)
 
            # Construct a message with role=tool to show the result of the tool call to the model;
            # Note that we need to provide the tool_call_id and name fields in the message so that Kimi can
            # correctly match it to the corresponding tool_call.
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "name": tool_call_name,
                "content": json.dumps(tool_result),  # <-- We agree to submit the tool call result as a string, so we serialize it here
            })
 
print(choice.message.content)  # <-- Finally, we return the model's response to the user

About tool_choice

The Kimi API supports the tool_choice parameter, but there are some subtle differences in the values for tool_choice compared to OpenAI. The values for tool_choice that are currently compatible between Kimi API and OpenAI API are:

  • "none"
  • "auto"
  • null

Please note that the current version of Kimi API does not support the tool_choice=required parameter.

Migration suggestion: If your application or service relies on the required value of the tool_choice field in the OpenAI API to ensure that the large model "definitely" selects a certain tool for invocation, we suggest using some special methods to enhance the Kimi large language model's awareness of invoking tools to partially accommodate the original business logic. For example, you can emphasize the use of a certain tool in the prompt to achieve a similar effect. We demonstrate this logic with a simplified version of the code:

from openai import OpenAI
 
client = OpenAI(
    api_key="MOONSHOT_API_KEY",  # Replace MOONSHOT_API_KEY with the API Key you obtained from the Kimi Open Platform
    base_url="https://api.moonshot.ai/v1",
)
 
tools = {
    # Define your tools here
}
 
messages = [
    # Store your message history here
]
 
completion = client.chat.completions.create(
    model="kimi-k2.5",
    messages=messages,
    tools=tools,
    # tool_choice="required",  # <-- Since Kimi API does not currently support tool_choice=required, we have temporarily disabled this option
)
 
choice = completion.choices[0]
if choice.finish_reason != "tool_calls":
    # We assume that our business logic can confirm that tool_calls must be invoked here.
    # Without using tool_choice=required, we use the prompt to make Kimi choose a tool for invocation.
    messages.append(choice.message)
    messages.append({
        "role": "user",
        "content": "Please select a tool to handle the current issue.",  # Usually, the Kimi large language model understands the intention to invoke a tool and selects one for invocation
    })
    completion = client.chat.completions.create(
        model="kimi-k2.5",
        messages=messages,
        tools=tools,
    )
    choice = completion.choices[0]
    assert choice.finish_reason == "tool_calls"  # This request should return finish_reason=tool_calls
    print(choice.message.content)

Please note that this method cannot guarantee a 100% success rate in triggering tool_calls. If your application or service has a very strong dependency on tool_calls, please wait for the launch of the tool_choice=required feature in Kimi API.