We will build a lightweight chain-of-thought research agent that breaks complex questions into explicit reasoning steps before committing to an answer. This architecture improves accuracy on multi-step analytical problems, and because Oxlo.ai uses flat per-request pricing, long reasoning traces do not inflate your bill.
What you will need
- Python 3.10 or later
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
Step 1: Scaffold the project and test the connection
First, I verify that the Oxlo.ai client is configured correctly and that I can reach the API. I will use the DeepSeek V3.2 model because it handles reasoning well and is available on the free tier.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "user", "content": "Say hello"}
],
)
print(response.choices[0].message.content)
Step 2: Write the chain-of-thought system prompt
The core of this architecture is the system prompt. It forces the model to emit a reasoning trace inside <think> tags before giving the final answer. I store this as a module-level constant so I can iterate on it without touching the calling code.
SYSTEM_PROMPT = '''You are a research analyst that solves problems through explicit chain-of-thought reasoning.
When you receive a question, follow these rules strictly:
1. First, analyze what the question is asking and identify the key facts and sub-problems.
2. Second, reason through each sub-problem step by step inside <think>...</think> tags.
3. Third, verify your intermediate results and note any uncertainties.
4. Finally, provide the concise final answer outside of the <think> tags.
Always include the reasoning trace. Do not skip the <think> block.'''
Step 3: Call the model with the CoT prompt
Now I wire the system prompt into the chat completion. I send a multi-step math problem that is easy to get wrong if you rush to the answer.
USER_QUESTION = (
"A bat and a ball cost $110 in total. "
"The bat costs $100 more than the ball. "
"How much does the ball cost? "
"Think carefully and show your reasoning."
)
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": USER_QUESTION},
],
)
raw_output = response.choices[0].message.content
print(raw_output)
Step 4: Parse reasoning and final answer
Raw text is not enough for a production agent. I need to separate the reasoning trace from the answer so I can log the chain of thought or surface it in a UI. I will use a small parser with a regular expression.
import re
def parse_cot(response_text: str):
think_match = re.search(r"<think>(.*?)</think>", response_text, re.DOTALL)
reasoning = think_match.group(1).strip() if think_match else ""
answer = re.sub(r"<think>.*?</think>", "", response_text, flags=re.DOTALL).strip()
return reasoning, answer
reasoning, answer = parse_cot(raw_output)
print("=== REASONING ===")
print(reasoning)
print("\n=== ANSWER ===")
print(answer)
Step 5: Add a self-check loop
A strong CoT architecture does not stop at one pass. I add a verification step where the model critiques its own answer. If it detects a mistake, it regenerates. This costs only one more request on Oxlo.ai because pricing is per request, not per token.
VERIFY_PROMPT = (
"You just answered a question. Review your previous reasoning and answer below. "
"If you find an error, say CORRECTION_NEEDED and provide the corrected answer. "
"If the answer is correct, say VERIFIED.\n\n"
f"Previous reasoning:\n{reasoning}\n\n"
f"Previous answer:\n{answer}"
)
verify_response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": USER_QUESTION},
{"role": "assistant", "content": raw_output},
{"role": "user", "content": VERIFY_PROMPT},
],
)
print(verify_response.choices[0].message.content)
Step 6: Wrap everything in a reusable agent class
To make this shippable, I package the parser and the verification logic into a small class. This is the architecture I would actually import into a larger service.
class CoTAgent:
def __init__(self, client: OpenAI, model: str = "deepseek-v3.2"):
self.client = client
self.model = model
self.system_prompt = SYSTEM_PROMPT
def ask(self, question: str, verify: bool = True):
messages = [
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": question},
]
resp = self.client.chat.completions.create(
model=self.model,
messages=messages,
)
raw = resp.choices[0].message.content
reasoning, answer = parse_cot(raw)
if verify:
messages.append({"role": "assistant", "content": raw})
messages.append({"role": "user", "content": (
"Review your reasoning and answer for errors. "
"Say VERIFIED if correct, otherwise give the correction."
)})
v_resp = self.client.chat.completions.create(
model=self.model,
messages=messages,
)
verification = v_resp.choices[0].message.content
return reasoning, answer, verification
return reasoning, answer, None
agent = CoTAgent(client)
r, a, v = agent.ask(
"Roger has 5 tennis balls. He buys 2 more cans of tennis balls. "
"Each can has 3 balls. How many does he have now?"
)
print("Reasoning:\n", r)
print("\nAnswer:\n", a)
print("\nVerification:\n", v)
Run it
Save the complete script as cot_agent.py, export your key, and run it.
export OXLO_API_KEY="your-key-here"
python cot_agent.py
When I run this against the bat-and-ball problem, the agent outputs something like the following. Notice how the reasoning trace catches the intuitive but wrong answer of $10 and corrects it to $5.
=== REASONING ===
The total cost is $110. The bat costs $100 more than the ball.
If the ball cost $10, the bat would cost $110, and the total would be $120.
That is too high. Let the ball cost x. Then the bat costs x + 100.
x + (x + 100) = 110
2x + 100 = 110
2x = 10
x = 5
So the ball costs $5.
=== ANSWER ===
The ball costs $5.
=== VERIFICATION ===
VERIFIED. The algebra checks out and the total is $110.
Wrap-up and next steps
You now have a working chain-of-thought agent that separates reasoning from answers and can self-verify. Two concrete next steps: wire the reasoning trace into a structured logging pipeline so you can audit failures, or swap in kimi-k2.6 or deepseek-r1-671b on Oxlo.ai for harder reasoning benchmarks without worrying about token costs on long context windows. See https://oxlo.ai/pricing for plan details.
Top comments (0)