Tampilan
2.1 Tool Pertama
Tujuan bab
Setelah bab ini kamu bisa:
- Membuat tool dengan
createTool()dan menjelaskan keempat properti wajibnya - Menulis fungsi
executedengan signature yang benar - Menyambungkan satu atau beberapa tool ke agent
- Menjelaskan kenapa mendefinisikan tool sebagai objek biasa akan gagal tanpa pesan error
- Membagikan satu tool ke beberapa agent
Prasyarat
- Bagian 1 selesai
- Paket
@mastra/coredanzodterpasang
Bentuk dasar
ts
// src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'get-weather',
description: 'Ambil cuaca terkini untuk sebuah kota',
inputSchema: z.object({
location: z.string().describe('Nama kota'),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return { location, temperatureCelsius: 21, conditions: 'cerah' }
},
})Empat properti yang membentuk sebuah tool:
| Properti | Perannya | Pembacanya |
|---|---|---|
id | Pengenal unik tool | Runtime Mastra |
description | Penjelasan tool ini untuk apa | Model, untuk memutuskan kapan memanggilnya |
inputSchema | Bentuk argumen yang diterima | Model (untuk menyusun panggilan) dan runtime (untuk memvalidasi) |
outputSchema | Bentuk hasil yang dikembalikan | Runtime, dan menjadi kontrak bagi pemakai tool |
Perhatikan kolom "pembacanya". Dua dari empat properti itu dibaca oleh model, bukan hanya oleh mesin. description adalah satu-satunya dasar model memutuskan apakah tool ini relevan untuk pertanyaan yang sedang dihadapi. Deskripsi yang malas menghasilkan tool yang tidak pernah dipanggil, atau dipanggil di saat yang salah — dan ini dibahas tuntas di 2.2.
Signature execute
Ini bagian yang paling sering salah, karena banyak contoh lama di internet memakai bentuk berbeda. Dokumentasi resmi menyatakannya tanpa ruang tafsir: execute punya tepat satu signature.
ts
execute: async (inputData, context) => { /* ... */ }- Parameter pertama adalah input yang sudah divalidasi terhadap
inputSchema. Kamu bisa langsung memakainya, dan tipenya sudah terinfer dari schema. - Parameter kedua adalah konteks eksekusi, yang selalu disediakan runtime. Isinya antara lain
requestContext,tracingContext, danabortSignal.
Parameter kedua boleh dihilangkan kalau tidak dipakai — itu sebabnya contoh di atas hanya menulis async ({ location }) => ....
Bentuk lama yang sudah tidak berlaku
Kalau kamu menemukan contoh yang menulis execute: async ({ context }) => ... dan mengambil argumen dari context.location, itu pola lama. Dokumentasi resmi menyebutnya secara eksplisit: "If you've seen a different execute shape elsewhere, it's outdated."
Ini salah satu alasan kenapa menyalin kode Mastra dari hasil pencarian atau dari ingatan model bahasa berisiko — pola v0 masih tersebar luas.
Contoh dengan parameter kedua dipakai:
ts
// src/mastra/tools/profil-tool.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const profilTool = createTool({
id: 'get-profil',
description: 'Ambil profil pengguna yang sedang login',
inputSchema: z.object({}),
outputSchema: z.object({
userId: z.string(),
nama: z.string(),
}),
execute: async (_input, { requestContext }) => {
const userId = requestContext.get('userId') as string
return { userId, nama: 'Budi' }
},
})Pola ini penting untuk keamanan: identitas pengguna diambil dari requestContext yang diisi server, bukan dari argumen yang dikirim model. Kalau userId masuk lewat inputSchema, model bisa mengarangnya — dan agent akan dengan senang hati mengambil data pengguna lain.
Menyambungkan ke agent
ts
// src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool.ts'
export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
Kamu asisten cuaca yang membantu.
Pakai weatherTool untuk mengambil data cuaca terkini.`,
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})Dua hal yang layak diperhatikan.
Pertama, tools adalah objek, bukan array. Key-nya menjadi nama yang dikenal model.
Kedua, instruksinya menyebut nama tool secara eksplisit. Ini bukan formalitas. Menyebut "Pakai weatherTool untuk mengambil data cuaca terkini" di instruksi meningkatkan kemungkinan tool dipakai pada situasi yang tepat. Dokumentasi resmi menyebut bahwa keputusan agent didasarkan pada pesan pengguna, instruksi agent, serta deskripsi dan schema tool — jadi instruksi adalah salah satu dari tiga tuas yang kamu punya.
Beberapa tool sekaligus
ts
// src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool.ts'
import { hazardsTool } from '../tools/hazards-tool.ts'
export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
Kamu asisten cuaca yang membantu.
Pakai weatherTool untuk mengambil data cuaca terkini.
Pakai hazardsTool untuk memberi informasi potensi bahaya cuaca.`,
model: 'openai/gpt-5.6-sol',
tools: { weatherTool, hazardsTool },
})Perhatikan polanya: satu baris instruksi per tool, menjelaskan kapan masing-masing dipakai. Saat jumlah tool bertambah, kebiasaan ini yang menjaga agent tetap memilih dengan tepat.
Berbagi tool antar agent
Kalau satu tool dipakai beberapa agent, cara yang disarankan dokumentasi adalah yang paling sederhana: impor langsung di masing-masing agent.
ts
// src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool.ts'
export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: 'Jawab pertanyaan tentang cuaca saat ini.',
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})ts
// src/mastra/agents/travel-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool.ts'
export const travelAgent = new Agent({
id: 'travel-agent',
name: 'Travel Agent',
instructions: 'Bantu pengguna merencanakan perjalanan, termasuk cuaca tujuan.',
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})Keuntungannya, sebagaimana disebut dokumentasi: dependensi tetap eksplisit dan tiap agent bisa dipakai secara independen. Tidak ada registry tersembunyi yang harus kamu telusuri untuk tahu agent ini sebenarnya bisa apa.
Bukan hanya fungsi yang bisa jadi tool
Dua konfigurasi lain mengubah komponen Mastra menjadi tool secara otomatis:
ts
// Agent lain sebagai tool → menjadi tool bernama agent-<key>
export const supervisor = new Agent({
id: 'supervisor',
name: 'Supervisor',
instructions: 'Koordinasikan penulis untuk menghasilkan konten.',
model: 'openai/gpt-5.6-sol',
agents: { writer },
})ts
// Workflow sebagai tool → menjadi tool bernama workflow-<key>
export const researchAgent = new Agent({
id: 'research-agent',
name: 'Research Agent',
instructions: 'Kamu asisten riset.',
model: 'openai/gpt-5.6-sol',
workflows: { researchWorkflow },
})Untuk keduanya, sertakan description pada agent atau workflow yang didelegasikan — itulah yang dibaca pemanggilnya untuk tahu kapan harus mendelegasikan. Pola ini dibahas lebih dalam di 4.4 dan 7.3.
Kesalahan umum
Gejala: Tool tidak pernah dipanggil. Tidak ada error, tidak ada peringatan — agent hanya menjawab seolah tool itu tidak ada. Penyebab: Tool didefinisikan sebagai objek biasa, bukan lewat createTool(). Dokumentasi menyatakan bahwa definisi tool berbentuk objek polos gagal secara diam-diam. Karena tidak ada yang dilempar, kesalahan ini bisa memakan waktu lama untuk ditemukan. Perbaikan: Pastikan setiap tool dibuat lewat createTool() dengan id, description, inputSchema, dan execute.
Gejala: Error tipe di dalam execute saat mengakses argumen, atau argumen selalu bernilai undefined. Penyebab: Memakai signature lama async ({ context }) => ... lalu mengambil nilai dari context. Pada versi sekarang, parameter pertama adalah input yang sudah tervalidasi; context adalah parameter kedua dan isinya metadata eksekusi, bukan argumen tool. Perbaikan: Ubah menjadi async ({ location }) => ... untuk mengambil argumen, dan pakai parameter kedua hanya saat butuh requestContext, abortSignal, atau metadata lain.
Coba sendiri
Tantangan: Bangun agent perpustakaan bernama pustaka-agent dengan dua tool yang bekerja atas data buku dalam memori (array biasa di dalam kode, belum perlu database).
Tool yang harus dibuat:
cari-buku— menerima kata kunci, mengembalikan daftar buku yang cocok beserta ketersediaannyacek-denda— menerima nomor anggota, mengembalikan total denda dan daftar buku yang terlambat
Ketentuan:
- Keduanya dibuat dengan
createTool(), lengkap denganinputSchemadanoutputSchema - Instruksi agent menyebut kedua tool dan kapan masing-masing dipakai
- Sediakan minimal enam buku dan tiga anggota sebagai data
- Uji lewat Studio dengan empat pesan: pencarian yang menemukan hasil, pencarian yang tidak menemukan apa pun, pengecekan denda, dan satu pesan yang butuh kedua tool sekaligus
- Amati di Studio berapa kali tool dipanggil untuk pesan keempat
Checklist penerimaan:
- [ ] Kedua tool muncul dan benar-benar dipanggil, terlihat di Studio
- [ ] Pencarian tanpa hasil menghasilkan jawaban yang jujur, bukan buku karangan
- [ ] Pesan keempat memicu dua pemanggilan tool dalam satu giliran
- [ ]
outputSchemakedua tool mendeskripsikan bentuk hasil yang sebenarnya dikembalikan — bukan sekadarz.any()atauz.string() - [ ] Kamu bisa menunjukkan di Studio urutan: tool dipanggil, hasil kembali, lalu jawaban disusun
Petunjuk: Ketentuan 4 poin terakhir adalah yang paling menarik. Kalau agent hanya memanggil satu tool padahal pertanyaannya butuh dua, periksa dua hal sebelum menyalahkan model: apakah description tiap tool cukup jelas membedakan keduanya, dan apakah instruksi agent menyebutkan bahwa keduanya boleh dipakai bersamaan.
Ikhtisar
- Tool dibuat dengan
createTool()— objek polos akan gagal diam-diam, tanpa error apa pun. - Empat properti wajib:
id,description,inputSchema,execute.descriptiondaninputSchemadibaca model, bukan hanya mesin. executepunya tepat satu signature:(inputData, context). Parameter pertama adalah input yang sudah tervalidasi; parameter kedua berisirequestContext,abortSignal, dan metadata lain, dan boleh dihilangkan.- Data identitas seperti
userIdsebaiknya diambil darirequestContext, bukan dariinputSchema— supaya model tidak bisa mengarangnya. toolspada agent adalah objek, dan menyebut nama tool diinstructionsmeningkatkan ketepatan pemanggilan.- Berbagi tool antar agent dilakukan dengan impor langsung, supaya dependensi tetap eksplisit.
- Agent lain (
agents) dan workflow (workflows) otomatis menjadi tool dengan namaagent-<key>danworkflow-<key>.
Lanjut ke mana
Tool-mu sudah jalan. Sekarang bagian yang menentukan apakah ia dipanggil pada saat yang tepat — dan itu hampir seluruhnya soal schema: 2.2 Schema yang Baik.