河北省地图专业网站优化培训
在Linux系统命令行如何调用deepseek官方API调用AI大模型?
书接上文:
同样的开头哈哈哈哈:
”在这个AI技术飞速发展的时代,每一个程序员都应该问问自己:如何将人工智能的强大能力融入到我们熟悉的操作系统中?Linux,这个开源世界的基石,正在悄然拥抱这场认知革命。你是否想过,在你的服务器、你的开发环境中,也能轻松接入强大的AI大模型?这不仅仅是一个技术突破,更是一场开源精神与人工智能的完美邂逅。无需复杂界面,只需几行命令就能让AI帮你解答数学题、写代码、甚至分析数据!本文将手把手教你 零基础搭建专属AI命令行工具,让你在终端里体验「钢铁侠的贾维斯」般的智能助手!“
但我们今天不再使用本地搭建的AI大模型了,毕竟自己的电脑性能有限,搭建的AI大模型根本没办法支撑我们进行一些复杂共工作,所以我今天为大家介绍如何调用官方API进行使用AI大模型。
开始吧~~~
充值
哈哈哈哈哈么得办法,想用人家好一点的AI大模型就只能充钱啦,当然在网页上使用是无需花费的,但是我们毕竟要调用嘛,所以还是要收费的。
搜索deepseek官方:
点击API开放平台:
在充值界面就可以支付相应的金额了,毕竟是按照请求的token算的,整10块应该能用好久的了,当然仅限没事的时候玩玩哈。
二.创建API Keys
充值完成之后,点击API Keys,创建一个Keys,随便起一个名字,官方也有提示:
列表内是你的全部 API key,API key 仅在创建时可见可复制,请妥善保存。不要与他人共享你的 API key,或将其暴露在浏览器或其他客户端代码中。创建一个Keys后自己要记得好好保存哦,只能查看一次这个Keys。
创建完成之后我们就可以去Linux系统上进行操作了。
三.搭建Linux基本环境
创建调用文件:
[root@ai-linux ~]# touch /usr/local/bin/ai
[root@ai-linux ~]# vi /usr/local/bin/ai
#!/bin/bash# 配置参数
API_KEY="你的API Keys"
API_URL="https://api.deepseek.com/v1/chat/completions"
MODEL_NAME="deepseek-chat"# 构建请求数据
QUESTION="$*"
REQUEST_DATA=$(jq -n \--arg q "$QUESTION" \--arg model "$MODEL_NAME" \'{model: $model, messages: [{role: "user", content: $q}], temperature: 0.0}') #0.0表示我要调用它干推理的事情# 发送请求并捕获响应
response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST "$API_URL" \-H "Content-Type: application/json" \-H "Authorization: Bearer $API_KEY" \-d "$REQUEST_DATA")# 分离状态码和响应内容
http_status=$(echo "$response" | grep 'HTTP_STATUS:' | cut -d':' -f2 | tr -d ' ')
response_body=$(echo "$response" | sed '/HTTP_STATUS:/d')# 错误处理
if [[ $http_status -ne 200 ]]; thenecho "Error: API request failed (HTTP $http_status)" >&2echo "$response_body" | jq . >&2exit 1
fi# 提取并格式化内容
content=$(echo "$response_body" | jq -r '.choices[0].message.content' 2>/dev/null)# 美化输出格式
if [ -n "$content" ]; thenecho "$content" | awk '# 移除Markdown标记{ gsub(/\\n### |### |\\n---.*|\*\*/, "") }# 处理列表项/^[0-9]+\./ { gsub(/^[0-9]+\./, "•")print " " $0next}# 处理空行/^$/ { print ; next }# 默认输出{ print }' | sed -e 's/\\n/\n/g' -e 's/“/"/g' -e 's/”/"/g'
elseecho "Error: Empty response" >&2exit 1
fi
赋予执行权限:
[root@ai-linux ~]# chmod +x /usr/local/bin/ai
下载jq工具:
[root@ai-linux ~]# yum -y install epel-release
[root@ai-linux ~]# yum -y install jq
那么接下来我们就可以开始玩了哦。
四.测试
介绍一下什么是Kubernetes:
[root@ai-linux ~]# ai "讲解一下Kubernetes的原理。"
Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。其核心原理围绕声明式配置和控制器模式展开,通过一系列组件协同工作实现分布式系统的自动化运维。以下是其核心原理的详细解析:---一、核心架构
Kubernetes采用主从架构(Master-Worker),分为控制平面(Control Plane)和工作节点(Node)两部分:#1. 控制平面(Master)- API Server:核心入口,接收所有REST请求(如`kubectl`命令),验证并更新集群状态到`etcd`。- etcd:分布式键值数据库,存储集群所有配置数据和状态(如Pod、Service等资源对象)。- Scheduler:监听未调度的Pod,根据资源需求、亲和性等规则将其绑定到合适节点。- Controller Manager:运行多个控制器(如Deployment、ReplicaSet控制器),持续比对实际状态与期望状态,驱动集群向目标状态收敛。#2. 工作节点(Node)- kubelet:节点代理,负责与API Server通信,管理本机Pod生命周期(创建/销毁容器)、监控资源使用。- kube-proxy:维护节点网络规则(如iptables/IPVS),实现Service的负载均衡和流量转发。- 容器运行时(如containerd、CRI-O):实际运行容器的引擎。---二、核心概念与工作原理
#1. 声明式API与期望状态(Desired State)- 用户通过YAML/JSON文件定义应用的期望状态(如副本数、镜像版本)。- Kubernetes持续监控实际状态,通过控制循环(Control Loop)自动修复偏差(如重启崩溃的Pod)。#2. Pod:最小调度单元- 一个Pod包含一个或多个共享网络/存储的容器,是K8s调度的基本单位。- 每个Pod分配唯一IP,内部容器通过`localhost`通信。#3. 控制器模式(Controller Pattern)- Deployment:管理无状态应用,通过ReplicaSet确保指定数量的Pod副本运行,支持滚动更新和回滚。- StatefulSet:为有状态应用(如数据库)提供有序部署、持久化存储和稳定网络标识。- DaemonSet:确保每个节点运行一个Pod副本(如日志收集器)。- Job/CronJob:运行一次性或定时任务。#4. 服务发现与负载均衡- Service:为一组Pod提供稳定的虚拟IP(ClusterIP)和DNS名称,流量自动负载均衡到后端Pod。- Ingress:通过HTTP路由规则暴露服务到集群外,支持基于路径/域名的流量分发。#5. 配置与存储管理- ConfigMap/Secret:将配置或敏感数据(如密码)与容器解耦,通过环境变量或卷挂载使用。- PersistentVolume(PV):抽象存储资源(如云盘、NFS),由PersistentVolumeClaim(PVC)动态申请。---三、关键工作流程示例
#1. Pod创建流程1. 用户提交Pod定义到API Server。2. Scheduler选择合适节点,绑定Pod与节点。3. 目标节点的kubelet通过容器运行时创建Pod。4. 控制器持续监控Pod状态,确保与期望状态一致。#2. Service流量转发- 用户创建Service时,kube-proxy在节点上配置iptables规则。- 请求到达Service IP时,自动转发到后端Pod(通过Endpoints对象动态维护)。---四、扩展机制• CRD(Custom Resource Definition):自定义资源类型,扩展K8s API。• Operator:基于CRD和控制器模式,封装领域知识(如管理数据库集群)。---五、设计思想
- 声明式优于命令式:用户关注"做什么"而非"如何做"。
- 自愈能力:自动重启失败容器、替换不可用节点。
- 水平扩展:通过控制器轻松调整应用规模。---六、可视化理解
```
用户提交YAML → API Server → etcd存储期望状态↓
控制器检测偏差 → 驱动创建Pod → Scheduler分配节点 → kubelet运行容器↓
Service/Ingress暴露服务 → kube-proxy配置流量规则
```Kubernetes通过分层抽象和自动化机制,将复杂的分布式系统管理简化为对声明式配置的操作,成为云原生时代的操作系统级平台。
可以看到,由于我们在/usr/local/bin/ai文件中定义了很多关于格式的操作,致使ai输出的文件是比较干净整洁的,并且格式也较为合理,如果不去设置相关规则,那么他输出的就会很乱套,比如:
哈哈哈哈哈。
我们让他写写Kubernetes的yaml文件试试:
编写一个wordpress搭建脚本,定义数据库镜像版本、wordpress版本、pv-pvc持久化存储:
[root@ai-linux ~]# ai "在Kubernetes部署一个wordpress,要求要使用PV和PVC实现持久化存储,数据库使用mysql:5.7,wordpress使用latest,帮我写成一个yaml"
以下是一个使用 PV 和 PVC 实现持久化存储的 WordPress 部署 YAML 文件,包含 MySQL 5.7 数据库:```yaml
apiVersion: v1
kind: Namespace
metadata:name: wordpress
---
# MySQL 持久卷声明 (PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mysql-pvcnamespace: wordpress
spec:accessModes:- ReadWriteOnceresources:requests:storage: 5GistorageClassName: standard
---
# WordPress 持久卷声明 (PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: wordpress-pvcnamespace: wordpress
spec:accessModes:- ReadWriteOnceresources:requests:storage: 5GistorageClassName: standard
---
# MySQL 部署
apiVersion: apps/v1
kind: Deployment
metadata:name: mysqlnamespace: wordpress
spec:selector:matchLabels:app: mysqlstrategy:type: Recreatetemplate:metadata:labels:app: mysqlspec:containers:- image: mysql:5.7name: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: rootpassword- name: MYSQL_DATABASEvalue: wordpress- name: MYSQL_USERvalue: wordpress- name: MYSQL_PASSWORDvalue: wordpressports:- containerPort: 3306name: mysqlvolumeMounts:- name: mysql-persistent-storagemountPath: /var/lib/mysqlvolumes:- name: mysql-persistent-storagepersistentVolumeClaim:claimName: mysql-pvc
---
# MySQL 服务
apiVersion: v1
kind: Service
metadata:name: mysqlnamespace: wordpress
spec:ports:- port: 3306selector:app: mysqlclusterIP: None
---
# WordPress 部署
apiVersion: apps/v1
kind: Deployment
metadata:name: wordpressnamespace: wordpress
spec:selector:matchLabels:app: wordpressstrategy:type: Recreatetemplate:metadata:labels:app: wordpressspec:containers:- image: wordpress:latestname: wordpressenv:- name: WORDPRESS_DB_HOSTvalue: mysql- name: WORDPRESS_DB_USERvalue: wordpress- name: WORDPRESS_DB_PASSWORDvalue: wordpress- name: WORDPRESS_DB_NAMEvalue: wordpressports:- containerPort: 80name: wordpressvolumeMounts:- name: wordpress-persistent-storagemountPath: /var/www/htmlvolumes:- name: wordpress-persistent-storagepersistentVolumeClaim:claimName: wordpress-pvc
---
# WordPress 服务
apiVersion: v1
kind: Service
metadata:name: wordpressnamespace: wordpress
spec:type: NodePortports:- port: 80nodePort: 30080selector:app: wordpress
```使用说明:• 这个 YAML 文件创建了一个名为 `wordpress` 的命名空间• 为 MySQL 和 WordPress 分别创建了 PVC(PersistentVolumeClaim)• 部署了 MySQL 5.7 数据库,使用 PVC 持久化存储数据• 部署了最新版 WordPress,同样使用 PVC 持久化存储• 创建了 WordPress 的 NodePort 服务,可以通过节点 IP 和 30080 端口访问注意事项:• 根据你的 Kubernetes 集群环境,可能需要调整 `storageClassName`(默认为 "standard")• 生产环境中建议使用更安全的密码替换示例中的密码• 如果需要使用动态存储供应,确保你的集群已配置 StorageClass• 对于生产环境,建议考虑使用 StatefulSet 替代 Deployment 来管理数据库要应用这个配置,保存为 wordpress.yaml 后运行:
```bash
kubectl apply -f wordpress.yaml
```
写个Python代码:
[root@ai-linux ~]# ai "使用Python写一个俄罗斯方块。"# Python俄罗斯方块游戏下面是一个使用Python和Pygame库实现的简单俄罗斯方块游戏:```python
import pygame
import random# 初始化
pygame.init()# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
COLORS = [(0, 255, 255), # I - 青色(0, 0, 255), # J - 蓝色(255, 165, 0), # L - 橙色(255, 255, 0), # O - 黄色(0, 255, 0), # S - 绿色(128, 0, 128), # T - 紫色(255, 0, 0) # Z - 红色
]# 游戏设置
BLOCK_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SCREEN_WIDTH = BLOCK_SIZE * (GRID_WIDTH + 6)
SCREEN_HEIGHT = BLOCK_SIZE * GRID_HEIGHT
GAME_AREA_LEFT = BLOCK_SIZE# 方块形状
SHAPES = [[[1, 1, 1, 1]], # I[[1, 0, 0],[1, 1, 1]], # J[[0, 0, 1],[1, 1, 1]], # L[[1, 1],[1, 1]], # O[[0, 1, 1],[1, 1, 0]], # S[[0, 1, 0],[1, 1, 1]], # T[[1, 1, 0],[0, 1, 1]] # Z
]# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")clock = pygame.time.Clock()class Tetris:def __init__(self):self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]self.current_piece = self.new_piece()self.game_over = Falseself.score = 0self.level = 1self.fall_speed = 0.5 # 初始下落速度(秒)self.fall_time = 0def new_piece(self):# 随机选择一个方块形状shape = random.choice(SHAPES)color = COLORS[SHAPES.index(shape)]# 初始位置(居中)x = GRID_WIDTH // 2 - len(shape[0]) // 2y = 0return {"shape": shape, "color": color, "x": x, "y": y}def valid_move(self, piece, x_offset=0, y_offset=0):for y, row in enumerate(piece["shape"]):for x, cell in enumerate(row):if cell:new_x = piece["x"] + x + x_offsetnew_y = piece["y"] + y + y_offsetif (new_x < 0 or new_x >= GRID_WIDTH or new_y >= GRID_HEIGHT or (new_y >= 0 and self.grid[new_y][new_x])):return Falsereturn Truedef rotate_piece(self):# 获取当前方块形状shape = self.current_piece["shape"]# 旋转矩阵(转置然后反转每一行)rotated = [[shape[y][x] for y in range(len(shape)-1, -1, -1)] for x in range(len(shape[0]))]old_shape = self.current_piece["shape"]self.current_piece["shape"] = rotated# 如果旋转后位置无效,则恢复原状if not self.valid_move(self.current_piece):self.current_piece["shape"] = old_shapedef lock_piece(self):for y, row in enumerate(self.current_piece["shape"]):for x, cell in enumerate(row):if cell:if self.current_piece["y"] + y < 0:self.game_over = Trueelse:self.grid[self.current_piece["y"] + y][self.current_piece["x"] + x] = self.current_piece["color"]# 检查是否有完整的行self.clear_lines()# 生成新方块self.current_piece = self.new_piece()# 检查游戏是否结束if not self.valid_move(self.current_piece):self.game_over = Truedef clear_lines(self):lines_cleared = 0for y in range(GRID_HEIGHT):if all(self.grid[y]):lines_cleared += 1# 移动上面的行下来for y2 in range(y, 0, -1):self.grid[y2] = self.grid[y2-1][:]self.grid[0] = [0 for _ in range(GRID_WIDTH)]# 更新分数if lines_cleared == 1:self.score += 100 * self.levelelif lines_cleared == 2:self.score += 300 * self.levelelif lines_cleared == 3:self.score += 500 * self.levelelif lines_cleared == 4:self.score += 800 * self.level# 更新等级和下落速度self.level = self.score // 2000 + 1self.fall_speed = max(0.05, 0.5 - (self.level - 1) * 0.05)def update(self, delta_time):if self.game_over:returnself.fall_time += delta_timeif self.fall_time >= self.fall_speed:self.fall_time = 0if self.valid_move(self.current_piece, 0, 1):self.current_piece["y"] += 1else:self.lock_piece()def draw(self):# 绘制游戏区域背景pygame.draw.rect(screen, BLACK, (GAME_AREA_LEFT, 0, BLOCK_SIZE * GRID_WIDTH, SCREEN_HEIGHT))# 绘制网格线for x in range(GRID_WIDTH + 1):pygame.draw.line(screen, GRAY, (GAME_AREA_LEFT + x * BLOCK_SIZE, 0), (GAME_AREA_LEFT + x * BLOCK_SIZE, SCREEN_HEIGHT))for y in range(GRID_HEIGHT + 1):pygame.draw.line(screen, GRAY, (GAME_AREA_LEFT, y * BLOCK_SIZE), (GAME_AREA_LEFT + GRID_WIDTH * BLOCK_SIZE, y * BLOCK_SIZE))# 绘制已固定的方块for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):if self.grid[y][x]:pygame.draw.rect(screen, self.grid[y][x], (GAME_AREA_LEFT + x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))pygame.draw.rect(screen, WHITE, (GAME_AREA_LEFT + x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)# 绘制当前方块if not self.game_over:for y, row in enumerate(self.current_piece["shape"]):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, self.current_piece["color"], (GAME_AREA_LEFT + (self.current_piece["x"] + x) * BLOCK_SIZE, (self.current_piece["y"] + y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))pygame.draw.rect(screen, WHITE, (GAME_AREA_LEFT + (self.current_piece["x"] + x) * BLOCK_SIZE, (self.current_piece["y"] + y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)# 绘制分数和等级font = pygame.font.SysFont(None, 36)score_text = font.render(f"分数: {self.score}", True, WHITE)level_text = font.render(f"等级: {self.level}", True, WHITE)screen.blit(score_text, (GAME_AREA_LEFT + GRID_WIDTH * BLOCK_SIZE + 10, 30))screen.blit(level_text, (GAME_AREA_LEFT + GRID_WIDTH * BLOCK_SIZE + 10, 70))# 游戏结束提示if self.game_over:font = pygame.font.SysFont(None, 48)game_over_text = font.render("游戏结束!", True, (255, 0, 0))screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2 - 30))def main():game = Tetris()running = Truewhile running:delta_time = clock.tick(60) / 1000.0 # 转换为秒for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif not game.game_over:if event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:if game.valid_move(game.current_piece, -1, 0):game.current_piece["x"] -= 1elif event.key == pygame.K_RIGHT:if game.valid_move(game.current_piece, 1, 0):game.current_piece["x"] += 1elif event.key == pygame.K_DOWN:if game.valid_move(game.current_piece, 0, 1):game.current_piece["y"] += 1elif event.key == pygame.K_UP:game.rotate_piece()elif event.key == pygame.K_SPACE:# 硬降落while game.valid_move(game.current_piece, 0, 1):game.current_piece["y"] += 1game.lock_piece()screen.fill(BLACK)game.update(delta_time)game.draw()pygame.display.flip()pygame.quit()if __name__ == "__main__":main()
```## 游戏说明• 控制方式:- 左箭头:向左移动方块- 右箭头:向右移动方块- 下箭头:加速下落- 上箭头:旋转方块- 空格键:硬降落(立即下落到底部)• 游戏规则:- 当一行被填满时,该行会被消除,上面的行会下落- 消除的行数越多,得分越高- 随着分数增加,游戏等级会提高,方块下落速度会加快- 当新方块无法放置时,游戏结束• 运行要求:- 需要安装Pygame库:`pip install pygame`这个实现包含了俄罗斯方块的基本功能,你可以根据需要进一步扩展,比如添加音效、暂停功能、下一个方块预览等。
哈哈哈哈当然可以这么玩哈,但是一定要注意自己的余额¥!
那我就再用一个相同的结尾结束这篇文章吧:
“想象一下,当Linux的稳定性和可定制性遇上AI的强大能力,会迸发出怎样的火花?这不仅让开发者如虎添翼,更为整个开源生态注入了新的活力。未来的世界级应用或许就诞生于这样的结合之中。现在,让我们一起走进这个激动人心的技术前沿,探索如何将Linux与AI大模型完美融合,开启属于我们的智能化新时代!“