Skip to main content

CrewAI で GitHub リポジトリ要約システムを構築する

CrewAI によるマルチエージェント協調と Weave によるリアルタイムのデバッグと可観測性を活用して、GitHub ドキュメント作成を完全自動化するための実践ガイド。この記事は AI による翻訳です。誤訳の可能性があればコメント欄でお知らせください。
Created on August 27|Last edited on September 3
マルチエージェントシステム複数の AI エージェントが専門タスクを分担して協調するマルチエージェントシステムは、複雑なワークフローを自動化するための中核的な手法になりつつあります。 CrewAI は、こうしたシステムを設計するためのプラットフォームで、開発者がタスクを割り当て、エージェントの役割を定義し、ツールを接続して実世界のプロジェクトに対応できるようにします。これに W&B Weave各エージェントの挙動を追跡・デバッグするためのツールであるため、結果として完全な透明性と制御性が得られます エージェント型ワークフロー全体
このチュートリアルでは、GitHub リポジトリを自動でドキュメント化するマルチエージェントシステムを構築します。エージェントはリポジトリを探索し、コードを要約し、使用ガイドを作成し、アーキテクチャ図を生成し、すべてを HTML ページにまとめます。フローの管理には CrewAI を、各意思決定の過程を監視するためには Weave を使用します。


目次



エージェントとは何か?

AI エージェント は、計画立案、外部ツールの活用、記憶の保持、そして時間経過に伴う適応を通じて、特定の目標を達成するよう設計された知的システムです。あらかじめ定義された厳格なルールに従う従来の自動化とは異なり、AI エージェントは情報を動的に処理し、意思決定を行い、フィードバックに基づいて手法を洗練していきます。
一方で チャットボット 主に対話に従事し、あらゆる段階でユーザー入力を必要とするのに対して、AI エージェントは自律的に動作します。単に応答を生成するだけでなく、行動を起こし、外部システムとやり取りし、 複数ステップのエージェント型ワークフローを管理する 常時の監督なしで。
AI エージェントの主要な構成要素には、次のようなものがあります。
  • ツールAPI、データベース、ソフトウェアに接続して機能を拡張する。
  • メモリタスク間で情報を保存し、整合性と想起を向上させる。
  • 継続学習過去の実績に基づいて戦略を適応・洗練する。
  • オーケストレーション複数ステップのプロセスを管理し、タスクを分解し、他のエージェントと連携する。

マルチエージェントシステムを理解する

本質的には、マルチエージェントシステムはネットワークです。 自律型 AI エージェント 互いに通信・協調し、単一のエージェントでは成し得ない複雑なタスクをより効率的に達成する。各エージェントには固有の役割と責務が割り当てられ、これにより専門化が進み、適切な場合には並列処理も可能になる。たとえばニュース集約システムでは、あるエージェントが最新の見出しを収集し、別のエージェントが詳細な分析を行う。効果的なマルチエージェント設計は、モジュール性、明確なタスク委譲、シームレスなデータ交換を要件とし、その結果として、人間のチームのダイナミクスを反映したスケーラブルで適応力の高い AI ソリューションが実現する。
複数の特化エージェントを活用すると、大規模で複雑な問題を小さく明確なサブタスクに分解できます。ワークフローのあらゆる側面を単一の巨大なシステムで処理するのではなく、各コンポーネントやフェーズを、その責務に最適化されたエージェントに割り当てられます。たとえば、 テキストの要約コードスニペットの生成感情分析、または 出力の整形この分業化により、システムの理解が容易になるだけでなく、保守性と堅牢性も向上します。個々のエージェントを、全体のパイプラインを乱すことなく更新・置換・スケールできます。
また、モデルのコンテキスト制限を管理しやすくし、特定のタスクごとに別のモデルへ切り替えたり、システム全体でプロンプトの使い方を微調整・制御したりできるため、各段階でのリソース使用と精度を最適化できます。

CrewAI プラットフォームの主な特長

CrewAI プラットフォーム は、構造化された抽象化と柔軟なオーケストレーション機構を提供することで、スケーラブルなエージェント型ワークフローの構築を容易にします。
  • 自動化フレームワークCrewAI の中核には、エージェント・タスク・��ールを明確に分離する設計があります。エージェントは役割と目的を持つ自律的な主体であり、タスクはそれらに割り当てられる個別の作業単位です。ツールは、外部の API、検索エンジン、あるいはカスタム関数で、エージェントがタスクを実行・強化するために利用します。エージェント・タスク・ツールから成るこの三位一体こそが、モジュール性と保守性に優れた AI ワークフローを構成する基本要素です。
  • クルーとフローCrewAI では、複数のエージェントとそのタスクをオーケストレーションするために Crew(クルー)を使用します。クルーは、全体の実行フローとエージェント間のデータ受け渡しを制御します。プラットフォームは、Process クラスを通じて異なるワークフロー処理戦略をサポートします。
  • 逐次実行タスクは逐次的に、ひとつずつ実行され、前のタスクの出力が後続のタスクに受け渡されます。
  • 階層型タスクは入れ子や依存関係を持つ構造に整理でき、エージェント間での複雑な調整や委任を可能にします。
  • 柔軟なデプロイ��ントCrewAI は、素早い開発に適したインラインの Python スクリプトと、より構造化されスケールしやすい YAML 設定ファイルの両方をサポートします。この柔軟性により、開発者は迅速にプロトタイプを作り、その後シームレスに拡張して、より複雑なマルチエージェントシステムに対応できます。
  • 外部ツールとの統合CrewAI のエージェントは、各種ツールを接続して拡張できます。これらのツールは、Web 検索 API、データベース、その他のサービスなど、外部のデータや機能へのインターフェースとして機能します。ツールを活用することで、エージェントは最新情報の取得、専門的な計算の実行、サードパーティシステムとの対話が可能になり、自動化ワークフローの範囲を大幅に広げられます。
  • 明確なタスク割り当てCrewAI では、タスクを明示的に定義し、エージェントへ割り当てる必要があります。自律的な自己監視や自動委任に頼るのではなく、開発者が各タスクの責務と担当エージェントを明確に指定します。こうした明示性により、透明性と予測可能性が高まり、複雑なマルチエージェント間の相互作用もデバッグしやすくなります。

チュートリアル:CrewAI と Weave で構築する GitHub リポジトリ・ドキュメンターのマルチエージェントシステム

このチュートリアルでは、CrewAI を用いて、GitHub リポジトリを自動的に探索・理解・ドキュメント化・可視化するマルチエージェント AI システムの作り方を解説します。目的は、生のコードベースを、包括的な利用ガイドとアーキテクチャ図に変換し、整った HTML ドキュメントとしてまとめる完全自動のパイプラインを構築することです。
AI エージェントを作成する前に、まず GitHub リポジトリとやり取りするために必要な機能をエージェントに与える、特化ツール群を用意する必要があります。ツールは、ファイル検索、内容の読み取り、コードの要約といった特定の機能を実行するために、エージェントが呼び出せる外部インターフェースまたはユーティリティとして機能します。
このチュートリアルでは、次の3つの中核ツールを実装します。
  1. リポジトリ探索ツールユーザーのクエリを受け取り、リポジトリ全体のファイル構造を検索し、分析の焦点を定めるのに役立つ関連ファイルのパスを返します。
  2. ファイル閲覧ツール指定したファイルパスの内容を全文読み取り、エージェントに生のソースコードやドキュメントへのアクセスを提供します。
  3. ファイル要約ツール言語モデルを用いてファイルの内容を要約し、簡潔なサマリーを生成します。これにより、エージェントはすべてを逐一読むことなく、複雑なコードやドキュメントの要点を素早く把握できます。
import os
import subprocess
from typing import Type
from pydantic import BaseModel, Field
from crewai.tools import BaseTool
from langchain_openai import ChatOpenAI

# Clone the repo if not already cloned
REPO_URL = "https://github.com/karpathy/nanogpt.git"
REPO_DIR = "./nanogpt"

if not os.path.exists(REPO_DIR):
subprocess.run(["git", "clone", REPO_URL])

# --- Define the Repo Explorer Tool ---
class RepoQueryInput(BaseModel):
query: str = Field(..., description="Describe what you are looking for in the codebase.")

class RepoExplorerTool(BaseTool):
name: str = "Repo Explorer"
description: str = "Given a query, find relevant file paths from the nanogpt repo."
args_schema: Type[BaseModel] = RepoQueryInput

def _run(self, query: str) -> str:
file_list = []
for root, _, files in os.walk(REPO_DIR):
for file in files:
full_path = os.path.join(root, file)
file_list.append(full_path)

llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)
prompt = f"""
You are a codebase expert. Here is a list of files:\n{file_list}\n\n
Based on the user query "{query}", return ONLY the full file paths that are most relevant.
Respond with one file path per line, no extra text.
"""
response = llm.invoke(prompt)
return response.content.strip()

# --- Define the View File Content Tool ---
class ViewFileInput(BaseModel):
filepath: str = Field(..., description="Full path to the file you want to read.")

class ViewFileTool(BaseTool):
name: str = "View File Content"
description: str = "Reads the full content of a given file path from the nanogpt repo."
args_schema: Type[BaseModel] = ViewFileInput

def _run(self, filepath: str) -> str:
filepath = filepath.strip() # <<< add this
try:
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
return content
except Exception as e:
return f"Error reading file: {str(e)}"

# --- Instantiate the tools ---
repo_explorer_tool = RepoExplorerTool()
view_file_tool = ViewFileTool()

# --- Example usage ---
if __name__ == "__main__":
# Step 1: Find files related to training loop
query = "Where is the training loop defined?"
result_paths = repo_explorer_tool._run(query=query)
print("Relevant Files:\n", result_paths)

# Step 2: Read the first file found
first_file = result_paths.splitlines()[0]
file_content = view_file_tool._run(filepath=first_file)
print("\nContent of the first relevant file:\n")
print(file_content[:3000]) # only print first 3000 chars to keep output readable

これで、作成したツールを活用して、AI エージェントとそれぞれが実行するタスクを定義する準備が整いました。
このシステムは、複数の特化エージェントが逐次的に協調し、最終的なドキュメント出力を生成します。
  • デモ生成エージェントリポジトリの初心者向け導入ガイドを作成し、最小構成の実行例コマンドも含めます。
  • フォローアップ分析エージェント生成された導入ガイドをレビューし、抜けや不足を特定して確認質問を行い、改善のための具体的な提案を提示します。
  • リポジトリ要約エージェントリポジトリ内の主要ファイルを走査して要約し、開発者が理解しやすい簡潔な説明を提供します。
  • 図生成エージェント:ファイル要約に基づき、PlantUML や ASCII などでテキスト形式のアーキテクチャ図を作成し、リポジトリの高レベル構造を俯瞰できる概要を提供します。
  • シェルスクリプト自動化エンジニア:依存関係のインストール、環境構築、デモ実行を含むリポジトリのセットアップ手順をすべて自動化し、再実行しても同じ結果になる包括的な Bash スクリプトを生成します。これにより、開発者は単一のコマンドで作業を開始できます。
  • HTML コーダー:改良版の使用ガイド、アーキテクチャ図、生成されたセットアップスクリプトを統合し、読みやすく整ったスタイルの HTML ドキュメントページとして出力します。
コードはこちらです。
import os
import subprocess
from typing import Type, List
from pydantic import BaseModel, Field
from crewai import Agent, Task, Crew, Process
from crewai.tools import BaseTool
from langchain_openai import ChatOpenAI
import weave; weave.init("crewai_git_documenter")
# --- Repo Setup ---

REPO_URL = os.getenv('REPO_URL', 'https://github.com/LiveCodeBench/LiveCodeBench')
REPO_NAME = REPO_URL.split("/")[-1].replace(".git", "")
REPO_DIR = f"./{REPO_NAME}"

if not os.path.exists(REPO_DIR):
subprocess.run(["git", "clone", REPO_URL])

# --- Tools ---

class RepoQueryInput(BaseModel):
query: str = Field(..., query="Describe what you are looking for in the codebase.")

class RepoExplorerTool(BaseTool):
name: str = "Repo Explorer"
description: str = "Given a query, find relevant file paths from the repo."
args_schema: Type[BaseModel] = RepoQueryInput

def _run(self, query: str) -> str:
file_list = []
for root, _, files in os.walk(REPO_DIR):
for file in files:
full_path = os.path.join(root, file)
file_list.append(full_path)

llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)
prompt = f"""
Here is a list of files:\n{file_list}\n\n
User query: "{query}"
Return ONLY full file paths that match. One per line.
"""
response = llm.invoke(prompt)
return response.content.strip()

class ViewFileInput(BaseModel):
filepath: str = Field(..., description="Full path to the file you want to read.")

class ViewFileTool(BaseTool):
name: str = "View File Content"
description: str = "Reads the full content of a given file path from the repo."
args_schema: Type[BaseModel] = ViewFileInput

def _run(self, filepath: str) -> str:
filepath = filepath.strip()
try:
with open(filepath, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
return f"Error reading file: {str(e)}"

class SummarizeFileTool(BaseTool):
name: str = "Summarize File Content"
description: str = "Summarizes a given file's content into a short description."
args_schema: Type[BaseModel] = ViewFileInput

def _run(self, filepath: str) -> str:
filepath = filepath.strip()
try:
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)
prompt = f"Summarize the following code file in 5 sentences:\n\n{content}"
response = llm.invoke(prompt)
return response.content.strip()
except Exception as e:
return f"Error summarizing file: {str(e)}"

# --- Instantiate tools ---
repo_explorer_tool = RepoExplorerTool()
view_file_tool = ViewFileTool()
summarize_file_tool = SummarizeFileTool()

# --- Agents ---

demo_generator_agent = Agent(
role="Demo Generator",
goal="Write and expand a basic usage example for the repo.",
backstory="Expert technical writer.",
tools=[repo_explorer_tool, view_file_tool],
allow_delegation=False,
verbose=True,
llm=ChatOpenAI(model_name="gpt-4o-mini", temperature=0.5)
)

followup_analyst_agent = Agent(
role="Follow-Up Analyst",
goal="Analyze the usage guide, find missing info, suggest improvements.",
backstory="Developer experience expert.",
allow_delegation=False,
verbose=True,
llm=ChatOpenAI(model_name="gpt-4o-mini", temperature=0.3)
)

html_coder_agent = Agent(
role="HTML Coder",
goal="Turn the improved usage guide into a clean HTML page.",
backstory="Frontend dev specializing in docs websites. DO NOT GENERATE IMAGES MAN eg dont do src=data:image/png etc etc",
allow_delegation=False,
verbose=True,
llm=ChatOpenAI(model_name="gpt-4o-2024-08-06", temperature=0.4)
)

repo_summarizer_agent = Agent(
role="Repo Summarizer",
goal="Summarize all important files in the repo for easier understanding.",
backstory="Documentation architect.",
tools=[repo_explorer_tool, view_file_tool, summarize_file_tool],
allow_delegation=False,
verbose=True,
llm=ChatOpenAI(model_name="gpt-4o-mini", temperature=0.4)
)

diagram_generator_agent = Agent(
role="Diagram Generator",
goal="Using file summaries, generate a full architecture diagram of the repo.",
backstory="System architect skilled in explaining large codebases.",
allow_delegation=False,
verbose=True,
llm=ChatOpenAI(model_name="gpt-4o-mini", temperature=0.4)
)


shell_script_agent = Agent(
role="Shell Script Automation Engineer",
goal="Create a working shell script that sets up all requirements and runs the repo's demo or basic usage.",
backstory="Expert in bash scripting, devops, and repo onboarding automations.",
tools=[repo_explorer_tool, view_file_tool, summarize_file_tool], # Optional, useful for reading files
allow_delegation=False,
verbose=True,
llm=ChatOpenAI(model_name="gpt-4o-mini", temperature=0.3)
)

# --- Tasks ---


demo_generation_task = Task(
description=f"Write a beginner-friendly usage guide explaining how to use {REPO_NAME}. Include a minimal example command.",
expected_output="Markdown snippet with instructions.",
agent=demo_generator_agent,
output_file="basic_usage.md"
)

followup_task = Task(
description="Read 'basic_usage.md', find confusing parts, generate 5+ questions and improvements.",
expected_output="List of questions + feedback report.",
agent=followup_analyst_agent,
context=[demo_generation_task],
output_file="feedback_report.md"
)

improvement_task = Task(
description="Use 'feedback_report.md' to expand and improve the usage guide.",
expected_output="New improved guide.",
agent=demo_generator_agent,
context=[followup_task],
output_file="improved_usage.md"
)

repo_summarization_task = Task(
description="Scan the repo, summarize the major files (training, models, data utils, etc.).",
expected_output="List of file summaries.",
agent=repo_summarizer_agent,
output_file="repo_summary.md"
)

diagram_generation_task = Task(
description="Using 'repo_summary.md', create an overall architecture diagram of the repo in text/plantuml format.",
expected_output="Architecture diagram text.",
agent=diagram_generator_agent,
context=[repo_summarization_task],
tools=[repo_explorer_tool, view_file_tool, summarize_file_tool],

output_file="architecture_diagram.md"
)

shell_script_task = Task(
description=(
"Read the improved usage guide and repo summary. Write a BASH shell script that fully sets up the repo from scratch, "
"including dependency installation, environment setup, any required downloads, and running the minimal example demo. "
"The script should be idempotent (safe to rerun), and **explain each step with comments**. Output the script in a codeblock."
),
expected_output="A complete shell script (setup_and_run_demo.sh) with comments.",
agent=shell_script_agent,
context=[improvement_task, repo_summarization_task], # Uses improved usage and file summaries
output_file="setup_and_run_demo.sh"
)



html_generation_task = Task(
description="Combine 'improved_usage.md', and 'architecture_diagram.md' into a final HTML file. Make sure to append the full setup_and_run_demo.sh script at the end",
expected_output="Final styled HTML guide. Follow styling similar to Wandb's website styling",
agent=html_coder_agent,
context=[improvement_task, diagram_generation_task, shell_script_task],
output_file="final_guide.html"
)


# --- Run Crew ---
crew = Crew(
agents=[
demo_generator_agent,
followup_analyst_agent,
repo_summarizer_agent,
diagram_generator_agent,
html_coder_agent,
shell_script_agent, # <-- Add here
],
tasks=[
demo_generation_task,
followup_task,
improvement_task,
repo_summarization_task,
diagram_generation_task,
shell_script_task, # <-- Add here, before html_generation_task
html_generation_task,
],
process=Process.sequential,
verbose=True
)

if __name__ == "__main__":
result = crew.kickoff()
print("\n\nFinal HTML Guide and Repo Diagram Created:\n")
print(result)

このコードは、CrewAI と Weave を用いて GitHub リポジトリのドキュメント作成を自動化するマルチエージェントシステムを構築します。まずリポジトリをクローンし、エージェントがファイル検索・内容の読み取り・要約生成を行えるツール群を初期化します。各エージェントには明確な役割があり、使用ガイドの作成、レビューと改善、ソースファイルの要約、セットアップ用シェルスクリプトの構築、アーキテクチャ図の作成、そしてすべてを HTML ページにまとめる処理を担います。
これらのタスクは厳密な順序で実行されます。使用ガイドやリポジトリ要約といった前段のエージェントの出力は、後続のエージェントにコンテキストとして引き渡されます。システムはすべてをログに記録します。 大規模言語モデル インタラクション 可観測性のために Weave を使用する一度実行すると、洗練された使用ガイド、リポジトリ構造のビジュアル概要、実行可能なセットアップスクリプトを含む完全な HTML ドキュメントが、ソースコードから自動生成されます。
CrewAI の Agent、Task、Crew クラスを用いて、ワークフロー全体をオーケストレーションします。各エージェントには専門のタスクを割り当て、すべてのタスクは逐次実行されます。これにより、ある段階の出力が次の段階の入力となり、情報が段階的に蓄積されます。具体的には、最初の使用ガイドやファイル要約から始まり、図やシェルスクリプトの生成を経て、最終的にはすべての成果を統合した包括的な HTML ドキュメントページを生成します。
スクリプトを実行すると、次の名前の新しいファイルが作成されます final_guide.html(リポジトリの使い方ガイドが含まれています)こちらは見た目の参考になるスクリーンショットです。



LLM の可観測性とデバッグを強化するための Weave 統合

このマルチエージェントシステムを効率的に監視・デバッグするために、冒頭で Weave を初期化して統合します。 import weave; weave.init("crewai_git_documenter"). このセットアップにより、各エージェントが行う OpenAI モデルへのすべての呼び出しが記録され、プロンプト、レスポンス、関連するコンテキストが中央でロギングされます。
〜を用いて Weave の可視化ダッシュボード、開発者は各エージェントの LLM 呼び出しごとの詳細なリクエスト/レスポンスのサイクルを確認し、エージェントが情報を取得・分析・生成していくフローをトレースし、ボトルネックや想定外の出力、チェーン内のエラーを迅速に特定し、実際の利用データに基づいてプロンプトやパラメータをチューニングできます。こちらは Weave のスクリーンショットです。エージェントが行った LLM へのあらゆる呼び出しをどのように容易に可視化できるかを示しています。

このようなエージェント同士のやり取りまで見通せる粒度の高い可視化は、複数のモデルが専門知識を持ち寄る私たちのようなマルチエージェント型ワークフローで特に有用です。ローカルファイルの断片的なログを掘り起こす代わりに、Weave はパイプライン全体の履歴をウェブ上で検索可能な形で提供し、より効果的な反復的開発と保守を可能にします。
専門特化したエージェントに責務を分担し、Weave で各ステップを追跡することで、CrewAI を基盤とするこのマルチエージェントシステムは、スケーラブルで保守しやすく、透明性の高い自動ドキュメント作成手法を提供します。

まとめ

マルチエージェントシステムは、AI エージェントが協調して複雑なタスクに取り組めるようにすることで、自動化を大きく変革しています。CrewAI はこの用途に特化しており、開発者が役割を明確に定義したエージェントを作成し、ツールやタスクに接続できるようにします。コードと設定の両方によるワークフローをサポートし、明確なオーケストレーションでデバッグとスケールを容易にします。Weave と組み合わせれば、あらゆるモデル呼び出しが追跡・可視化され、エージェントがどのように考え、行動し、連携しているかを開発者が全体像として把握できます。
GitHub のドキュメント作成システムでは、各エージェントが特定の役割を担います。コードの要約、図の生成、使用ガイドの執筆、セットアップスクリプトの作成などです。システムは逐次実行で進み、各ステップの結果が次のステップに受け渡されます。Weave を統合することで、開発者はプロンプトとレスポンスの対応を監視し、ロジックをトレースしてエラーを修正し、出力品質を改善できます。CrewAI が自動化を担い、Weave が内部の可視化を提供することで、保守しやすく透明性の高いマルチエージェントシステムが実現します。



この記事は AI による翻訳です。誤訳の可能性があれば、コメント欄でお知らせください。元のレポートはこちらをご覧ください。 元のレポートを見る
Iterate on AI agents and models faster. Try Weights & Biases today.