ワークフローステップとしてのツール/エージェント
この例では、ツールまたはエージェントをワークフローステップとして作成し、統合する方法を示しています。
Mastraは、ステップまたはエージェントを受け入れ、Stepインターフェースを満たすオブジェクトを返すcreateStep
ヘルパー関数を提供しています。
セットアップ
npm install @ai-sdk/openai @mastra/core
天気レポーターエージェントの定義
LLMを活用して天気レポーターのように天気予報を説明する天気レポーターエージェントを定義します。
agents/weather-reporter-agent.ts
import { openai } from '@ai-sdk/openai'
import { Agent } from '@mastra/core/agent'
// Create an agent that explains weather reports in a conversational style
export const weatherReporterAgent = new Agent({
name: 'weatherExplainerAgent',
model: openai('gpt-4o'),
instructions: `
You are a weather explainer. You have access to input that will help you get weather-specific activities for any city.
The tool uses agents to plan the activities, you just need to provide the city. Explain the weather report like a weather reporter.
`,
})
天気ツールの定義
場所の名前を入力として受け取り、詳細な天気情報を出力する天気ツールを定義します。
tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
interface GeocodingResponse {
results: {
latitude: number
longitude: number
name: string
}[]
}
interface WeatherResponse {
current: {
time: string
temperature_2m: number
apparent_temperature: number
relative_humidity_2m: number
wind_speed_10m: number
wind_gusts_10m: number
weather_code: number
}
}
// Create a tool to fetch weather data
export const weatherTool = createTool({
id: 'get-weather',
description: 'Get current weather for a location',
inputSchema: z.object({
location: z.string().describe('City name'),
}),
outputSchema: z.object({
temperature: z.number(),
feelsLike: z.number(),
humidity: z.number(),
windSpeed: z.number(),
windGust: z.number(),
conditions: z.string(),
location: z.string(),
}),
execute: async ({ context }) => {
return await getWeather(context.location)
},
})
// Helper function to fetch weather data from external APIs
const getWeather = async (location: string) => {
const geocodingUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(location)}&count=1`
const geocodingResponse = await fetch(geocodingUrl)
const geocodingData = (await geocodingResponse.json()) as GeocodingResponse
if (!geocodingData.results?.[0]) {
throw new Error(`Location '${location}' not found`)
}
const { latitude, longitude, name } = geocodingData.results[0]
const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_gusts_10m,weather_code`
const response = await fetch(weatherUrl)
const data = (await response.json()) as WeatherResponse
return {
temperature: data.current.temperature_2m,
feelsLike: data.current.apparent_temperature,
humidity: data.current.relative_humidity_2m,
windSpeed: data.current.wind_speed_10m,
windGust: data.current.wind_gusts_10m,
conditions: getWeatherCondition(data.current.weather_code),
location: name,
}
}
// Helper function to convert numeric weather codes to human-readable descriptions
function getWeatherCondition(code: number): string {
const conditions: Record<number, string> = {
0: 'Clear sky',
1: 'Mainly clear',
2: 'Partly cloudy',
3: 'Overcast',
45: 'Foggy',
48: 'Depositing rime fog',
51: 'Light drizzle',
53: 'Moderate drizzle',
55: 'Dense drizzle',
56: 'Light freezing drizzle',
57: 'Dense freezing drizzle',
61: 'Slight rain',
63: 'Moderate rain',
65: 'Heavy rain',
66: 'Light freezing rain',
67: 'Heavy freezing rain',
71: 'Slight snow fall',
73: 'Moderate snow fall',
75: 'Heavy snow fall',
77: 'Snow grains',
80: 'Slight rain showers',
81: 'Moderate rain showers',
82: 'Violent rain showers',
85: 'Slight snow showers',
86: 'Heavy snow showers',
95: 'Thunderstorm',
96: 'Thunderstorm with slight hail',
99: 'Thunderstorm with heavy hail',
}
return conditions[code] || 'Unknown'
}
インターオプワークフローの定義
ステップとしてエージェントとツールを使用するワークフローを定義します。
workflows/interop-workflow.ts
import { createWorkflow, createStep } from '@mastra/core/workflows/vNext'
import { weatherTool } from '../tools/weather-tool'
import { weatherReporterAgent } from '../agents/weather-reporter-agent'
import { z } from 'zod'
// Create workflow steps from existing tool and agent
const fetchWeather = createStep(weatherTool)
const reportWeather = createStep(weatherReporterAgent)
const weatherWorkflow = createWorkflow({
steps: [fetchWeather, reportWeather],
id: 'weather-workflow-step1-single-day',
inputSchema: z.object({
location: z.string().describe("The city to get the weather for"),
}),
outputSchema: z.object({
text: z.string(),
}),
})
.then(fetchWeather)
.then(
createStep({
id: "report-weather",
inputSchema: fetchWeather.outputSchema,
outputSchema: z.object({
text: z.string(),
}),
execute: async ({ inputData, mastra }) => {
// Create a prompt with the weather data
const prompt = 'Forecast data: ' + JSON.stringify(inputData)
const agent = mastra.getAgent('weatherReporterAgent')
// Generate a weather report using the agent
const result = await agent.generate([
{
role: "user",
content: prompt,
},
]);
return { text: result.text };
},
}),
);
weatherWorkflow.commit();
export { weatherWorkflow };
Mastraクラスでワークフローインスタンスを登録する
ワークフローをmastraインスタンスに登録します。
index.ts
import { Mastra } from '@mastra/core/mastra'
import { createLogger } from '@mastra/core/logger'
import { weatherWorkflow } from './workflows/interop-workflow'
import { weatherReporterAgent } from './agents/weather-reporter-agent'
// Create a new Mastra instance with our components
const mastra = new Mastra({
vnext_workflows: {
weatherWorkflow,
},
agents: {
weatherReporterAgent,
},
logger: createLogger({
name: "Mastra",
level: "info",
}),
})
export { mastra }
ワークフローを実行する
ここでは、mastraインスタンスから天気ワークフローを取得し、実行を作成して、必要なinputDataで作成した実行を実行します。
exec.ts
import { mastra } from "./";
const workflow = mastra.vnext_getWorkflow('weatherWorkflow')
const run = workflow.createRun()
// Start the workflow with Lagos as the location
const result = await run.start({ inputData: { location: "Lagos" } })
console.dir(result, { depth: null })