本文详细介绍 DeepSeek R1 模型的特性,分析为什么需要直接调用API而不是使用现有框架,并提供完整的 Java 实现方案
reasoning_content
ollama run deepseek-r1:14b
<think>
export function withMessageThought(message: ChatMessage, startTime?: number) { const content = message.content; const thinkPattern = /<think>(.*?)<\/think>/s; const matches = content.match(thinkPattern); if (matches) { const reasoning_content = matches[1].trim(); return reasoning_content; } return message; }
@PostMapping(value = "/deepseek", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<Map<String, String>> chatStream(String inputPrompt) { Map<String, Object> message = new HashMap<>(); message.put("role", "user"); message.put("content", inputPrompt); Map<String, Object> requestBody = new HashMap<>(); requestBody.put("messages", List.of(message)); requestBody.put("stream", true); requestBody.put("model", "deepseek-reason"); WebClient webClient = WebClient.builder() .baseUrl("https://api.deepseek.com/v1") .defaultHeader("Authorization", "Bearer ${DEEPSEEK_API_KEY}") .build(); return webClient.post() .uri("/chat/completions") .bodyValue(requestBody) .retrieve() .bodyToFlux(JsonNode.class) .map(this::parseDeepseekResponse) .takeUntil(response -> response.containsKey("finish_reason")) .onErrorResume(error -> Flux.just(Map.of("content", "API 调用异常:" + error.getMessage()))); }
private Map<String, String> parseDeepseekResponse(JsonNode response) { JsonNode choices = response.get("choices"); Map<String, String> result = new HashMap<>(); if (choices != null && choices.isArray() && !choices.isEmpty()) { JsonNode choice = choices.get(0); JsonNode delta = choice.get("delta"); if (delta != null) { result.put("content", Optional.ofNullable(delta.get("content")) .map(JsonNode::asText) .orElse("")); result.put("reasoning_content", Optional.ofNullable(delta.get("reasoning_content")) .map(JsonNode::asText) .orElse("")); } Optional.ofNullable(choice.get("finish_reason")) .filter(node -> !node.isNull()) .ifPresent(node -> result.put("finish_reason", node.asText())); } return result; }