エージェント型ワークフロー:AIエージェント入門
マルチエージェントシステムと生成AIを活用して、業務を自動化するエージェント型ワークフローを探ります。AI論文の要約を行うリサーチアシスタントを構築するチュートリアルも含みます。なお、この記事はAIによる翻訳です。誤訳の可能性があればコメント欄でお知らせください。
Created on August 27|Last edited on September 3
Comment
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 を活用して機能を拡張します。これは「エージェント型ワークフローが生産性を高める理由」でも強調されています。これらのツールにより、エージェントは次のことが可能になります。
- 関連データをデータベースにクエリする���
- 詳細なレポートや可視化を生成する。
- リアルタイムで計算を実行したり、ウェブ上の情報を取得したりする。
たとえばコンテンツ制作のワークフローでは、あるエージェントが 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 関数は1回だけ呼び出されるようになりました。これにより、実行時間だけでなく各実行で消費するトークン量も削減され、その結果は更新されたトレースに反映されています。
最適化されたワークフローにより、エージェントは不要な計算をやり直すことなく各参考文献の要約生成を進められるようになり、より効率的でスケーラブルなシステムになりました。
改善後のワークフローの概要を、Weave で分かりやすく可視化したものがこちらです。

質問生成を1段階に集約したことで、出力品質を保ったままエージェントの実行コストを大幅に削減できました。Weave のインターフェースは、明確な可視化とコスト内訳により、この最適化の必要性を認識するうえで重要な役割を果たしました。どこでリソースが誤配分されているかを正確に可視化し、問題解決に必要な示唆を提供してくれたのです。この経験は、エージェント型ワークフローにおける多段階プロセスのデバッグと微調整で Weave が持つ価値を改めて裏付けるものになりました。
Weave でコストを可視化して節約する
Weave では、関数ごとのトークン使用量とコストを可視化できる点も、コスト最適化に有用な機能です。詳細な内訳により、エージェントの各コンポーネントが全体コストにどう寄与しているかを把握できました。この機能はエージェント設計の反復に役立ち、最適化が機能面だけでなくコスト面でも効果的であることを保証します。

継続学習のためのフィードバック機構の追加
システムの性能を動的に向上させるため、ユーザーからのフィードバックをシームレスに収集するスクリプトを作成します。このスクリプトは、選定した研究トピックの関連性や品質に関するフィードバックをメールから自動的に監視・取得し、ユーザーが実行可能な入力を簡単に提供できるようにします。
仕組み
- フィードバック検知:このスクリプトは、ユーザーが自分宛てに送ったメールを走査し、「良い」「悪い」などの簡潔なフィードバックを検出します。
- システム動作の調整
- フィードバックが「良い」の場合、直近に選定した論文のタイトルをプロンプトファイルの「good」セクションに追加し、今後は類似トピックが優先されるようにします。
- フィードバックが「悪い」の場合は、そのタイトルをプロンプトファイルの「bad」セクションに追記し、望ましくないトピックを避けられるようにします。
- 意思決定の高度化このフィードバックループにより、システムは変化するユーザーの嗜好に素早く適応し、関連する研究トピックを選定する能力を大幅に高めます。
- Weave 連携 保存された Call 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 リサーチシステムの性能を高めるプロセスを効率化します。ユーザーの受信トレイにアクセスし、自分宛に送信された最新のメールを特定して、「良い」や「悪い」といったフィードバックを検出します。
フィードバックが「良い」の場合は、直近の論文タイトルをプロンプトファイルの優先セクションに追記し、類似トピックを優先できるようにします。逆に「悪い」フィードバックが検出された場合は、そのタイトルをプロンプト内の「ネガティブ例」セクションへ移し、望ましくないテーマを避けられるようにします。さらに、特定の論文を選んだ関数に対応する 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.