Callback

Callback adalah fitur lanjutan yang menyediakan mekanisme canggih untuk terhubung ke proses eksekusi agen tertentu menggunakan kode Python. Dengan demikian, Anda dapat mengamati, menyesuaikan, dan bahkan mengontrol perilaku agen pada titik-titik tertentu yang telah ditentukan sebelumnya.

Ada berbagai jenis callback yang dapat Anda gunakan, dengan setiap jenis callback dieksekusi pada titik tertentu dalam giliran percakapan. Jenis ini dijelaskan di bagian di bawah.

Runtime dan class Python

Dalam kode callback Python, Anda memiliki akses ke class dan fungsi tertentu yang membantu Anda menulis kode. Untuk mengetahui informasi selengkapnya, lihat Referensi runtime Python.

Jenis callback

Bergantung pada jenis callback, fungsi callback utama Anda harus memiliki nama tertentu. Hal ini memungkinkan Anda menentukan fungsi pembantu dengan nama apa pun dalam kode callback.

Setiap jenis callback dieksekusi pada titik tertentu dalam giliran percakapan:

alur callback

Jika Anda menentukan beberapa callback dari jenis tertentu, callback tersebut akan dieksekusi sesuai urutan penentuannya.

Bagian di bawah ini menjelaskan setiap jenis callback, dengan info berikut yang dijelaskan untuk setiap jenis:

X X
Nama Nama fungsi callback yang diperlukan
Eksekusi Titik eksekusi dalam giliran percakapan.
Tujuan Skenario yang berguna untuk menggunakan callback.
Argumen Argumen input untuk fungsi.
Kembali Nilai yang ditampilkan untuk fungsi.
Callback ADK Link ke dokumentasi callback ADK yang sesuai.

Sebelum agen dimulai (before_agent_callback)

X X
Nama before_agent_callback
Eksekusi Dipanggil sebelum agen dipanggil.
Tujuan Berguna untuk menyiapkan resource atau status yang diperlukan untuk agen, melakukan pemeriksaan validasi pada status sesi, atau menghindari pemanggilan agen.
Argumen CallbackContext
Kembali Konten(opsional): Jika disetel, agen tidak dipanggil, dan respons yang diberikan akan digunakan.
Callback ADK before agent callback

Contoh kode:

import random

def before_agent_callback(
  callback_context: CallbackContext
) -> Optional[Content]:
  username = callback_context.variables.get("username", None)
  if not username:
    # default user
    final_name = "Default Name"
  else:
    # add a random integer to the username
    final_name = f"{username} {random.randint(1,10)}"
  # update the username variable
  callback_context.variables["username"] = final_name

Setelah agen selesai (after_agent_callback)

X X
Nama after_agent_callback
Eksekusi Dipanggil setelah agen selesai.
Tujuan Berguna untuk tugas pembersihan, validasi pasca-eksekusi, memodifikasi status akhir, atau memperbarui respons agen.
Argumen CallbackContext
Kembali Konten(opsional): Jika disetel, ganti output agen dengan output yang diberikan.
Callback ADK after agent callback

Contoh kode:

def after_agent_callback(
  callback_context: CallbackContext
) -> Optional[Content]:
  if callback_context.agent_name == "Routing Agent":
    counter = callback_context.variables.get("counter", 0)
    counter += 1
    # increment the invoked counter for this agent
    callback_context.variables["counter"] = int(counter)

Sebelum panggilan LLM (before_model_callback)

X X
Nama before_model_callback
Eksekusi Dipanggil sebelum permintaan model.
Tujuan Berguna untuk memeriksa/mengubah permintaan model, atau untuk menghindari penggunaan model.
Argumen CallbackContext, LlmRequest
Kembali LlmResponse: Jika disetel, panggilan model dilewati, dan respons digunakan seolah-olah berasal dari model.
Callback ADK before model callback

Contoh kode:

def before_model_callback(
  callback_context: CallbackContext,
  llm_request: LlmRequest
) -> Optional[LlmResponse]:
  """
  This callback executes *before* a request is sent to the LLM.

  By returning an `LlmResponse` object, we are intercepting the call to the
  LLM. The LLM will *not* be called, and the framework will instead use the
  `LlmResponse` we provide as if it came from the model.

  This is the core mechanism for implementing input guardrails, prompt
  validation, or serving responses from a cache. Here, we force the agent to
  call a function instead of thinking with the LLM.
  """
  # Modify the shared session state.
  callback_context.variables['foo'] = 'baz'

  # Skip the LLM call and return a custom response telling the agent to
  # execute a specific function.
  return LlmResponse(
    content=Content(parts=[Part(
      function_call=FunctionCall(
        name="function_name", args={"arg_name": "arg_value"}))],
      role="model"))

Setelah panggilan LLM (after_model_callback)

X X
Nama after_model_callback
Eksekusi Dipanggil setelah respons model diterima.
Tujuan Berguna untuk memformat ulang respons model, menyensor informasi sensitif yang dihasilkan oleh model, mengurai data terstruktur dari model untuk digunakan dalam variabel, dan penanganan error model.
Argumen CallbackContext, LlmResponse
Kembali LlmResponse: Jika disetel, ganti respons model dengan respons yang diberikan.
Callback ADK after model callback

Contoh kode:

def after_model_callback(
  callback_context: CallbackContext,
  llm_response: LlmResponse
) -> Optional[LlmResponse]:
  """
  This callback executes *after* a response has been received from the LLM,
  but before the agent processes it.

  The `llm_response` parameter contains the actual data from the LLM.
  By returning `None`, we are approving this response and allowing the agent
  to use it as-is.

  If we returned a new `LlmResponse` object, it would *replace* the original,
  which is useful for redacting sensitive information, enforcing output
  formatting, or adding disclaimers.
  """
  # Returning None allows the LLM's actual response to be used.
  return None

Sebelum panggilan alat (before_tool_callback)

X X
Nama before_tool_callback
Eksekusi Dipanggil sebelum panggilan alat.
Tujuan Berguna untuk pemeriksaan dan modifikasi argumen alat, pemeriksaan otorisasi sebelum eksekusi alat, atau penerapan caching tingkat alat.
Argumen Tool, Dict[str,Any]: input alat, CallbackContext
Kembali Dict[str,Any] : Jika disetel, eksekusi alat akan dilewati dan output ini akan diberikan ke model.
Callback ADK sebelum callback alat

Contoh kode:

def before_tool_callback(
  tool: Tool,
  input: dict[str, Any],
  callback_context: CallbackContext
) -> Optional[dict[str, Any]]:
  """
  This callback executes *before* a specific tool is called by the agent.

  Here, we modify the input arguments intended for the tool and then return
  a dictionary. By returning a dictionary instead of `None`, we are
  overriding the default behavior. The actual tool function will *not* be
  executed. Instead, the dictionary we return will be treated as the
  llm.tool's result and passed back to the LLM for the next step.

  This is ideal for validating tool inputs, applying policies, or returning
  mocked/cached data for testing.
  """
  # Modify the shared session state.
  callback_context.variables['foo'] = 'baz'

  # Modify the arguments for the tool call in-place.
  input['input_arg'] = 'updated_val1'
  input['additional_arg'] = 'updated_val2'

  # Override the tool call and return a mocked result.
  return {"result": "ok"}

Setelah panggilan alat (after_tool_callback)

X X
Nama after_tool_callback
Eksekusi Dipanggil setelah penyelesaian alat.
Tujuan Berguna untuk memeriksa dan mengubah respons alat sebelum dikirim kembali ke model, pasca-pemrosesan hasil alat, atau menyimpan bagian tertentu dari respons alat ke variabel.
Argumen Tool, Dict[str,Any]: input alat, CallbackContext, Dict[str,Any]: respons alat
Kembali Dict[str,Any]: Jika disetel, ini akan menggantikan respons alat yang diberikan ke model.
Callback ADK after tool callback

Contoh kode:

# Previous tool was named `get_user_info`
# Previous tool returned the payload:
# {"username": "Patrick", "fave_food": ["pizza"]}

def after_tool_callback(
  tool: Tool,
  input: dict[str, Any],
  callback_context: CallbackContext,
  tool_response: dict
) -> Optional[dict]:

  if tool.name == "get_user_info":
    tool_response["username"] = "Gary"
    tool_response["pet"] = "dog"

    # Override tool response
    return tool_response

Membuat callback

Untuk membuat callback:

  1. Buka setelan agen.
  2. Klik Tambahkan kode.
  3. Pilih jenis panggilan balik.
  4. Berikan kode Python.
  5. Klik Simpan.

Payload kustom (custom_payloads)

Payload kustom memfasilitasi penyertaan data terstruktur tambahan, non-tekstual (biasanya diformat sebagai JSON) dalam respons agen. Payload ini berperan penting dalam mengarahkan atau meningkatkan interaksi agen dengan sistem eksternal atau aplikasi klien.

Nilai payload tidak terlihat oleh Model Bahasa Besar (LLM); nilai ini hanya digunakan untuk menghasilkan respons akhir. Payload kustom dibuat dan ditetapkan menggunakan callback, khususnya before_model_callback atau after_model_callback.

Payload kustom dapat digunakan untuk beberapa tujuan, yang umumnya berpusat pada pengaktifan interaksi terstruktur yang kaya:

  • Eskalasi/Pengalihan Agen: Sering digunakan untuk mengalihkan interaksi ke agen manusia dengan memberikan petunjuk perutean (misalnya, antrean tertentu yang akan dituju).
  • Konten Multimedia dan Tindakan Sisi Klien: API ini mendukung penyematan widget multimedia dan konten multimedia lainnya langsung ke dalam pengalaman chat, yang sangat berguna untuk integrasi chat kustom.
    • Contohnya mencakup menampilkan URL gambar atau chip dan opsi balasan cepat untuk pelanggan yang menggunakan antarmuka seperti pendamping panggilan.
  • Komposisi Respons: Payload kustom dapat dikonfigurasi untuk ditampilkan dengan berbagai cara:
    • Hanya menampilkan payload eksplisit secara deterministik.
    • Menampilkan payload beserta respons teks yang dihasilkan LLM.
    • Menampilkan payload dengan respons teks statis

Penyiapan Agen

Payload kustom hanya dapat dibuat dan ditetapkan menggunakan callback. Payload ditetapkan sebagai Blob dengan mime_type application/json.

Part.from_json(data=payload_string)

Contoh after_model_callback

Ini adalah contoh after_model_callback yang menampilkan respons model bersama dengan respons payload kustom tambahan.

import json

def after_model_callback(callback_context: CallbackContext, llm_response: LlmResponse) -> Optional[LlmResponse]:
 """
 Adds a custom payload to every model response which is a text
 """
 if (llm_response.content.parts[0].text is not None):
   # construct payload
   payload_dict = { "custom_payload_key": "custom_payload_value"}
   payload_json_string = json.dumps(payload_dict)

   new_parts = []
   # Keep the origial agent response part, as model only sees text in the historical context.
   new_parts.append(Part(text=llm_response.content.parts[0].text))

   # Append custom payload
   new_parts.append(Part.from_json(data=payload_string))

   return LlmResponse(content=Content(parts=new_parts))

Contoh before_model_callback

Ini adalah contoh before_model_callback yang menampilkan payload kustom tambahan setelah alat tertentu dipicu.

import json

def has_escalate(llm_request: LlmRequest) -> bool:
  for content in llm_request.contents:
    for part in content.parts:
      if part.function_call and part.function_call.name == 'escalate':
        return True
  return False

def before_model_callback(callback_context: CallbackContext, llm_request: LlmRequest) -> Optional[LlmResponse]:
  # checks if `escalate` tool is being called
  if not has_escalate(llm_request):
    return None
  payload_dict = { "escalate": "user ask for escalation"}
  payload_json_string = json.dumps(payload_dict)

  return LlmResponse(content=Content(parts=[Part(text="ESCALATE!!!"), Part.from_json(data=payload_json_string)]))

Memverifikasi payload runtime dalam respons

Payload diisi sebagai Struct di kolom payload untuk RunSession dan BidiRunSession.

Nilai payload tidak terlihat oleh LLM.