1717 字
9 分钟
本地AI搭建-python示例代码
Random Cover
对话API知识点
获取API Key
API Key可以在DeepSeek官网获取。
获取后建议不要写在代码里面,建议使用环境变量保存
首次调用API
DeepSeek API 使用与 OpenAI 兼容的 API 格式,通过修改配置,您可以使用 OpenAI SDK 来访问 DeepSeek API,或使用与 OpenAI API 兼容的软件。
| PARAM | VALUE |
|---|---|
| base_url * | https://api.deepseek.com |
| api_key | apply for an API key |
-
出于与 OpenAI 兼容考虑,您也可以将
base_url设置为https://api.deepseek.com/v1来使用,但注意,此处v1与模型版本无关。 -
deepseek-chat模型已全面升级为 DeepSeek-V3,接口不变。 通过指定model='deepseek-chat'即可调用 DeepSeek-V3。 -
deepseek-reasoner是 DeepSeek 最新推出的推理模型 DeepSeek-R1。通过指定model='deepseek-reasoner',即可调用 DeepSeek-R1。
调用API示例
curl
curl https://api.deepseek.com/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <DeepSeek API Key>" \ -d '{ "model": "deepseek-chat", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"} ], "stream": false }'python
# Please install OpenAI SDK first: `pip3 install openai`# 需要先安装openai支持: `pip3 install openai`
from openai import OpenAI
client = OpenAI(api_key="<DeepSeek API Key>", base_url="https://api.deepseek.com")
response = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "You are a helpful assistant"}, {"role": "user", "content": "Hello"}, ], stream=False)
print(response.choices[0].message.content)nodejs
// Please install OpenAI SDK first: `npm install openai`// 需要先安装openai支持: `npm install openai`
import OpenAI from 'openai'
const openai = new OpenAI({ baseURL: 'https://api.deepseek.com', apiKey: '<DeepSeek API Key>',})
async function main() { const completion = await openai.chat.completions.create({ messages: [{role: 'system', content: 'You are a helpful assistant.'}], model: 'deepseek-chat', })
console.log(completion.choices[0].message.content)}
main()关于role参数
在AI对话系统中,role参数用于区分对话中不同参与者的身份或角色:
messages.push({role: 'user', content: userMessage})这里的role可以有以下几种取值,每种都有特定含义:
1. 主要角色类型
| 角色(role) | 说明 |
|---|---|
"system" | 系统指令,用于设置AI的初始行为或背景 |
"user" | 用户发送的消息/问题 |
"assistant" | AI助手的回复 |
2. 具体解释
-
system (系统角色)
- 通常放在对话历史的最开始
- 用于设定AI的行为模式或对话上下文
- 例如:
{ role: "system", content: "你是一个专业的医疗助手,用简单易懂的语言回答" }
-
user (用户角色)
- 代表人类用户输入的内容
- 例如:
{ role: "user", content: "感冒有哪些症状?" }
-
assistant (助手角色)
- 代表AI之前的回复内容
- 用于维持对话上下文
- 例如:
{ role: "assistant", content: "感冒常见症状包括..." }
3. 为什么需要区分角色?
- 上下文维护:AI需要知道哪些是用户说的,哪些是自己说过的
- 行为控制:系统消息可以指导AI如何回应
- 多轮对话:保持对话的自然流畅性
4. 实际对话示例
一个完整的messages数组可能长这样:
;[ {role: 'system', content: '你是一个有帮助的助手'}, {role: 'user', content: '你好'}, {role: 'assistant', content: '你好!有什么可以帮您的吗?'}, {role: 'user', content: '推荐几本好书'},]5. 在你的代码中的作用
当你执行:
messages.push({role: 'user', content: userMessage})你是在告诉AI: “接下来这条消息是用户(user)发送的,内容是userMessage”
这样当AI处理时,就能正确理解对话的流向和上下文关系。
6. 高级用法
有些API可能还支持其他角色,如:
"function"- 用于函数调用"tool"- 用于工具调用
但在基础对话场景中,主要使用上述三种基本角色。
本地AI对接DeepSeek
首先需要在DeepSeek官网购买API,获取API Key,随后可以使用脚本搭建一个本地对话
from openai import OpenAIimport os
# 初始化对话历史messages = [ {"role": "system", "content": "你是一个乐于助人的AI助手"},]
def main(): # 建议从环境变量读取API Key api_key = os.getenv("DEEPSEEK_API_KEY") or input("请输入DeepSeek API Key: ")
if not api_key: print("API Key不能为空!") return
client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com") print("请输入任意问题回车发出对话(键入exit退出): ")
counter = 0
while True: try: counter += 1 user_input = input(f"{counter}.问:")
if user_input.lower() == "exit": break
messages.append({"role": "user", "content": user_input})
print(f"{counter}.AI:", end="", flush=True) assistant_output = ""
response = client.chat.completions.create( model="deepseek-reasoner", messages=messages, stream=True, )
for chunk in response: if chunk.choices[0].delta.content: content = chunk.choices[0].delta.content assistant_output += content print(content, end="", flush=True)
print("") # 换行 messages.append({"role": "assistant", "content": assistant_output})
except KeyboardInterrupt: print("\n对话已中断") break except Exception as e: print(f"\n发生错误: {str(e)}") break
if __name__ == '__main__': main()如果需要UI界面,也可以本地创建一个web服务,加入web服务后完整代码如下
from flask import Flask, render_template_string, request, jsonifyfrom openai import OpenAIimport os
app = Flask(__name__)
# 初始化对话历史messages = [ {"role": "system", "content": "你是一个乐于助人的AI助手"},]
# 建议从环境变量读取API Keyapi_key = os.getenv("DEEPSEEK_API_KEY")client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com")
# HTML模板HTML_TEMPLATE = """<!DOCTYPE html><html><head> <title>AI对话助手</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f5f5f5; } .chat-container { background-color: white; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 20px; height: 500px; overflow-y: auto; margin-bottom: 20px; } .message { margin-bottom: 15px; padding: 10px 15px; border-radius: 18px; max-width: 70%; word-wrap: break-word; } .user-message { background-color: #e3f2fd; margin-left: auto; border-bottom-right-radius: 5px; } .assistant-message { background-color: #f1f1f1; margin-right: auto; border-bottom-left-radius: 5px; } #input-form { display: flex; gap: 10px; } #user-input { flex-grow: 1; padding: 10px; border-radius: 20px; border: 1px solid #ddd; } button { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 20px; cursor: pointer; } button:hover { background-color: #45a049; } .typing-indicator { display: inline-block; padding: 10px 15px; background-color: #f1f1f1; border-radius: 18px; margin-bottom: 15px; border-bottom-left-radius: 5px; } .typing-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: #888; margin: 0 2px; animation: typing-animation 1.4s infinite ease-in-out; } .typing-dot:nth-child(1) { animation-delay: 0s; } .typing-dot:nth-child(2) { animation-delay: 0.2s; } .typing-dot:nth-child(3) { animation-delay: 0.4s; } @keyframes typing-animation { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-5px); } } </style></head><body> <h1>AI对话助手</h1> <div class="chat-container" id="chat-container"> {% for message in messages %} {% if message.role == 'user' %} <div class="message user-message">{{ message.content }}</div> {% elif message.role == 'assistant' %} <div class="message assistant-message">{{ message.content }}</div> {% endif %} {% endfor %} <div id="typing-indicator" style="display: none;"> <div class="typing-indicator"> <span class="typing-dot"></span> <span class="typing-dot"></span> <span class="typing-dot"></span> </div> </div> </div> <form id="input-form" onsubmit="sendMessage(); return false;"> <input type="text" id="user-input" placeholder="输入你的问题..." autocomplete="off"> <button type="submit">发送</button> </form>
<script> function sendMessage() { const input = document.getElementById('user-input'); const message = input.value.trim(); if (!message) return;
// 显示用户消息 const chatContainer = document.getElementById('chat-container'); const userMessageDiv = document.createElement('div'); userMessageDiv.className = 'message user-message'; userMessageDiv.textContent = message; chatContainer.appendChild(userMessageDiv);
// 显示打字指示器 const typingIndicator = document.getElementById('typing-indicator'); typingIndicator.style.display = 'block';
// 清空输入框 input.value = '';
// 滚动到底部 chatContainer.scrollTop = chatContainer.scrollHeight;
// 发送到服务器 fetch('/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: message }) }) .then(response => response.json()) .then(data => { // 隐藏打字指示器 typingIndicator.style.display = 'none';
// 显示AI回复 const assistantMessageDiv = document.createElement('div'); assistantMessageDiv.className = 'message assistant-message'; assistantMessageDiv.textContent = data.response; chatContainer.appendChild(assistantMessageDiv);
// 滚动到底部 chatContainer.scrollTop = chatContainer.scrollHeight; }) .catch(error => { console.error('Error:', error); typingIndicator.style.display = 'none';
const errorDiv = document.createElement('div'); errorDiv.className = 'message assistant-message'; errorDiv.textContent = '抱歉,发生了错误: ' + error; chatContainer.appendChild(errorDiv);
chatContainer.scrollTop = chatContainer.scrollHeight; }); }
// 允许按Enter键发送消息 document.getElementById('user-input').addEventListener('keypress', function(e) { if (e.key === 'Enter') { sendMessage(); } }); </script></body></html>"""
@app.route('/')def home(): return render_template_string(HTML_TEMPLATE, messages=messages[1:]) # 跳过系统消息
@app.route('/chat', methods=['POST'])def chat(): user_message = request.json.get('message') if not user_message: return jsonify({"error": "消息不能为空"}), 400
# 添加用户消息到历史 messages.append({"role": "user", "content": user_message})
try: # 获取AI回复 response = client.chat.completions.create( model="deepseek-reasoner", messages=messages, stream=False, )
assistant_output = response.choices[0].message.content
# 添加AI回复到历史 messages.append({"role": "assistant", "content": assistant_output})
return jsonify({"response": assistant_output})
except Exception as e: return jsonify({"error": str(e)}), 500
if __name__ == '__main__': # 在局域网中运行,host='0.0.0.0' 允许其他设备访问 app.run(host='0.0.0.0', port=5000, debug=True)参考资料
本地AI搭建-python示例代码
https://march7th.online/blog/posts/0030-本地ai搭建-python/ 最后更新于 2025-05-25,距今已过 168 天
部分内容可能已过时
March7th