Создать простого текстового агента с вызовом функции

В Yandex AI Studio вы можете создать текстового агента с вызовом функции, способного взаимодействовать с пользователем в текстовом формате и поддерживать диалог, близкий к естественному человеческому общению.

Чтобы воспользоваться примером, вам понадобится сервисный аккаунт с ролями ai.assistants.editor и ai.languageModels.user, а также API-ключ с областью действия yc.ai.foundationModels.execute. API-ключ, который вы можете создать в AI Studio, имеет такие разрешения. Пример того, как настроить рабочее окружение, можно найти в разделе Начало работы.

Реализуйте чат

import openai
        from openai import OpenAI
        import json
        
        YANDEX_MODEL = "yandexgpt"
        YANDEX_API_KEY = "<API-ключ>"
        YANDEX_FOLDER_ID = "<идентификатор_каталога>"
        
        client = openai.OpenAI(
            api_key=YANDEX_API_KEY,
            base_url="https://ai.api.cloud.yandex.net/v1",
            project=YANDEX_FOLDER_ID
        )
        
        # 1. Определение списка функций, которые модель может вызывать
        tools = [
            {
                "type": "function",
                "name": "get_weather",
                "description": "Получить текущую погоду для указанного города.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "city": {
                            "type": "string",
                            "description": "Название города, например: Петербург или Москва",
                        },
                    },
                    "required": ["city"],
                },
            },
        ]
        
        # Простейшая реализация функции (можно заменить на вызов реального API)
        def get_weather(city):
            # Здесь можно реализовать интеграцию, например, с Яндекс Погодой
            return {
                "город": city,
                "температура": "12 °C",
                "состояние": "Облачно, легкий ветер"
            }
        
        # Формирование списка сообщений, который будет пополняться
        input_list = [
            {"role": "user", "content": "Какая погода в Красноярске?"}
        ]
        
        # 2. Запрос модели с определенными функциями
        response = client.responses.create(
            model=f"gpt://{YANDEX_FOLDER_ID}/{YANDEX_MODEL}",
            tools=tools,
            input=input_list,
        )
        
        # Добавление ввода модели в историю
        input_list += response.output
        
        for item in response.output:
            if item.type == "function_call":
                if item.name == "get_weather":
                    # 3. Выполнение функции get_weather
                    weather_info = get_weather(**json.loads(item.arguments))
        
                    # 4. Передача результата функции обратно модели
                    input_list.append({
                        "type": "function_call_output",
                        "call_id": item.call_id,
                        "output": json.dumps(weather_info)
                    })
        
        print("Финальный ввод:")
        for item in input_list:
            if isinstance(item, dict) and item.get("type") == "function_call_output":
                parsed = json.loads(item["output"])
                print("function_call_output:", parsed)
            else:
                print(item)
        
        response = client.responses.create(
            model=f"gpt://{YANDEX_FOLDER_ID}/{YANDEX_MODEL}",
            instructions="Отвечай только данными о погоде, которые вернула функция.",
            tools=tools,
            input=input_list,
        )
        
        # 5. Финальный ответ
        print("Финальный вывод:")
        print(response.model_dump_json(indent=2))
        print("\n" + response.output_text)
        

Где:

  • YANDEX_API_KEYAPI-ключ для работы в AI Studio.
  • YANDEX_FOLDER_IDидентификатор каталога сервисного аккаунта.
  • YANDEX_MODEL — имя модели, которая будет обрабатывать запрос.
  • instructions — системная инструкция, задающая поведение модели при финальном ответе.

Пример ответа:

  Финальный ввод:
          {'role': 'user', 'content': 'Какая погода в Красноярске?'}
          ResponseFunctionToolCall(arguments='{"city":"Красноярск"}', call_id='get_weather', name='get_weather', type='function_call', id='get_weather', status='completed', valid=True)
          function_call_output: {'город': 'Красноярск', 'температура': '12 °C', 'состояние': 'Облачно, легкий ветер'}
          Финальный вывод:
          {
            "id": "70d96fac-1c4b-4f4a-9f80-56df********",
            "created_at": 1758556157206.0,
            "error": null,
            "incomplete_details": null,
            "instructions": "Отвечай только данными о погоде, которые вернула функция.",
            "metadata": null,
            "model": "gpt://b1gstllj8rgs********/yandexgpt",
            "object": "response",
            "output": [
              {
                "id": "f15c66e8-99a2-4647-a820-406e********",
                "content": [
                  {
                    "annotations": [],
                    "text": "В Красноярске сейчас 12 °C, облачно, легкий ветер.",
                    "type": "output_text",
                    "logprobs": null,
                    "valid": true
                  }
                ],
                "role": "assistant",
                "status": "completed",
                "type": "message",
                "valid": true
              }
            ],
            "parallel_tool_calls": true,
            "temperature": null,
            "tool_choice": "auto",
            "tools": [
              {
                "name": "get_weather",
                "parameters": {
                  "type": "object",
                  "properties": {
                    "city": {
                      "type": "string",
                      "description": "Название города, например: Петербург или Москва"
                    }
                  },
                  "required": [
                    "city"
                  ]
                },
                "strict": null,
                "type": "function",
                "description": "Получить текущую погоду для указанного города.",
                "valid": true
              }
            ],
            "top_p": null,
            "background": false,
            "conversation": null,
            "max_output_tokens": null,
            "max_tool_calls": null,
            "previous_response_id": null,
            "prompt": null,
            "prompt_cache_key": null,
            "reasoning": null,
            "safety_identifier": null,
            "service_tier": null,
            "status": "completed",
            "text": null,
            "top_logprobs": null,
            "truncation": null,
            "usage": null,
            "user": "",
            "valid": true
          }
        
          В Красноярске сейчас 12 °C, облачно, легкий ветер.
        
const OpenAI = require("openai");
        
        const YANDEX_MODEL = "yandexgpt";
        const YANDEX_API_KEY = "<API-ключ>";
        const YANDEX_FOLDER_ID = "<идентификатор_каталога>";
        
        const client = new OpenAI({
        apiKey: YANDEX_API_KEY,
        baseURL: "https://ai.api.cloud.yandex.net/v1",
        project: YANDEX_FOLDER_ID,
        });
        
        // 1. Определение списка функций, которые модель может вызывать
        const tools = [
        {
            type: "function",
            name: "get_weather",
            description: "Получить текущую погоду для указанного города.",
            parameters: {
            type: "object",
            properties: {
                city: {
                type: "string",
                description: "Название города, например: Петербург или Москва",
                },
            },
            required: ["city"],
            },
        },
        ];
        
        // Простейшая реализация функции (можно заменить на вызов реального API)
        function getWeather(city) {
        // Здесь можно реализовать интеграцию, например, с Яндекс Погодой
        return {
            город: city,
            температура: "12 °C",
            состояние: "Облачно, легкий ветер",
        };
        }
        
        async function main() {
        // Формирование списка сообщений, который будет пополняться
        let inputList = [
            { role: "user", content: "Какая погода в Красноярске?" },
        ];
        
        // 2. Запрос модели с определенными функциями
        const response = await client.responses.create({
            model: `gpt://${YANDEX_FOLDER_ID}/${YANDEX_MODEL}`,
            tools: tools,
            input: inputList,
        });
        
        // Добавление вывода модели в историю
        inputList = inputList.concat(response.output);
        
        for (const item of response.output) {
            if (item.type === "function_call") {
            if (item.name === "get_weather") {
                // 3. Выполнение функции getWeather
                const args = JSON.parse(item.arguments);
                const weatherInfo = getWeather(args.city);
        
                // 4. Передача результата функции обратно модели
                inputList.push({
                type: "function_call_output",
                call_id: item.call_id,
                output: JSON.stringify(weatherInfo),
                });
            }
            }
        }
        
        console.log("Финальный ввод:");
        for (const item of inputList) {
            if (
            typeof item === "object" &&
            item !== null &&
            item.type === "function_call_output"
            ) {
            const parsed = JSON.parse(item.output);
            console.log("function_call_output:", parsed);
            } else {
            console.log(item);
            }
        }
        
        const finalResponse = await client.responses.create({
            model: `gpt://${YANDEX_FOLDER_ID}/${YANDEX_MODEL}`,
            instructions: "Отвечай только данными о погоде, которые вернула функция.",
            tools: tools,
            input: inputList,
        });
        
        // 5. Финальный ответ
        console.log("Финальный вывод:");
        console.log(JSON.stringify(finalResponse, null, 2));
        console.log("\n" + finalResponse.output_text);
        }
        
        main().catch(console.error);
        
        

Где:

  • YANDEX_API_KEYAPI-ключ для работы в AI Studio.
  • YANDEX_FOLDER_IDидентификатор каталога сервисного аккаунта.
  • YANDEX_MODEL — имя модели, которая будет обрабатывать запрос.
  • instructions — системная инструкция, задающая поведение модели при финальном ответе.

Пример ответа:

  Финальный ввод:
          {'role': 'user', 'content': 'Какая погода в Красноярске?'}
          ResponseFunctionToolCall(arguments='{"city":"Красноярск"}', call_id='get_weather', name='get_weather', type='function_call', id='get_weather', status='completed', valid=True)
          function_call_output: {'город': 'Красноярск', 'температура': '12 °C', 'состояние': 'Облачно, легкий ветер'}
          Финальный вывод:
          {
            "id": "70d96fac-1c4b-4f4a-9f80-56df********",
            "created_at": 1758556157206.0,
            "error": null,
            "incomplete_details": null,
            "instructions": "Отвечай только данными о погоде, которые вернула функция.",
            "metadata": null,
            "model": "gpt://b1gstllj8rgs********/yandexgpt",
            "object": "response",
            "output": [
              {
                "id": "f15c66e8-99a2-4647-a820-406e********",
                "content": [
                  {
                    "annotations": [],
                    "text": "В Красноярске сейчас 12 °C, облачно, легкий ветер.",
                    "type": "output_text",
                    "logprobs": null,
                    "valid": true
                  }
                ],
                "role": "assistant",
                "status": "completed",
                "type": "message",
                "valid": true
              }
            ],
            "parallel_tool_calls": true,
            "temperature": null,
            "tool_choice": "auto",
            "tools": [
              {
                "name": "get_weather",
                "parameters": {
                  "type": "object",
                  "properties": {
                    "city": {
                      "type": "string",
                      "description": "Название города, например: Петербург или Москва"
                    }
                  },
                  "required": [
                    "city"
                  ]
                },
                "strict": null,
                "type": "function",
                "description": "Получить текущую погоду для указанного города.",
                "valid": true
              }
            ],
            "top_p": null,
            "background": false,
            "conversation": null,
            "max_output_tokens": null,
            "max_tool_calls": null,
            "previous_response_id": null,
            "prompt": null,
            "prompt_cache_key": null,
            "reasoning": null,
            "safety_identifier": null,
            "service_tier": null,
            "status": "completed",
            "text": null,
            "top_logprobs": null,
            "truncation": null,
            "usage": null,
            "user": "",
            "valid": true
          }
        
          В Красноярске сейчас 12 °C, облачно, легкий ветер.
        
package main
        
        import (
            "context"
            "encoding/json"
            "fmt"
            "log"
        
            "github.com/openai/openai-go"
            "github.com/openai/openai-go/option"
            "github.com/openai/openai-go/responses"
        )
        
        const (
            YANDEX_MODEL     = "yandexgpt"
            YANDEX_API_KEY   = "<API-ключ>"
            YANDEX_FOLDER_ID = "<идентификатор_каталога>"
        )
        
        // 1. Определение инструмента
        var tools = []responses.ToolUnionParam{
            {
                OfFunction: &responses.FunctionToolParam{
                    Name:        "get_weather",
                    Description: openai.String("Получить текущую погоду для указанного города."),
                    Parameters: map[string]any{
                        "type": "object",
                        "properties": map[string]any{
                            "city": map[string]any{
                                "type":        "string",
                                "description": "Название города, например: Петербург или Москва",
                            },
                        },
                        "required": []string{"city"},
                    },
                    Strict: openai.Bool(false),
                },
            },
        }
        
        // Простейшая реализация функции
        func getWeather(city string) map[string]string {
            return map[string]string{
                "город":       city,
                "температура": "12 °C",
                "состояние":   "Облачно, легкий ветер",
            }
        }
        
        func main() {
            client := openai.NewClient(
                option.WithAPIKey(YANDEX_API_KEY),
                option.WithBaseURL("https://ai.api.cloud.yandex.net/v1"),
                option.WithProject(YANDEX_FOLDER_ID),
            )
        
            model := fmt.Sprintf("gpt://%s/%s", YANDEX_FOLDER_ID, YANDEX_MODEL)
        
            // Формирование списка сообщений
            inputList := []responses.ResponseInputItemUnionParam{
                {
                    OfMessage: &responses.EasyInputMessageParam{
                        Role: responses.EasyInputMessageRoleUser,
                        Type: "message",
                        Content: responses.EasyInputMessageContentUnionParam{
                            OfString: openai.String("Какая погода в Красноярске?"),
                        },
                    },
                },
            }
        
            // 2. Запрос модели с инструментами
            r1, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
                Model: model,
                Tools: tools,
                Input: responses.ResponseNewParamsInputUnion{
                    OfInputItemList: inputList,
                },
            })
            if err != nil {
                log.Fatalf("Ошибка r1: %v", err)
            }
        
            // Добавляем вывод модели в историю
            for _, item := range r1.Output {
                switch item.Type {
                case "function_call":
                    fc := item.AsFunctionCall()
                    inputList = append(inputList, responses.ResponseInputItemUnionParam{
                        OfFunctionCall: &responses.ResponseFunctionToolCallParam{
                            ID:        openai.String(fc.ID),
                            CallID:    fc.CallID,
                            Name:      fc.Name,
                            Arguments: fc.Arguments,
                        },
                    })
                case "message":
                    msg := item.AsMessage()
                    // конвертируем content
                    var content []responses.ResponseOutputMessageContentUnionParam
                    for _, c := range msg.Content {
                        content = append(content, responses.ResponseOutputMessageContentUnionParam{
                            OfOutputText: &responses.ResponseOutputTextParam{
                                Text: c.AsOutputText().Text,
                            },
                        })
                    }
                    inputList = append(inputList, responses.ResponseInputItemUnionParam{
                        OfOutputMessage: &responses.ResponseOutputMessageParam{
                            ID:      msg.ID,
                            Status:  responses.ResponseOutputMessageStatus(msg.Status),
                            Content: content,
                        },
                    })
                }
            }
        
            // Обрабатываем вызовы функций
            for _, item := range r1.Output {
                if item.Type == "function_call" {
                    fc := item.AsFunctionCall()
                    if fc.Name == "get_weather" {
                        // 3. Парсим аргументы и выполняем функцию
                        var args struct {
                            City string `json:"city"`
                        }
                        if err := json.Unmarshal([]byte(fc.Arguments), &args); err != nil {
                            log.Fatalf("Ошибка парсинга аргументов: %v", err)
                        }
        
                        weatherInfo := getWeather(args.City)
                        weatherJSON, _ := json.Marshal(weatherInfo)
        
                        // 4. Передаем результат обратно через хелпер SDK
                        inputList = append(inputList,
                            responses.ResponseInputItemParamOfFunctionCallOutput(fc.CallID, string(weatherJSON)),
                        )
                    }
                }
            }
        
            // Выводим финальный ввод
            fmt.Println("Финальный ввод:")
            for _, item := range inputList {
                itemJSON, _ := json.MarshalIndent(item, "", "  ")
                fmt.Println(string(itemJSON))
            }
        
            // 5. Финальный запрос
            r2, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
                Model:        model,
                Instructions: openai.String("Отвечай только данными о погоде, которые вернула функция."),
                Tools:        tools,
                Input: responses.ResponseNewParamsInputUnion{
                    OfInputItemList: inputList,
                },
            })
            if err != nil {
                log.Fatalf("Ошибка r2: %v", err)
            }
        
            // Финальный ответ
            fmt.Println("\nФинальный вывод:")
            finalJSON, _ := json.MarshalIndent(r2, "", "  ")
            fmt.Println(string(finalJSON))
            fmt.Println("\n" + r2.OutputText())
        }
        

Где:

  • YANDEX_API_KEYAPI-ключ для работы в AI Studio.
  • YANDEX_FOLDER_IDидентификатор каталога сервисного аккаунта.
  • YANDEX_MODEL — имя модели, которая будет обрабатывать запрос.
  • instructions — системная инструкция, задающая поведение модели при финальном ответе.

Пример ответа:

  Финальный ввод:
          {'role': 'user', 'content': 'Какая погода в Красноярске?'}
          ResponseFunctionToolCall(arguments='{"city":"Красноярск"}', call_id='get_weather', name='get_weather', type='function_call', id='get_weather', status='completed', valid=True)
          function_call_output: {'город': 'Красноярск', 'температура': '12 °C', 'состояние': 'Облачно, легкий ветер'}
          Финальный вывод:
          {
            "id": "70d96fac-1c4b-4f4a-9f80-56df********",
            "created_at": 1758556157206.0,
            "error": null,
            "incomplete_details": null,
            "instructions": "Отвечай только данными о погоде, которые вернула функция.",
            "metadata": null,
            "model": "gpt://b1gstllj8rgs********/yandexgpt",
            "object": "response",
            "output": [
              {
                "id": "f15c66e8-99a2-4647-a820-406e********",
                "content": [
                  {
                    "annotations": [],
                    "text": "В Красноярске сейчас 12 °C, облачно, легкий ветер.",
                    "type": "output_text",
                    "logprobs": null,
                    "valid": true
                  }
                ],
                "role": "assistant",
                "status": "completed",
                "type": "message",
                "valid": true
              }
            ],
            "parallel_tool_calls": true,
            "temperature": null,
            "tool_choice": "auto",
            "tools": [
              {
                "name": "get_weather",
                "parameters": {
                  "type": "object",
                  "properties": {
                    "city": {
                      "type": "string",
                      "description": "Название города, например: Петербург или Москва"
                    }
                  },
                  "required": [
                    "city"
                  ]
                },
                "strict": null,
                "type": "function",
                "description": "Получить текущую погоду для указанного города.",
                "valid": true
              }
            ],
            "top_p": null,
            "background": false,
            "conversation": null,
            "max_output_tokens": null,
            "max_tool_calls": null,
            "previous_response_id": null,
            "prompt": null,
            "prompt_cache_key": null,
            "reasoning": null,
            "safety_identifier": null,
            "service_tier": null,
            "status": "completed",
            "text": null,
            "top_logprobs": null,
            "truncation": null,
            "usage": null,
            "user": "",
            "valid": true
          }
        
          В Красноярске сейчас 12 °C, облачно, легкий ветер.
        

См. также