55import uuid
66from datetime import UTC , datetime
77
8+ from core .model_manager import ModelManager
9+ from core .model_runtime .entities .llm_entities import LLMUsage
10+ from core .model_runtime .entities .model_entities import ModelType
811from core .rag .datasource .vdb .vector_factory import Vector
912from core .rag .index_processor .constant .doc_type import DocType
1013from core .rag .models .document import Document
@@ -24,7 +27,7 @@ def generate_summary_for_segment(
2427 segment : DocumentSegment ,
2528 dataset : Dataset ,
2629 summary_index_setting : dict ,
27- ) -> str :
30+ ) -> tuple [ str , LLMUsage ] :
2831 """
2932 Generate summary for a single segment.
3033
@@ -34,7 +37,7 @@ def generate_summary_for_segment(
3437 summary_index_setting: Summary index configuration
3538
3639 Returns:
37- Generated summary text
40+ Tuple of (summary_content, llm_usage) where llm_usage is LLMUsage object
3841
3942 Raises:
4043 ValueError: If summary_index_setting is invalid or generation fails
@@ -43,7 +46,7 @@ def generate_summary_for_segment(
4346 # Use lazy import to avoid circular import
4447 from core .rag .index_processor .processor .paragraph_index_processor import ParagraphIndexProcessor
4548
46- summary_content = ParagraphIndexProcessor .generate_summary (
49+ summary_content , usage = ParagraphIndexProcessor .generate_summary (
4750 tenant_id = dataset .tenant_id ,
4851 text = segment .content ,
4952 summary_index_setting = summary_index_setting ,
@@ -53,7 +56,7 @@ def generate_summary_for_segment(
5356 if not summary_content :
5457 raise ValueError ("Generated summary is empty" )
5558
56- return summary_content
59+ return summary_content , usage
5760
5861 @staticmethod
5962 def create_summary_record (
@@ -153,6 +156,22 @@ def vectorize_summary(
153156 str (e ),
154157 )
155158
159+ # Calculate embedding tokens for summary (for logging and statistics)
160+ embedding_tokens = 0
161+ try :
162+ model_manager = ModelManager ()
163+ embedding_model = model_manager .get_model_instance (
164+ tenant_id = dataset .tenant_id ,
165+ provider = dataset .embedding_model_provider ,
166+ model_type = ModelType .TEXT_EMBEDDING ,
167+ model = dataset .embedding_model ,
168+ )
169+ if embedding_model :
170+ tokens_list = embedding_model .get_text_embedding_num_tokens ([summary_record .summary_content ])
171+ embedding_tokens = tokens_list [0 ] if tokens_list else 0
172+ except Exception as e :
173+ logger .warning ("Failed to calculate embedding tokens for summary: %s" , str (e ))
174+
156175 # Create document with summary content and metadata
157176 summary_document = Document (
158177 page_content = summary_record .summary_content ,
@@ -179,9 +198,18 @@ def vectorize_summary(
179198 # we still want to re-vectorize (upsert will overwrite)
180199 vector .add_texts ([summary_document ], duplicate_check = False )
181200
201+ # Log embedding token usage
202+ if embedding_tokens > 0 :
203+ logger .info (
204+ "Summary embedding for segment %s used %s tokens" ,
205+ segment .id ,
206+ embedding_tokens ,
207+ )
208+
182209 # Success - update summary record with index node info
183210 summary_record .summary_index_node_id = summary_index_node_id
184211 summary_record .summary_index_node_hash = summary_hash
212+ summary_record .tokens = embedding_tokens # Save embedding tokens
185213 summary_record .status = "completed"
186214 # Explicitly update updated_at to ensure it's refreshed even if other fields haven't changed
187215 summary_record .updated_at = datetime .now (UTC ).replace (tzinfo = None )
@@ -364,14 +392,24 @@ def generate_and_vectorize_summary(
364392 db .session .add (summary_record )
365393 db .session .flush ()
366394
367- # Generate summary
368- summary_content = SummaryIndexService .generate_summary_for_segment (
395+ # Generate summary (returns summary_content and llm_usage)
396+ summary_content , llm_usage = SummaryIndexService .generate_summary_for_segment (
369397 segment , dataset , summary_index_setting
370398 )
371399
372400 # Update summary content
373401 summary_record .summary_content = summary_content
374402
403+ # Log LLM usage for summary generation
404+ if llm_usage and llm_usage .total_tokens > 0 :
405+ logger .info (
406+ "Summary generation for segment %s used %s tokens (prompt: %s, completion: %s)" ,
407+ segment .id ,
408+ llm_usage .total_tokens ,
409+ llm_usage .prompt_tokens ,
410+ llm_usage .completion_tokens ,
411+ )
412+
375413 # Vectorize summary (will delete old vector if exists before creating new one)
376414 SummaryIndexService .vectorize_summary (summary_record , segment , dataset )
377415
0 commit comments