@@ -135,15 +135,44 @@ class DataAnalysis(BaseModel):
135135
136136 summary: str = Field(description = " High-level summary of the dataset" )
137137 key_findings: list[str ] = Field(
138- description = " 3-5 key insights discovered from the data"
138+ description = " Key findings discovered from the data" , min_length = 3 , max_length = 5
139139 )
140140 recommendations: list[str ] = Field(
141- description = " Actionable recommendations based on the analysis"
141+ description = " Actionable recommendations based on the findings" ,
142+ min_length = 3 ,
143+ max_length = 5 ,
142144 )
143145 columns_analyzed: list[str ] = Field(
144146 description = " List of columns that were analyzed"
145147 )
146148
149+ def __str__ (self ) -> str :
150+ """ Format the analysis results for clean display."""
151+ findings = " \n " .join(
152+ f " { i} . { finding} " for i, finding in enumerate (self .key_findings, 1 )
153+ )
154+ recommendations = " \n " .join(
155+ f " { i} . { rec} " for i, rec in enumerate (self .recommendations, 1 )
156+ )
157+
158+ return f """
159+ { " =" * 80 }
160+ ANALYSIS RESULTS
161+ { " =" * 80 }
162+
163+ 📋 Summary:
164+ { self .summary}
165+
166+ 🔑 Key Findings:
167+ { findings}
168+
169+ 💡 Recommendations:
170+ { recommendations}
171+
172+ 📊 Columns Analyzed: { " , " .join(self .columns_analyzed)}
173+ { " =" * 80 }
174+ """
175+
147176
148177```
149178
@@ -167,6 +196,8 @@ def create_data_analyst_agent() -> PrefectAgent[pd.DataFrame, DataAnalysis]:
167196 name = " data-analyst-agent" ,
168197 output_type = DataAnalysis,
169198 deps_type = pd.DataFrame,
199+ # Register tools that the agent can use
200+ tools = [calculate_statistics, detect_anomalies, get_column_info],
170201 system_prompt = (
171202 " You are an expert data analyst. Analyze the provided dataset using "
172203 " the available tools. Focus on finding meaningful patterns, anomalies, "
@@ -175,11 +206,6 @@ def create_data_analyst_agent() -> PrefectAgent[pd.DataFrame, DataAnalysis]:
175206 ),
176207 )
177208
178- # Register tools that the agent can use
179- agent.tool(calculate_statistics)
180- agent.tool(detect_anomalies)
181- agent.tool(get_column_info)
182-
183209 # Wrap with PrefectAgent for durable execution with custom retry policy
184210 return PrefectAgent(
185211 agent,
@@ -252,38 +278,14 @@ async def analyze_dataset_with_ai() -> DataAnalysis:
252278 )
253279
254280 # Display results
255- findings = " \n " .join(
256- f " { i} . { finding} " for i, finding in enumerate (result.output.key_findings, 1 )
257- )
258- recommendations = " \n " .join(
259- f " { i} . { rec} " for i, rec in enumerate (result.output.recommendations, 1 )
260- )
261-
262- output = f """
263- { " =" * 80 }
264- ANALYSIS RESULTS
265- { " =" * 80 }
266-
267- 📋 Summary:
268- { result.output.summary}
269-
270- 🔑 Key Findings:
271- { findings}
272-
273- 💡 Recommendations:
274- { recommendations}
275-
276- 📊 Columns Analyzed: { " , " .join(result.output.columns_analyzed)}
277- { " =" * 80 }
278- """
279- print (output)
281+ print (result.output)
280282
281283 return result.output
282284
283285
284286```
285287
286- ## Deploy the Flow
288+ ## Serve the Flow
287289
288290To get full durable execution with automatic idempotency, serve the flow to create a deployment.
289291Deployed flows enable Prefect's transactional semantics for agent operations.
@@ -345,7 +347,6 @@ When you serve and trigger this flow, Prefect and `pydantic-ai` work together to
345347 completed tasks are skipped and only failed operations are re-executed. This prevents duplicate API calls and
346348 wasted compute.
347349
348-
349350## Key Takeaways
350351
351352* ** Deploy for Durability** – Use ` flow.serve() ` or ` flow.deploy() ` to unlock automatic idempotency and transactional semantics
0 commit comments