From a60ad01a3a987964b0329b9243ac810d366ed2ba Mon Sep 17 00:00:00 2001 From: liujie_student2 <101@qq.com> Date: Tue, 22 Sep 2026 14:33:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0w1=5Fd2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .idea/vcs.xml | 6 + test.py | 20 + w1_d1/git.md | 412 ++++++++++++++++++ w1_d2/deepseek_api.py | 27 ++ w1_d2/llm-api-demo/01_deepseek_demo.py | 22 + w1_d2/llm-api-demo/02_qwen_demo.py | 23 + w1_d2/llm-api-demo/03_streaming_demo.py | 37 ++ w1_d2/llm-api-demo/04_multi_turn_demo.py | 47 ++ .../05_deepseek_api_params_demo.py | 253 +++++++++++ w1_d2/llm-api-demo/06_dashscope.py | 17 + w1_d2/llm-api-demo/requirements.txt | 1 + 12 files changed, 867 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/vcs.xml create mode 100644 test.py create mode 100644 w1_d1/git.md create mode 100644 w1_d2/deepseek_api.py create mode 100644 w1_d2/llm-api-demo/01_deepseek_demo.py create mode 100644 w1_d2/llm-api-demo/02_qwen_demo.py create mode 100644 w1_d2/llm-api-demo/03_streaming_demo.py create mode 100644 w1_d2/llm-api-demo/04_multi_turn_demo.py create mode 100644 w1_d2/llm-api-demo/05_deepseek_api_params_demo.py create mode 100644 w1_d2/llm-api-demo/06_dashscope.py create mode 100644 w1_d2/llm-api-demo/requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c96e81 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +.jbeval \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..49e3f2e --- /dev/null +++ b/test.py @@ -0,0 +1,20 @@ +class OpenAI(): + def __init__(self,api_key,base_url): + self.api_key=api_key, + self.base_url=base_url + + def create(self): + print('调用create1方法') + + @property + def create2(self): + print('调用create2方法') + return '调用大模型' + +client=OpenAI('123','www.wolin.com') + +print(client) +print(client.api_key) +client.create() +print(client.create) +print(client.create2) \ No newline at end of file diff --git a/w1_d1/git.md b/w1_d1/git.md new file mode 100644 index 0000000..db85211 --- /dev/null +++ b/w1_d1/git.md @@ -0,0 +1,412 @@ +## git介绍 + +- 思考1:任何项目,是否有多个版本?如果是,每个版本的代码是否需要保存? + - 有多个版本,每个版本的代码都要保存。如果没有其他工具可能就是一个文件夹一个版本,那样版本一多就乱了 +- 思考2:公司里的项目一般是多人开发的,要不要共享代码? + - 要共享代码,但是传统共享代码,就是微信传递、u盘传递等 +- 以上问题,都可以由`git`这个工具解决 +- git是什么? + - 一款分布式的版本管理、多人协作工具 +- 集中式版本管理 + - 一个团队的代码,全部集中存到一个服务器上。所以如果这个服务器挂,版本都没了 +- 分布式版本管理 + - 一个团队的代码,整体是存到服务器上的,但是当某个人下载这份代码,会相当于下载了全部的副本,这就叫分布式。好处:数据不易丢失 +- 总结:git是什么? + - 就是一款分布式的版本管理、多人协作的工具 + - 作用1:控制和记录版本变化 + - 作用2:方便多人协作共享代码 + - ....... + +## git下载与安装 + +[官网](https://git-scm.com/downloads) + +- 下载完了后就建议下一步下一步直到完成,毛都不要改 +- 建议:开发软件就建议装在C盘 +- 如何判断安装成功? + - windows系统可以:右键看有没有 `git bash here`,有就代表成功 + - 或者windows和mac都可以在`终端`(cmd、小黑窗),输入git按回车,如果出现一大坨英文,就代表成功 + +## git 配置用户名与邮箱 + +- 作用:用来标识自己是谁 + +- 配置方法: + - 打开小黑窗 + - 方法1:右键开始菜单,然后点运行,然后输入cmd按回车 + - 快捷键winows键+r再输入cmd回车 + - 方法2: + - 随便打开一个文件夹,在地址栏上输入cmd按回车 + - mac直接搜“终端”两个字 +- 命令如下 + +```Bash +# git config user.name 你的目标用户名 +# git config user.email 你的目标邮箱名 + +# 使用--global参数,配置全局的用户名和邮箱,只需要配置一次即可 +# 用户名有意义即可 +# 邮箱要真实可用 +git config --global user.name mm +git config --global user.email mm@mmm.com + +# 查看配置信息 +git config --list + +# 取消配置 - 把它们从配置文件里删掉 - 一般不用 +git config --unset --global user.name +git config --unset --global user.email +``` + +- 总结: + - 把`gitee`上的用户名和邮箱配置到git上 + - 要配置几次? + - 1次 + - 有什么用? + - 可以给服务器识别你的身份 + - 命令为 + +```Bash +git config --global user.name 用户名 +git config --global user.email 邮箱 +``` + +## 初始化仓库 + +- git作用:可以做版本管理,相当于游戏里的`存档` +- 并不是说你电脑上安装了git,那么所有的项目都被管理了 +- 而是你要给这个项目做**初始化仓库**的操作,才代表这个项目被git管理了 +- 如果希望一个项目被`git`要用 `git init`初始化这个项目 +- 步骤: + - 来到这个项目文件夹,右键`git bash here`会弹出一个专门给`git`用的小黑窗,而且直接就在这个项目的路径上,输入 + +```Bash +git init +- 敲完会在这个项目文件夹里多一个 `.git`的隐藏文件夹,所以如果以后在项目中看到有这个文件夹,代表这个项目已经被`git`管理,就不用再初始化了 +``` + +- 注意: + + `.git`文件夹不能删了,删了就相当于所有的`版本`都没了,只留下当前代码 + + - 有些人即使初始化了也看不到这个文件夹,是因为系统设置了隐藏文件夹不可见,所以可以通过下图设置 + + ![image-20230217113139174](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230217113139174.png) + + - 请问一个项目`搞一次`,而且这个项目如果已经有了,就不搞 + +## git - 记录改动 + +![image-20230216213606771](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230216213606771.png) + +- 作用:相当于就是产生`存档` +- git三大区域: + - 工作区:就是指项目代码 + - 暂存区和仓库区:对我们而言是不可见的 +- 如果你`工作区`改动了代码,想产生一个`存档`,就要先把改动加到`暂存区`,再加到`仓库区` +- 先改代码,然后敲命令 + +```Bash +# 查看当前状态 +git status + +# 把当前改动到的所有文件都加到暂存区 +git add . +# 添加某个文件到暂存区 -- 用的少 +git add 文件名 + +# 把暂存区的内容提交到仓库区 +git commit -m'本次操作的说明文字' +``` + +- 如果仓库此时没有任何新的改动,`git status`会出现`干净`的提示 + + ![image-20230217114048810](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230217114048810.png) + +## git - 快速提交的说明 + +```Bash +git commit -a -m '提交说明' +``` + +- 仅能用于本就存在于仓库的文件 +- 仓库中新建的文件,还是得先加到`暂存区`,再提交到`仓库区` + +## git - 修改已提交的说明文字 + +- 如果刚刚提交的文字不小心写错了,可以修改 + +```Bash +git commit --amend +``` + +- 此时会进入到编辑模式,默认的编辑器非常难用 + - 进入后你需要输入`i`,代表进入修改,然后通过键盘上下左右改动光标位置,再把你需要的文字删掉或改掉 + - 改完后,还得按一下`esc`键,然后英文状态下输入 `:wq`按回车才代表修改完成 + - ``` + git config --global core.editor "notepad" + ``` + + + +## git - 查看记录 + +```Bash +# 查看详细记录 +git log + +# 一行显示每条记录 +git log --oneline +``` + +## git - 回滚记录 + +- 作用:可以把代码恢复到某个记录的状态 +- 命令 + +```Bash +git reset --hard 记录的hash值(记录的id) +- 如何获取记录的hash值? +git log +# 用的多 +git log --oneline +``` + +- 注意: + - 回滚到某个记录后,你再`git log`只能看到当前记录和它之前的,后面的看不到 + - 要想看到全部操作记录,用 + +```Bash +git reflog +``` + +- 练习: + - 要求产生至少3个记录 + - 能自由切换3个记录的代码 + - 最后一次一定要回滚到最新记录 + +## git - 配置被git忽略的文件 + +- 有些文件可能不需要被git管理,例如一些自己手写的笔记,密码等,那就可以配置忽略文件 +- 需要在仓库根目录,新建 `.gitignore`文件,在这个文件里写需要被忽略的文件,例 + +```JavaScript +密码.md +情书.md +小电影 +``` + +- 如果这些文件被git忽略,将不会被提交,也不受git记录变化而变化 + +## git - 分支的概念 + +- 所谓分支,就是指把当前的代码克隆一份 +- 这样做的好处是:可以按员工开分支代码,一人负责一个分支,好处是方便管理,以及某一个分支有问题绝对不影响其他分支 +- git初始化后,默认就会有一个分支叫`master`,我们也称之为主分支 +- 开发中有个规范:**主分支上不直接进行开发**,它里面只保留经过测试的最稳定的版本代码,开发不会直接在这个分支上进行 +- 所以还会在主分支的基础上克隆出一份代码(开一个新的分支),分支名叫`develop`或者`dev`,代表是专门用来开发的分支 +- 再然后在 `develop`基础上又开多个分支,不同的人负责不同的分支,他们写完代码,又各自合并到develop分支,然后经过大量测试和试运行发现很稳定,就合并到 `master`产生一个稳定的版本 + +![image-20230217162251228](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230217162251228.png) + +## git - 分支操作 + +- 命令如下 + +```Bash +# 查看当前所有分支 +git branch +# 新建分支 +git branch 分支名 +# 切换分支 +git checkout 分支名 + +# 新建分支并切换过去 +git checkout -b 分支名 +``` + +- 合并分支一定要小心(要找对分支、确保写的代码都已经提交了),再切换到想合并的目标分支 + - 比如我想合并到`develop`,我就要先切换到`develop` + +```Bash +git checkout develop +``` + +- 合并语法 + +```Bash +git merge 分支名 +# 例如:当前是develop分支,然后你写git merge zs,意思就是把zs分支的代码合并到develop里面 +git merge zs +``` + +- 练习要求: + - 默认有master分支,需要新建develop分支,再然后在develop基础上创建`dy`、`ls` + - `dy`写`dy`,`ls`写`ls`的代码(新建dy.html,ls.html) + - 每个分支写完了先提交到当前分支 + - 然后合并到develop + - 等develop有所有代码了,再合并到`master` + +## git - 分支合并冲突 + +- 工作中必须学会如何解决冲突 + +![img](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230217171545728.png) + +- 当不同分支负责人员改动到同一个文件,合并时就会产生冲突 + +- 如果冲突了,在vscode中将看到如下界面 + + ![](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230217171754089.png) + +- 三个选项具体怎么选要看需求 + + - 例如1:当前的有bug,所以领导指派李四去修复bug,然后合并过来,肯定是保留李四,也就是保留合并过来的(点第二个按钮) + - 例如2: 如果当前分支代码比较多,还包含了要合并过来的分支的代码,就选第一个 + - 例如3:如果两段代码分别是完成不同的功能,而且这两个功能都要,就选第三个都保留 + +## git - 删除分支 + +```Bash +git branch -d 分支名 +# 强行删 +git branch -D 分支名 +``` + +- 如果你要删某个分支,你要确保不在这个分支上,才可以删 +- 如果被删的分支有新的记录,但是还没有合并,那么也删不掉,用`git branch -D 分支名` + + + +## 远程仓库 - 建库、删库 + +- 建库 + +![image-20230218094506675](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218094506675.png) + +- 删库 + + ![image-20230218094553000](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218094553000.png) + + ![image-20230218094630995](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218094630995.png) + +## 远程仓库 - 添加团队成员 + +![image-20230218095123406](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218095123406.png) + +## 远程仓库 - 推送 + +- 让本地仓库跟远程仓库建立链接 + +```Bash +git remote add 起一个远程仓库名字 仓库地址 +git remote add origin https://gitee.com/xpzll/viewdemo95.git +``` + +- 推送代码到远程仓库 + +```Bash +git push -u origin "master" +``` + +- 以上两段命令,gitee上可以复制 +- 第一次推送会需要登录,但是这个登录只要成功一次,后面都不用登录 + +![image-20230218095746921](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218095746921.png) + +## 远程仓库 - 开源 + +![image-20230218095939726](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218095939726.png) + +## 远程仓库 - 多远程仓库连接 + +```Bash +# 建立链接 +git remote add origin 仓库地址 +``` + +- remote是远程的意思 +- add是添加的意思 +- origin只是给这个远程仓库的连接起了一个名字叫origin + +```Bash +# 把本地仓库推送到 origin 连接的远程仓库,并且也把远程仓库分支叫为master +git push -u origin "master" +``` + +- 所以如果你一个本地仓库,要推送多个远程仓库,要建立新的连接,而新的连接名字不能重复 + +```Bash +# 也就是说连接到这个新仓库的别名叫xx +git remote add xx 新仓库地址 + +## 意思是把本地仓库推送到xx这个连接的远程仓库 +git push -u xx "master" +``` + +## 远程仓库 - 删除连接 + +- 工作中一般一个本地仓库只连接一个远程仓库 +- 问题来了如果之前我在本地建立了一个连接,而且连接名字叫origin,后面再建立连接除非改名字,不然还叫origin会报错 +- 但是我就是想用origin,就把之前的origin删掉 + +```Bash +git remote remove origin +``` + +## 远程仓库 - 克隆 + +- 作用:把远程仓库的代码克隆下来 + +```Bash +# 要么这个仓库是开源,要么你是这个仓库的成员 +git clone 仓库地址 +``` + +## 远程仓库 - 拉取 + +- 作用:可以把远程仓库最新的代码拉取下来 + +```Bash +git pull +``` + +## 解决推送冲突 + +![img](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218111524877.png) + +- 解决办法: + - 先`git pull`拉取最新代码 + - 再`git push` +- 注意: + - 为什么以后只要写 `git push`,因为完整写法是之前空仓库用一次就够了,后面都不是空仓库,直接`push` + +## windows的凭据管理器 + +- 它把密码保存到windows的凭据管理器里了 +- 如果你不想用了,就去里面删除,如果删除了下次还得输入 +- 最多就是去里面修改它,因为我可能把gitee账号密码给改了,那这里也得修改 +- 或者如果公司刚好也是用gitee,而且公司没给你发电脑,你用的还是自己的电脑,而且还要满足公司的gitee没用你的邮箱,而是直接给你指派了邮箱,这时候就去要修改 + +## SSH私钥与公钥方式 + +- 因为有人的电脑因为系统原因是没有凭据管理的,那就意味着每次都要输入账号和密码 + +- 所以还有一种方式叫使用`私钥`配合`公钥`的形式来免登录 + + ![image-20230218120707585](https://typorapic-1306801437.cos.ap-guangzhou.myqcloud.com/image-20230218120707585.png) + +- 在任意小黑窗里输入如下命令 + +```Bash +ssh-keygen -t ed25519 -C "你的邮箱地址" +``` + +- 以后去到公司,公司负责人会问你要你的邮箱,或者问你要公钥 +- 如果是要邮箱,就要用`https`,然后输入账号和密码来登录 +- 如果问你要公钥,你就在电脑上生成公钥和私钥,再把公钥部分的内容发给负责人 +- 公钥文件以 `.pub`结尾,去`~/.ssh`文件夹找文件 +- ~代表自己电脑的个人文件夹 +- 例如: `C:\Users\你电脑的用户名\.ssh` +- 如果是账号密码登录用 `https`的仓库地址 +- 如果是公钥用`ssh`的仓库地址 \ No newline at end of file diff --git a/w1_d2/deepseek_api.py b/w1_d2/deepseek_api.py new file mode 100644 index 0000000..12456a7 --- /dev/null +++ b/w1_d2/deepseek_api.py @@ -0,0 +1,27 @@ +# Please install OpenAI SDK first: `pip3 install openai` +import os +from openai import OpenAI +from dotenv import load_dotenv +load_dotenv() +client = OpenAI( + api_key=os.environ.get('DEEPSEEK_API_KEY'), + base_url="https://api.deepseek.com") + +while True: + user_input=input("请输入你的问题:") + if user_input=="q": + break + response = client.chat.completions.create( + model="deepseek-v4-pro", + messages=[ + {"role": "system", "content": "You are a helpful assistant"}, + {"role": "user", "content": user_input}, + ], + stream=False, + reasoning_effort="high", + extra_body={"thinking": {"type": "enabled"}} + ) + print(response.choices[0].message.content) + + +# print(response.model_dump_json(indent=2)) diff --git a/w1_d2/llm-api-demo/01_deepseek_demo.py b/w1_d2/llm-api-demo/01_deepseek_demo.py new file mode 100644 index 0000000..ac514b0 --- /dev/null +++ b/w1_d2/llm-api-demo/01_deepseek_demo.py @@ -0,0 +1,22 @@ +# Please install OpenAI SDK first: `pip3 install openai` +import os +from openai import OpenAI +from dotenv import load_dotenv +load_dotenv() +client = OpenAI( + api_key=os.environ.get('DEEPSEEK_API_KEY'), + base_url="https://api.deepseek.com") + +response = client.chat.completions.create( + model="deepseek-v4-pro", + messages=[ + {"role": "system", "content": "You are a helpful assistant"}, + {"role": "user", "content": "Hello"}, + ], + stream=False, + reasoning_effort="high", + extra_body={"thinking": {"type": "enabled"}} +) + +# print(response.model_dump_json(indent=2)) +print(response.choices[0].message.content) \ No newline at end of file diff --git a/w1_d2/llm-api-demo/02_qwen_demo.py b/w1_d2/llm-api-demo/02_qwen_demo.py new file mode 100644 index 0000000..1a68e50 --- /dev/null +++ b/w1_d2/llm-api-demo/02_qwen_demo.py @@ -0,0 +1,23 @@ +# https://docs.bailian.console.aliyun.com/zh/model-studio/qwen-api-via-openai-chat-completions +import os +from openai import OpenAI +from dotenv import load_dotenv +load_dotenv() +WorkspaceId='llm-zw41x57m8nuezmhp' + +client = OpenAI( + # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx" + api_key=os.getenv("DASHSCOPE_API_KEY"), + base_url=f"https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1", +) + +completion = client.chat.completions.create( + # 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models + model="qwen3.8-max", + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "你是谁?"}, + ] +) +print(completion.model_dump_json(indent=2)) +print(completion.choices[0].message.content) \ No newline at end of file diff --git a/w1_d2/llm-api-demo/03_streaming_demo.py b/w1_d2/llm-api-demo/03_streaming_demo.py new file mode 100644 index 0000000..e3a64b2 --- /dev/null +++ b/w1_d2/llm-api-demo/03_streaming_demo.py @@ -0,0 +1,37 @@ +import os +from openai import OpenAI +from dotenv import load_dotenv + +load_dotenv() + +client = OpenAI( + api_key=os.environ.get("DEEPSEEK_API_KEY"), + base_url="https://api.deepseek.com", +) + +response = client.chat.completions.create( + model="deepseek-v4-flash", + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "请用三句夸赞一下大帝,大帝是我爸爸"} + ], + stream=True, # 开启流式输出 + # 不设置 reasoning_effort 和 extra_body 中的 thinking,即不使用深度思考 + reasoning_effort="high", + extra_body={"thinking": {"type": "disabled"}} +) + +count = 0 +for chunk in response: + content = chunk.choices[0].delta.content + if content: + count += 1 + print(f"[{count}] {content}") + +# 逐块输出内容 +# for chunk in response: +# # print(chunk) +# # ChatCompletionChunk(id='c2291fe4-6757-4de8-a7bb-5033f6a8bd03', choices=[Choice(delta=ChoiceDelta(content='', function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)], created=1790050006, model='deepseek-flash', object='chat.completion.chunk', moderation=None, obfuscation=None, service_tier=None, system_fingerprint='aeb56401ca74e127821c4f9126dcb669', usage=None) +# content = chunk.choices[0].delta.content +# if content: # 避免输出 None +# print(content, end="", flush=True) \ No newline at end of file diff --git a/w1_d2/llm-api-demo/04_multi_turn_demo.py b/w1_d2/llm-api-demo/04_multi_turn_demo.py new file mode 100644 index 0000000..26cf61b --- /dev/null +++ b/w1_d2/llm-api-demo/04_multi_turn_demo.py @@ -0,0 +1,47 @@ +# 作业: +# 1.完成多轮对话的demo +# 2.完成让用户选择不同模型的调用不同模型的回复demo +# 3.完成一次持久化存储对话 +# 4.完成一次流式输出demo +# 5.完成RAG流程图的绘制 +# 6.选做:调用xiaomi、硅基流动、chatgpt等其他 AI API 服务 +import os +from openai import OpenAI +from dotenv import load_dotenv +load_dotenv() + +client = OpenAI( + api_key=os.getenv("DASHSCOPE_API_KEY"), + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", +) + +model = "qwen-plus" + +messages = [ + { + "role": "system", + "content": "你是一名聊天高手,幽默,嘲讽用户,自带 emoji表情", + } +] + +while True: + question = input("用户:").strip() + + if question.lower() in {"exit", "quit"}: + print("对话结束") + break + + if not question: + continue + + messages.append({"role": "user", "content": question}) + + response = client.chat.completions.create( + model=model, + messages=messages, + ) + + answer = response.choices[0].message.content + messages.append({"role": "assistant", "content": answer}) + + print(f"AI:{answer}") \ No newline at end of file diff --git a/w1_d2/llm-api-demo/05_deepseek_api_params_demo.py b/w1_d2/llm-api-demo/05_deepseek_api_params_demo.py new file mode 100644 index 0000000..a724dcd --- /dev/null +++ b/w1_d2/llm-api-demo/05_deepseek_api_params_demo.py @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- +""" +DeepSeek API 参数教学演示脚本 +用法: + python demo.py # 默认跑 stream 示例 + python demo.py 1 # 跑第1个示例(model) + python demo.py 8 # 跑第8个示例(tools) +""" +import os +import sys +import json +from openai import OpenAI +from dotenv import load_dotenv + +load_dotenv() + +client = OpenAI( + api_key=os.environ.get("DEEPSEEK_API_KEY"), + base_url="https://api.deepseek.com", +) + +MODEL = "deepseek-chat" + + +# ---------- 1. model ---------- +def demo_model(): + print("【1. model —— 指定模型】") + response = client.chat.completions.create( + model=MODEL, + messages=[{"role": "user", "content": "你好,请用一句话自我介绍。"}], + ) + print(response.choices[0].message.content) + + +# ---------- 2. messages ---------- +def demo_messages(): + print("【2. messages —— 系统/用户/历史消息】") + response = client.chat.completions.create( + model=MODEL, + messages=[ + {"role": "system", "content": "你是一个只用文言文回答的助手。"}, + {"role": "user", "content": "什么是API?"}, + {"role": "assistant", "content": "应用程序接口也。"}, + {"role": "user", "content": "那什么是流式输出?"}, + ], + ) + print(response.choices[0].message.content) + + +# ---------- 3. stream ---------- +def demo_stream(): + print("【3. stream —— 流式输出】") + response = client.chat.completions.create( + model=MODEL, + messages=[{"role": "user", "content": "用三句话介绍AI的API。"}], + stream=True, + ) + for chunk in response: + content = chunk.choices[0].delta.content + if content: + print(content, end="", flush=True) + print() # 收尾换行 + + +# ---------- 4. temperature ---------- +def demo_temperature(): + print("【4. temperature —— 随机性】") + prompt = [{"role": "user", "content": "给我小孩起个名字,有一个凯字,只给1个。"}] + + cold = client.chat.completions.create( + model=MODEL, messages=prompt, temperature=0.2 + ) + hot = client.chat.completions.create( + model=MODEL, messages=prompt, temperature=2 + ) + + print("低温(0.2):", cold.choices[0].message.content.strip()) + print("高温(2.0):", hot.choices[0].message.content.strip()) + + +# ---------- 5. top_p ---------- +def demo_top_p(): + print("【5. top_p —— 候选词概率范围】") + response = client.chat.completions.create( + model=MODEL, + messages=[{"role": "user", "content": "续写:从前有座山,"}], + top_p=0.1, + ) + print(response.choices[0].message.content) + + +# ---------- 6. max_tokens ---------- +def demo_max_tokens(): + print("【6. max_tokens —— 限制输出长度】") + response = client.chat.completions.create( + model=MODEL, + messages=[{"role": "user", "content": "讲一个很长的故事。"}], + max_tokens=50, + ) + print(response.choices[0].message.content) + print("结束原因:", response.choices[0].finish_reason) # 可能是 "length" + + +# ---------- 7. response_format ---------- +def demo_response_format(): + print("【7. response_format —— 结构化输出】") + response = client.chat.completions.create( + model=MODEL, + messages=[ + {"role": "system", "content": "请以JSON格式返回。"}, + {"role": "user", "content": "介绍张三,年龄30,职业工程师"}, + ], + response_format={"type": "json_object"}, + ) + text = response.choices[0].message.content + print("原始输出:", text) + + # 验证是不是合法 JSON + try: + data = json.loads(text) + print("解析成功:", data) + except json.JSONDecodeError as e: + print("解析失败:", e) + + +# ---------- 8. tools ---------- +def demo_tools(): + print("【8. tools —— 声明外部工具】") + tools = [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "查询指定城市的天气", + "parameters": { + "type": "object", + "properties": { + "city": {"type": "string", "description": "城市名"} + }, + "required": ["city"], + }, + }, + } + ] + + response = client.chat.completions.create( + model=MODEL, + messages=[{"role": "user", "content": "北京今天天气怎么样?"}], + tools=tools, + ) + + msg = response.choices[0].message + if msg.tool_calls: + call = msg.tool_calls[0] + print("要调用的函数:", call.function.name) + print("参数:", call.function.arguments) + else: + print("模型直接回答:", msg.content) + + +# ---------- 9. tool_choice ---------- +def demo_tool_choice(): + print("【9. tool_choice —— 控制工具选择】") + tools = [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "查询指定城市的天气", + "parameters": { + "type": "object", + "properties": { + "city": {"type": "string", "description": "城市名"} + }, + "required": ["city"], + }, + }, + } + ] + + # 三种模式演示 + modes = [ + ("auto", "auto"), + ("none", "none"), + ("强制get_weather", {"type": "function", "function": {"name": "get_weather"}}), + ] + + for label, choice in modes: + response = client.chat.completions.create( + model=MODEL, + messages=[{"role": "user", "content": "北京天气?"}], + tools=tools, + tool_choice=choice, + ) + msg = response.choices[0].message + if msg.tool_calls: + print(f"[{label}] 调用工具 -> {msg.tool_calls[0].function.arguments}") + else: + print(f"[{label}] 直接回答 -> {msg.content}") + + +# ---------- 10. extra_body ---------- +def demo_extra_body(): + print("【10. extra_body —— 厂商私有参数】") + # 说明:这里以 deepseek-reasoner 的 thinking 控制为例, + # 具体字段名请以官方文档为准。若模型不支持,可能报错。 + try: + response = client.chat.completions.create( + model="deepseek-reasoner", + messages=[{"role": "user", "content": "9.11 和 9.8 哪个大?"}], + extra_body={"thinking": {"type": "disabled"}}, + ) + print(response.choices[0].message.content) + except Exception as e: + print("调用失败(可能模型或字段不支持):", e) + + +# ---------- 调度 ---------- +DEMOS = { + 1: demo_model, + 2: demo_messages, + 3: demo_stream, + 4: demo_temperature, + 5: demo_top_p, + 6: demo_max_tokens, + 7: demo_response_format, + 8: demo_tools, + 9: demo_tool_choice, + 10: demo_extra_body, +} + + +def main(): + if len(sys.argv) < 2: + choice = 3 # 默认跑 stream + else: + try: + choice = int(sys.argv[1]) + except ValueError: + print("参数必须是 1~10 的数字") + return + + if choice not in DEMOS: + print(f"没有编号 {choice} 的示例,可用:{sorted(DEMOS.keys())}") + return + + print("=" * 50) + DEMOS[choice]() + print("=" * 50) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/w1_d2/llm-api-demo/06_dashscope.py b/w1_d2/llm-api-demo/06_dashscope.py new file mode 100644 index 0000000..05fb328 --- /dev/null +++ b/w1_d2/llm-api-demo/06_dashscope.py @@ -0,0 +1,17 @@ +import os +import dashscope + +from dotenv import load_dotenv +load_dotenv() +dashscope.base_http_api_url = 'https://maas.qianwenaiapi.com/api/v1' +messages = [ + {'role': 'system', 'content': 'You are a helpful assistant.'}, + {'role': 'user', 'content': 'Who are you?'} +] +response = dashscope.Generation.call( + api_key=os.getenv('DASHSCOPE_API_KEY'), + model='qwen-plus', + messages=messages, + result_format='message' +) +print(response) \ No newline at end of file diff --git a/w1_d2/llm-api-demo/requirements.txt b/w1_d2/llm-api-demo/requirements.txt new file mode 100644 index 0000000..f0dd0ae --- /dev/null +++ b/w1_d2/llm-api-demo/requirements.txt @@ -0,0 +1 @@ +openai \ No newline at end of file