wu981526092 commited on
Commit
f779b69
·
1 Parent(s): 911b955
agentgraph/methods/production/openai_structured_extractor.py CHANGED
@@ -255,9 +255,9 @@ TRACE DATA:
255
  {input_data}"""
256
 
257
  try:
258
- response = self.client.beta.chat.completions.parse(
259
  model=self.model,
260
- messages=[
261
  {"role": "system", "content": system_prompt},
262
  {"role": "user", "content": user_prompt}
263
  ],
@@ -266,10 +266,10 @@ TRACE DATA:
266
 
267
  # Get the parsed response with reasoning steps
268
  logger.info("Parsing OpenAI response...")
269
- reasoning_result = response.choices[0].message.parsed
270
  logger.info(f"Response parsed successfully. Type: {type(reasoning_result)}")
271
 
272
- knowledge_graph = reasoning_result.final_answer
273
  logger.info(f"Knowledge graph extracted. Type: {type(knowledge_graph)}")
274
 
275
  # Save reasoning steps and knowledge graph for analysis
@@ -279,7 +279,7 @@ TRACE DATA:
279
 
280
  # Log reasoning steps for debugging
281
  logger.info("CoT Reasoning Steps:")
282
- for step in reasoning_result.steps:
283
  logger.info(f"Step: {step.explanation}")
284
 
285
  logger.info(f"Extraction complete: {len(knowledge_graph.entities)} entities, {len(knowledge_graph.relations)} relations")
@@ -309,11 +309,11 @@ TRACE DATA:
309
 
310
  # Prepare data to save using model_dump for safe serialization
311
  logger.info("Serializing reasoning steps...")
312
- reasoning_steps_data = [step.model_dump() for step in reasoning_result.steps]
313
  logger.info(f"Reasoning steps serialized: {len(reasoning_steps_data)} steps")
314
 
315
  logger.info("Serializing knowledge graph...")
316
- kg_data = reasoning_result.final_answer.model_dump()
317
  logger.info(f"Knowledge graph serialized: {kg_data.get('system_name', 'Unknown')}")
318
 
319
  save_data = {
 
255
  {input_data}"""
256
 
257
  try:
258
+ response = self.responses.parse(
259
  model=self.model,
260
+ input=[
261
  {"role": "system", "content": system_prompt},
262
  {"role": "user", "content": user_prompt}
263
  ],
 
266
 
267
  # Get the parsed response with reasoning steps
268
  logger.info("Parsing OpenAI response...")
269
+ reasoning_result = response.output_parsed
270
  logger.info(f"Response parsed successfully. Type: {type(reasoning_result)}")
271
 
272
+ knowledge_graph = reasoning_result["final_answer"]
273
  logger.info(f"Knowledge graph extracted. Type: {type(knowledge_graph)}")
274
 
275
  # Save reasoning steps and knowledge graph for analysis
 
279
 
280
  # Log reasoning steps for debugging
281
  logger.info("CoT Reasoning Steps:")
282
+ for step in reasoning_result["steps"]:
283
  logger.info(f"Step: {step.explanation}")
284
 
285
  logger.info(f"Extraction complete: {len(knowledge_graph.entities)} entities, {len(knowledge_graph.relations)} relations")
 
309
 
310
  # Prepare data to save using model_dump for safe serialization
311
  logger.info("Serializing reasoning steps...")
312
+ reasoning_steps_data = [step.model_dump() for step in reasoning_result["steps"]]
313
  logger.info(f"Reasoning steps serialized: {len(reasoning_steps_data)} steps")
314
 
315
  logger.info("Serializing knowledge graph...")
316
+ kg_data = reasoning_result['final_answer'].model_dump()
317
  logger.info(f"Knowledge graph serialized: {kg_data.get('system_name', 'Unknown')}")
318
 
319
  save_data = {
agentgraph/methods/production/openai_structured_extractor_backup_20250907_161109.py DELETED
@@ -1,548 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- OpenAI Structured Outputs Knowledge Extractor
4
-
5
- A simple, direct approach using OpenAI's structured outputs API to extract
6
- knowledge graphs in one step using Pydantic models.
7
- """
8
-
9
- import os
10
- import json
11
- import logging
12
- from typing import Optional, List, Dict, Any
13
- import uuid
14
- from datetime import datetime
15
- from dotenv import load_dotenv
16
- from openai import OpenAI
17
- from pydantic import BaseModel
18
-
19
- # Import Pydantic models
20
- from agentgraph.shared.models.reference_based import KnowledgeGraph, Entity, Relation, ContentReference
21
-
22
- # CoT reasoning models
23
- class Step(BaseModel):
24
- explanation: str
25
- output: str
26
-
27
- class KnowledgeGraphReasoning(BaseModel):
28
- steps: List[Step]
29
- final_answer: KnowledgeGraph
30
-
31
- # Load environment variables from root directory
32
- load_dotenv('/Users/zekunwu/Desktop/agent_monitoring/.env')
33
-
34
- # Configure logging
35
- logger = logging.getLogger(__name__)
36
-
37
-
38
- class OpenAIStructuredExtractor:
39
- """
40
- Simple knowledge graph extractor using OpenAI's structured outputs.
41
- """
42
-
43
- def __init__(self, model: str = "gpt-5-mini"):
44
- """
45
- Initialize the extractor.
46
-
47
- Args:
48
- model: OpenAI model to use (must support structured outputs)
49
- """
50
- self.model = model
51
- self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
52
- logger.info(f"OpenAI Structured Extractor initialized with model: {model}")
53
-
54
- def extract_knowledge_graph(self, input_data: str, context_documents: Optional[List[Dict[str, Any]]] = None) -> KnowledgeGraph:
55
- """
56
- Extract knowledge graph from input data using OpenAI structured outputs.
57
-
58
- Args:
59
- input_data: The trace data to analyze
60
- context_documents: Optional context documents (unused in this simple version)
61
-
62
- Returns:
63
- KnowledgeGraph: Extracted knowledge graph
64
- """
65
- logger.info(f"Starting knowledge graph extraction for {len(input_data)} characters of input")
66
-
67
- # System prompt - focus on your role and methodology
68
- system_prompt = """You are an expert knowledge graph analyst specializing in agent system traces.
69
-
70
- Extract comprehensive knowledge graphs capturing all entities and their precise relationships. Focus on workflow accuracy and relationship completeness.
71
-
72
- CORE PRINCIPLES:
73
- 1. Capture ALL participants: agents, tools, tasks, inputs, outputs, humans
74
- 2. Use professional naming (spaces, not underscores)
75
- 3. Map complete workflows: Input → Agents perform Tasks → Output → Human
76
- 4. Focus on MAIN workflow tasks (avoid over-decomposition into subtasks)
77
- 5. Use NEXT only for clear sequential task dependencies
78
- 6. Use REQUIRED_BY for essential tool dependencies (not USES for general support)
79
- 7. Identify failures: errors, mistakes, broken processes, incorrect outputs
80
- 8. Suggest optimizations: improvements, efficiency gains, better approaches
81
-
82
- ID ASSIGNMENT GUIDELINES:
83
- - Use sequential numbering starting from 001 for each entity type
84
- - agent_001, agent_002, agent_003... (in order of appearance/importance)
85
- - task_001, task_002, task_003... (in workflow order)
86
- - input_001, output_001, human_001 (typically one of each)
87
- - tool_001 for Computer Terminal or similar tools
88
- - Assign based on trace content, not predetermined roles
89
-
90
- RELATIONSHIP TYPES (use exactly these):
91
- - CONSUMED_BY: Input consumed by agent (input_001 → agent_001)
92
- - PERFORMS: Agent performs task (agent_001 → task_001)
93
- - NEXT: Task A leads to Task B in sequence (task_001 → task_002)
94
- - PRODUCES: Task produces output (task_001 → output_001)
95
- - DELIVERS_TO: Output delivered to human (output_001 → human_001)
96
- - REQUIRED_BY: Tool required by task (agent_004 → task_001)
97
- - USES: Agent uses tool (agent_001 → agent_004)
98
- - ASSIGNED_TO: Task assigned to agent (task_001 → agent_002)
99
- - INTERVENES: Agent coordinates task (agent_002 → task_001)
100
-
101
- Return complete, accurate knowledge graphs with proper workflow sequences."""
102
-
103
- # User prompt - specific instructions with few-shot example and data
104
- user_prompt = f"""Analyze this agent system trace step by step and extract a knowledge graph.
105
-
106
- Think through this systematically. Use as many reasoning steps as needed to thoroughly analyze the trace.
107
- Each step should have a clear explanation and specific output findings.
108
-
109
- IMPORTANT FORMATTING RULES:
110
- - Set raw_prompt to empty string "" for ALL entities (content should only be in raw_prompt_ref)
111
- - Set interaction_prompt to empty string "" for ALL relations (content should only be in interaction_prompt_ref)
112
- - Use only line number references in raw_prompt_ref and interaction_prompt_ref, never include actual text content
113
- - Determine your own number of reasoning steps based on trace complexity
114
-
115
- EXAMPLE OUTPUT STRUCTURE:
116
- Here's the expected knowledge graph structure for multi-agent collaboration traces:
117
- {{
118
- "system_name": "California Great America Ticket Analysis System",
119
- "system_summary": "This system helps analyze the cost-saving potential of purchasing season passes versus individual daily tickets at California's Great America in San Jose. The process starts with an inquiry regarding savings from the Inquiry about Savings from Season Pass vs Daily Tickets (input_001), which is consumed by the Verification Expert (agent_002), who performs the Verify Cost of Daily Ticket and Season Pass in 2024 (task_001).",
120
- "entities": [
121
- {{
122
- "id": "agent_001",
123
- "type": "Agent",
124
- "name": "Problem Solving Expert",
125
- "importance": "HIGH",
126
- "raw_prompt": "",
127
- "raw_prompt_ref": [{{"line_start": 17, "line_end": 17}}, {{"line_start": 34, "line_end": 34}}, {{"line_start": 45, "line_end": 45}}]
128
- }},
129
- {{
130
- "id": "agent_002",
131
- "type": "Agent",
132
- "name": "Verification Expert",
133
- "importance": "HIGH",
134
- "raw_prompt": "",
135
- "raw_prompt_ref": [{{"line_start": 66, "line_end": 66}}, {{"line_start": 112, "line_end": 112}}, {{"line_start": 149, "line_end": 149}}, {{"line_start": 164, "line_end": 164}}]
136
- }},
137
- {{
138
- "id": "agent_003",
139
- "type": "Agent",
140
- "name": "Arithmetic Progressions Expert",
141
- "importance": "MEDIUM",
142
- "raw_prompt": "",
143
- "raw_prompt_ref": [{{"line_start": 172, "line_end": 172}}, {{"line_start": 181, "line_end": 181}}]
144
- }},
145
- {{
146
- "id": "agent_004",
147
- "type": "Tool",
148
- "name": "Computer Terminal",
149
- "importance": "LOW",
150
- "raw_prompt": "",
151
- "raw_prompt_ref": [{{"line_start": 21, "line_end": 21}}, {{"line_start": 32, "line_end": 32}}]
152
- }},
153
- {{
154
- "id": "task_001",
155
- "type": "Task",
156
- "name": "Verify Cost of Daily Ticket and Season Pass in 2024",
157
- "importance": "HIGH",
158
- "raw_prompt": "",
159
- "raw_prompt_ref": [{{"line_start": 8, "line_end": 8}}, {{"line_start": 10, "line_end": 10}}, {{"line_start": 11, "line_end": 12}}]
160
- }},
161
- {{
162
- "id": "task_002",
163
- "type": "Task",
164
- "name": "Calculate Savings Amount",
165
- "importance": "HIGH",
166
- "raw_prompt": "",
167
- "raw_prompt_ref": [{{"line_start": 119, "line_end": 126}}]
168
- }},
169
- {{
170
- "id": "input_001",
171
- "type": "Input",
172
- "name": "Inquiry about Savings from Season Pass vs Daily Tickets",
173
- "importance": "HIGH",
174
- "raw_prompt": "",
175
- "raw_prompt_ref": [{{"line_start": 6, "line_end": 6}}]
176
- }},
177
- {{
178
- "id": "output_001",
179
- "type": "Output",
180
- "name": "Saved Amount from Season Pass Purchase",
181
- "importance": "HIGH",
182
- "raw_prompt": "",
183
- "raw_prompt_ref": [{{"line_start": 119, "line_end": 119}}, {{"line_start": 126, "line_end": 126}}]
184
- }},
185
- {{
186
- "id": "human_001",
187
- "type": "Human",
188
- "name": "Park Visitor",
189
- "importance": "HIGH",
190
- "raw_prompt": "",
191
- "raw_prompt_ref": [{{"line_start": 1, "line_end": 1}}]
192
- }}
193
- ],
194
- "relations": [
195
- {{
196
- "id": "relation_001",
197
- "source": "input_001",
198
- "target": "agent_002",
199
- "type": "CONSUMED_BY",
200
- "importance": "HIGH",
201
- "interaction_prompt": "",
202
- "interaction_prompt_ref": [{{"line_start": 6, "line_end": 6}}]
203
- }},
204
- {{
205
- "id": "relation_002",
206
- "source": "agent_002",
207
- "target": "task_001",
208
- "type": "PERFORMS",
209
- "importance": "HIGH",
210
- "interaction_prompt": "",
211
- "interaction_prompt_ref": [{{"line_start": 112, "line_end": 112}}, {{"line_start": 164, "line_end": 164}}]
212
- }},
213
- {{
214
- "id": "relation_003",
215
- "source": "task_001",
216
- "target": "agent_002",
217
- "type": "ASSIGNED_TO",
218
- "importance": "HIGH",
219
- "interaction_prompt": "",
220
- "interaction_prompt_ref": [{{"line_start": 8, "line_end": 8}}]
221
- }},
222
- {{
223
- "id": "relation_004",
224
- "source": "task_001",
225
- "target": "output_001",
226
- "type": "PRODUCES",
227
- "importance": "HIGH",
228
- "interaction_prompt": "",
229
- "interaction_prompt_ref": [{{"line_start": 119, "line_end": 119}}]
230
- }},
231
- {{
232
- "id": "relation_005",
233
- "source": "output_001",
234
- "target": "human_001",
235
- "type": "DELIVERS_TO",
236
- "importance": "HIGH",
237
- "interaction_prompt": "",
238
- "interaction_prompt_ref": [{{"line_start": 126, "line_end": 126}}]
239
- }},
240
- {{
241
- "id": "relation_006",
242
- "source": "task_001",
243
- "target": "task_002",
244
- "type": "NEXT",
245
- "importance": "HIGH",
246
- "interaction_prompt": "",
247
- "interaction_prompt_ref": [{{"line_start": 164, "line_end": 164}}]
248
- }},
249
- {{
250
- "id": "relation_007",
251
- "source": "task_002",
252
- "target": "agent_004",
253
- "type": "REQUIRED_BY",
254
- "importance": "MEDIUM",
255
- "interaction_prompt": "",
256
- "interaction_prompt_ref": [{{"line_start": 50, "line_end": 55}}]
257
- }}
258
- ],
259
- "failures": [
260
- {{
261
- "id": "failure_001",
262
- "description": "Verification Expert failed to access real-time pricing data, relying on potentially outdated cost estimates",
263
- "raw_text": "However, since I am currently unable to access external websites, I will use the provided cost",
264
- "raw_text_ref": [],
265
- "affected_id": "agent_002",
266
- "risk_type": "RETRIEVAL_ERROR"
267
- }}
268
- ],
269
- "optimizations": [
270
- {{
271
- "id": "opt_001",
272
- "description": "Implement automated price verification system to reduce manual verification overhead and improve accuracy",
273
- "raw_text": "Enhanced price verification with real-time data access",
274
- "raw_text_ref": [],
275
- "affected_ids": ["agent_002", "task_001"],
276
- "recommendation_type": "TOOL_ENHANCEMENT"
277
- }}
278
- ]
279
- }}
280
-
281
- Now analyze the following trace data:
282
-
283
- ENTITY TYPES:
284
- - Agent: AI agents with specific roles
285
- - Task: Specific tasks or objectives
286
- - Tool: Tools or functions used
287
- - Input: Data inputs to the system
288
- - Output: Data outputs from the system
289
- - Human: Human users or stakeholders
290
-
291
- RELATIONSHIP TYPES:
292
- - CONSUMED_BY: Input→Agent
293
- - PERFORMS: Agent→Task
294
- - ASSIGNED_TO: Task→Agent
295
- - USES: Agent→Tool
296
- - REQUIRED_BY: Tool→Task
297
- - SUBTASK_OF: Task→Task
298
- - NEXT: Task→Task (sequence)
299
- - PRODUCES: Task→Output
300
- - DELIVERS_TO: Output→Human
301
- - INTERVENES: Agent/Human→Task
302
-
303
- REQUIREMENTS:
304
- For each entity provide:
305
- - id: unique identifier
306
- - type: one of the types above
307
- - name: descriptive name
308
- - importance: HIGH, MEDIUM, or LOW
309
- - raw_prompt: actual prompt/specification content that defines this entity
310
- - raw_prompt_ref: list of content references pointing to relevant lines in the input trace where this entity is mentioned or defined
311
-
312
- For each relation provide:
313
- - id: unique identifier
314
- - source/target: entity IDs
315
- - type: one of the types above
316
- - importance: HIGH, MEDIUM, or LOW
317
- - interaction_prompt: runtime evidence showing this relationship occurred
318
- - interaction_prompt_ref: list of content references pointing to relevant lines in the input trace where this relationship evidence is found
319
-
320
- IMPORTANT: Create appropriate line number references based on where entities and relationships are mentioned in the trace. Use reasonable line estimates for JSON structure.
321
-
322
- Also provide system_name and system_summary for the overall system.
323
-
324
- EXTRACTION FOCUS:
325
- 1. Identify MAIN participants: primary agents, core tasks, key inputs/outputs, humans
326
- 2. Focus on the PRIMARY workflow (avoid creating too many subtasks)
327
- 3. Connect entities based on ACTUAL interactions in the trace
328
- 4. Use clean professional naming (no underscores)
329
- 5. DETECT FAILURES: Look for errors, exceptions, incorrect results, failed executions
330
- 6. SUGGEST OPTIMIZATIONS: Identify inefficiencies, improvement opportunities
331
-
332
- CRITICAL RELATIONSHIP PATTERNS (follow exactly):
333
- - input_001 --CONSUMED_BY--> agent_002 (main processing agent)
334
- - agent_002 --PERFORMS--> task_001 (primary task execution)
335
- - task_001 --ASSIGNED_TO--> agent_002 (task ownership)
336
- - task_001 --PRODUCES--> output_001 (direct output generation)
337
- - output_001 --DELIVERS_TO--> human_001 (final delivery)
338
- - agent_002 --INTERVENES--> task_001 (coordination/oversight)
339
- - agent_001 --USES--> agent_004 (tool utilization)
340
-
341
- ENTITY ID RULES:
342
- - agent_001: First mentioned expert, agent_002: Main performer, agent_003: Supporting expert
343
- - agent_004: Always Computer Terminal (tool type)
344
- - task_001: Primary workflow task (avoid creating task_002 unless truly sequential)
345
- - Use exactly these IDs, don't create tool_001 or extra tasks unnecessarily
346
-
347
- FAILURE DETECTION (look for):
348
- - Execution errors, exceptions, failed operations
349
- - Incorrect outputs, wrong calculations, invalid results
350
- - Missing validations, incomplete processes
351
- - Tool limitations, access restrictions
352
- - Agent coordination problems
353
-
354
- OPTIMIZATION OPPORTUNITIES (suggest):
355
- - Tool enhancements, automation possibilities
356
- - Workflow simplifications, redundancy removal
357
- - Agent merging or specialization
358
- - Performance improvements, efficiency gains
359
- - Missing capabilities or better approaches
360
-
361
- IMPORTANT: Always provide at least 1-2 failures and optimizations based on trace analysis.
362
-
363
- TRACE DATA:
364
- {input_data}"""
365
-
366
- try:
367
- response = self.client.responses.parse(
368
- model=self.model,
369
- input=[
370
- {"role": "system", "content": system_prompt},
371
- {"role": "user", "content": user_prompt}
372
- ],
373
- text_format=KnowledgeGraphReasoning,
374
- )
375
-
376
- # Get the parsed response with reasoning steps
377
- logger.info("Parsing OpenAI response...")
378
- reasoning_result = response.output_parsed
379
- logger.info(f"Response parsed successfully. Type: {type(reasoning_result)}")
380
-
381
- knowledge_graph = reasoning_result.final_answer
382
- logger.info(f"Knowledge graph extracted. Type: {type(knowledge_graph)}")
383
-
384
- # Save reasoning steps and knowledge graph for analysis
385
- logger.info("About to save extraction results...")
386
- self._save_extraction_results(reasoning_result, input_data)
387
- logger.info("Save extraction results completed.")
388
-
389
- # Log reasoning steps for debugging
390
- logger.info("CoT Reasoning Steps:")
391
- for step in reasoning_result.steps:
392
- logger.info(f"Step: {step.explanation}")
393
-
394
- logger.info(f"Extraction complete: {len(knowledge_graph.entities)} entities, {len(knowledge_graph.relations)} relations")
395
- return knowledge_graph
396
-
397
- except Exception as e:
398
- logger.error(f"Extraction failed: {e}")
399
- raise
400
-
401
- def _save_extraction_results(self, reasoning_result, trace_text: str):
402
- """Save reasoning steps and knowledge graph for analysis"""
403
- try:
404
- logger.info("Starting to save extraction results...")
405
-
406
- # Create results directory if it doesn't exist
407
- results_dir = "extraction_analysis"
408
- os.makedirs(results_dir, exist_ok=True)
409
- logger.info(f"Results directory ready: {results_dir}")
410
-
411
- # Generate timestamp and unique ID
412
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
413
- extraction_id = str(uuid.uuid4())[:8]
414
- filename = f"cot_extraction_{timestamp}_{extraction_id}.json"
415
- logger.info(f"Generated filename: {filename}")
416
-
417
- # Prepare data to save using model_dump for safe serialization
418
- logger.info("Serializing reasoning steps...")
419
- reasoning_steps_data = [step.model_dump() for step in reasoning_result.steps]
420
- logger.info(f"Reasoning steps serialized: {len(reasoning_steps_data)} steps")
421
-
422
- logger.info("Serializing knowledge graph...")
423
- kg_data = reasoning_result.final_answer.model_dump()
424
- logger.info(f"Knowledge graph serialized: {kg_data.get('system_name', 'Unknown')}")
425
-
426
- save_data = {
427
- "timestamp": timestamp,
428
- "extraction_id": extraction_id,
429
- "model": self.model,
430
- "reasoning_steps": reasoning_steps_data,
431
- "knowledge_graph": kg_data,
432
- "input_trace_length": len(trace_text),
433
- "input_trace_preview": trace_text[:500] + "..." if len(trace_text) > 500 else trace_text
434
- }
435
-
436
- # Save to file
437
- filepath = os.path.join(results_dir, filename)
438
- logger.info(f"Writing to file: {filepath}")
439
-
440
- with open(filepath, 'w', encoding='utf-8') as f:
441
- json.dump(save_data, f, indent=2, ensure_ascii=False)
442
-
443
- # Verify file was written
444
- file_size = os.path.getsize(filepath)
445
- logger.info(f"Extraction results saved successfully: {filepath} ({file_size} bytes)")
446
-
447
- except Exception as e:
448
- logger.error(f"Failed to save extraction results: {e}")
449
- import traceback
450
- logger.error(f"Traceback: {traceback.format_exc()}")
451
-
452
- def process_text(self, input_data: str) -> Dict[str, Any]:
453
- """
454
- Process text and return structured response (for compatibility with extraction factory).
455
-
456
- Args:
457
- input_data: The trace data to analyze
458
-
459
- Returns:
460
- Dict with success status and kg_data
461
- """
462
- try:
463
- kg = self.extract_knowledge_graph(input_data)
464
- return {
465
- "success": True,
466
- "kg_data": kg.model_dump()
467
- }
468
- except Exception as e:
469
- return {
470
- "success": False,
471
- "error": str(e),
472
- "kg_data": {}
473
- }
474
-
475
- def extract_knowledge_graph_with_context(
476
- input_data: str,
477
- context_documents: Optional[List[Dict[str, Any]]] = None,
478
- model: str = "gpt-5-mini"
479
- ) -> KnowledgeGraph:
480
- """
481
- Main entry point for knowledge graph extraction.
482
-
483
- Args:
484
- input_data: The trace data to analyze
485
- context_documents: Optional context documents
486
- model: OpenAI model to use
487
-
488
- Returns:
489
- KnowledgeGraph: Extracted knowledge graph
490
- """
491
- extractor = OpenAIStructuredExtractor(model=model)
492
- return extractor.extract_knowledge_graph(input_data, context_documents)
493
-
494
- def extract_knowledge_graph(input_data: str) -> KnowledgeGraph:
495
- """
496
- Simple entry point without context (for backward compatibility).
497
-
498
- Args:
499
- input_data: The trace data to analyze
500
-
501
- Returns:
502
- KnowledgeGraph: Extracted knowledge graph
503
- """
504
- return extract_knowledge_graph_with_context(input_data)
505
-
506
- # Factory class for integration
507
- class OpenAIStructuredFactory:
508
- """Factory class for OpenAI structured extraction method."""
509
-
510
- def __init__(self, model: str = "gpt-5-mini"):
511
- self.model = model
512
- self.extractor = OpenAIStructuredExtractor(model)
513
-
514
- def set_model(self, model: str):
515
- """Set the model for this factory."""
516
- self.model = model
517
- self.extractor = OpenAIStructuredExtractor(model)
518
-
519
- def process_text(self, input_data: str) -> Dict[str, Any]:
520
- """Process text using the extractor."""
521
- return self.extractor.process_text(input_data)
522
-
523
- def extract_knowledge_graph(self, input_data: str, context_documents: Optional[List[Dict[str, Any]]] = None) -> KnowledgeGraph:
524
- """Extract knowledge graph using the current model."""
525
- return self.extractor.extract_knowledge_graph(input_data, context_documents)
526
-
527
- # Export factory instance
528
- openai_structured_factory = OpenAIStructuredFactory()
529
-
530
- if __name__ == "__main__":
531
- # Simple test
532
- test_input = """
533
- Agent: DataAnalyzer
534
- Task: Analyze customer data and generate insights
535
- Tool: pandas_analyzer
536
-
537
- The DataAnalyzer agent processes customer data using pandas_analyzer tool
538
- to generate business insights for the marketing team.
539
- """
540
-
541
- print("Testing OpenAI Structured Extractor...")
542
- try:
543
- kg = extract_knowledge_graph(test_input)
544
- print(f"✅ Success! Extracted {len(kg.entities)} entities and {len(kg.relations)} relations")
545
- print(f"System: {kg.system_name}")
546
- print(f"Summary: {kg.system_summary}")
547
- except Exception as e:
548
- print(f"❌ Error: {e}")