서버 프롬프트 템플릿과의 다중 턴 상호작용


이 가이드는 다음을 비롯하여 멀티턴 상호작용에 의존하는 모든 기능에 적용됩니다.

높은 수준의 개요

멀티턴 상호작용의 경우 Firebase AI Logic SDK는 대화 상태를 관리합니다. 이는 서버 프롬프트 템플릿을 사용할 때도 적용됩니다.

멀티턴 상호작용 및 서버 프롬프트 템플릿의 기본 워크플로는 몇 가지 중요한 차이점을 제외하고 기본적으로 단일 턴 요청과 동일합니다.

  1. 안내 UI를 사용하여 템플릿을 만듭니다.Firebase 콘솔

    멀티턴 상호작용의 경우 템플릿의 콘텐츠에 {{history}} 태그를 추가해야 합니다. 이 태그는 클라이언트 SDK에서 관리하는 대화 턴을 삽입할 위치를 템플릿에 알려줍니다.

  2. 콘솔의 테스트 환경을 사용하여 실제 요청에서 템플릿을 테스트합니다.Firebase

    멀티턴 상호작용의 경우 콘솔 테스트 환경은 초기 턴만 테스트하는 데 도움이 될 수 있습니다. 실제 앱에서 템플릿을 사용하여 후속 턴 (기록)이 처리되는 방식을 테스트할 수 있습니다.

  3. templateGenerativeModel을 사용하여 앱의 코드에서 템플릿에 액세스합니다.

    멀티턴 상호작용의 경우 서버 프롬프트 템플릿을 사용하지 않을 때 멀티턴 상호작용에 사용하는 것과 마찬가지로 startChatsendMessage를 사용해야 합니다.

함수 호출의 경우 몇 가지 차이점이 더 있으며, 이 페이지의 뒷부분에 있는 해당 섹션에서 설명합니다.



멀티턴 대화 (채팅)

아직 검토하지 않았다면 멀티턴 대화 (채팅)를 빌드하기 위한 일반 가이드 를 서버 프롬프트 템플릿을 사용하지 않을 때 검토하세요.

서버 프롬프트 템플릿의 기본 형식

Firebase AI Logic의 경우 Firebase 콘솔 은 템플릿의 프런트매터와 콘텐츠를 지정할 수 있는 안내 UI를 제공합니다.

서버 프롬프트 템플릿은 Dotprompt 기반 문법과 형식을 사용합니다. 자세한 내용은 템플릿 형식, 문법, 예시를 참고하세요.

아래 예시 템플릿은 멀티턴 대화 (채팅)를 빌드할 때 템플릿의 가장 중요한 구성요소를 보여줍니다. 템플릿의 콘텐츠에 {{history}} 태그가 추가된 것을 확인하세요. 이 태그는 클라이언트 SDK에서 관리하는 대화 턴을 삽입할 위치를 템플릿에 알려줍니다.

---
model: 'gemini-3-flash-preview'
---

{{role "system"}}
You help customers with their invoices, including answering questions or providing their invoices to them.
If an invoice is requested, it must be a clearly structured invoice document that uses a tabular or clearly delineated list format for line items.

{{history}}

코드에서 템플릿 사용

Gemini API 제공업체를 클릭하여 이 페이지에서 제공업체별 콘텐츠 및 코드를 확인합니다.

아래 예시 클라이언트 코드는 코드에서 템플릿을 사용하는 방법을 보여줍니다. 멀티턴 상호작용을 빌드할 때 startChatsendMessage와 함께 templateGenerativeModel을 사용하는 것에 유의하세요.

Swift

For Swift, using server prompt templates with multi-turn interactions is not yet supported. Check back soon!

Kotlin


// ...

// Initialize the Gemini Developer API backend service
// Create a `TemplateGenerativeModel` instance.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
                        .templateGenerativeModel()

// Start a chat session with a template.
val chatSession = model.startChat(
  // Specify your template ID
  templateId= "my-chat-template-v1-0-0",
  inputs = emptyMap()
)

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
val response = chatSession.sendMessage(
  content("user") { text("I need a copy of my invoice.") }
)

val text = response.text
println(text)

Java

For Java, using server prompt templates with multi-turn interactions is not yet supported. Check back soon!

Web


// ...

// Initialize the Gemini Developer API backend service.
const ai = getAI(app, { backend: new GoogleAIBackend() });

// Create a `TemplateGenerativeModel` instance.
const model = getTemplateGenerativeModel(ai);

// Start a chat session with a template.
const chatSession = model.startChat({
  // Specify your template ID.
  templateId: 'my-chat-template-v1-0-0',
});

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
const result = await chatSession.sendMessage("I need a copy of my invoice.");

const text = result.response.text();
console.log(text);

Dart


// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
final model = FirebaseAI.googleAI().templateGenerativeModel();

// Start a chat session with a template.
final chatSession = model.startChat(
  // Specify your template ID.
  templateId: 'my-chat-template-v1-0-0',
);

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
final response = await chatSession.sendMessage(
  Content.text('I need a copy of my invoice.'),
);

final text = response.text;
print(text);

Unity


// ...

// Initialize the Gemini Developer API backend service.
var firebaseAI = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Create a `TemplateGenerativeModel` instance.
var model = firebaseAI.GetTemplateGenerativeModel();

// Start a chat session with a template.
var chatSession = model.StartChat(
    // Specify your template ID.
    "my-chat-template-v1-0-0"
);

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
try
{
   var response = await chatSession.SendMessageAsync(ModelContent.Text("I need a copy of my invoice."));
   Debug.Log($"Response Text: {response.Text}");
}
catch (Exception e) {
  Debug.LogError($"An error occurred: {e.Message}");
}



함수 호출

아직 검토하지 않았다면 서버 프롬프트 템플릿을 사용하지 않을함수 호출 에 관한 일반 가이드를 검토하세요. 서버 프롬프트 템플릿 사용에 관한 이 가이드는 함수 호출이 일반적으로 작동하는 방식을 이해하고 있다고 가정합니다.

서버 프롬프트 템플릿의 기본 형식

Firebase AI Logic의 경우 Firebase 콘솔 은 템플릿의 프런트매터와 콘텐츠를 지정할 수 있는 안내 UI를 제공합니다.

서버 프롬프트 템플릿은 Dotprompt 기반 문법과 형식을 사용합니다. 자세한 내용은 템플릿 형식, 문법, 예시를 참고하세요.

아래 예시 템플릿은 함수 호출을 사용할 때 템플릿의 가장 중요한 구성요소를 보여줍니다. 다음에 유의하세요.

  • 템플릿의 프런트매터에서 tools 객체에 함수 선언을 제공하여 모델이 액세스할 수 있는 함수를 나열합니다.

    • 모델이 액세스할 수 있는 각 함수의 name (필수)description (선택사항)을(를) 정의합니다.

    • 모델이 액세스할 수 있는 각 함수의 스키마를 정의합니다.

      아래 예시 템플릿은 템플릿에서 함수 스키마를 정의한다고 가정합니다. 하지만 클라이언트 코드에서 함수의 스키마를 제공할 수도 있습니다. 클라이언트 코드에서 정의된 스키마는 템플릿에 정의된 스키마를 재정의 합니다. 이 페이지의 뒷부분에서 클라이언트 코드에서 스키마를 정의하기 위한 예시 템플릿과 클라이언트 코드 를 찾습니다.

  • 템플릿의 콘텐츠에 {{history}} 태그를 추가합니다. 이 태그는 클라이언트 SDK에서 관리하는 대화 턴을 삽입할 위치를 템플릿에 알려줍니다.

템플릿에 함수 스키마가 정의된 예시 템플릿

---
model: gemini-3-flash-preview
tools:
  - name: fetchWeather
    description: Get the weather conditions for a specific city on a specific date.
    input:
      schema:
        location(object, The name of the city and its state for which to get the weather. Only cities in the USA are supported.):
          city: string, The city of the location.
          state: string, The state of the location.
        date: string, The date for which to get the weather. Date must be in the format YYYY-MM-DD.

---

What was the weather like in Boston, Massachusetts on 10/17 in year 2024?

{{history}}

코드에서 템플릿 사용

Gemini API 제공업체를 클릭하여 이 페이지에서 제공업체별 콘텐츠 및 코드를 확인합니다.

아래 예시 클라이언트 코드는 코드에서 템플릿을 사용하는 방법을 보여줍니다. 다음에 유의하세요.

  • 멀티턴 상호작용을 사용할 때 startChatsendMessage와 함께 templateGenerativeModel을 사용합니다.

  • 클라이언트 코드에서 모델을 초기화하는 동안 모델이 액세스할 수 있는 함수를 나열하지 마세요. 대신 함수는 템플릿의 프런트매터에 있는 tools 객체에 나열되어야 합니다 (위 참고).

  • 아래 예시 클라이언트 코드는 템플릿에서 함수 스키마를 정의한다고 가정합니다. 대신 클라이언트 코드에서 스키마를 정의하기로 결정하면 템플릿 정의 스키마를 재정의 합니다. 이 페이지의 뒷부분에서 클라이언트 코드에서 스키마를 정의하기 위한 예시 템플릿과 클라이언트 코드를 확인하세요.

  • 모델이 요청을 처리하는 과정에서 함수 호출을 반환하는지 확인합니다. 반환하는 경우 앱은 로컬 로직을 실행한 다음 결과를 모델에 다시 전송해야 합니다.

템플릿에 함수 스키마가 정의된 예시 클라이언트 코드

Swift

For Swift, using server prompt templates with multi-turn interactions is not yet supported. Check back soon!

Kotlin


// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .templateGenerativeModel()

// Start a chat session with a template that has functions listed as tools.
val chatSession = model.startChat(
    // Specify your template ID
    templateId = "my-function-calling-template-v1-0-0",
    inputs = emptyMap()
)

// Send a message that might trigger a function call.
val response = chatSession.sendMessage(
    content("user") { text(userMessage) }
)

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
val functionCalls = response.functionCalls
val fetchWeatherCall = functionCalls.find { it.name == "fetchWeather" }

// Forward the structured input data from the model to the hypothetical external API.
val functionResponse = fetchWeatherCall?.let {
  // Alternatively, if your `Location` class is marked as @Serializable, you can use
  // val location = Json.decodeFromJsonElement(it.args["location"]!!)
  val location = Location(
      it.args["location"]!!.jsonObject["city"]!!.jsonPrimitive.content,
      it.args["location"]!!.jsonObject["state"]!!.jsonPrimitive.content
  )
  val date = it.args["date"]!!.jsonPrimitive.content
  fetchWeather(location, date)
}

Java

For Java, using server prompt templates with multi-turn interactions is not yet supported. Check back soon!

Web


// ...

// Initialize the Gemini Developer API backend service.
const ai = getAI(app, { backend: new GoogleAIBackend() });

// Create a `TemplateGenerativeModel` instance.
const model = getTemplateGenerativeModel(ai);

// Start a chat session with a template that has functions listed as tools.
const chatSession = model.startChat({
  // Specify your template ID
  templateId: 'my-function-calling-template-v1-0-0',
});

// Send a message that might trigger a function call.
const result = await chatSession.sendMessage(userMessage);

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
const functionCalls = result.response.functionCalls();
let functionCall;
let functionResult;

if (functionCalls.length > 0) {
  for (const call of functionCalls) {
    if (call.name === "fetchWeather") {
      // Forward the structured input data prepared by the model
      // to the hypothetical external API.
      functionResult = await fetchWeather(call.args);
      functionCall = call;
    }
  }
}

Dart


// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
final model = FirebaseAI.googleAI().templateGenerativeModel()

// Start a chat session with a template that has functions listed as tools.
var chatSession = model.startChat(
    // Specify your template ID
    'my-function-calling-template-v1-0-0',
);

// Send a message that might trigger a function call.
var response = await chatSession.sendMessage(
    Content.text(userMessage),
);

// Check if the model wants to call a function.
// Note that this is the same as when *not* using server prompt templates.
final functionCalls = response?.functionCalls.toList();
// When the model responds with one or more function calls, invoke the function(s).
if (functionCalls != null && functionCalls.isNotEmpty) {
  for (final functionCall in functionCalls) {
    if (functionCall.name == 'fetchWeather') {
      Map<String, dynamic> location =
          functionCall.args['location']! as Map<String, dynamic>;
      var date = functionCall.args['date']! as String;
      var city = location['city'] as String;
      var state = location['state'] as String;
      final functionResult =
          await fetchWeather(Location(city, state), date);
      // Send the response to the model so that it can use the result to
      // generate text for the user.
      response = await chatSession.sendMessage(
        Content.functionResponse(functionCall.name, functionResult),
      );
    }
  }
}

Unity


// ...

// Initialize the Gemini Developer API backend service.
var firebaseAI = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Create a `TemplateGenerativeModel` instance.
var model = firebaseAI.GetTemplateGenerativeModel();

// Start a chat session with a template that has functions listed as tools.
var chatSession = model.StartChat(
    // Specify your template ID
    "my-function-calling-template-v1-0-0"
);

try
{
   // Send a message that might trigger a function call.
   var response = await chatSession.SendMessageAsync(ModelContent.Text(userMessage));
   var functionResponses = new List();

  // When the model responds with one or more function calls, invoke the function(s).
  // Note that this is the same as when *not* using server prompt templates.
  foreach (var functionCall in response.FunctionCalls) {
    if (functionCall.Name == "fetchWeather") {
      // TODO(developer): Handle invalid arguments.
      var location = functionCall.Args["location"] as Dictionary<string, object>;
      var city = location["city"] as string;
      var state = location["state"] as string;
      var date = functionCall.Args["date"] as string;

      functionResponses.Add(ModelContent.FunctionResponse(
        name: functionCall.Name,
        // Forward the structured input data prepared by the model
        // to the hypothetical external API.
        response: FetchWeather(city: city, state: state, date: date)
      ));
    }
    // TODO(developer): Handle other potential function calls, if any.
  }

  // Send the function responses back to the model.
  var functionResponseResult = await chatSession.SendMessageAsync(functionResponses);
}
catch (Exception e) {
  Debug.LogError($"An error occurred: {e.Message}");
}


함수 호출 - 클라이언트 코드에서 스키마 정의

서버 프롬프트 템플릿으로 함수 호출이 작동하는 방식 (특히 템플릿 콘텐츠에서 {{history}} 태그 사용)에 관한 위의 섹션을 검토하세요. 이 섹션에서는 템플릿 대신 클라이언트 코드에서 함수 스키마를 정의하려는 경우 예시 템플릿과 클라이언트 코드를 제공합니다.

클라이언트 코드에서 함수 스키마를 정의하는 것에 유의하세요.

  • 클라이언트 코드에서 함수의 스키마를 정의하면 (아래 예시 참고) 클라이언트 측 스키마가 해당 함수의 템플릿 정의 스키마를 재정의 합니다.

  • 클라이언트 코드에서 함수 스키마를 정의하려면 함수 선언을 작성한 다음 startChat모델 초기화 중이 아닌 선언을 제공 합니다 (서버 프롬프트 템플릿을 사용하지 않을 때 수행하는 작업).

  • 함수 선언에서 name을 지정하더라도 템플릿은 모델이 액세스할 수 있는 함수를 계속 나열해야 합니다. 템플릿의 name은 클라이언트 코드의 name과 일치해야 합니다.

클라이언트 코드에 함수 스키마가 정의된 예시 템플릿

---
model: gemini-3-flash-preview
tools:
  - name: fetchWeather
    description: Get the weather conditions for a specific city on a specific date.
---

What was the weather like in Boston, Massachusetts on 10/17 in year 2024, formatted in CELSIUS?

{{history}}

클라이언트 코드에 함수 스키마가 정의된 예시 클라이언트 코드
(이 예시에서 생략된 세부정보는 위의 예시 클라이언트 코드를 참고하세요)

Swift

For Swift, using server prompt templates with multi-turn interactions is not yet supported. Check back soon!

Kotlin

// ...

// Initialize your desired Gemini API backend service.
// Create a `TemplateGenerativeModel` instance.
...

// Define the schema for any functions listed in your template.
val fetchWeatherTool = functionDeclarations(
    functionDeclarations = listOf(
        FunctionDeclaration(
            name = "fetchWeather",
            description = "Returns the weather for a given location at a given time",
            parameters = mapOf(
                "location" to Schema.obj(
                    description = "The name of the city and its state for which to get the weather. Only cities in the USA are supported.",
                    properties = mapOf(
                        "city" to Schema.string(
                            description = "The city of the location."
                        ),
                        "state" to Schema.string(
                            description = "The state of the location."
                        ),
                        "zipCode" to Schema.string(
                            description = "Optional zip code of the location.",
                            nullable = true
                        )
                    ),
                    optionalProperties = listOf("zipCode")
                ),
                "date" to Schema.string(
                    description = "The date for which to get the weather. Date must be in the format: YYYY-MM-DD."
                ),
                "unit" to Schema.enumeration(
                    description = "The temperature unit.",
                    values = listOf("CELSIUS", "FAHRENHEIT"),
                    nullable = true
                )

            ),
            optionalParameters = listOf("unit"),
        )
    )
)

// Start a chat session with a template that has functions listed as tools.
var chatSessionWithSchemaOverride = model.startChat(
    // Specify your template ID.
    templateId = "my-function-calling-template-with-no-function-schema-v1-0-0",
    // In `startChat`, provide the schema for any functions listed in your template.
    // This client-side schema will override any schema defined in the template.
    tools = listOf(fetchWeatherTool)
)

// Send a message that might trigger a function call.
...

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
...

// Forward the structured input data from the model to the hypothetical external API.
...

Java

For Java, using server prompt templates with multi-turn interactions is not yet supported. Check back soon!

Web

// ...

// Initialize your desired Gemini API backend service.
...

// Create a `TemplateGenerativeModel` instance.
...

// Start a chat session with a template that has functions listed as tools.
const chatSessionWithSchemaOverride = model.startChat({
  // Specify your template ID.
  templateId: 'my-function-calling-template-with-no-function-schema-v1-0-0',
  // In `startChat`, provide the schema for any functions listed in your template.
  // This client-side schema will override any schema defined in the template.
  tools: [
    {
      functionDeclarations: [
        {
          name: "fetchWeather",
          parameters: {
            type: Type.OBJECT,
            properties: {
              location: {
                type: Type.OBJECT,
                description: "The name of the city and its state for which to get the weather. Only cities in the USA are supported.",
                properties: {
                  city: {
                    type: Type.STRING,
                    description: "The city of the location."
                  },
                  state: {
                    type: Type.STRING,
                    description: "The state of the location."
                  },
                  zipCode: {
                    type: Type.INTEGER,
                    description: "Optional zip code of the location.",
                    nullable: true
                  },
                },
                required: ["city", "state"],
              },
              date: {
                type: Type.STRING,
                description: "The date for which to get the weather. Date must be in the format: YYYY-MM-DD.",
              },
              unit: {
                type: Type.STRING,
                description: "The temperature unit.",
                enum: ["CELSIUS", "FAHRENHEIT"],
                nullable: true,
              },
            },
            required: ["location", "date"],
          },
        },
      ],
    }
  ],
});

// Send a message that might trigger a function call.
...

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
...

Dart

// ...

// Initialize your desired Gemini API backend service.
// Create a `TemplateGenerativeModel` instance.
...

// Start a chat session with a template that has functions listed as tools.
final chatSessionWithSchemaOverride = model?.startChat(
      // Specify your template ID.
      'my-function-calling-template-with-no-function-schema-v1-0-0',
      inputs: {},
      // In `startChat`, provide the schema for any functions listed in your template.
      // This client-side schema will override any schema defined in the template.
      tools: [
        TemplateTool.functionDeclarations(
          [
            TemplateFunctionDeclaration(
              'fetchWeather',
              parameters: {
                'location': JSONSchema.object(
                  description:
                      'The name of the city and its state for which to get '
                      'the weather. Only cities in the USA are supported.',
                  properties: {
                    'city': JSONSchema.string(
                      description: 'The city of the location.',
                    ),
                    'state': JSONSchema.string(
                      description: 'The state of the location.',
                    ),
                    'zipCode': JSONSchema.integer(
                      description: 'Optional zip code of the location.',
                      nullable: true,
                    ),
                  },
                  optionalProperties: ['zipCode'],
                ),
                'date': JSONSchema.string(
                  description: 'The date for which to get the weather. '
                      'Date must be in the format: YYYY-MM-DD.',
                ),
                'unit': JSONSchema.enumString(
                  enumValues: ['CELSIUS', 'FAHRENHEIT'],
                  description: 'The temperature unit.',
                  nullable: true,
                ),
              },
              optionalParameters: ['unit'],
            ),
          ],
        ),
      ],
    );

// Send a message that might trigger a function call.
...

// Check if the model wants to call a function.
// Note that this is the same as when *not* using server prompt templates.
...

Unity

// ...

// Initialize your desired Gemini API backend service.
...

// Create a `TemplateGenerativeModel` instance.
...

// Define the schema for any functions listed in your template.
var fetchWeatherTool = new TemplateTool.FunctionDeclaration(
    name: "fetchWeather",
    parameters: new Dictionary<string, JsonSchema>() {
        { "location", JsonSchema.Object(
            description: "The name of the city and its state for which to get the weather. Only cities in the USA are supported.",
            properties: new Dictionary<string, JsonSchema>() {
                { "city", JsonSchema.String(description: "The city of the location.") },
                { "state", JsonSchema.String(description: "The state of the location.") },
                { "zipCode", JsonSchema.Int(description: "Optional zip code of the location.", nullable: true) }
            },
            optionalProperties: new[] { "zipCode" })
        },
        { "date", JsonSchema.String(description: "The date for which to get the weather. Date must be in the format: YYYY-MM-DD.")},
        { "unit", JsonSchema.Enum(
            values: new[] { "CELSIUS", "FAHRENHEIT" },
            description: "The temperature unit.",
            nullable: true)
        }
    },
    optionalParameters: new[] { "unit" }
);

// Start a chat session with a template that has functions listed as tools.
var chatSessionWithSchemaOverride = model.StartChat(
    // Specify your template ID.
    templateId: "my-function-calling-template-with-no-function-schema-v1-0-0",
    // In `startChat`, provide the schema for any functions listed in your template.
    // This client-side schema will override any schema defined in the template.
    tools: new[] { fetchWeatherTool }
);

try
{
   // Send a message that might trigger a function call.
   ...

  // When the model responds with one or more function calls, invoke the function(s).
  // Note that this is the same as when *not* using server prompt templates.
  ...
}

// ...



다음 단계