はじめに
これは、このシリーズの最も重要なレッスンです。フレームワークを使用せずに、完全なエージェント ループを最初から実装します。このループを深く理解すると、後でフレームワークを使用するときにエージェントをより効果的にデバッグおよび最適化するのに役立ちます。
1. エージェント ループ — コア アーキテクチャ
class SimpleAgent:
def __init__(self, model="gpt-4o-mini", max_steps=10):
self.client = OpenAI()
self.model = model
self.max_steps = max_steps
self.tools = ToolRegistry()
self.messages = []
self.cost_tracker = CostTracker()
def run(self, user_input: str) -> str:
self.messages = [
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": user_input}
]
for step in range(self.max_steps):
response = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
tools=self.tools.schemas,
)
message = response.choices[0].message
self.messages.append(message)
self.cost_tracker.track(self.model, response.usage)
# No tool calls → final answer
if not message.tool_calls:
return message.content
# Execute tools
for tool_call in message.tool_calls:
result = self.tools.execute(
tool_call.function.name,
json.loads(tool_call.function.arguments)
)
self.messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result),
})
return "Max steps reached without final answer."
2. トークンの予算管理
def trim_messages(messages, max_tokens=100000):
"""Giữ messages trong budget token."""
# Luôn giữ system prompt và user message gần nhất
essential = [messages[0], messages[-1]]
middle = messages[1:-1]
# Xóa messages cũ nhất nếu vượt budget
while estimate_tokens(essential + middle) > max_tokens and middle:
middle.pop(0)
return [essential[0]] + middle + [essential[1]]
3. 停止条件
エージェントは、いつ停止するかを知る必要があります。
- LLM は独自の判断で停止を決定します (追加のツールは呼び出されません)
- 最大歩数に達しました — セーフティネット
- トークンの予算超過 — 予期せぬコストを回避
- エラーしきい値 - ツールの連続失敗が多すぎる
- ユーザー割り込み — 人間参加型
概要
- エージェントループ = while ループは LLM を呼び出します → ツール呼び出しをチェック → 実行 → 繰り返します
- トークンの予算管理により、エージェントの「暴走」を防止します
- 安全のための複数の停止条件
- デバッグのための各ステップのログ記録
演習
- 5 つ以上のツールを備えた SimpleAgent クラスを実装する
- トークン予算管理の追加
- 会話履歴の永続化を追加(ファイルの保存/読み込み)
- 5 つ以上のステップを必要とする複雑なタスクでテストする