CoT API Reference¶
Complete API reference for the Chain of Thought system, including all classes, methods, parameters, and return values.
Core Classes¶
ChainOfThoughtService¶
Main orchestration service for CoT reasoning.
Constructor¶
def __init__(
self,
settings: Settings | None = None,
llm_service: Any = None,
search_service: Any = None,
db: Session | None = None
) -> None
Parameters: - settings: Application settings instance (default: creates new Settings()) - llm_service: LLM service instance for answer generation - search_service: Search service instance for context retrieval - db: Database session for persistence
Methods¶
classify_question(question: str) -> QuestionClassification¶
Analyzes question complexity and determines if CoT is needed.
Parameters: - question (str): User's input question
Returns: - QuestionClassification: Classification result with type, complexity, and CoT recommendation
Example:
classification = await cot_service.classify_question("Compare machine learning and deep learning")
print(f"Type: {classification.question_type}") # "comparison"
print(f"Requires CoT: {classification.requires_cot}") # True
execute_chain_of_thought(cot_input: ChainOfThoughtInput, context_documents: list[str] | None = None) -> ChainOfThoughtOutput¶
Executes the complete CoT reasoning pipeline.
Parameters: - cot_input (ChainOfThoughtInput): Input configuration and question - context_documents (list[str] | None): Optional context documents
Returns: - ChainOfThoughtOutput: Complete reasoning results
Raises: - ValidationError: Invalid input configuration - LLMProviderError: LLM service failures - TimeoutError: Execution timeout exceeded
Example:
cot_input = ChainOfThoughtInput(
question="Why is the sky blue?",
collection_id=uuid4(),
user_id=uuid4()
)
result = await cot_service.execute_chain_of_thought(cot_input)
print(f"Answer: {result.final_answer}")
print(f"Steps: {len(result.reasoning_steps)}")
execute_reasoning_step(step_number: int, question: str, context: list[str], previous_answers: list[str]) -> ReasoningStep¶
Executes a single reasoning step.
Parameters: - step_number (int): Step number (1-based) - question (str): Question for this step - context (list[str]): Context documents - previous_answers (list[str]): Previous step answers
Returns: - ReasoningStep: Step result with answer and metadata
Raises: - LLMProviderError: LLM service failure
Example:
step = await cot_service.execute_reasoning_step(
step_number=1,
question="What is machine learning?",
context=["Machine learning is a subset of AI..."],
previous_answers=[]
)
print(f"Answer: {step.intermediate_answer}")
print(f"Confidence: {step.confidence_score}")
decompose_question(question: str, max_depth: int = 3) -> Any¶
Decomposes complex question into sub-questions.
Parameters: - question (str): Question to decompose - max_depth (int): Maximum decomposition depth
Returns: - Decomposition result with sub_questions list
synthesize_answer(original_question: str, reasoning_steps: list[ReasoningStep]) -> str¶
Synthesizes final answer from reasoning steps.
Parameters: - original_question (str): Original user question - reasoning_steps (list[ReasoningStep]): Completed reasoning steps
Returns: - str: Final synthesized answer
Properties¶
question_decomposer: QuestionDecomposer¶
Lazy-initialized question decomposer instance.
answer_synthesizer: AnswerSynthesizer¶
Lazy-initialized answer synthesizer instance.
source_attribution_service: SourceAttributionService¶
Lazy-initialized source attribution service instance.
SourceAttributionService¶
Service for tracking document sources used in reasoning.
Constructor¶
Initializes empty source cache for deduplication.
Methods¶
create_source_attribution(**kwargs) -> SourceAttribution¶
Creates structured source attribution object.
Parameters: - document_id (str): Unique document identifier - relevance_score (float): Relevance score (0.0-1.0) - document_title (str | None): Document title - excerpt (str | None): Relevant text excerpt - chunk_index (int | None): Chunk index within document - retrieval_rank (int | None): Original retrieval ranking
Returns: - SourceAttribution: Created attribution object
Example:
attribution = service.create_source_attribution(
document_id="doc_123",
relevance_score=0.85,
document_title="Machine Learning Guide",
excerpt="Machine learning algorithms can be categorized...",
retrieval_rank=1
)
extract_sources_from_context(context_documents: List[str], search_results: Optional[List[Dict[str, Any]]] = None) -> List[SourceAttribution]¶
Extracts source attributions from context or search results.
Parameters: - context_documents (List[str]): Raw context document strings - search_results (Optional[List[Dict[str, Any]]]): Structured search results
Returns: - List[SourceAttribution]: List of extracted attributions
Example:
# From structured search results
search_results = [
{
"document_id": "doc_1",
"title": "AI Introduction",
"score": 0.92,
"content": "Artificial intelligence involves..."
}
]
attributions = service.extract_sources_from_context([], search_results)
# From raw context strings
context = ["id:doc_1 AI content here...", "More AI information..."]
attributions = service.extract_sources_from_context(context)
aggregate_sources_across_steps(reasoning_steps: List[ReasoningStep]) -> SourceSummary¶
Aggregates sources from all reasoning steps.
Parameters: - reasoning_steps (List[ReasoningStep]): Steps with source attributions
Returns: - SourceSummary: Aggregated source information
Example:
summary = service.aggregate_sources_across_steps([step1, step2, step3])
print(f"Total sources: {len(summary.all_sources)}")
print(f"Primary sources: {len(summary.primary_sources)}")
print(f"Step breakdown: {summary.source_usage_by_step}")
enhance_reasoning_step_with_sources(step: ReasoningStep, retrieved_documents: Optional[List[Dict[str, Any]]] = None) -> ReasoningStep¶
Adds source attributions to reasoning step.
Parameters: - step (ReasoningStep): Step to enhance - retrieved_documents (Optional[List[Dict[str, Any]]]): Retrieved documents for this step
Returns: - ReasoningStep: Enhanced step with source attributions
format_sources_for_display(source_summary: SourceSummary, include_excerpts: bool = True) -> Dict[str, Any]¶
Formats sources for UI display.
Parameters: - source_summary (SourceSummary): Summary to format - include_excerpts (bool): Whether to include text excerpts
Returns: - Dict[str, Any]: UI-friendly formatted source information
QuestionDecomposer¶
Service for breaking down complex questions.
Constructor¶
Parameters: - settings: Application settings
Methods¶
decompose(question: str, max_depth: int = 3) -> QuestionDecomposition¶
Decomposes question into sub-questions.
Parameters: - question (str): Question to decompose - max_depth (int): Maximum decomposition depth
Returns: - Question decomposition with sub_questions list
Decomposition Strategies: - Multi-part questions: Split on conjunctions - Comparison questions: Create definition + comparison steps - Causal questions: Create why โ how โ impact chains
AnswerSynthesizer¶
Service for combining reasoning step results.
Constructor¶
Methods¶
synthesize(original_question: str, reasoning_steps: List[ReasoningStep]) -> str¶
Synthesizes final answer from steps.
Parameters: - original_question (str): Original question - reasoning_steps (List[ReasoningStep]): Completed reasoning steps
Returns: - str: Final synthesized answer
Data Models¶
ChainOfThoughtInput¶
Input schema for CoT requests.
class ChainOfThoughtInput(BaseModel):
question: str = Field(..., min_length=1, description="User question")
collection_id: UUID4 = Field(..., description="Collection ID")
user_id: UUID4 = Field(..., description="User ID")
cot_config: Optional[Dict[str, Any]] = Field(None, description="CoT configuration")
context_metadata: Optional[Dict[str, Any]] = Field(None, description="Context metadata")
ChainOfThoughtOutput¶
Output schema for CoT results.
class ChainOfThoughtOutput(BaseModel):
original_question: str = Field(..., description="Original user question")
final_answer: str = Field(..., description="Final synthesized answer")
reasoning_steps: List[ReasoningStep] = Field(default_factory=list, description="Reasoning steps taken")
source_summary: Optional[SourceSummary] = Field(None, description="Summary of source attributions")
total_confidence: float = Field(default=0.0, description="Overall confidence score")
token_usage: Optional[int] = Field(None, description="Total tokens used")
total_execution_time: Optional[float] = Field(None, description="Total execution time")
reasoning_strategy: Optional[str] = Field(None, description="Strategy used")
Validation: - total_confidence: 0.0-1.0 - token_usage: > 0 if specified - total_execution_time: > 0 if specified
ChainOfThoughtConfig¶
Configuration schema for CoT behavior.
class ChainOfThoughtConfig(BaseModel):
enabled: bool = Field(default=False, description="Whether CoT is enabled")
max_reasoning_depth: int = Field(default=3, description="Maximum reasoning steps")
reasoning_strategy: str = Field(default="decomposition", description="Strategy: decomposition, iterative, hierarchical, causal")
context_preservation: bool = Field(default=True, description="Preserve context across steps")
token_budget_multiplier: float = Field(default=2.0, description="Token budget multiplier")
evaluation_threshold: float = Field(default=0.6, description="Evaluation threshold")
Validation: - max_reasoning_depth: > 0 - token_budget_multiplier: > 0 - evaluation_threshold: 0.0-1.0 - reasoning_strategy: One of ["decomposition", "iterative", "hierarchical", "causal"]
QuestionClassification¶
Question analysis result.
class QuestionClassification(BaseModel):
question_type: str = Field(..., description="Type of question")
complexity_level: str = Field(..., description="Complexity level")
requires_cot: bool = Field(..., description="Whether CoT is needed")
estimated_steps: Optional[int] = Field(None, description="Estimated reasoning steps")
confidence: Optional[float] = Field(None, description="Classification confidence")
reasoning: Optional[str] = Field(None, description="Classification reasoning")
Validation: - question_type: One of ["simple", "multi_part", "comparison", "causal", "complex_analytical"] - complexity_level: One of ["low", "medium", "high", "very_high"] - confidence: 0.0-1.0 if specified - estimated_steps: > 0 if specified
ReasoningStep¶
Individual reasoning step result.
class ReasoningStep(BaseModel):
step_number: int = Field(..., description="Step number")
question: str = Field(..., description="Question for this step")
context_used: List[str] = Field(default_factory=list, description="Context documents used (legacy)")
source_attributions: List[SourceAttribution] = Field(default_factory=list, description="Structured source attributions")
intermediate_answer: Optional[str] = Field(None, description="Intermediate answer")
confidence_score: Optional[float] = Field(default=0.0, description="Confidence score 0-1")
reasoning_trace: Optional[str] = Field(None, description="Reasoning trace")
execution_time: Optional[float] = Field(None, description="Execution time in seconds")
SourceAttribution¶
Source document attribution.
class SourceAttribution(BaseModel):
document_id: str = Field(..., description="Unique identifier for the source document")
document_title: Optional[str] = Field(None, description="Title or name of the source document")
relevance_score: float = Field(..., description="Relevance score for this source (0-1)")
excerpt: Optional[str] = Field(None, description="Relevant excerpt from the source")
chunk_index: Optional[int] = Field(None, description="Index of the chunk within the document")
retrieval_rank: Optional[int] = Field(None, description="Rank in the retrieval results")
SourceSummary¶
Aggregated source information.
class SourceSummary(BaseModel):
all_sources: List[SourceAttribution] = Field(default_factory=list, description="All unique sources used")
primary_sources: List[SourceAttribution] = Field(default_factory=list, description="Most influential sources")
source_usage_by_step: Dict[int, List[str]] = Field(default_factory=dict, description="Sources used by each step")
Error Handling¶
Custom Exceptions¶
LLMProviderError¶
Raised when LLM service operations fail.
class LLMProviderError(Exception):
def __init__(self, provider: str, error_type: str = None, message: str = None, operation: str | None = None, details: dict[str, Any] | None = None)
Parameters: - provider: LLM provider name - error_type: Type of error (optional) - message: Error message (optional) - operation: Failed operation (optional) - details: Additional error details (optional)
ValidationError¶
Raised for configuration validation failures.
Parameters: - field: Field that failed validation - value: Invalid value - message: Validation error message
Error Examples¶
try:
result = await cot_service.execute_chain_of_thought(invalid_input)
except ValidationError as e:
print(f"Configuration error: {e.message}")
except LLMProviderError as e:
print(f"LLM error: {e.message}")
except TimeoutError as e:
print(f"Execution timeout: {e}")
Integration Examples¶
With Search Service¶
class SearchService:
def __init__(self, cot_service: ChainOfThoughtService):
self.cot_service = cot_service
async def search_with_cot(self, search_input: SearchInput) -> SearchOutput:
# Check if CoT should be used
classification = await self.cot_service.classify_question(search_input.question)
if classification.requires_cot:
# Execute CoT reasoning
cot_input = ChainOfThoughtInput(
question=search_input.question,
collection_id=search_input.collection_id,
user_id=search_input.user_id,
cot_config=search_input.config_metadata.get("cot_config")
)
cot_result = await self.cot_service.execute_chain_of_thought(cot_input)
return SearchOutput(
answer=cot_result.final_answer,
sources=cot_result.source_summary.primary_sources,
confidence=cot_result.total_confidence,
reasoning_trace=cot_result.reasoning_steps
)
else:
# Regular search
return await self.regular_search(search_input)
With FastAPI¶
from fastapi import FastAPI, HTTPException
from rag_solution.schemas.chain_of_thought_schema import ChainOfThoughtInput, ChainOfThoughtOutput
app = FastAPI()
@app.post("/cot/execute", response_model=ChainOfThoughtOutput)
async def execute_cot(cot_input: ChainOfThoughtInput):
try:
result = await cot_service.execute_chain_of_thought(cot_input)
return result
except ValidationError as e:
raise HTTPException(status_code=400, detail=str(e))
except LLMProviderError as e:
raise HTTPException(status_code=502, detail=f"LLM service error: {e}")
Testing Support¶
import pytest
from unittest.mock import Mock
@pytest.fixture
def mock_cot_service():
mock_llm = Mock()
mock_search = Mock()
return ChainOfThoughtService(
settings=test_settings,
llm_service=mock_llm,
search_service=mock_search
)
async def test_cot_execution(mock_cot_service):
cot_input = ChainOfThoughtInput(
question="Test question",
collection_id=uuid4(),
user_id=uuid4()
)
result = await mock_cot_service.execute_chain_of_thought(cot_input)
assert result.final_answer is not None
assert len(result.reasoning_steps) > 0
assert result.total_confidence >= 0.0
Performance Monitoring¶
Metrics Collection¶
def collect_cot_metrics(result: ChainOfThoughtOutput) -> Dict[str, Any]:
return {
"execution_time": result.total_execution_time,
"token_usage": result.token_usage,
"steps_count": len(result.reasoning_steps),
"confidence_score": result.total_confidence,
"sources_count": len(result.source_summary.all_sources) if result.source_summary else 0,
"avg_step_confidence": sum(s.confidence_score for s in result.reasoning_steps) / len(result.reasoning_steps) if result.reasoning_steps else 0
}
This comprehensive API reference covers all public interfaces and usage patterns for the Chain of Thought system.