> ## Documentation Index
> Fetch the complete documentation index at: https://platform.kimi.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from OpenAI to Kimi API

## About API Compatibility

The Kimi API is compatible with OpenAI's interface specifications. You can use the [Python](https://github.com/openai/openai-python) or [NodeJS](https://github.com/openai/openai-node) 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:

<Tabs>
  <Tab title="python">
    ```python theme={null}
    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
    )
    ```
  </Tab>

  <Tab title="node.js">
    ```js theme={null}
    const OpenAI = require("openai");
     
    const client = new OpenAI({
        apiKey: "MOONSHOT_API_KEY", // <-- Replace MOONSHOT_API_KEY with the API Key you obtained from the Kimi Open Platform
        baseURL: "https://api.moonshot.ai/v1",  // <-- Replace the baseURL from https://api.openai.com/v1 to https://api.moonshot.ai/v1
    });
    ```
  </Tab>
</Tabs>

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.6` and `kimi-k2.5` models, the temperature parameter has special requirements:**

* Thinking mode uses a fixed `temperature=1.0`
* Non-thinking mode uses `temperature=0.6`

Any other value will result in an error. We recommend not explicitly setting the temperature when calling these models, or following the above requirements.

## 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)](/guide/use-kimi-api-to-complete-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.*

<Tabs>
  <Tab title="python">
    ```python theme={null}
    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.6",
            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
    ```
  </Tab>

  <Tab title="node.js">
    ```js theme={null}
    const { OpenAI } = require('openai');

    const client = new OpenAI({
      apiKey: "MOONSHOT_API_KEY", // Replace MOONSHOT_API_KEY with your API Key from the Kimi Open Platform
      baseURL: "https://api.moonshot.ai/v1",
    });

    const functions = [
      {
        "name": "search",
        "description": "Search the internet using a search engine. Call this tool when your knowledge cannot answer the user's question or when the user requests an online search. Extract the content the user wants to search from the conversation as the value of the query parameter. The search results include the website title, URL, and a brief description.",
        "parameters": {
          "type": "object",
          "required": ["query"],
          "properties": {
            "query": {
              "type": "string",
              "description": "The content the user wants to search for, extracted from the user's question or chat context."
            }
          }
        }
      }
    ];

    async function search_impl(query) {
      const response = await fetch("https://your.search.api", {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ query: query })
      });
      return await response.json();
    }

    async function search(arguments) {
      const query = arguments.query;
      const result = await search_impl(query);
      return { result };
    }

    const function_map = {
      "search": search,
    };

    const tools = [];
    const tool_map = {};
    for (const function_ of functions) {
      const tool = {
        "type": "function",
        "function": function_,
      };
      tools.push(tool);
      tool_map[function_.name] = function_map[function_.name];
    }

    const 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."}
    ];

    let finish_reason = null;

    async function main() {
      while (finish_reason !== "tool_calls") {
        const completion = await client.chat.completions.create({
          model: "kimi-k2.6",
          messages: messages,
          tools: tools,
        });
        const choice = completion.choices[0];
        finish_reason = choice.finish_reason;

        if (finish_reason === "tool_calls") {
          messages.push(choice.message);
          for (const tool_call of choice.message.tool_calls) {
            const tool_call_name = tool_call.function.name;
            const tool_call_arguments = JSON.parse(tool_call.function.parameters);
            const tool_function = tool_map[tool_call_name];
            const tool_result = await tool_function(tool_call_arguments);

            messages.push({
              "role": "tool",
              "tool_call_id": tool_call.id,
              "name": tool_call_name,
              "content": JSON.stringify(tool_result),
            });
          }
        }
      }
      console.log(choice.message.content);
    }

    main();
    ```
  </Tab>
</Tabs>

## 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:

<Tabs>
  <Tab title="python">
    ```python theme={null}
    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.6",
        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.6",
            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)
    ```
  </Tab>

  <Tab title="node.js">
    ```js theme={null}
    const OpenAI = require('openai')
    client = OpenAI({
        apiKey: "MOONSHOT_API_KEY",  // Replace MOONSHOT_API_KEY with the API Key you obtained from the Kimi Open Platform
        baseURL: "https://api.moonshot.ai/v1",
    })
     
    tools = {
        // Define your tools here
    }
     
    messages = [
        // Store your message history here
    ]

    async function main() {
        completion = await client.chat.completions.create({
            model: "kimi-k2.6",
            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 = await client.chat.completions.create({
                model: "kimi-k2.6",
                messages: messages,
                tools: tools,
        })
            choice = completion.choices[0]
            assert(choice.finish_reason == "tool_calls")  // This request should return finish_reason=tool_calls
            console.log(choice.message.content)
        }
    }

    main()
    ```
  </Tab>
</Tabs>

**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.**
