最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python調(diào)用DeepSeek API查詢ClickHouse的流程步驟

 更新時(shí)間:2026年03月20日 09:38:35   作者:言之。  
本文介紹如何利用DeepSeek API和ClickHouse構(gòu)建自然語言查詢數(shù)據(jù)庫,文章詳細(xì)說明了環(huán)境配置步驟,包括Python安裝、必備庫安裝、DeepSeek API Key獲取和ClickHouse連接配置,需要的朋友可以參考下

調(diào)用 DeepSeek API,并通過 MCP (Model Context Protocol) 協(xié)議接入 mcp-clickhouse,從而讓 DeepSeek 能夠查詢 ClickHouse 數(shù)據(jù)庫來回答用戶問題。

  • stdio 模式

前置準(zhǔn)備

在運(yùn)行代碼之前,你需要確保環(huán)境中有以下依賴:

安裝 Python 庫

pip install mcp openai

安裝 uv (因?yàn)槟愕呐渲弥惺褂昧?uv 來運(yùn)行 mcp-clickhouse):

pip install uv

獲取 DeepSeek API Key:你需要一個(gè)有效的 DeepSeek API 密鑰。

Python 代碼 (main.py)

請將代碼中的 <YOUR_DEEPSEEK_API_KEY> 替換為你的實(shí)際 Key,并確保 <clickhouse-host> 等配置已填入正確的值。

import asyncio
import os
import json
import sys
from typing import List, Dict, Any, Optional

# 導(dǎo)入 MCP 相關(guān)庫
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import mcp.types as types

# 導(dǎo)入 OpenAI SDK (DeepSeek 兼容 OpenAI 格式)
from openai import AsyncOpenAI

# ================= 配置部分 =================

# DeepSeek API 配置
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY", "<YOUR_DEEPSEEK_API_KEY>")
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
MODEL_NAME = "deepseek-chat"  # 或者 "deepseek-reasoner" (R1)

# MCP ClickHouse Server 配置 (來自你的 JSON)
MCP_CLICKHOUSE_CONFIG = {
    "command": "uv",
    "args": [
        "run",
        "--with",
        "mcp-clickhouse",
        "--python",
        "3.10",
        "mcp-clickhouse"
    ],
    "env": {
        "CLICKHOUSE_HOST": "<clickhouse-host>",
        "CLICKHOUSE_PORT": "<clickhouse-port>",
        "CLICKHOUSE_USER": "<clickhouse-user>",
        "CLICKHOUSE_PASSWORD": "<clickhouse-password>",
        "CLICKHOUSE_ROLE": "<clickhouse-role>",
        "CLICKHOUSE_SECURE": "true",
        "CLICKHOUSE_VERIFY": "true",
        "CLICKHOUSE_CONNECT_TIMEOUT": "30",
        "CLICKHOUSE_SEND_RECEIVE_TIMEOUT": "30"
    }
}

# ================= 工具函數(shù) =================

def convert_mcp_tool_to_openai(mcp_tool: types.Tool) -> Dict[str, Any]:
    """
    將 MCP 工具定義轉(zhuǎn)換為 OpenAI/DeepSeek 支持的 Function Calling 格式。
    """
    return {
        "type": "function",
        "function": {
            "name": mcp_tool.name,
            "description": mcp_tool.description,
            "parameters": mcp_tool.inputSchema
        }
    }

# ================= 主邏輯 =================

async def run_chat_loop():
    # 1. 初始化 DeepSeek 客戶端
    client = AsyncOpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)
    
    # 2. 準(zhǔn)備 MCP Server 參數(shù)
    server_params = StdioServerParameters(
        command=MCP_CLICKHOUSE_CONFIG["command"],
        args=MCP_CLICKHOUSE_CONFIG["args"],
        env={**os.environ, **MCP_CLICKHOUSE_CONFIG["env"]} # 合并當(dāng)前環(huán)境變量
    )

    print(f"正在啟動(dòng) MCP Server: {MCP_CLICKHOUSE_CONFIG['command']}...")
    
    # 3. 連接 MCP Server 并開始對話循環(huán)
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            # 初始化連接
            await session.initialize()
            
            # 獲取 MCP Server 提供的工具列表
            mcp_tools_list = await session.list_tools()
            openai_tools = [convert_mcp_tool_to_openai(tool) for tool in mcp_tools_list.tools]
            
            print(f"\n已連接 MCP Server,加載了 {len(openai_tools)} 個(gè)工具: {[t['function']['name'] for t in openai_tools]}")
            print("-" * 50)
            print("你可以開始詢問關(guān)于 ClickHouse 的問題了 (輸入 'quit' 退出)。")

            messages = [
                {"role": "system", "content": "你是一個(gè)智能助手,可以利用工具查詢 ClickHouse 數(shù)據(jù)庫來回答用戶問題。"}
            ]

            while True:
                user_input = input("\n用戶: ")
                if user_input.lower() in ["quit", "exit"]:
                    break

                messages.append({"role": "user", "content": user_input})

                # 第一輪調(diào)用:發(fā)送用戶問題 + 工具定義給 DeepSeek
                try:
                    response = await client.chat.completions.create(
                        model=MODEL_NAME,
                        messages=messages,
                        tools=openai_tools,
                    )
                except Exception as e:
                    print(f"API 調(diào)用錯(cuò)誤: {e}")
                    continue

                assistant_msg = response.choices[0].message
                messages.append(assistant_msg)

                # 檢查 DeepSeek 是否想調(diào)用工具
                if assistant_msg.tool_calls:
                    print(f"\n[思考] 模型決定調(diào)用工具...")
                    
                    for tool_call in assistant_msg.tool_calls:
                        tool_name = tool_call.function.name
                        tool_args = json.loads(tool_call.function.arguments)
                        
                        print(f"  -> 調(diào)用工具: {tool_name}, 參數(shù): {tool_args}")

                        # 執(zhí)行 MCP 工具
                        try:
                            mcp_result = await session.call_tool(tool_name, arguments=tool_args)
                            
                            # 獲取文本結(jié)果 (ClickHouse MCP 通常返回文本或 JSON 文本)
                            tool_output = ""
                            if mcp_result.content:
                                for content in mcp_result.content:
                                    if content.type == "text":
                                        tool_output += content.text
                            
                            print(f"  <- 工具返回結(jié)果 (前100字符): {tool_output[:100]}...")

                            # 將工具結(jié)果添加回對話歷史
                            messages.append({
                                "role": "tool",
                                "tool_call_id": tool_call.id,
                                "content": tool_output
                            })

                        except Exception as e:
                            error_msg = f"工具執(zhí)行出錯(cuò): {str(e)}"
                            print(f"  ! {error_msg}")
                            messages.append({
                                "role": "tool",
                                "tool_call_id": tool_call.id,
                                "content": error_msg
                            })

                    # 第二輪調(diào)用:將工具結(jié)果發(fā)送回 DeepSeek 獲取最終回答
                    final_response = await client.chat.completions.create(
                        model=MODEL_NAME,
                        messages=messages,
                        # 這里依然傳入 tools,以防模型需要繼續(xù)多步調(diào)用
                        tools=openai_tools, 
                    )
                    
                    final_content = final_response.choices[0].message.content
                    print(f"\nDeepSeek: {final_content}")
                    messages.append(final_response.choices[0].message)
                
                else:
                    # 如果不需要調(diào)用工具,直接輸出結(jié)果
                    print(f"\nDeepSeek: {assistant_msg.content}")

if __name__ == "__main__":
    # Windows 下通常需要這個(gè)策略
    if sys.platform.startswith('win'):
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
        
    asyncio.run(run_chat_loop())

代碼邏輯解釋

MCP 連接 (stdio_client):

  • 代碼使用 uv run ... 命令啟動(dòng) mcp-clickhouse 的子進(jìn)程。
  • 通過標(biāo)準(zhǔn)輸入/輸出 (stdio) 與該進(jìn)程建立通信通道。
  • CLICKHOUSE_HOST 等敏感信息通過環(huán)境變量 (env) 傳遞給子進(jìn)程,保證安全性。

工具發(fā)現(xiàn)與轉(zhuǎn)換 (convert_mcp_tool_to_openai):

  • session.list_tools() 從 mcp-clickhouse 獲取可用的工具(例如執(zhí)行 SQL 查詢的工具)。
  • 由于 MCP 的工具定義格式與 OpenAI/DeepSeek 的 Function Calling 格式略有不同(主要在于外層結(jié)構(gòu)),代碼中定義了一個(gè)轉(zhuǎn)換函數(shù)將其適配。

對話循環(huán) (Chat Loop):

  • User Input: 接收你的問題。
  • First API Call: 將問題和轉(zhuǎn)換后的工具列表發(fā)送給 DeepSeek。
  • Tool Execution: 如果 DeepSeek 返回 tool_calls(例如它生成了一個(gè) SQL 語句來查詢數(shù)據(jù)),Python 代碼會攔截這個(gè)請求,通過 session.call_tool 在本地的 mcp-clickhouse 服務(wù)中執(zhí)行該 SQL。
  • Second API Call: 將 ClickHouse 返回的查詢結(jié)果(數(shù)據(jù))作為 tool 類型的消息發(fā)回給 DeepSeek。
  • Final Answer: DeepSeek 根據(jù)查詢結(jié)果生成最終的自然語言回答。

運(yùn)行示例

假設(shè)你問:“查詢 users 表里有多少行數(shù)據(jù)?”

  1. DeepSeek 分析意圖,返回 tool_calls,調(diào)用 query_sql 工具,參數(shù)為 SELECT count() FROM users。
  2. Python 腳本通過 MCP 執(zhí)行該 SQL。
  3. ClickHouse 返回 105。
  4. Python 腳本將 105 發(fā)給 DeepSeek。
  5. DeepSeek 回答:“users 表里共有 105 行數(shù)據(jù)。”

到此這篇關(guān)于Python調(diào)用DeepSeek API查詢ClickHouse的流程步驟的文章就介紹到這了,更多相關(guān)Python DeepSeek API查詢ClickHouse內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python自動(dòng)化unittest yaml使用過程解析

    python自動(dòng)化unittest yaml使用過程解析

    這篇文章主要介紹了python自動(dòng)化unittest yaml使用過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 用python制作游戲外掛

    用python制作游戲外掛

    玩過電腦游戲的同學(xué)對于外掛肯定不陌生,但是你在用外掛的時(shí)候有沒有想過如何做一個(gè)外掛呢?那我們就來看一下如何用python來制作一個(gè)外掛
    2018-01-01
  • 無需壓縮軟件,用python幫你操作壓縮包

    無需壓縮軟件,用python幫你操作壓縮包

    這篇文章主要介紹了如何用python幫你操作壓縮包,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下
    2020-08-08
  • Python提取JSON格式數(shù)據(jù)實(shí)戰(zhàn)案例

    Python提取JSON格式數(shù)據(jù)實(shí)戰(zhàn)案例

    這篇文章主要給大家介紹了關(guān)于Python提取JSON格式數(shù)據(jù)的相關(guān)資料, Python提供了內(nèi)置的json模塊,用于處理JSON數(shù)據(jù),文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-07-07
  • Pandas創(chuàng)建DataFrame提示:type?object?'object'?has?no?attribute?'dtype'解決方案

    Pandas創(chuàng)建DataFrame提示:type?object?'object'?has?n

    Pandas數(shù)據(jù)幀(DataFrame)是二維數(shù)據(jù)結(jié)構(gòu),它包含一組有序的列,每列可以是不同的數(shù)據(jù)類型,這篇文章主要給大家介紹了關(guān)于Pandas創(chuàng)建DataFrame提示:type?object?‘object‘?has?no?attribute?‘dtype‘的解決方案,需要的朋友可以參考下
    2023-02-02
  • Python的Flask框架標(biāo)配模板引擎Jinja2的使用教程

    Python的Flask框架標(biāo)配模板引擎Jinja2的使用教程

    Jinja2是Python世界的一款高人氣template engine,是許多開源Web框架的選擇,包括Flask這樣的明星級項(xiàng)目,這里我們就來共同學(xué)習(xí)Python的Flask框架標(biāo)配模板引擎Jinja2的使用教程
    2016-07-07
  • Scrapy框架基本命令與settings.py設(shè)置

    Scrapy框架基本命令與settings.py設(shè)置

    這篇文章主要介紹了Scrapy框架基本命令與settings.py設(shè)置,結(jié)合實(shí)例形式分析了創(chuàng)建爬蟲項(xiàng)目、創(chuàng)建爬蟲文件、存儲、打開網(wǎng)頁及settings.py設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下
    2020-02-02
  • django連接mysql數(shù)據(jù)庫及建表操作實(shí)例詳解

    django連接mysql數(shù)據(jù)庫及建表操作實(shí)例詳解

    這篇文章主要介紹了django連接mysql數(shù)據(jù)庫及建表操作,結(jié)合實(shí)例形式詳細(xì)分析了Django框架連接mysql數(shù)據(jù)庫、創(chuàng)建與查詢數(shù)據(jù)表相關(guān)操作實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-12-12
  • Windows上安裝tensorflow  詳細(xì)教程(圖文詳解)

    Windows上安裝tensorflow 詳細(xì)教程(圖文詳解)

    這篇文章主要介紹了Windows上安裝TENSORFLOW 詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Python3 關(guān)于pycharm自動(dòng)導(dǎo)入包快捷設(shè)置的方法

    Python3 關(guān)于pycharm自動(dòng)導(dǎo)入包快捷設(shè)置的方法

    今天小編就為大家分享一篇Python3 關(guān)于pycharm自動(dòng)導(dǎo)入包快捷設(shè)置的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01

最新評論

司法| 浮梁县| 吉木萨尔县| 德清县| 济阳县| 泉州市| 镶黄旗| 白沙| 冷水江市| 高唐县| 岳阳市| 科技| 岳阳市| 临洮县| 翁牛特旗| 澄迈县| 如东县| 中西区| 神池县| 大冶市| 治县。| 呼和浩特市| 比如县| 东宁县| 开鲁县| 桃园市| 桓仁| 吐鲁番市| 辉南县| 平定县| 洛隆县| 高陵县| 客服| 华阴市| 沾化县| 莱阳市| 高邮市| 清水县| 芜湖市| 旬阳县| 来安县|