ワークフローステップとしてのツール/エージェント
この例では、ツールまたはエージェントをワークフローステップとして作成し、統合する方法を示しています。
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 { PinoLogger } from "@mastra/loggers";
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: new PinoLogger({
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 });