Tương tác nhiều lượt với mẫu câu lệnh của máy chủ


Hướng dẫn này áp dụng cho mọi khả năng phụ thuộc vào các lượt tương tác nhiều lượt, bao gồm:

Thông tin tổng quan

Đối với các lượt tương tác nhiều lượt, các SDK Firebase AI Logic sẽ quản lý trạng thái của cuộc trò chuyện. Điều này cũng áp dụng khi sử dụng mẫu câu lệnh trên máy chủ.

Quy trình làm việc cơ bản cho các lượt tương tác nhiều lượt và mẫu câu lệnh của máy chủ về cơ bản giống với các yêu cầu một lượt, nhưng có một số điểm khác biệt quan trọng:

  1. Tạo mẫu bằng giao diện người dùng có hướng dẫn trong bảng điều khiển Firebase.

    Đối với các lượt tương tác nhiều lượt, bạn phải thêm thẻ {{history}} vào nội dung của mẫu. Thẻ này cho biết vị trí cần chèn các lượt trò chuyện do SDK ứng dụng quản lý.

  2. Kiểm thử mẫu trong một yêu cầu thực tế bằng cách sử dụng trải nghiệm kiểm thử trong bảng điều khiển Firebase.

    Đối với các lượt tương tác nhiều lượt, trải nghiệm kiểm thử trên bảng điều khiển chỉ có thể giúp kiểm thử lượt đầu tiên. Bạn có thể kiểm thử cách các lượt tương tác tiếp theo (nhật ký) được xử lý bằng cách sử dụng mẫu với ứng dụng thực tế của mình.

  3. Truy cập vào mẫu từ mã của ứng dụng bằng cách sử dụng templateGenerativeModel.

    Đối với các lượt tương tác nhiều lượt, bạn phải sử dụng startChatsendMessage (giống như khi bạn thực hiện các lượt tương tác nhiều lượt khi không sử dụng mẫu câu lệnh của máy chủ).

Xin lưu ý rằng đối với lệnh gọi hàm, có một số điểm khác biệt khác được mô tả trong phần đó ở phần sau của trang này.



Cuộc trò chuyện nhiều lượt (trò chuyện)

Nếu chưa, hãy xem hướng dẫn chung về cách xây dựng cuộc trò chuyện nhiều lượt (chat) khi không sử dụng mẫu câu lệnh của máy chủ.

Định dạng cơ bản của mẫu câu lệnh trên máy chủ

Đối với Firebase AI Logic, bảng điều khiển Firebase cung cấp một giao diện người dùng có hướng dẫn để bạn chỉ định phần đầu và nội dung của mẫu.

Mẫu câu lệnh trên máy chủ sử dụng cú pháp và định dạng dựa trên Dotprompt. Để biết thêm thông tin chi tiết, hãy xem phần Định dạng, cú pháp và ví dụ về mẫu.

Mẫu ví dụ bên dưới cho thấy các thành phần quan trọng nhất của một mẫu khi bạn xây dựng cuộc trò chuyện nhiều lượt (trò chuyện). Lưu ý việc bổ sung thẻ {{history}} vào nội dung của mẫu. Thẻ này cho mẫu biết vị trí cần chèn các lượt trò chuyện do SDK ứng dụng khách quản lý.

---
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}}

Sử dụng mẫu trong mã

Nhấp vào nhà cung cấp Gemini API để xem nội dung và mã dành riêng cho nhà cung cấp trên trang này.

Đoạn mã ví dụ về ứng dụng dưới đây cho thấy cách sử dụng mẫu trong mã của bạn. Lưu ý việc sử dụng templateGenerativeModel cùng với startChatsendMessage khi xây dựng các lượt tương tác nhiều lượt.

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}");
}



Gọi hàm

Nếu bạn chưa thực hiện, hãy xem hướng dẫn chung về lệnh gọi hàm khi không sử dụng mẫu câu lệnh của máy chủ. Hướng dẫn này về cách sử dụng mẫu câu lệnh trên máy chủ giả định rằng bạn hiểu rõ cách hoạt động của tính năng gọi hàm nói chung.

Định dạng cơ bản của mẫu câu lệnh trên máy chủ

Đối với Firebase AI Logic, bảng điều khiển Firebase cung cấp một giao diện người dùng có hướng dẫn để bạn chỉ định phần đầu và nội dung của mẫu.

Mẫu câu lệnh trên máy chủ sử dụng cú pháp và định dạng dựa trên Dotprompt. Để biết thêm thông tin chi tiết, hãy xem phần Định dạng, cú pháp và ví dụ về mẫu.

Mẫu ví dụ dưới đây cho thấy các thành phần quan trọng nhất của một mẫu khi sử dụng tính năng gọi hàm. Lưu ý những điều sau:

  • Trong phần đầu của mẫu, hãy liệt kê các hàm mà mô hình có quyền truy cập bằng cách cung cấp các khai báo hàm trong đối tượng tools.

    • Xác định name (bắt buộc)description (không bắt buộc) cho từng hàm mà mô hình có quyền truy cập.

    • Xác định giản đồ cho từng hàm mà mô hình có quyền truy cập.

      Mẫu ví dụ bên dưới giả định rằng bạn đang xác định giản đồ hàm trong mẫu. Tuy nhiên, bạn có thể cung cấp giản đồ của hàm trong mã ứng dụng. Giản đồ được xác định trong mã ứng dụng sẽ ghi đè mọi giản đồ được xác định trong mẫu. Sau đó, trên trang này, hãy tìm ví dụ về mẫu và mã ứng dụng để xác định giản đồ trong mã ứng dụng.

  • Trong nội dung của mẫu, hãy thêm thẻ {{history}}. Thẻ này cho biết vị trí mà mẫu sẽ chèn các lượt trò chuyện do SDK ứng dụng khách quản lý.

Mẫu ví dụ có giản đồ hàm được xác định trong mẫu

---
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}}

Sử dụng mẫu trong mã

Nhấp vào nhà cung cấp Gemini API để xem nội dung và mã dành riêng cho nhà cung cấp trên trang này.

Đoạn mã ví dụ về ứng dụng dưới đây cho thấy cách sử dụng mẫu trong mã của bạn. Lưu ý những điều sau:

  • Sử dụng templateGenerativeModel cùng với startChatsendMessage khi sử dụng các lượt tương tác nhiều lượt.

  • Trong quá trình khởi tạo mô hình trong mã ứng dụng, không liệt kê các hàm mà mô hình có quyền truy cập. Thay vào đó, các hàm phải được liệt kê trong đối tượng tools của phần đầu trang của mẫu (xem ở trên).

  • Đoạn mã ví dụ về ứng dụng sau đây giả định rằng bạn đang xác định giản đồ hàm trong mẫu. Nếu thay vào đó, bạn quyết định xác định giản đồ trong mã ứng dụng, thì giản đồ đó sẽ ghi đè giản đồ do mẫu xác định. Sau đó, trên trang này, hãy xem mẫu và mã ứng dụng ví dụ để xác định giản đồ trong mã ứng dụng.

  • Kiểm tra xem mô hình có trả về một lệnh gọi hàm trong quá trình thực hiện yêu cầu hay không. Nếu có, ứng dụng của bạn cần thực thi logic cục bộ rồi gửi kết quả trở lại mô hình.

Ví dụ về mã ứng dụng có giản đồ hàm được xác định trong mẫu

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}");
}


Gọi hàm – xác định giản đồ trong mã ứng dụng

Hãy nhớ xem lại các phần ở trên về cách hoạt động của tính năng gọi hàm với mẫu câu lệnh trên máy chủ (đặc biệt là việc sử dụng thẻ {{history}} trong nội dung của mẫu). Phần này cung cấp một mẫu ví dụ và mã ứng dụng nếu bạn muốn xác định giản đồ hàm trong mã ứng dụng (thay vì trong mẫu).

Hãy lưu ý những thông tin sau về việc xác định giản đồ hàm trong mã ứng dụng:

  • Nếu bạn xác định giản đồ của một hàm trong mã ứng dụng (như minh hoạ trong ví dụ bên dưới), thì giản đồ phía máy khách sẽ ghi đè mọi giản đồ do mẫu xác định cho hàm đó.

  • Để xác định giản đồ hàm trong mã ứng dụng, hãy viết khai báo hàm rồi cung cấp khai báo trong startChat, không phải trong quá trình khởi chạy mô hình (đây là những gì bạn làm khi không sử dụng mẫu câu lệnh của máy chủ).

  • Mặc dù khai báo hàm chỉ định một name, nhưng mẫu vẫn phải liệt kê các hàm mà bạn muốn mô hình có quyền truy cập. name trong mẫu phải khớp với name trong mã ứng dụng.

Ví dụ về mẫu có giản đồ hàm được xác định trong mã ứng dụng

---
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}}

Ví dụ về mã ứng dụng khách có giản đồ hàm được xác định trong mã ứng dụng khách
(để biết thông tin chi tiết bị bỏ qua trong ví dụ này, hãy xem ví dụ về mã ứng dụng khách ở trên)

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

// ...



Bước tiếp theo là gì?