Cpptai / src /cpptai /baselines.py
Fra150
CPPTAI v2 + Gradio demo offline (rispetta .gitignore)
c0e3412
Raw History Blame Contribute Delete
5.65 kB
"""Real reasoning baselines using DeepSeek API.
Implements actual Chain-of-Thought, Tree-of-Thought, Graph-of-Thought,
and ReAct strategies that call the LLM and depend on the problem input.
"""
from __future__ import annotations
import json
import logging
from abc import ABC, abstractmethod
from typing import Dict, List, Optional
from .deepseek_client import deepseek_chat, extract_text_answer
logger = logging.getLogger(__name__)
class ReasoningBaseline(ABC):
"""Abstract base class for reasoning baselines."""
def __init__(self, model: str = "deepseek-chat", temperature: float = 0.0):
self.model = model
self.temperature = temperature
@abstractmethod
def solve(self, problem: str) -> str:
"""Solve a problem using this reasoning strategy."""
...
def _call_llm(self, messages: List[Dict[str, str]]) -> str:
"""Call DeepSeek API and return the text response."""
resp = deepseek_chat(messages, model=self.model, stream=False, temperature=self.temperature)
text = extract_text_answer(resp) if resp else ""
return text.strip() if text else ""
class CoTBaseline(ReasoningBaseline):
"""Chain-of-Thought: step-by-step reasoning using the LLM."""
def solve(self, problem: str) -> str:
prompt = (
"Let's think step by step.\n\n"
f"Problem: {problem}\n\n"
"Solution:"
)
messages = [
{"role": "system", "content": "You are a careful reasoning assistant. Always show your step-by-step thinking before giving the final answer."},
{"role": "user", "content": prompt},
]
return self._call_llm(messages)
class ToTBaseline(ReasoningBaseline):
"""Tree-of-Thought: explores multiple reasoning branches and evaluates them.
Uses a simple BFS approach: generate K branches, evaluate each,
select the best, expand further.
"""
def __init__(self, branches: int = 3, depth: int = 2, model: str = "deepseek-chat", temperature: float = 0.3):
super().__init__(model=model, temperature=temperature)
self.branches = branches
self.depth = depth
def solve(self, problem: str) -> str:
# Step 1: Generate initial branches
branch_prompt = (
f"Problem: {problem}\n\n"
f"Generate {self.branches} distinct approaches to solve this problem. "
f"Number them 1, 2, 3.\n\n"
f"Approaches:"
)
messages = [
{"role": "system", "content": "You are a creative problem solver. Generate diverse solution approaches."},
{"role": "user", "content": branch_prompt},
]
branches_text = self._call_llm(messages)
# Step 2: Evaluate and select the best branch
eval_prompt = (
f"Problem: {problem}\n\n"
f"Possible approaches:\n{branches_text}\n\n"
f"Evaluate each approach. Which one is most likely to be correct? "
f"Select the best approach and solve the problem with it.\n\n"
f"Final solution:"
)
messages = [
{"role": "system", "content": "You are a critical evaluator. Select the best approach and solve thoroughly."},
{"role": "user", "content": eval_prompt},
]
return self._call_llm(messages)
class GoTBaseline(ReasoningBaseline):
"""Graph-of-Thought: non-linear reasoning with interconnected ideas.
Generates reasoning nodes, identifies connections, merges related concepts,
and synthesizes a final solution.
"""
def __init__(self, model: str = "deepseek-chat", temperature: float = 0.2):
super().__init__(model=model, temperature=temperature)
def solve(self, problem: str) -> str:
prompt = (
f"Problem: {problem}\n\n"
f"Use Graph-of-Thought reasoning:\n"
f"1. Identify key concepts and reasoning nodes\n"
f"2. Connect related nodes and find relationships\n"
f"3. Merge interconnected ideas\n"
f"4. Synthesize a final solution from the reasoning graph\n\n"
f"Solution:"
)
messages = [
{"role": "system", "content": "You reason by building a graph of interconnected ideas and merging them into a solution."},
{"role": "user", "content": prompt},
]
return self._call_llm(messages)
class ReActBaseline(ReasoningBaseline):
"""Reason + Act: alternating reasoning and action steps.
Simulates a Thought -> Action -> Observation cycle, where each
thought proposes an action and the observation informs the next thought.
"""
def __init__(self, cycles: int = 3, model: str = "deepseek-chat", temperature: float = 0.1):
super().__init__(model=model, temperature=temperature)
self.cycles = cycles
def solve(self, problem: str) -> str:
prompt = (
f"Problem: {problem}\n\n"
f"Use ReAct (Reasoning + Acting) to solve this problem:\n\n"
)
for i in range(1, self.cycles + 1):
prompt += (
f"Thought {i}: What do I need to figure out?\n"
f"Action {i}: [reasoning step or calculation]\n"
f"Observation {i}: What did this tell me?\n\n"
)
prompt += "Based on the above, the final answer is:"
messages = [
{"role": "system", "content": "You reason using the ReAct framework: alternating thoughts, actions, and observations."},
{"role": "user", "content": prompt},
]
return self._call_llm(messages)