PostgreSQL码农集散地

DuckDB接入DeepSeek

DuckDB如何接入DeepSeek?

如何在DuckDB中调用openAI/ollama API接口, 接入DeepSeek等大模型? 使用DuckDB http_client插件, 这个插件将http请求接口封装成了函数可以直接调用. 例如http_post.

demo

1、ollama

API文档

  • https://github.com/ollama/ollama/blob/main/docs/api.md

假设我们要调用generate接口, 例子如下

# 请求  
POST /api/generate  

# 例子  
curl http://localhost:11434/api/generate -d '{  
  "model": "deepseek-r1:1.5b",  
  "prompt": "Why is the sky blue?",  
  "stream": false,  
  "options": {  
    "temperature": 0.01  
  }  
}'

# 返回  
{  
"model": "llama3.2",  
"created_at": "2023-08-04T08:52:19.385406455-07:00",  
"response": "The",  
"done": false
}  

假设本地有这些模型

$ ollama list  
NAME                        ID              SIZE      MODIFIED        
qwen2.5:1.5b                65ec06548149    986 MB    3 minutes ago      
deepseek-r1:7b              0a8c26691023    4.7 GB    8 days ago         
qwen_1.5b_test1:latest      682ad25636bd    1.1 GB    13 days ago        
deepseek-r1:1.5b            a42b25d8c10a    1.1 GB    13 days ago        
deepseek-r1:14b             ea35dfe18182    9.0 GB    4 weeks ago        
mxbai-embed-large:latest    468836162de7    669 MB    3 months ago   

启动ollama服务

OLLAMA_HOST=0.0.0.0:11434 OLLAMA_KEEP_ALIVE=-1 nohup ollama serve > /dev/null 2>&1 &  

2、DuckDB

使用http_client插件, 将http请求接口封装成了函数, 参考文档

  • https://duckdb.org/community_extensions/extensions/http_client.html
  • https://github.com/quackscience/duckdb-extension-httpclient

例子. 原文例子中params有个MAP, 会报错. 感谢涛哥提供的解决办法, 去掉MAP就可以了. 

下面是一些例子

-- POST Request Example w/ Headers and Parameters  
WITH __input AS (  
SELECT  
  http_post(  
'http://localhost:11434/api/generate',  
      headers => MAP {  
'accept': 'application/json',  
      },  
      params => {  
'model': 'qwen2.5:1.5b',  
'prompt': 'Why is the sky blue?',  
'stream': false,  
'options': {  
'temperature': 0.01  
        }  
      }  
  ) AS res  
),  
__response AS (  
  SELECT  
    (res->>'status')::INT AS status,  
    (res->>'reason') AS reason,  
    ((res->>'body')::JSON)->'response' AS response  
  FROM  
    __input  
)  
SELECT  
  __response.status,  
  __response.reason,  
  __response.response  
FROM  
  __response  
;  
┌────────┬─────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐  
│ status │ reason  │                                                                                      response                                                                                       │  
│ int32  │ varchar │                                                                                        json                                                                                         │  
├────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤  
│  200   │ OK      │ "The sky appears blue because of a phenomenon called Rayleigh scattering. This occurs when light from the sun passes through Earth's atmosphere and interacts with air molecules.…  │  
└────────┴─────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘  
.mode csv  
.width 10 100000  

-- POST Request Example w/ Headers and Parameters  
WITH __input AS (  
SELECT  
  http_post(  
'http://localhost:11434/api/generate',  
      headers => MAP {  
'accept': 'application/json',  
      },  
      params => {  
'model': 'qwen2.5:1.5b',  
'prompt': '9.11 和 9.9 哪个数值更大?',  
'stream': false,  
'options': {  
'temperature': 0.01  
        }  
      }  
  ) AS res  
),  
__response AS (  
  SELECT  
    (res->>'status')::INT AS status,  
    (res->>'reason') AS reason,  
    ((res->>'body')::JSON)->'response' AS response  
  FROM  
    __input  
)  
SELECT  
  __response.status,  
  __response.reason,  
  __response.response  
FROM  
  __response  
;  

status,reason,response  
200,OK,"""要比较两个数字的大小,我们需要逐位进行比较。以下是详细的步骤:\n\n1. 比较整数部分:\n   - 9.11 的整数部分是 9。\n   - 9.9 的整数部分也是 9。\n\n2. 比较小数部分:\n   - 9.11 的小数部分是 0.11。\n   - 9.9 的小数部分是 0.9。\n\n3. 比较小数点后的第一位:\n   - 9.11 的第一位是 1。\n   - 9.9 的第一位是 9。\n\n由于 1 < 9,所以 9.11 小于 9.9。\n\n因此,9.9 更大。"""