Coverage for src/refinire/agents/gen_agent.py: 100%
57 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-15 18:51 +0900
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-15 18:51 +0900
1from __future__ import annotations
3"""GenAgent — Modern LLMPipeline-based Step for Flow workflows.
5GenAgentはLLMPipelineをStepとして使用するためのモダンなクラスです。
6生成、評価、リトライ機能をFlow/Stepアーキテクチャ内で提供します。
7"""
9import warnings
10from typing import Any, Callable, List, Dict, Optional, Type
12from .flow.step import Step
13from .flow.context import Context
14from .pipeline.llm_pipeline import LLMPipeline, LLMResult
17# GenAgent implementation using LLMPipeline
18# LLMPipelineを使用するGenAgent実装
20class GenAgent(Step):
21 """
22 Modern Step implementation using LLMPipeline instead of deprecated AgentPipeline
23 非推奨のAgentPipelineに代わってLLMPipelineを使用するモダンなStep実装
25 This class provides generation, evaluation, and retry capabilities within Flow workflows
26 without depending on the deprecated AgentPipeline.
27 このクラスは非推奨のAgentPipelineに依存することなく、Flowワークフロー内で
28 生成、評価、リトライ機能を提供します。
29 """
31 def __init__(
32 self,
33 name: str,
34 generation_instructions: str,
35 evaluation_instructions: Optional[str] = None,
36 *,
37 output_model: Optional[Type[Any]] = None,
38 model: str = "gpt-4o-mini",
39 evaluation_model: Optional[str] = None,
40 temperature: float = 0.7,
41 max_tokens: Optional[int] = None,
42 timeout: float = 30.0,
43 threshold: float = 85.0,
44 max_retries: int = 3,
45 input_guardrails: Optional[List[Callable[[str], bool]]] = None,
46 output_guardrails: Optional[List[Callable[[Any], bool]]] = None,
47 session_history: Optional[List[str]] = None,
48 history_size: int = 10,
49 improvement_callback: Optional[Callable[[LLMResult, Any], str]] = None,
50 locale: str = "en",
51 next_step: Optional[str] = None,
52 store_result_key: Optional[str] = None,
53 tools: Optional[List[Dict]] = None,
54 mcp_servers: Optional[List[str]] = None,
55 ) -> None:
56 """
57 Initialize GenAgent with LLMPipeline configuration
58 LLMPipeline設定でGenAgentを初期化する
60 Args:
61 name: Step name / ステップ名
62 generation_instructions: System prompt for generation / 生成用システムプロンプト
63 evaluation_instructions: System prompt for evaluation / 評価用システムプロンプト
64 output_model: Pydantic model for structured output / 構造化出力用Pydanticモデル
65 model: LLM model name / LLMモデル名
66 evaluation_model: Optional LLM model name for evaluation / 評価用LLMモデル名(任意)
67 temperature: Sampling temperature / サンプリング温度
68 max_tokens: Maximum tokens / 最大トークン数
69 timeout: Request timeout / リクエストタイムアウト
70 threshold: Evaluation score threshold / 評価スコア閾値
71 max_retries: Number of retry attempts / リトライ試行回数
72 input_guardrails: Input validation functions / 入力検証関数
73 output_guardrails: Output validation functions / 出力検証関数
74 session_history: Session history / セッション履歴
75 history_size: Size of history to keep / 保持する履歴サイズ
76 improvement_callback: Callback for improvement suggestions / 改善提案用コールバック
77 locale: Language code for localized messages / ローカライズメッセージ用言語コード
78 next_step: Next step after pipeline execution / パイプライン実行後の次ステップ
79 store_result_key: Key to store result in context shared_state / コンテキスト共有状態に結果を格納するキー
80 """
81 # Initialize Step base class
82 # Step基底クラスを初期化
83 super().__init__(name)
85 # Store flow-specific configuration
86 # フロー固有の設定を保存
87 self.next_step = next_step
88 self.store_result_key = store_result_key or f"{name}_result"
90 # Create internal LLMPipeline instance
91 # 内部LLMPipelineインスタンスを作成
92 self.llm_pipeline = LLMPipeline(
93 name=f"{name}_pipeline",
94 generation_instructions=generation_instructions,
95 evaluation_instructions=evaluation_instructions,
96 output_model=output_model,
97 model=model,
98 evaluation_model=evaluation_model,
99 temperature=temperature,
100 max_tokens=max_tokens,
101 timeout=timeout,
102 threshold=threshold,
103 max_retries=max_retries,
104 input_guardrails=input_guardrails,
105 output_guardrails=output_guardrails,
106 session_history=session_history,
107 history_size=history_size,
108 improvement_callback=improvement_callback,
109 locale=locale,
110 tools=tools,
111 mcp_servers=mcp_servers,
112 )
114 async def run(self, user_input: Optional[str], ctx: Context) -> Context:
115 """
116 Execute GenAgent step using LLMPipeline
117 LLMPipelineを使用してGenAgentステップを実行する
119 Args:
120 user_input: User input for the pipeline / パイプライン用ユーザー入力
121 ctx: Current workflow context / 現在のワークフローコンテキスト
123 Returns:
124 Context: Updated context with pipeline results / パイプライン結果付き更新済みコンテキスト
125 """
126 # English: Update step information in context
127 # 日本語: コンテキストのステップ情報を更新
128 ctx.update_step_info(self.name)
130 try:
131 # English: Determine input text for pipeline
132 # 日本語: パイプライン用入力テキストを決定
133 input_text = user_input or ctx.last_user_input or ""
135 if not input_text:
136 # English: If no input available, add system message and continue
137 # 日本語: 入力がない場合、システムメッセージを追加して続行
138 ctx.add_system_message(f"GenAgent {self.name}: No input available, skipping pipeline execution")
139 result = None
140 else:
141 # English: Execute LLMPipeline synchronously (no async issues)
142 # 日本語: LLMPipelineを同期的に実行(非同期問題なし)
143 llm_result = self.llm_pipeline.run(input_text)
144 result = llm_result.content if llm_result.success else None
146 # English: Store result in context
147 # 日本語: 結果をコンテキストに保存
148 if result is not None:
149 # English: Store in shared state for other steps to access
150 # 日本語: 他のステップがアクセスできるよう共有状態に保存
151 ctx.shared_state[self.store_result_key] = result
152 ctx.prev_outputs[self.name] = result
154 # English: Add result as assistant message
155 # 日本語: 結果をアシスタントメッセージとして追加
156 ctx.add_assistant_message(str(result))
158 # English: Add success system message
159 # 日本語: 成功システムメッセージを追加
160 ctx.add_system_message(f"GenAgent {self.name}: Pipeline executed successfully")
161 else:
162 # English: Handle case where pipeline returned None (evaluation failed)
163 # 日本語: パイプラインがNoneを返した場合(評価失敗)を処理
164 ctx.shared_state[self.store_result_key] = None
165 ctx.prev_outputs[self.name] = None
167 # English: Add failure system message
168 # 日本語: 失敗システムメッセージを追加
169 ctx.add_system_message(f"GenAgent {self.name}: Pipeline execution failed (evaluation threshold not met)")
171 except Exception as e:
172 # English: Handle execution errors
173 # 日本語: 実行エラーを処理
174 error_msg = f"GenAgent {self.name} execution error: {str(e)}"
175 ctx.add_system_message(error_msg)
176 ctx.shared_state[self.store_result_key] = None
177 ctx.prev_outputs[self.name] = None
179 # English: Log error for debugging
180 # 日本語: デバッグ用エラーログ
181 print(f"🚨 {error_msg}")
183 # English: Set next step if specified
184 # 日本語: 指定されている場合は次ステップを設定
185 if self.next_step:
186 ctx.goto(self.next_step)
188 return ctx
190 def get_pipeline_history(self) -> List[Dict[str, Any]]:
191 """
192 Get the internal pipeline history
193 内部パイプライン履歴を取得する
195 Returns:
196 List[Dict[str, Any]]: Pipeline history / パイプライン履歴
197 """
198 return self.llm_pipeline.get_history()
200 def get_session_history(self) -> Optional[List[str]]:
201 """
202 Get the session history
203 セッション履歴を取得する
205 Returns:
206 Optional[List[str]]: Session history / セッション履歴
207 """
208 return self.llm_pipeline.session_history
210 def update_instructions(
211 self,
212 generation_instructions: Optional[str] = None,
213 evaluation_instructions: Optional[str] = None
214 ) -> None:
215 """
216 Update pipeline instructions
217 パイプライン指示を更新する
219 Args:
220 generation_instructions: New generation instructions / 新しい生成指示
221 evaluation_instructions: New evaluation instructions / 新しい評価指示
222 """
223 self.llm_pipeline.update_instructions(generation_instructions, evaluation_instructions)
225 def clear_history(self) -> None:
226 """
227 Clear pipeline history
228 パイプライン履歴をクリア
229 """
230 self.llm_pipeline.clear_history()
232 def set_threshold(self, threshold: float) -> None:
233 """
234 Update evaluation threshold
235 評価閾値を更新する
237 Args:
238 threshold: New threshold value (0-100) / 新しい閾値(0-100)
239 """
240 self.llm_pipeline.set_threshold(threshold)
242 def __str__(self) -> str:
243 return f"GenAgent({self.name}, model={self.llm_pipeline.model})"
245 def __repr__(self) -> str:
246 return self.__str__()
249# Modern utility functions for creating GenAgent with common configurations
250# モダンなGenAgent作成用ユーティリティ関数
252def create_simple_gen_agent(
253 name: str,
254 instructions: str,
255 model: str = "gpt-4o-mini",
256 next_step: Optional[str] = None,
257 threshold: float = 85.0,
258 retries: int = 3,
259 tools: Optional[List[Dict]] = None,
260 mcp_servers: Optional[List[str]] = None
261) -> GenAgent:
262 """
263 Create a simple GenAgent with basic configuration
264 基本設定でシンプルなGenAgentを作成
266 Args:
267 name: Agent name / エージェント名
268 instructions: Generation instructions / 生成指示
269 model: LLM model name / LLMモデル名
270 next_step: Next step name / 次ステップ名
271 threshold: Evaluation threshold / 評価閾値
272 retries: Retry attempts / リトライ回数
273 tools: OpenAI function tools / OpenAI関数ツール
274 mcp_servers: MCP server identifiers / MCPサーバー識別子
276 Returns:
277 GenAgent: Configured agent / 設定済みエージェント
278 """
279 return GenAgent(
280 name=name,
281 generation_instructions=instructions,
282 model=model,
283 next_step=next_step,
284 threshold=threshold,
285 max_retries=retries,
286 tools=tools,
287 mcp_servers=mcp_servers
288 )
291def create_evaluated_gen_agent(
292 name: str,
293 generation_instructions: str,
294 evaluation_instructions: str,
295 model: str = "gpt-4o-mini",
296 evaluation_model: Optional[str] = None,
297 next_step: Optional[str] = None,
298 threshold: float = 85.0,
299 retries: int = 3,
300 tools: Optional[List[Dict]] = None,
301 mcp_servers: Optional[List[str]] = None
302) -> GenAgent:
303 """
304 Create a GenAgent with evaluation capabilities
305 評価機能付きGenAgentを作成
307 Args:
308 name: Agent name / エージェント名
309 generation_instructions: Generation instructions / 生成指示
310 evaluation_instructions: Evaluation instructions / 評価指示
311 model: LLM model name / LLMモデル名
312 evaluation_model: Evaluation model name / 評価モデル名
313 next_step: Next step name / 次ステップ名
314 threshold: Evaluation threshold / 評価閾値
315 retries: Retry attempts / リトライ回数
317 Returns:
318 GenAgent: Configured agent with evaluation / 評価機能付き設定済みエージェント
319 """
320 return GenAgent(
321 name=name,
322 generation_instructions=generation_instructions,
323 evaluation_instructions=evaluation_instructions,
324 model=model,
325 evaluation_model=evaluation_model,
326 next_step=next_step,
327 threshold=threshold,
328 max_retries=retries,
329 tools=tools,
330 mcp_servers=mcp_servers
331 )