在 MicroPython ESP32-C3 单片机 中调用 DeepSeek API 以及部分问题的解决

在 MicroPython ESP32-C3 单片机 中调用 DeepSeek API 的实践与问题解决

背景

本文记录在 MicroPython ESP32-C3 上调用 DeepSeek API 时遇到的问题及解决方案,包含中文编码异常处理和请求报文长度限制问题。

依赖

  • 代码使用到urequests模块(requests模块的micropython版本)
    安装方法参考 mpremote安装第三方库
mpremote mip install urequests
  • 代码中需要用自己的DeepSeek API key,可以在DeepSeek官方开发文档注册获得
    ,需要费用,但是很便宜。DeepSeek开放平台

完整实现代码

# udeepseek.py

import requests
import json

# 手动Unicode转义函数
def _unicode_escape(s):
    return ''.join(f'\\u{ord(c):04x}' if ord(c) > 127 else c for c in s)

def _chat_func(api_key, base_url, model, messages):
    url = f"{base_url}/chat/completions"
    
    headers = {
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {api_key}"
    }
    
    data = json.dumps({"model": model,"messages": messages})
    data = _unicode_escape(data)
        
    try:
        response = requests.post(
            url,
            headers=headers,
            data=data
        )
        if response.status_code == 200:
            result = response.json()
            return result["choices"][0]["message"]["content"]
        else:
            return f"Error: {response.status_code} - {response.text}"
    except Exception as e:
        return f"Exception: {str(e)}"
    finally:
        if 'response' in locals():
            response.close()
    
class DeepSeek:
    def __init__(self, api_key, base_url=None):
        self.__api_key = api_key
        self.__base_url = base_url or "https://api.deepseek.com/v1"

    def chat(self, model='deepseek-chat', messages):
        return _chat_func(self.__api_key, self.__base_url, model, messages)
    
    def memory_chat(self):
        welcome_text = "\n\t[AI Chat] I'll remember our conversation. Type '/bye' to exit.\n"
        print(welcome_text)
        text = ""
        messages = []
        while True:
            if (text := input("User>>")) == "/bye": break
            messages.append({"role": "user", "content": text})
            res = self.chat("deepseek-chat", messages)
            messages.append({"role": "assistant", "content": res})
            print("Chat>>", res)
            
if __name__ == '__main__':
	##### 此处使用你自己的key 
	api_key = ''
	#####
	client = DeepSeek(api_key)
	client.memory_chat()

简单使用方法

from udeepseek import DeepSeek
DeekSeek('your_api_key').memory_chat()

遇到的问题

问题一:报文长度限制

现象和可能的原因
  • 首次请求后,后续请求长度不能超过第一次请求长度,超长请求服务器会返回 400 错误,提示格式错误,疑似请求套接字未正确释放,后续请求被截断
解决方案

把核心函数写在类的外面

# 将核心实现函数移出类定义
def _chat_func(...):
    # 实现代码...

class DeepSeek:
    # 通过类方法调用外部函数
    def chat(self, ...):
        return _chat_func(...)

问题二:中文编码异常

现象
  • 请求包含中文时服务器返回 400 错误
  • 错误提示格式验证失败
原因分析

MicroPython 官方 JSON 库对非 ASCII 字符处理与标准库存在差异

解决方案
# 手动 Unicode 转义函数
def _unicode_escape(s):
    return ''.join(f'\\u{ord(c):04x}' if ord(c) > 127 else c for c in s)

# 在请求前处理数据
data = json.dumps(...)
data = _unicode_escape(data)

参考文档

  • MicroPython 官方文档
  • MicroPython 中文文档
  • MicroPython 官方仓库(json模块源码在这)
  • MicroPython-lib 仓库(requests模块源码在这)

你可能感兴趣的:(python,单片机,嵌入式硬件)