[GenAI] Combine DeepSeek R1 Reasoning with GPT 3.5 Turbo for the Cheapest, Fastest, and Best AI

DeepSeek Reasoning

A CLI tool that combines DeepSeek's reasoning capabilities with GPT's summarization power. This project demonstrates how to:

  1. Use DeepSeek's reasoning model to analyze questions in detail
  2. Stream the reasoning process in real-time
  3. Use GPT to create concise, single-sentence summaries of the reasoning

🎓 What You'll Learn

This project is tied to an egghead.io lesson that teaches you how to:

  • Extract and utilize DeepSeek's reasoning phase from their R1 model
  • Stream and parse API responses in real-time
  • Optimize costs by using different models for different tasks
  • Combine multiple AI models in a single workflow
  • Build a practical CLI tool that demonstrates these concepts

Why This Matters

DeepSeek's R1 model provides detailed reasoning before summarization. By isolating this reasoning phase and using a faster model (like GPT-3.5-turbo) for summarization, you can:

  • Get high-quality reasoning from DeepSeek
  • Optimize costs by using a cheaper model for summarization
  • Improve response times in your applications
  • Create more efficient AI workflows

Features

  • Interactive CLI using Clack
  • Real-time streaming of DeepSeek's reasoning process
  • Automatic logging of all interactions
  • Clean summarization of complex reasoning
  • Cost-effective hybrid model approach

Requirements

You'll need API key for:

  • OpenRouter API (for GPT & DeepSeek access)

Setup

  1. Clone the repo:
git clone https://github.com/johnlindquist/deepseek-reasoning.git
cd deepseek-reasoning
  1. Install dependencies:
pnpm install
  1. Create a .env file with your API keys:
OPENROUTER_API_KEY=your_openrouter_api_key
  1. Run the CLI:
pnpm tsx index.ts

How It Works

  1. The CLI prompts you for a question
  2. DeepSeek's reasoning model analyzes your question, streaming its thought process in real-time
  3. The reasoning is captured and logged
  4. GPT 3.5 creates a concise, single-sentence summary of the reasoning
  5. Both the reasoning and summary are saved to timestamped log files

Implementation Details

The code demonstrates several key patterns:

  • Streaming API responses with proper TypeScript types
  • Early stream termination to capture only reasoning content
  • Efficient model switching for cost optimization
  • Structured logging for debugging and analysis
  • Clean CLI interactions with proper error handling

Tech Stack

  • TypeScript
  • OpenAI SDK (for OpenRouter)
  • Clack (for CLI interactions)
  • dotenv (for environment management)

Code:

import dotenv from "dotenv";
dotenv.config();

import { log, spinner, text } from "@clack/prompts";
import { existsSync } from "node:fs";
import { appendFile, mkdir } from "node:fs/promises";
import OpenAI from "openai";

const OPEN_ROUTER_API_URL = "https://openrouter.ai/api/v1";
const REASON_MODEL = "deepseek/deepseek-r1" // or "google/gemini-2.0-flash-thinking-exp:free"
const SUMMARIZER_MODEL = "openai/gpt-4o-mini" // or "gpt-3.5-turbo-0613"

const s = spinner();
const timestamp = new Date()
	.toISOString()
	.replace("T", "-")
	.replace(/:/g, "-")
	.split(".")[0];
const logFile = `logs/${timestamp}.log`;

const appendLog = async (data: unknown) => {
	if (!existsSync("logs")) {
		await mkdir("logs");
	}
	appendFile(logFile, `---\n\n${JSON.stringify(data, null, 2)}\n\n`);
}

declare global {
	namespace NodeJS {
		interface ProcessEnv {
			OPENROUTER_API_KEY: string;
		}
	}
}

const question = (await text({
	message: "How can I help?",
})) as string;

log.info("Thinking...");
const deepseek = new OpenAI({
	baseURL: OPEN_ROUTER_API_URL,
	apiKey: process.env.OPENROUTER_API_KEY,
});

const reasoningResponse = await deepseek.chat.completions.create({
	model: REASON_MODEL,
	messages: [{ role: "user", content: question }],
	stream: true,
	stop: "</think>", // for stopping right after the reasoning
	include_reasoning: true, // not in types yet
});

let reasoning = "";

for await (const chunk of reasoningResponse) {
	const reasoningContent = (
		chunk.choices?.[0]?.delta as { reasoning: string }
	)?.reasoning;

	if (reasoningContent !== null) {
		const content = reasoningContent;
		reasoning += content;
		process.stdout.write(content);
	} else {
		reasoningResponse.controller.abort(); // stop the stream before it summarizes
		log.success("Reasoning done!");
		break;
	}
}

await appendLog(`
REASONING:
${reasoning}
---------
`);

s.start("Summarizing...");
const openai = new OpenAI({
	baseURL: OPEN_ROUTER_API_URL,
	apiKey: process.env.OPENROUTER_API_KEY,
});

const gptResponse = await openai.chat.completions.create({
	model: SUMMARIZER_MODEL,
	messages: [
		{
			role: "system",
			content:
				"Answer the initial <QUESTION> in a single sentence based on the <REASONING>",
		},
		{
			role: "user",
			content: `
<QUESTION>
${question}
</QUESTION>

<REASONING>
${reasoning}
</REASONING>
`,
		},
	],
});

const summary = gptResponse.choices[0]?.message.content ?? "";

s.stop();
log.info(summary);

await appendLog(`
SUMMARY:
${summary}
---------
`);
posted @   Zhentiw  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2023-02-03 [Typescript] Defining exclusive properties with TypeScript
2021-02-03 [Docker] Run Stateless Docker Containers (Volumes with docker compose)
2021-02-03 [Javascript] Link to Other Objects through the JavaScript Prototype Chain (Object.setPrototypeOf())
2021-02-03 [Docker] Ensure Containers Run with High-Availability
2018-02-03 [Angular + TsLint] Disable directive selector tslint error
2018-02-03 [Angular] Create a ng-true-value and ng-false-value in Angular by controlValueAccessor
2018-02-03 [AngularJS] ng-ture-value & ng-false-value
点击右上角即可分享
微信分享提示