読んだサンプルコード
-
agents_as_tools.py
- OpenAI Agents SDKのCommon agentic patternsのAgents as toolsのサンプル
Agents as toolsとは
- エージェントをツールとして使用すること
- ツールとして呼び出されたエージェントは独立して動作し、結果を元のエージェントに返す
- その結果を次のステップで使用することができる
- Handoffsとの違い
-
Handoffsでは引き継ぎ先のエージェントが過去の会話履歴を参照し、引き継ぎ後の会話のオーナーとなるが、Agents as toolsでは別のエージェントをツールとして呼び出す
- 以下が公式の説明
The mental model for handoffs is that the new agent "takes over". It sees the previous conversation history, and owns the conversation from that point onwards. However, this is not the only way to use agents. You can also use agents as a tool - the tool agent goes off and runs on its own, and then returns the result to the original agent.
For example, you could model the translation task above as tool calls instead: rather than handing over to the language-specific agent, you could call the agent as a tool, and then use the result in the next step. This enables things like translating multiple languages at once.
See the agents_as_tools.py file for an example of this.
(Agents as toolsより)
-
agents_as_tools.py
import asyncio
from agents import Agent, ItemHelpers, MessageOutputItem, Runner, trace
"""
This example shows the agents-as-tools pattern. The frontline agent receives a user message and
then picks which agents to call, as tools. In this case, it picks from a set of translation
agents.
"""
-
import
- 以下については後述
ItemHelpers
MessageOutputItem
- 以下については後述
- docstring
- frontlineのagentがユーザーのメッセージを受け、どのサブagentをツールとして呼び出すかを選択する。このサンプルコードではスペイン語、フランス語、イタリア語のそれぞれのエージェントから選択する。
spanish_agent = Agent(
name="spanish_agent",
instructions="You translate the user's message to Spanish",
handoff_description="An english to spanish translator",
)
french_agent = Agent(
name="french_agent",
instructions="You translate the user's message to French",
handoff_description="An english to french translator",
)
italian_agent = Agent(
name="italian_agent",
instructions="You translate the user's message to Italian",
handoff_description="An english to italian translator",
)
- ツールとして呼び出すサブエージェントのインスタンス生成
- コンストラクタの引数について
-
name
はエージェントの名前 -
instructions
はシステムプロンプト -
handoff_description
については以下の公式説明があるagent.pyhandoff_description: str | None = None """A description of the agent. This is used when the agent is used as a handoff, so that an LLM knows what it does and when to invoke it. """
- この
handoff_description
はhandoffとして使用される際に使われるとのこと。今回はtoolとしての呼び出しなので実際には使用されないものと思われる。
- この
-
- コンストラクタの引数について
orchestrator_agent = Agent(
name="orchestrator_agent",
instructions=(
"You are a translation agent. You use the tools given to you to translate."
"If asked for multiple translations, you call the relevant tools in order."
"You never translate on your own, you always use the provided tools."
),
tools=[
spanish_agent.as_tool(
tool_name="translate_to_spanish",
tool_description="Translate the user's message to Spanish",
),
french_agent.as_tool(
tool_name="translate_to_french",
tool_description="Translate the user's message to French",
),
italian_agent.as_tool(
tool_name="translate_to_italian",
tool_description="Translate the user's message to Italian",
),
],
)
-
orchestrator_agent
の生成 - 各サブエージェントを
as_tool()
メソッドを使用してTool型で登録している
synthesizer_agent = Agent(
name="synthesizer_agent",
instructions="You inspect translations, correct them if needed, and produce a final concatenated response.",
)
-
synthesizer_agent
の生成 - このエージェントは
orchestrator_agent
の会話履歴を受け取り翻訳のチェックを行い、必要であれば修正を行う
async def main():
msg = input("Hi! What would you like translated, and to which languages? ")
- キーボード入力で翻訳元のテキストと翻訳先の言語を受け取る
# Run the entire orchestration in a single trace
with trace("Orchestrator evaluator"):
orchestrator_result = await Runner.run(orchestrator_agent, msg)
for item in orchestrator_result.new_items:
if isinstance(item, MessageOutputItem):
text = ItemHelpers.text_message_output(item)
if text:
print(f" - Translation step: {text}")
- 一連の会話を単一のTrace内に記録する
-
orchestrator_agent
の実行 -
result.new_items
(list[RunItem]
)内のMessageOutputItem
型の要素のみをprint
している-
MessageOutputItem
はRunItemBase
を継承するクラスでLLMからの1件のメッセージを表す -
ItemHelpers.text_message_output()
はMessageOutputItem
型の引数を取りそこからテキストコンテンツを抽出して返す
-
synthesizer_result = await Runner.run(
synthesizer_agent, orchestrator_result.to_input_list()
)
print(f"\n\nFinal response:\n{synthesizer_result.final_output}")
-
synthesizer_agent
の実行 - 先に実行した
orchestrator_agent
の会話履歴をinputとして使っている - このエージェントが翻訳をチェックし、必要であれば修正を行う
- 最終アウトプットを
print
で表示
if __name__ == "__main__":
asyncio.run(main())