エージェント型ワークフロー:AIエージェント入門
マルチエージェントシステムと生成AIを活用してタスクを自動化するAIエージェント型ワークフローを紹介します。AI論文サマリー用のリサーチアシスタントを構築するチュートリアルも含みます。この記事はAIによる翻訳です。誤訳の可能性があればコメント欄でお知らせください。
Created on August 27|Last edited on August 27
Comment
AIシステムは急速に進化しており、機械が複雑で多段階のタスクにこれまでにない効率で取り組めるようになっています。こうした革新の最前線にあるのがAIエージェント型ワークフローです。これは、知的なエージェント同士が動的に連携し、特定の目標達成に向けて協働する変革的な仕組みです。従来の自動化やチャットボットと異なり、これらのワークフローは状況に適応し、意思決定を行い、さまざまな領域にまたがるタスクを実行します。
本記事では、エージェント型ワークフローの概要、その主要コンポーネントと活用例を解説し、最先端のAI研究論文を要約してメール送信するシステムを自作する手順まで案内します。

目次
AIエージェント型ワークフローとは何かAIエージェント型ワークフローが生産性を高める理由エージェント型ワークフローにおけるAIエージェントの主要コンポーネントと機能メモリツールオーケストレーションと計画継続学習生成AIネットワークとマルチエージェント協調によるエージェント型ワークフローの強化特化が重要な理由オーケストレーションと協調の促進マルチエージェントシステムの利点LLMの長所と限界をつなぐAIエージェント型ワークフローの実践例とメリット定型業務の委任複雑なタスクの構造化コラボレーションの強化運用のスケールと適応イノベーションを推進するチュートリアル:リサーチジャーナリズムのためのエージェント型AIシステム構築仕組みシステム設計リサーチ選定用プロンプト質問生成用プロンプト要約用プロンプトエディター用プロンプトプロンプトの整理コードW&B Weaveでバグを捕まえるWeaveでコストを可視化し、節約する方法継続学習のためのフィードバック機構の追加結論
AIエージェント型ワークフローとは何か
AIエージェント型ワークフローとは、自律的なAIエージェントがそれぞれの判断でタスクを遂行しながら協調し、共通の目標を達成するための仕組みです。これらのワークフローはAIモデルを用いて情報を処理し、文脈に適応し、行動を動的に実行することで、さまざまな用途で柔軟な多段階オペレーションを可能にします。
エージェント型ワークフローの核となるのは、メモリ、ツール、意思決定能力といった機能の統合です。メモリはタスクをまたいだ文脈保持を可能にし、ツールは外部システムとの動的な連携を実現し、意思決定は自律的な動作を支えます。これらを組み合わせることで、知的で適応性の高いプロセスが構築されます。
たとえば、エージェント型ワークフローはコンテンツ制作の全工程を自動化できます。あるエージェントがリサーチを収集し、別のエージェントが原稿を作成し、三つ目が編集し、四つ目が公開する——これらを人手を介さずに行います。こうした途切れのない連携により、リサーチ、プロジェクト管理、カスタマーサービスといったタスクでエージェント型ワークフローは極めて有用です。
自律性・協調性・リアルタイム適応性を組み合わせることで、エージェント型ワークフローは複雑で多段階のオペレーションに、より賢く効率的なアプローチを提供します。
AIエージェント型ワークフローが生産性を高める理由
AIエージェント型ワークフローは、従来のチャットボットから大きく進化した形で、より深い機能性と適応性を備えています。チャットボットが特定のプロンプトに答えるといった直線的なやり取りを担うのに対し、エージェント型ワークフローは、AIが自律的に行動し、複数のタスクを管理し、変化する文脈に動的に適応できるようにします。
たとえば、記事の下書きを手伝うといった単一タスクの支援にとどまらず、エージェント型ワークフローなら、インターネットや社内データベースのデータに基づいて自律的にアイデアを生成し、構成を立て、原稿を書き、内容を推敲し、最終稿を公開するところまで—人手を介さずに—実行できます。こうした複雑で多段階のオペレーションを扱える能力が、これまでにない生産性を引き出します。
エージェント型ワークフローは、リサーチ分析、プロジェクト管理、コンテンツの選定や高度な生成といった場面で特に威力を発揮します。タスクを先回りして調整し、人間や他のエージェントと協調することで、目的志向のシステムを構築し、知的で無駄のない成果を生み出します。こうした適応性により、多様で変化し続ける課題にも最適に対応できます。
エージェント型ワークフローにおけるAIエージェントの主要コンポーネントと機能
エージェント型ワークフローにおけるAIエージェントの構成要素と機能は、その実装と目的によって形作られます。先述の基礎概念を土台に、これらの要素がエージェントに自律性・適応性・協調性を与え、主体的に動作できるようにします。
効果的なエージェント型ワークフローを支える主要コンポーネントは次のとおりです。
メモリ
メモリは、AIエージェントがタスクや対話をまたいで文脈を保持するうえで不可欠です。先述のとおり、メモリは短期的な処理に用いるセッションベースのものと、長期的な知識保持に用いる永続型のものがあります。たとえば、
- 短期メモリ:進行中のリサーチ議論を要約したり、追質問に一貫性のある形で応答できるようにします。
- 永続メモリ複数のセッションにまたがって、エージェントがプロジェクトのマイルストーンや顧客の嗜好を想起できるようにします。
この連続性は、一貫性を保ち、AIエージェントが最初からやり直すことなく過去の行動を土台に積み上げていくために不可欠です。
ツール
AIエージェントは外部ツールやAPIを活用して機能を拡張します。この点は「AIエージェント型ワークフローが生産性を高める理由」で強調されています。こうしたツールにより、エージェントは次のことが可能になります。
- 関連データをデータベースから照会する。
- 詳細なレポートや可視化を生成する。
- リアルタイムで計算を実行したり、ウェブ上の情報を取得したりする。
たとえばコンテンツ制作のワークフローでは、あるエージェントがAPIでトレンドのキーワードを取得し、別のエージェントがその入力に基づいて最適化されたコンテンツを生成します。
オーケストレーションと計画
オーケストレーションとは、複数のエージェントやコンポーネントを調整し、複雑なワークフローを完遂することです。これは先述の協調的な能力—エージェント同士が連携して共通の目標を達成する—と対応します。中心となるシステムが依存関係を管理し、競合を解消し、タスクが所定の順序で実行されるように担保するのが一���的です。
たとえば:
- プロジェクト管理のワークフローでは、あるエージェントがタイムラインを作成し、別のエージェントがタスクを割り当て、三つ目のエージェントが進捗を監視して、すべてのステップが全体計画に整合するよう担保します。
継続学習
継続学習により、エージェントは時間とともに進化・改善でき、動的な環境への適応に不可欠な機能となります。保存された対話履歴や人手によるラベル付きフィードバックを活用することで、エージェントは振る舞いや性能を洗練できます。例としては次のようなものがあります。
- 自己内省による改善成功・失敗のやり取りを分析し、意思決定を最適化すること。
- プロンプトの強化将来のタスクをより効率的に処理できるよう、より効果的なインコンテキスト例でシステムプロンプトを更新すること。
この反復的な改良は、先述のエージェント型ワークフローが持つ適応性と目標志向性と整合しています。
- 人手を介したフィードバックW&B Weaveを使うと、ユーザーはエージェントのパフォーマンスを監視し、成功・失敗の結果にラベルを付け、リアルタイムでフィードバックを提供できます。例えば次のとおりです。
- エージェントを使ってAI論文を要約する研究者は、生成された要約に含まれる誤りや不正確さにフラグを立てることができます。
- こうしてラベル付けされた例はシステムにフィードバックされ、将来の類似タスクに向けてエージェントが手法を洗練できるようにします。
- 評価指標:Weaveを使うと、開発者はタスク横断でエージェントの性能を評価するカスタム評価パイプラインを設計できます。正確性、関連性、レイテンシなどの指標をログ化して可視化し、改善すべき領域への示唆を得られます。
- 動的プロンプト最適化W&B Weaveで収集したフィードバックは、エージェントのプロンプト更新を導き、より適切なインコンテキスト例を含められるようにします。こうした継続的な洗練により、新規または変化するタスク要件への適応力が高まります。
- データ主導の反復改善:やり取りや結果の詳細なログを継続的に記録することで、W&B Weaveはエージェントの振る舞いにおけるパターンを特定し、どのワークフローが最良の成果をもたらすかを可視化します。こうしたインサイトにより、エージェントのアーキテクチャと運用戦略の双方をデータ主導で更新できます。
たとえば、自動コンテンツ生成のワークフローでは、Weaveを使って、トーンやトピックの関連性といったユーザー定義の基準に基づき、エージェントが下書きをどの程度うまく生成できているかを追跡できます。人間の介在による修正を取り込むことで、将来の反復が改善され、出力はユーザーの期待により近づきます。
生成AIネットワークとマルチエージェント協調によるエージェント型ワークフローの強化
エージェント型ワークフローを設計するうえで重要な戦略は、タスクを機能ごとに分割し、各タスクを特化したエージェントに担当させることです。こうしたモジュール型アーキテクチャは、ワークフロー内部を整理するだけでなく、現在の生成AIモデルの強みも引き出します。複雑なワークフローを明確に定義された個別タスクへ細分化することで、システムはよりスケーラブルで解釈しやすく、適応性の高いものになります。
特化が重要な理由
大規模言語モデル 単一で焦点の定まったタスクを割り当てたときに最も効果を発揮します。情報の取得、データの要約、行動シーケンスの計画を一度に求めてモデルに過負荷をかけると、出力が不安定になったり最適から外れたりしがちです。たとえば、
- 研究論文の取得を任された単一のエージェントであれば、検索クエリの最適化に専念できます。
- 別の要約専任エージェントは、取得したデータを用いて簡潔で正確な要約を生成できます。
役割を分離することで、各エージェントはモデルの能力を最大限に引き出し、性能劣化を最小限に抑えつつ、より信頼性が高く精度の高い結果を生み出せます。さらに、必要なエージェントや機能ごとに異なるモデルを使い分けることも可能になります。
オーケストレーションと協調の促進
モジュール化のアプローチは、ワークフローのオーケストレーションも強化します。特化したエージェント同士が明確に定義された通信プロトコルで連携し、必要に応じてタスクを逐次的または並列に完了させます。たとえば、
- コンテンツ制作のパイプラインでは、あるエージェントがトレンドの話題を収集し、別のエージェントが原稿を作成し、三つ目のエージェントがトーンと文法を磨き上げ、最後のエージェントが公開スケジュールを設定します。
- この構造化された協働は、人間社会の役割分担を映し出しています。教師、エンジニア、医師がそれぞれ異なる機能を担いながら、共通の目標達成に向けて協力するのと同じです。
マルチエージェントシステムの利点
- スケーラビリティタスクを複数のエージェントに分散できるため、需要や複雑さの増大にも柔軟に対応できるワークフローに適応しやすくなります。
- フォールトトレランスモジュール化されたシステムなら、ワークフロー全体を乱すことなく、弱点の特定と最適化や、性能の低いエージェントの置き換えを容易に行えます。
- 解釈可能性各エージェントの出力はその機能に遡って追跡できるため、デバッグと評価が容易になります。
LLMの長所と限界をつなぐ
活用することで 生成AI このタスク特化のやり方によって、エージェント型ワークフローは、同時に複数のタスクを扱うことの難しさなど、LLM(大規模言語モデル)が本来抱える制約に対処します。これにより、ワークフローは次のようになります。
- 効率的:リソースはタスクの特定のニーズに基づいて割り当てられます。
- 適応力が高い:大規模な改修なしに、エージェントの追加や変更が可能です。
- 堅牢:あるコンポーネントの不具合が、システム全体に連鎖しません。
マルチエージェント協調のモジュール性は、実用的であるだけでなく変革的でもあります。これにより、エージェント型ワークフローは複雑で微妙な要求にも精緻に対応でき、現代のAI主導の業務に不可欠な存在となります。
AIエージェント型ワークフローの実践例とメリット
AIエージェント型ワークフローは、反復作業の自動化、コラボレーションの強化、そして組織が戦略目標に集中できる環境の実現によって、生産性を大きく変革する可能性があります。自律的なエージェントを活用することで、業務を効率化し、手作業を減らし、個人やチームがよりインパクトのある成果を生み出せるようになります。
定型業務の委任
エージェント型ワークフローを使えば、反復的または時間のかかる業務をAIエージェントに委ねられます。例えば、次のようなケースがあります。
- 日常的なデータ分析エージェントは販売動向や顧客行動を分析し、意思決定者に直接活用可能なインサイトを提供できます。
- 報告書の作成エージェントはビジネス報告書の初稿を作成でき、従業員は内容の磨き込みや戦略的な提言に時間を割けるようになります。
- 情報検索リサーチ用エージェントは、膨大なデータセットやデータベースを素早く精査し、最も関連性の高い情報を迅速に取得できます。
このパーソナライズされた支援により、単調な業務が不要になり、従業員は創造的・戦略的、あるいは優先度の高い業務に集中できます。
複雑なタスクの構造化
組織内では、エージェント型ワークフローが複雑な業務を扱いやすいステップに分解し、全体を明確かつ体系的にします。例えば、次のとおりです。
- プロジェクト計画エージェントは、リソースの空き状況と期限に基づいてタイムラインを作成し、タスクを割り当てられます。
- コンテンツ制作マルチステップのプロセスでは、あるエージェントがリサーチを収集し、別のエージェントが原稿を作成し、三つ目のエージェントが公開に向けて最終成果物を磨き上げます。
- カスタマーサポートエージェントは、サポートチケットの優先度付けを行い、簡単な問い合わせを解決し、複雑な問題は人間の担当者へエスカレーションできます。
一貫性と正確性を確保することで、これらのワークフローは全体の効率と品質を向上させます。
コラボレーションの強化
エージェント型AIワークフローは、複数の関係者やシステムからの入力が必要なプロジェクトにおいて、より良い調整を促進します。依存関係や引き継ぎを仲介・管理し、認識のずれや伝達ミスを減らします。例えば、次のようなケースです。
- 製品開発のプロセスでは、エージェントがデザイン・エンジニアリング・マーケティング各チームの更新を同期し、全員の足並みを揃えます。
- エージェントは、人間のチームや他の自動化システム間の引き継ぎをスムーズにし、ワークフローの中断を最小限に抑えます。
運用のスケールと適応
エージェント型ワークフローは、最小限の手作業で組織のプロセスをスケールさせるのに優れています。柔軟性が高いため、次のことが可能です。
- 優先順位の変化に対応するエージェントは、新たな目標やデータ入力に応じてワークフローを迅速に調整できます。
- 新しいツールを統合する新しいAPIやデータソース、ソフトウェアを、運用を妨げることなくワークフローにシームレスに追加できます。
- チーム横断でプロセスを標準化する成功したワークフローは部門間で横展開でき、成果とベストプラクティスの一貫性を確保します。
イノベーションを推進する
定型業務を自動化することで、エージェント型ワークフローは創造や実験に充てるリソースを生み出します。チームは次のことが可能です。
- エージェントにデータ収集と初期分析を任せて、新しいアイデアのプロトタイピングを迅速に進める。
- オーバーヘッドを抑えることでリスクを最小限に抑えつつ複数の解を試し、素早く反復できます。
- 運用の細部はAIが的確に管理していると踏まえ、高度な戦略に集中する。
これにより実験と成長の文化が育まれ、組織は変化する市場の需要や技術の進歩に継続的に適応できるようになります。
チュートリアル:リサーチジャーナリズムのためのエージェント型AIシステム構築
このチュートリアルでは、あなたの関心に合わせて学術論文の発見と要約を自動化する個人用AIリサーチエージェントを構築します。最後まで進めれば、リサーチのワークフローを効率化し、最小限の手作業で高品質なパーソナライズ要約を届ける、完全に機能するシステムが手に入ります。
仕組み
エージェントは、目標達成のために体系立てられたプロセスに従います。
- 検索と選定:エージェントは arXiv のような学術データベースを検索し、LLM を用いて結果を評価して、さらなる分析に最も関連性の高い論文を選定します。
- コンテンツ抽出:選定した論文から重要な内容を抽出し、明確化や深掘りが必要な箇所を特定します。
- 要約:的確な質問を重ねて、あなたの好みに合わせた簡潔で要点を押さえた要約を生成します。
- 洗練と配信要約は明瞭さのために洗練され、あなたに直接メール送信されます。
エージェントを時間とともに賢くするため、フィードバックループを組み込みます。メール本文に「good」または「bad」と返信して、要約を評価できます。
- 良い:エージェントは、類似トピックを優先するようにプロンプトを更新します。
- 悪い:今後は類似トピックを避けるように調整します。
この反復プロセスにより、エージェントはあなたの関心に合致する論文の特定能力を継続的に高めていきます。

システム設計
このシステムは、エージェント型AIワークフローの各段階を担当するよう、それぞれ固有のプロンプトで定義された専門エージェント群を中心に構築されています。
- リサーチ選定エージェント論文を評価し、あなたの嗜好に基づいて最も関連性の高いものを選定します。
- 質問生成エージェント要約の指針となる重要な不明点を特定します。
- 要約エージェントあなたの文体に合わせた簡潔な要約を作成します。
- 編集エージェント最終出力を読みやすく一貫性のある形に整えます。
リサーチ選定用プロンプト
このプロンプトは、エージェントが関連性とインパクトの高いリサーチトピックを選ぶための指針として機能します。望ましいトピックと望ましくないトピックの例を活用し、ユーザーの具体的な関心と目標に合致させます。最先端の進展と意義ある応用に焦点を当てることで、エージェントは選定プロセスを効果的に最適化できます。
You are an AI research assistant tasked with selecting the most relevant and impactful research topic from a list of options. Your goal is to choose a topic that aligns with my preferences, based on previous articles I’ve written. Below are examples of topics I have selected in the past:"Voyage-Code-3: Smarter, More Efficient Code Retrieval with Nested Embeddings""DeepSeek-V3: Training 671 billion parameters with a $6 million dollar budget""DeiT Outperforms Experts in Cancer Diagnosis""Meta's new LLM architecture: Large Concept Models""OpenAI Introduces o3: Pushing the Boundaries of AI Reasoning""Meta presents Coconut: Augmenting LLM Reasoning with Latent Thoughts""Meta introduces Llama 3.3""Google Cloud Introduces Veo and Imagen 3""AlphaQubit: Attention is all you need for Quantum Error Correction?""OmniVision-968M: A Ultra-lightweight Multimodal Model built on Qwen 2.5""Tokenformer: A GPT that uses tokens as parameters""Researchers Speed up Diffusion Modeling 17.5x""PhysGen: Training-Free Physics Grounding of Image-to-Video Generation""Deepmind trains self-correcting LLM's with RL"These topics typically share the following characteristics:- Cutting-edge advancements in AI, such as novel architectures, groundbreaking models, or innovative methodologies.- Large-scale experiments, resource efficiency, or methods that push performance or cost-effectiveness to new limits.- Real-world applications with transformative potential, such as breakthroughs in healthcare, physics, quantum computing, or multimodal learning.- A focus on AI reasoning, self-correction, and models that improve through iterative feedback.- Technical depth that appeals to readers interested in state-of-the-art developments.Your task:1. Review the provided list of research results.2. Analyze each option based on the characteristics above.3. Select the topic that best aligns with my preferred style and focus areas.4. Provide a brief explanation of why this topic is the best match, referencing similarities to my previous selections.Be precise, and ensure the chosen topic reflects both technical innovation and practical significance in AI research.Note, here are some previous articles that you have selected that I really am not that interested in -- use these to guide your decision making:########### beginning of negative preference list--- - Papers here you are less interest in ...
質問生成用プロンプト
このプロンプトにより、エージェントは論文の内容に基づいて考え抜かれた質問を生成できます。これらの質問は、明確化や追加の注目が必要な領域を特定し、要約プロセスを導きます。その結果、要約全体の深さと関連性が高まります。
You are an AI assistant. Based on the following text from a research paper, generate a list of major questions that:1. A reader might want to ask about the paper.2. Address potential areas of confusion or key points that need clarification.Please provide a list of meaningful and insightful questions. -- respond with just the questions!
要約用プロンプト
トピック選定後、このプロンプトによりエージェントは論文の簡潔で有益な要約を生成できます。要約には主要なアイデア、貢献、結果、示唆が確実に反映され、あわせてユーザーが定義した質問や関心事項にも対応します。
You are an AI research assistant. Your task is to summarize a research paper based on its content and a list of key questions. The summary should be 300-500 words long, and it must not only summarize the paper’s main ideas, contributions, and results but also attempt to address the provided questions.Instructions:1. Write a clear, concise, and comprehensive summary of the paper in 300-500 words.2. Ensure the summary highlights:- The core problem or challenge the paper addresses.- The methods, models, or experiments proposed or used in the paper.- The key results and insights obtained from the research.- The implications or potential applications of the research.3. Where possible, answer the questions provided based on the content of the paper. If the questions cannot be fully answered, summarize what is known from the provided content.Be precise and focus on the most important points, ensuring the summary is easy to understand for a technical audience.I will also give you a previous article that I want you to use as context/as a guide to write the new article.
エディター用プロンプト
このプロンプトは、生成された要約を所定の文体・構成要件に適合させることに重点を置きます。読みやすさの向上、見出しの追加、明確な流れの維持を行うことで、エディター工程が最終要約をユーザーの好むトーンや提示スタイルに合致させます。
You are an AI article editor. Your task is to rewrite the provided article to:1. Ensure all sections have proper headers (unstyled, ending with a colon).2. Meet the desired word count range (300-500 words).3. Improve the overall structure and flow of the content.4. Does not include bullets or lists.Return only the new article with the added changes. If no changes are required, just return the full article.
プロンプトの整理
このプロジェクトでは、各エージェントごとにプロンプトをテキストファイルとして保存するのが最も効率的な整理方法です。Pythonのロジックファイル内にプロンプトを埋め込む方法はやや扱いにくく、ロジックファイルは本来、自然言語や長い文字列ではなくコードを格納することを主目的として設計されているためです。
各プロンプトを個別のテキストファイルに分けて保存しておくと、メインのワークフローに干渉したり、コード中心のファイルの制約に影響されることなく、管理・修正・テストが容易になります。この方法により開発プロセスが効率化され、反復的な改善に向けて、プロンプトの可用性と構造の明瞭さを確保できます。
コード
これらのプロンプトを用いて、論文の探索・分析・要約を自動化するスクリプトを作成します。指定したトピックに基づき arXiv を検索し、LLM(大規模言語モデル)で最も関連性の高い論文を評価・選定します。論文をダウンロード後、最初の10ページから内容を抽出し、要約を導くためのターゲット質問を生成します。これらの質問と抽出した内容を用いて、ユーザーの嗜好に合致した洗練された要約を出力します。
最終的な要約はメールで私の受信箱に送られ、結果を手軽に確認できます。メール送信機能を有効にするには、通常のパスワードではなく、メールアカウントのアプリ パスワードを使用する必要があります。
Gmail の場合は、Google アカウントで 2 段階認証プロセスを有効にし、次にアクセスして アプリ パスワード セクションに進み、スクリプトで使用するパスワードを生成します。アプリ パスワードは、メインの認証情報を安全に保ったままアクセス権を付与できる安全な方法です。別のメールクライアントを使用している場合は、提供元によってアプリ パスワードの生成手順が異なることがあります。
ニュースエージェントのコードは次のとおりです。
import arxivimport asyncioimport osfrom PyPDF2 import PdfReaderfrom litellm import acompletionimport weaveimport smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartimport jsonimport wandb# Initialize Weaveweave.init("news_agent")# Email configurationemail = "your_email@gmail.com"pswd = "your app password"LAST_EMAIL_FILE = "last_email.json"# Helper function: Run model inferenceasync def run_inference(query):api_key = os.getenv("OPENAI_API_KEY")model_name = "gpt-4o-mini"response = await acompletion(model=model_name,api_key=api_key,messages=[{"role": "user", "content": query}],temperature=0.7,max_tokens=1024,)return response["choices"][0]["message"]["content"]# Helper function: Read a prompt from a filedef read_prompt(file_path):with open(file_path, "r") as file:return file.read()# Helper function: Read a reference articledef read_reference_article(article_file):if os.path.exists(article_file):with open(article_file, "r") as file:return file.read().strip()return ""# Helper function: Format Arxiv resultsdef format_arxiv_results(results):return "[" + ",\n".join([f'{{"index": {i+1}, "title": "{result["title"]}", "summary": "{result["summary"]}", "url": "{result["url"]}"}}'for i, result in enumerate(results)]) + "]"# Helper function: Convert Arxiv URL to PDF URLdef convert_to_pdf_url(abs_url):return abs_url.replace("/abs/", "/pdf/")# Helper function: Read the first 10 pages of a PDFdef read_pdf_first_10_pages(pdf_path):try:with open(pdf_path, "rb") as file:reader = PdfReader(file)return "\n".join(page.extract_text() for page in reader.pages[:10])except Exception:return ""# Arxiv search function@weave.opdef get_arxiv_possibilities(query, max_results=20):search = arxiv.Search(query=query,max_results=max_results,sort_by=arxiv.SortCriterion.SubmittedDate,)return [{"title": result.title, "summary": result.summary.replace("\n", " "), "url": result.entry_id}for result in search.results()]# Select the best Arxiv paper with call ID@weave.opasync def select_best_arxiv_paper(possibilities, prompt_file):if not possibilities:return None, None, None# Get the Weave call IDcall_id = weave.get_current_call().idformatted_results = format_arxiv_results(possibilities)selection_prompt = read_prompt(prompt_file)query = f"{selection_prompt}\n\nSearch Results:\n{formatted_results}\n\nRespond with ONLY the URL of the paper you recommend, nothing else."selected_response = await run_inference(query)selected_url = selected_response.strip()# Match the selected URL to possibilities for additional detailsselected_paper = next((item for item in possibilities if item["url"] in selected_url), None)return (convert_to_pdf_url(selected_url) if selected_url.startswith("http") and "/abs/" in selected_url else None,selected_paper["title"] if selected_paper else None,call_id, # Return the Weave call ID)# Generate questions from the paper content@weave.opasync def generate_questions_from_paper(paper_text, prompt_file):question_prompt = read_prompt(prompt_file)prompt = f"{question_prompt}\n\nText:\n{paper_text}\n\nPlease provide a list of questions."return await run_inference(prompt)# Generate a summary of the paper@weave.opasync def generate_summary_from_paper(paper_text, questions, summary_prompt_file, reference_text):summary_prompt = read_prompt(summary_prompt_file)prompt = (f"{summary_prompt}\n\nPREVIOUS Reference Article:\n{reference_text}\n\n"f"List of Questions to address in the article:\n{questions}\n\nPaper Content:\n{paper_text}")return await run_inference(prompt)# Edit the generated summary@weave.opasync def edit_summary(summary, editor_prompt_file):editor_prompt = read_prompt(editor_prompt_file)prompt = f"{editor_prompt}\n\nArticle Content:\n{summary}"return await run_inference(prompt)# Save email details to a fileasync def save_last_email(subject, body, call_id=None, call_url=None):"""Save the subject, body, Weave call ID, and call URL of the last email sent."""with open(LAST_EMAIL_FILE, "w") as f:json.dump({"subject": subject, "body": body, "call_id": call_id, "call_url": call_url}, f)print(f"Saved last email with call ID: {call_id} and URL: {call_url}")def get_wandb_username():try:# Initialize the W&B APIapi = wandb.Api()# Fetch the username of the authenticated userreturn api.default_entityexcept Exception as e:print(f"Error fetching W&B username: {e}")return "unknown_user"# Send an emailasync def send_email(subject, body, recipient_email, sender_email, sender_password, main_call_id=None, selection_call_id=None):try:# Dynamically fetch W&B usernameusername = get_wandb_username()call_url = f"https://wandb.ai/{username}/news_agent/r/call/{main_call_id}" if main_call_id else Nonemsg = MIMEMultipart()msg["From"] = sender_emailmsg["To"] = recipient_emailmsg["Subject"] = subjectmsg.attach(MIMEText(f"{body}\n\nView the process log: {call_url}", "plain"))with smtplib.SMTP("smtp.gmail.com", 587) as server:server.starttls()server.login(sender_email, sender_password)server.sendmail(sender_email, recipient_email, msg.as_string())print(f"Email sent to {recipient_email}")await save_last_email(subject, body, selection_call_id, call_url)except Exception as e:print(f"Failed to send email: {e}")# Main function@weave.opasync def main():main_call_id = weave.get_current_call().idtopic = "machine learning"select_prompt_file = "select_research_prompt.txt"question_prompt_file = "generate_questions_prompt.txt"summary_prompt_file = "summary_prompt.txt"editor_prompt_file = "editor_prompt.txt"reference_files = ["article1.txt", "article2.txt", "article3.txt"]# Step 1: Get Arxiv possibilitiesprint("Searching Arxiv...")possibilities = get_arxiv_possibilities(topic, max_results=20)# Step 2: Select the best paperpdf_url, selected_title, selection_call_id = await select_best_arxiv_paper(possibilities, select_prompt_file)if not pdf_url:print("No paper selected.")returnprint(f"Selected Paper: {selected_title}")pdf_path = f"{pdf_url.split('/')[-1]}.pdf"os.system(f"curl -L {pdf_url} -o {pdf_path}")# Step 3: Extract content and generate questionspaper_text = read_pdf_first_10_pages(pdf_path)if not paper_text.strip():print("Could not extract any text from the PDF.")returnprint("Generating questions based on the paper content...")questions = await generate_questions_from_paper(paper_text, question_prompt_file)# Step 4: Generate summariesall_summaries = ""for idx, ref_file in enumerate(reference_files):reference_text = read_reference_article(ref_file)if not reference_text:print(f"Reference article {ref_file} is missing or empty. Skipping...")continueprint(f"\n=== Generating Summary {idx + 1} based on {ref_file} ===")summary_output = await generate_summary_from_paper(paper_text, questions, summary_prompt_file, reference_text)print(f"Editing Summary {idx + 1}...")edited_summary = await edit_summary(summary_output, editor_prompt_file)all_summaries += f"=== Edited Summary {idx + 1} based on {ref_file} ===\n{edited_summary}\n\n"# Step 5: Email the summariesprint("Sending email with summaries...")await send_email(subject=f"{selected_title}",body=all_summaries,recipient_email=email,sender_email=email,sender_password=pswd,main_call_id=main_call_id,selection_call_id=selection_call_id)# Run the main functionasyncio.run(main())
このスクリプトは、学術論文の探索・分析・要約を自動化するAI駆動のリサーチアシスタントを作成します。逐次的なワークフローに記事の条件付けを組み合わせることで、ユーザーの嗜好や創作スタイルに合わせた結果を提供します。仕組みは次のとおりです。
- 関連論文を検索する
- その search_arxiv 指定したトピックに関する論文をarXivで検索する関数です。
- 〜を使用して @weave.op デコレータによって、問い合わせの入力と結果をログ化し、透明性と再現性を確保します。
- 最適な論文を選ぶ
- その select_best_arxiv_paper 関数は、LLMを用いて検索結果を評価します。
- ユーザーが定義したプロンプトに基づき、過去の関心や嗜好と整合するよう配慮しつつ、最も関連性の高い論文を選定します。
- 論文から内容を抽出する
- このスクリプトは選択した論文のPDFをダウンロードし、PyPDF2を用いて最初の10ページを抽出します。
- 抽出したテキストは、その後の分析の基礎となります。
- 目的に即した質問を生成する
- これらの質問は、明確化や深い洞察が必要な領域に焦点を当て、要約が有意義で網羅的になるようにします。
- 要約を生成する
- その generate_summary_from_paper 関数は、ユーザーが提供した参考記事を基に、要約のトーン・構成・文体を整えます。
- これらの参考資料を取り入れることで、ユーザーの嗜好を反映しつつ多角的な視点から検討でき、出力をより豊かにできます。
- 要約を洗練する
- その edit_summary 関数は下書きを磨き、語数要件を満たし、ユーザー指定の文体ガイドラインに準拠するよう整えます。
- 洗練された要約の配信準備が整いました。
- 要約を送信して追跡する
- その send_email 関数は磨き上げた要約をまとめ、メールで送信します。
- 最後に送信したメールの件名・本文・Weaveの呼び出しIDなどの詳細は、内に保存されます。 last_email.json トレーサビリティのためのファイル
- ユーザーのフィードバックを取り入れる
- ユーザーは、メールに「good」または「bad」と返信することでフィードバックを提供できます。
- このフィードバックに基づき、システムは内部プロンプトを更新して、類似トピックを優先または回避し、継続的な改善を促進します。
- フィードバックは対応するメールとその生成時のコンテキストに直接紐づけられ、継続的な最適化が保証されます。

W&B Weaveでバグを捕まえる
Weave内の推論呼び出し全体の流れを確認したところ、私のスクリプトが呼び出していることに気づきました。 generate_questions_from_paper 単一の論文に対して生成された各要約について、同じ処理を複数回実行していましたが、これは明らかに不要でした。

これに気づいてから、ワークフローを簡素化し、次の点を確実にしました。 generate_questions_from_paper 関数の呼び出しは一度だけになりました。これにより実行時間だけでなく、更新後のトレースが示すとおり、各実行あたりのトークン消費も削減されました。
最適化されたワークフローにより、エージェントは不要な計算をやり直すことなく、各参考記事の要約生成を進められるようになり、より効率的でスケーラブルなシステムが実現しました。
改善後のワークフローの全体像は、Weaveで明確に可視化できます。

質問生成を1ステップに集約したことで、出力品質を保ったままエージェントの実行コストを大幅に下げられました。明快な可視化とコスト内訳を備えたWeaveのインターフェースは、この最適化の必要性を見極めるうえで重要な役割を果たしました。どこでリソースが誤配分されているかを正確に示し、問題に効果的に対処するための示唆を与えてくれたのです。今回の経験は、エージェント型AIワークフローのマルチステップ処理におけるデバッグと微調整でWeaveが持つ価値を改めて裏付けるものとなりました。
Weaveでコストを可視化し、節約する方法
Weaveは関数ごとのトークン使用量とコストを可視化でき、コスト最適化に役立つ有用な機能です。詳細な内訳により、エージェントの各コンポーネントが総コストにどう寄与しているかを把握できました。これにより、エージェント設計を反復的に改善しつつ、最適化が機能面だけでなく費用対効果の面でも妥当であることを確実にできます。

継続学習のためのフィードバック機構の追加
システムの性能を動的に高めるため、ユーザーのフィードバックをシームレスに収集するスクリプトを作成します。このスクリプトは、選定した研究トピックの妥当性や品質に関するフィードバックをメールで監視する処理を自動化し、ユーザーが実用的な入力を手軽に提供できるようにします。
仕組み
- フィードバック検出このスクリプトは、ユーザーが自分宛てに送ったメールを走査し、「良い」「悪い」などの簡潔なフィードバックを検出します。
- システム動作の調整
- フィードバックが「良い」の場合、直近に選定した研究論文のタイトルをプロンプトファイルの「良い」セクションに追加し、今後は同様のトピックが優先されるようにします。
- フィードバックが「悪い」の場合は、タイトルをプロンプトファイルの「悪い」セクションに追加し、望ましくないトピックを避けるようにシステムを調整します。
- 意思決定の強化このフィードバックループにより、システムは変化するユーザーの嗜好に素早く適応し、関連性の高い研究トピックを選定する能力が大幅に向上します。
- Weave 連携 に保存された呼び出しIDを使用して last_email.json ファイルに加えて、フィードバックは Weave にもログ化されます。これにより、特定の研究選定に対するフィードバックを追跡し、時間の経過に伴うシステムのパフォーマンスを把握できます。
この自動フィードバックループを組み込むことで、システムは継続的に改善され、ユーザーのニーズに適合し続けます。
import jsonimport imaplibimport email as emimport weave# Initialize Weavewv_client = weave.init("news_agent")# ConfigurationEMAIL_ACCOUNT = "your_email@gmail.com"EMAIL_PASSWORD = "your app password"LAST_EMAIL_FILE = "last_email.json"PROMPT_FILE = "select_research_prompt.txt"def load_last_email():"""Load the last email details."""try:with open(LAST_EMAIL_FILE, "r") as f:return json.load(f)except FileNotFoundError:return {"title": None, "call_id": None}def update_prompt(paper_title, feedback):"""Update the prompt file based on feedback."""if not paper_title:print("No paper title available to update the prompt.")returnwith open(PROMPT_FILE, "r") as f:lines = f.readlines()# Check if the title already exists in the fileif any(paper_title in line for line in lines):print(f"The paper title '{paper_title}' is already in the prompt file. Skipping update.")returnif feedback == "good":lines.insert(2, f'"{paper_title}"\n') # Add to the top of the "good" sectionelif feedback == "bad":lines.append(f'"{paper_title}"\n') # Add to the "bad" sectionwith open(PROMPT_FILE, "w") as f:f.writelines(lines)print(f"Updated prompt with {feedback} feedback for: {paper_title}")def log_feedback_in_weave(call_id, feedback):"""Log feedback in Weave."""try:if 'good' in feedback.lower():wv_client.get_call(call_id).feedback.add_reaction("👍")elif 'bad' in feedback.lower():wv_client.get_call(call_id).feedback.add_reaction("👎")print(f"Weave feedback logged: {feedback} for call ID {call_id}")except Exception as e:print(f"Failed to log feedback in Weave: {e}")def get_email_body(msg):"""Extract the plain text body of an email."""if msg.is_multipart():for part in msg.walk():if part.get_content_type() == "text/plain":return part.get_payload(decode=True).decode()else:return msg.get_payload(decode=True).decode()def check_latest_email():"""Check the user's latest email for 'good' or 'bad' feedback."""# Connect to Gmailmail = imaplib.IMAP4_SSL("imap.gmail.com")mail.login(EMAIL_ACCOUNT, EMAIL_PASSWORD)mail.select("inbox")# Search for emails sent by the user to themselvesstatus, messages = mail.search(None, f'(FROM "{EMAIL_ACCOUNT}" TO "{EMAIL_ACCOUNT}")')email_ids = messages[0].split()if not email_ids:print("No emails found.")return None# Fetch the latest emaillatest_email_id = email_ids[-1]status, msg_data = mail.fetch(latest_email_id, "(RFC822)")raw_email = msg_data[0][1]msg = em.message_from_bytes(raw_email)# Get the body of the emailbody = get_email_body(msg).strip()print(f"Latest email body: {body}")# Ignore emails longer than 10 charactersif len(body) > 10:print("Email body is longer than 10 characters. Ignoring.")return None# Check for feedbackif "good" in body.lower():return "good"elif "bad" in body.lower():return "bad"else:print("No actionable feedback found in the email.")return Nonedef main():# Load the last sent emaillast_email = load_last_email()paper_title = last_email.get("subject")call_id = last_email.get("call_id")if not paper_title:print("No last email title found. Exiting.")returnif not call_id:print("No Weave call ID found for the last email. Exiting.")return# Check for feedback in the latest emailfeedback = check_latest_email()if feedback:# Update the prompt based on feedbackupdate_prompt(paper_title, feedback)# Log feedback in Weavelog_feedback_in_weave(call_id, feedback)if __name__ == "__main__":main()
このスクリプトは、ユーザーのフィードバックを組み込み、AI研究システムの性能を向上させるプロセスを効率化します。ユーザーの受信トレイにアクセスし、自分宛てに送信された直近のメールを特定して、「good」や「bad」などのフィードバックを検出します。
フィードバックが「good」の場合、スクリプトは直近の論文タイトルをプロンプト���ァイルの優先セクションに追加し、同様のトピックを優先します。フィードバックが「bad」の場合は、タイトルをプロンプト内の「負例」セクションに移し、望ましくないテーマを避けるのに役立てます。さらに、特定の論文を選択した関数に対応する Weave 内の該当トレースにフィードバックを追加します。これにより、時系列でのデータ追跡が可能になり、より効果的に論文を選定できるようモデルを再学習できます。
このフィードバック機構を自動化することで、システムはユーザーの嗜好に沿って進化し、意思決定を最適化しつつ、最小限のユーザー介入で高い関連性を維持します。
このフィードバックシステムの動作を示すために、ここではスクリプトを手動で実行し、メールでフィードバックを送信したうえで、更新されたプロンプトファイルを確認します。実際にはこれらのスクリプトはスケジュール実行を想定していますが、説明のため今回は手動で実行します。
まず、リサーチエージェントのスクリプトを実行します。これは、こちらの嗜好に基づいて関連する論文を選び、要約をメールで送信します。メールは次のとおりです。

次に、メールクライアントを開き、本文に「good」という語を入れてシステムにフィードバックを送ります。要約を誤ってフィードバックと見なさないため、このスクリプトは長文を無視する設計のため、本文は10文字以内に収めます。

フィードバックを送信したら、フィードバックハンドラーのスクリプトを実行します。このスクリプトは最新のメールを取得し、「good」というフィードバックを検出して、論文のタイトルを例示セクションに追記します。 select_research_prompt.txt ファイルです。スクリプトの実行が完了したら、プロンプトファイルを開き、プロンプトの「good」セクションに論文タイトルが追加されていることを確認します。

さらに、このフィードバックは Weave にもログ化され、右上の「いいね」👍アイコンで確認できます。

上記のスクリプトは、Unix系なら cron、Windows ならタスク スケジューラ、あるいはクラウド型のタスクスケジューラを使って定期実行に設定できます。たとえばリサーチエージェントのスクリプトを24時間ごとに実行し、新着論文を発見・分析・要約して、指定したメールアドレスに送信するよう構成できます。
フィードバックハンドラーのスクリプトは、リサーチエージェントのスクリプト実行から約23時間後に動くよう設定できます。これにより、前回の要約に対して提供されたフィードバックが処理され、次の要約セットを生成する前にシステムの好みに反映されていることを確実にします。
結論
本記事では、学術論文の発見・分析・要約を自動化できるAIリサーチエージェントの構築方法を示します。論文の選定、質問生成、要約作成、コンテキストによるコンディショニングを通じた出力の洗練といった構造化されたエージェント型ワークフローを活用することで、ユーザーはリサーチ作業を効率化し、生産性を高められます。
フィードバックループの統合はエージェントの適応性を際立たせ、ユーザーの嗜好に応じて進化できるようにします。「good」や「bad」といった簡単なフィードバックを与えるだけで、ユーザーはエージェントの意思決定に直接影響を及ぼし、時間とともにシステムをよりパーソナライズされ効果的なものにします。自動化と人による監督を組み合わせることで、個々のニーズとの整合性を保ちつつ、手作業の負担を減らせます。
実用面にとどまらず、本プロジェクトは生成AI、マルチエージェント、反復的なフィードバックを組み合わせることの変革的な可能性を示しています。研究者、実務家、愛好家のいずれにとっても、このワークフローは、人間中心の創造性と意思決定を損なうことなく、生産性を高める技術のあり方を具体的に示します。今後さらに洗練し、定期実行の自動化を進めることで、このエージェントは、変化の速いデータ豊富な現代において、複雑な情報を取捨選択・整理・運用するための強力なツールとして機能するでしょう。
Add a comment
Iterate on AI agents and models faster. Try Weights & Biases today.