Open2

voltagent 使ってみる

mizchimizchi

https://voltagent.dev

package.json
  "dependencies": {
    "@ai-sdk/anthropic": "^1.2.11",
    "@octokit/rest": "^21.1.1",
    "@voltagent/cli": "^0.1.5",
    "@voltagent/core": "^0.1.19",
    "@voltagent/vercel-ai": "^0.1.8",
    "ai": "^4.3.16"
  },

サンプルコードを動かす...前に .env に GitHub のトークンを設定

GH_TOKEN="..."

サンプルコードを分析する

プロンプトを日本語訳だけさせた

run.ts
import { Agent, createHooks, VoltAgent, VoltAgentExporter } from "@voltagent/core";
import { VercelAIProvider } from "@voltagent/vercel-ai";
import { anthropic } from "@ai-sdk/anthropic";
import { Octokit } from "@octokit/rest";
import { createTool } from "@voltagent/core";
import { z } from "zod";

const octokit = new Octokit({
  auth: process.env.GITHUB_TOKEN,
});

// Tool to fetch repository stars
export const fetchRepoStarsTool = createTool({
  name: "repo_stars",
  description: "GitHubリポジトリのスター数を取得します",
  parameters: z.object({
    owner: z.string().describe("リポジトリのオーナー"),
    repo: z.string().describe("リポジトリの名前"),
  }),
  execute: async ({ owner, repo }: { owner: string; repo: string }) => {
    try {
      const response = await octokit.repos.get({
        owner,
        repo,
      });
      return {
        success: true,
        stars: response.data.stargazers_count,
        message:
          `リポジトリ ${owner}/${repo}${response.data.stargazers_count} スターを持っています。`,
      };
    } catch (error) {
      return {
        success: false,
        stars: 0,
        message: `${owner}/${repo} のスター取得中にエラーが発生しました: ${
          error instanceof Error ? error.message : String(error)
        }`,
      };
    }
  },
});

// Tool to fetch repository contributors
export const fetchRepoContributorsTool = createTool({
  name: "repo_contributors",
  description: "GitHubリポジトリのコントリビューターリストを取得します",
  parameters: z.object({
    owner: z.string().describe("リポジトリのオーナー"),
    repo: z.string().describe("リポジトリの名前"),
  }),
  execute: async ({ owner, repo }: { owner: string; repo: string }) => {
    try {
      const response = await octokit.repos.listContributors({
        owner,
        repo,
      });

      const contributors = response.data.map((contributor) => ({
        login: contributor.login,
        contributions: contributor.contributions,
      }));

      return {
        success: true,
        contributors,
        message:
          `リポジトリ ${owner}/${repo}${contributors.length} 人のコントリビューターがいます。`,
        details: contributors,
      };
    } catch (error) {
      return {
        success: false,
        contributors: [],
        message: `${owner}/${repo} のコントリビューター取得中にエラーが発生しました: ${
          error instanceof Error ? error.message : String(error)
        }`,
      };
    }
  },
});

// スター取得エージェントを作成
const starsFetcherAgent = new Agent({
  name: "スター取得エージェント",
  description:
    "GitHub APIを使用してGitHubリポジトリのスター数を取得します",
  llm: new VercelAIProvider(),
  model: anthropic("claude-3-7-sonnet-20250219"),
  tools: [fetchRepoStarsTool],
});

// コントリビューター取得エージェントを作成
const contributorsFetcherAgent = new Agent({
  name: "コントリビューター取得エージェント",
  description:
    "GitHub APIを使用してGitHubリポジトリのコントリビューターリストを取得します",
  llm: new VercelAIProvider(),
  model: anthropic("claude-3-7-sonnet-20250219"),
  tools: [fetchRepoContributorsTool],
});

// 分析エージェントを作成
const analyzerAgent = new Agent({
  name: "リポジトリ分析エージェント",
  description: "リポジトリの統計を分析し、洞察を提供します",
  llm: new VercelAIProvider(),
  model: anthropic("claude-3-7-sonnet-20250219"),
});

// すべてのサブエージェントを調整する監督エージェントを作成
const supervisorAgent = new Agent({
  name: "監督エージェント",
  description:
    `あなたはGitHubリポジトリ分析ツールです。GitHubリポジトリのURLまたはowner/repo形式が与えられたら、以下を実行します:
1. StarsFetcherエージェントを使用してリポジトリのスター数を取得する
2. ContributorsFetcherエージェントを使用してリポジトリのコントリビューターを取得する
3. RepoAnalyzerエージェントを使用してこれらのデータを分析し、洞察を提供する

入力例: https://github.com/voltagent/voltagent または voltagent/voltagent
`,
  llm: new VercelAIProvider(),
  model: anthropic("claude-3-7-sonnet-20250219"),
  subAgents: [starsFetcherAgent, contributorsFetcherAgent, analyzerAgent],
});

// Initialize the VoltAgent with the agent hierarchy
new VoltAgent({
  agents: {
    supervisorAgent,
  },
});
  • Agent はそれぞれのプロンプトと tools を持つ
  • Agent は子に複数の subAgent を持てる(オーケストレーター的な)

node run.ts で実行数rと http://localhost:3141 が起動
https://console.voltagent.dev を開くと、このポートに接続してくる。ちょっとセキュリティ的に怖くないか。
この管理画面はOSSではない?が、おそらく n8n で実装されている。ノードはグラフベースだが、DnDで動かせるわけではない。

ここでタスクを流すと、結果が可視化される。

mizchimizchi

最小ケースを作る。足し算を行うエージェントを作る。
計算を行うエージェントと、それに指示をだす Supevisor を分割する。

import { Agent, createTool, VoltAgent, VoltAgentExporter } from "@voltagent/core";
import { VercelAIProvider } from "@voltagent/vercel-ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";

const calculatorAgent = new Agent({
  name: "Calculator Agent",
  description: `足し算を行うエージェントです`.trim(),
  llm: new VercelAIProvider(),
  model: anthropic("claude-3-7-sonnet-20250219"),
  tools: [
    createTool({
      name: "add",
      description: "2つの数を足し算します",
      parameters: z.object({
        a: z.number().describe("1つ目の数"),
        b: z.number().describe("2つ目の数"),
      }),
      execute: async ({ a, b }: { a: number; b: number }) => {
        return {
          success: true,
          result: a + b,
        };
      },
    }),
  ],
});

const supervisorAgent = new Agent({
  name: "Supervisor Agent",
  description:
    `あなたは計算を行うエージェントです。

1. CalculatorAgent に計算を依頼します。
`,
  llm: new VercelAIProvider(),
  model: anthropic("claude-3-7-sonnet-20250219"),
  subAgents: [calculatorAgent],
});

new VoltAgent({
  agents: {
    supervisorAgent,
  },
});

タスクを委譲してることだけわかればいい?

5+3 は? => 8 です

add ツールに引数が渡ってるのを確認