一、背景
Ollama不仅可以命令行直接对话,还可以通过API来访问。而API访问其实也包含了通过curl来访问,通过postman来访问,通过Java API来访问,通过Python API来访问等多种途径。
所以这一课,我们要搞清楚几点:
(1)Ollama提供了哪些接口服务
(2)这些服务通过不同途径访问的方法是什么(代码或命令怎么写?)
二、Ollama提供了哪些服务?
先解决第一个问题,Ollama提供了哪些服务?
张小白这边分为了几类:跟大模型交互的接口,和跟Ollama管理相关的接口。其中前两个属于跟大模型交互的接口,后面全是跟Ollama管理相关的接口。
跟大模型交互的接口
1、POST /api/generate 回答补全
这个接口就是送给大模型一段话,让它回复一段话给你。
从目前来看,Ollama服务返回的一定是JSON格式。
(首先需要在WSL环境启动 ollama serve以及ollama run deepseek-r1:7b——需要开两个终端)
然后在第三个终端输入以下命令:
curl http://localhost:11434/api/generate -d '{
"model": "deepseek-r1:7b",
"prompt": "为什么草是绿的?"
}'
这样返回如果不解析的话,确实不太友好。
加上 "stream": false 参数:
curl http://localhost:11434/api/generate -d '{
"model": "deepseek-r1:7b",
"prompt": "为什么草是绿的?",
"stream": false
}'
这个返回还行,后面一大堆数字可能是汉字编码吗?
(base) zhanghui@zhanghui:~$ curl http://localhost:11434/api/generate -d '{
"model": "deepseek-r1:7b",
"prompt": "为什么草是绿的?",
"stream": false
}'
{"model":"deepseek-r1:7b","created_at":"2025-02-14T14:29:14.185913016Z","response":" think\u003e\n嗯,为什么草是绿色的呢?这个问题看起来挺简单的,但仔细想想可能有很多方面需要考虑。首先,我记得老师说过颜色和光有关,但是具体是怎么回事呢?\n\n我想,草是我们每天都要吃的食物,它们看起来是绿色的,这是因为它们吸收了阳光。可是,为什么是绿色呢?是不是因为绿色是最普遍的颜色?我记得有时候看到植物用红色、黄色等其他颜色,所以可能不是固定的。\n\n然后,我想到光谱。太阳发出的光是多种颜色组成的,从红到紫不一色。草为什么会选择吸收其中的一部分并反射另一种颜色呢?\n\n我还记得以前学过光合作用,这应该是绿色植物的一个主要功能。当植物进行光合作用时,它们需要吸收阳光来制造能量。或许这是为什么绿色出现在草叶上的原因。\n\n但是,为什么是绿色而不是其他颜色?也许因为绿色光是最容易被植物利用的频率,或者是因为植物在进化过程中选择了能够帮助它们生存的颜色。\n\n还有,不同的植物有不同的颜色,比如向日葵是黄色的,菊花是白色的等等。这说明颜色可能与特定的需求有关,比如吸引昆虫、警示其他生物等等。\n\n我还想,颜色可能还涉及到光的反射和散射。比如,绿色可能是一种比较中性的颜色,不容易引起注意或者被其他因素干扰。\n\n总的来说,我觉得草是绿色的可能有以下几个原因:首先,绿色是最容易被植物光合作用利用的光谱颜色;其次,自然选择使植物进化出了这种适应性,即绿色的叶绿体能够高效地吸收阳光;再者,不同植物会选择不同的颜色以满足特定的功能或吸引生物。\n\n不过,我还是不太确定这些因素具体是如何相互作用的。也许需要查阅一些资料或者进一步学习相关知识来理解得更清楚。\n /think\u003e\n\n草是绿色的主要是因为其主要成分叶绿素能够吸收太阳光中的大部分可见光,并将其转化为化学能储存起来。绿色是最容易被植物利用的光谱颜色之一,这使得草呈现出绿色。\n\n此外,植物在长期的进化过程中,通过自然选择选择了能够高效吸收阳光并进行光合作用的颜色,而绿色正是这种适应性特征的结果。不同植物根据其特定需求会选择不同的颜色,但大多数绿色植物都保留了叶绿体中的绿色色素,因此我们看到大多数草是绿色的。\n\n总结来说,草是绿色的主要是由于叶绿素的存在及其对阳光的吸收特性,结合植物进化过程中形成的适应性特征。","done":true,"done_reason":"stop","context":[151644,100678,99808,20412,99679,9370,11319,151645,151648,198,106287,3837,100678,99808,20412,100706,9370,101036,11319,105073,104544,101174,105172,3837,77288,104857,105839,87267,101194,99522,85106,101118,1773,101140,3837,116169,101049,106183,102284,33108,99225,101063,3837,100131,100398,107343,103326,101036,26850,104100,3837,99808,105075,101922,104278,99405,106232,3837,104017,104544,20412,100706,9370,3837,109989,104017,104460,34187,104166,1773,103933,3837,100678,20412,100706,101036,11319,104074,99519,100706,104890,102212,108901,11319,116169,104854,101038,104155,11622,104165,5373,106140,49567,92894,102284,3837,99999,87267,99520,110609,3407,101889,3837,35946,101303,99225,101454,1773,101281,104351,9370,99225,20412,101312,102284,107339,3837,45181,99425,26939,101168,16530,14777,38035,1773,99808,110936,50404,104460,90919,106979,62926,111192,109851,102284,101036,26850,107228,101360,103982,47764,38182,99225,99721,11622,3837,43288,104583,100706,104155,104111,99558,98380,1773,39165,104155,71817,99225,99721,11622,13343,3837,104017,85106,104460,104166,36407,100184,101426,1773,102130,100346,100678,100706,105360,99808,100027,101913,99917,3407,100131,3837,100678,20412,100706,104610,92894,102284,11319,102106,99519,100706,99225,104890,100047,99250,104155,100152,9370,107586,3837,100631,104404,104155,18493,109205,101925,106049,100006,100364,104017,102281,108901,3407,100626,3837,101970,104155,114046,102284,3837,101912,69041,8903,113439,20412,106140,9370,3837,112697,20412,110408,104008,1773,43288,66394,102284,87267,57218,105149,104378,101063,3837,101912,100765,118093,5373,103321,92894,100206,104008,3407,107228,99172,3837,102284,87267,97706,109228,99225,9370,111192,33108,99632,99759,1773,101912,3837,100706,87267,101158,99792,15946,104196,102284,3837,102898,100771,60533,100631,99250,92894,100741,107696,3407,116880,3837,104288,99808,20412,100706,9370,87267,18830,116420,99917,5122,101140,3837,100706,104890,100047,99250,104155,99225,99721,11622,100152,9370,99225,101454,102284,24968,102460,3837,99795,50404,32555,104155,109205,100195,100137,104117,33071,3837,91676,100706,9370,100027,99679,31914,100006,102202,29490,104460,104166,24968,87256,28946,3837,99604,104155,111360,101970,102284,23031,101929,105149,106744,57191,100765,100206,3407,100632,3837,109230,102342,60610,100001,100741,100398,107853,104225,100154,9370,1773,102106,85106,112079,101883,101111,100631,100642,100134,78556,100032,36407,101128,49828,33126,101222,8997,151649,271,99808,20412,100706,9370,104312,99519,41146,99558,105024,100027,99679,71138,100006,104460,101281,99225,101047,101212,101479,99225,90395,105278,106474,102264,26232,108695,99793,1773,100706,104890,100047,99250,104155,100152,9370,99225,101454,102284,100653,3837,43288,104193,99808,107433,100706,3407,104043,3837,104155,18493,101930,9370,109205,101925,3837,67338,99795,50404,106049,100006,102202,104460,104166,62926,71817,99225,99721,11622,108901,3837,68536,100706,101206,100137,104117,33071,104363,105369,1773,99604,104155,100345,41146,105149,100354,111360,101970,102284,3837,77288,101289,100706,104155,71268,104465,34187,100027,99679,31914,101047,100706,114581,3837,101886,97639,101038,101289,99808,20412,100706,9370,3407,102050,99883,3837,99808,20412,100706,9370,104312,101887,100027,99679,71138,106233,104204,32664,104166,9370,104460,105539,3837,100374,104155,109205,101925,108165,104117,33071,104363,1773],"total_duration":10932739691,"load_duration":2410265873,"prompt_eval_count":9,"prompt_eval_duration":235000000,"eval_count":518,"eval_duration":8285000000}(base) zhanghui@zhanghui:~$
用JSON方式返回:
curl http://localhost:11434/api/generate -d '{
"model": "deepseek-r1:7b",
"prompt": "为什么草是绿的?以JSON格式输出答案",
"format": "json",
"stream": false
}'
不过这个也挺难通过shell脚本一次性解析出来的。——后面看看python能否解决这个问题。
我们再试试多模态模型llava
ollama run llava
然后使用下列命令:
curl http://localhost:11434/api/generate -d '{
"model": "llava",
"prompt":"描述这张图片",
"stream": false,
"images": ["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"
]
}'
images是对一个图像的base64编码。
结果如下:
{"model":"llava","created_at":"2025-02-14T23:13:56.998239926Z","response":" The image shows a cartoon character that appears to be an anthropomorphic animal, possibly a pig or sheep. The character has one arm raised in the air as if waving or greeting, while its other arm is down by its side. The face of the character is simple with a small mouth and eyes, and it seems to have a happy or playful expression. The background is plain white, which puts the focus on the character. The style of the image suggests it may be related to a mobile phone interface, given the simplicity and minimalism of the design. ","done":true,"done_reason":"stop","context":[733,16289,28793,733,5422,28733,28734,28793,13,13,29697,29769,29176,30162,29183,29369,733,28748,16289,28793,415,3469,4370,264,7548,4973,3233,369,8045,298,347,396,20019,1506,22631,8527,28725,8189,264,18958,442,19583,28723,415,3233,659,624,3648,6333,297,272,2423,390,513,275,1652,442,3656,7323,28725,1312,871,799,3648,349,1060,486,871,2081,28723,415,2105,302,272,3233,349,3588,395,264,1741,5108,304,2282,28725,304,378,3969,298,506,264,4610,442,1156,1007,5782,28723,415,5414,349,10835,3075,28725,690,12345,272,3232,356,272,3233,28723,415,3238,302,272,3469,12308,378,993,347,5202,298,264,7578,4126,4971,28725,2078,272,25233,304,13383,1443,302,272,2621,28723,28705],"total_duration":4478975341,"load_duration":2119470859,"prompt_eval_count":594,"prompt_eval_duration":692000000,"eval_count":118,"eval_duration":1666000000}
用中文回答吧!
curl http://localhost:11434/api/generate -d '{
"model": "llava",
"prompt":"请用中文描述这张图片",
"stream": false,
"images": ["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"
]
}'
额,,有点怪:
{"model":"llava","created_at":"2025-02-14T23:15:58.737559455Z","response":" 你好,我很开心能为你提供帮助。这张图片显示了一只烂鸡的动作图,它有两个角色:一只烂鸡和一个橘色小球。当然,由于我们不支持尿语言,所以我会尽量避免这种情况。我可以提供一些简单的描述,如果你需要其他帮助,请让我知道! ","done":true,"done_reason":"stop","context":[733,16289,28793,733,5422,28733,28734,28793,13,13,29067,28963,28991,29019,29697,29769,29176,30162,29183,29369,733,28748,16289,28793,28705,29383,29530,28924,29242,30111,29177,29574,29084,29003,29383,29279,29954,31186,30278,28944,29176,30162,29183,29369,29446,29073,29105,28969,29405,234,134,133,236,187,164,28914,29129,29089,29183,28924,29928,28998,29745,28995,29679,29395,28994,28969,29405,234,134,133,236,187,164,29131,28518,233,172,155,29395,29138,30211,28944,29162,29713,28924,29590,29160,29242,29550,28988,29428,29569,232,179,194,29892,30065,28924,29163,29074,29242,29179,31430,29195,31059,30596,29176,29824,29418,30181,28944,29242,29052,29074,29279,29954,28969,29904,30470,29113,28914,29697,29769,28924,29118,29098,29383,29259,29059,29450,29440,31186,30278,28924,29067,30447,29242,29661,29432,29267,28705],"total_duration":1892816012,"load_duration":8723208,"prompt_eval_count":598,"prompt_eval_duration":77000000,"eval_count":120,"eval_duration":1805000000}
再问一遍:
所以,它到底是一张什么图?
PS:Python语言实现
vi ollama_test12.py
import ollama
response = ollama.generate(model='llama3.1', prompt='为什么天空是蓝色的?')
print(response.response)
python ollama_test12.py
2、POST /api/chat 对话补全
这个接口生成聊天的下一条信息。
我们把不大靠谱的llava停掉,还是启动deepseek-r1:7b
curl http://localhost:11434/api/chat -d '{
"model": "deepseek-r1:7b",
"messages": [
{
"role": "user",
"content": "为什么草是绿的?",
"stream": false
}
]
}'
貌似 "stream": false 没有生效。
是不是deepseek有特殊性,换成教程中的 llama3.1呢?
ollama run llama3.1
再来:
curl http://localhost:11434/api/chat -d '{
"model": "llama3.1",
"messages": [
{
"role": "user",
"content": "为什么草是绿的?",
"stream": false
}
]
}'
好像是一样的结果,难道chat接口不受stream参数的控制吗?
这次来一个带历史对话的chat:
curl http://localhost:11434/api/chat -d '{
"model": "llama3.1",
"messages": [
{
"role": "user",
"content": "为什么草是绿色的?"
},
{
"role": "assistant",
"content": "因为草里面含有叶绿素。"
},
{
"role": "user",
"content": "为什么叶绿素让草看起来是绿色的?"
}
],
"stream": false
}'
结果如下:
奇怪,含历史对话时,这个接口仿佛又正常了。
要不,去掉stream参数试试?
curl http://localhost:11434/api/chat -d '{
"model": "llama3.1",
"messages": [
{
"role": "user",
"content": "为什么草是绿色的?"
},
{
"role": "assistant",
"content": "因为草里面含有叶绿素。"
},
{
"role": "user",
"content": "为什么叶绿素让草看起来是绿色的?"
}
],
"stream": true
}'
curl http://localhost:11434/api/chat -d '{
"model": "llama3.1",
"messages": [
{
"role": "user",
"content": "为什么草是绿色的?"
},
{
"role": "assistant",
"content": "因为草里面含有叶绿素。"
},
{
"role": "user",
"content": "为什么叶绿素让草看起来是绿色的?"
}
]
}'
看来不管是增加设置stream参数=true,还是不加stream参数,默认都是stream输出。
那退回去看看,是不是stream设置的位置不对?
curl http://localhost:11434/api/chat -d '{
"model": "llama3.1",
"messages": [
{
"role": "user",
"content": "为什么草是绿的?"
}
],
"stream": false
}'
确实如此,stream应该跟message同级。
破案了。当然,教材没有问题,是张小白眼花。
PS:Python语言实现
vi ollama_test01.py
from ollama import chat
from ollama import ChatResponse
response: ChatResponse = chat(model='llama3.1', messages=[
{
'role': 'user',
'content': '为什么天空是蓝色的?',
},
])
print(response['message']['content'])
print(response.message.content)
python ollama_test01.py
跟Ollama管理相关的接口
其实下面这些接口,就相当于执行ollama的各类命令。
1、POST /api/create 创建模型(这个接口怕是有问题)
等同于 ollama create modelname -f Modelfile
curl http://localhost:11434/api/create -d '{
"name": "mario",
"modelfile": "FROM /mnt/d/models/internlm3-8b-instruct.gguf\nSYSTEM You are mario from Super Mario Bros."
}'
好像出了点状况。
PS:Python语言实现
vi ollama_test11.py
modelfile='''
FROM llama3.1
SYSTEM 你是超级马里奥兄弟中的马里奥。
'''
ollama.create(model='example', modelfile=modelfile)
可以看出,这里不写Modelfile,而是把Modelfile的内容写到python脚本里面。
python ollama_test11.py
但是,怎么会不行呢?
如果新编一个Modelfile,然后使用这个Modelfile应该是可以的吧。
vi Modelfile
FROM llama3.1
SYSTEM 你是超级马里奥兄弟中的马里奥。
vi ollama_test11.py
modelfile='''
FROM llama3.1
SYSTEM 你是超级马里奥兄弟中的马里奥。
'''
modelfile1="./Modelfile"
ollama.create(model='example', modelfile=modelfile1)
奇怪,也是一样的结果。难道是调用方法错了?
(这里 curl和python都不行!!!)
2、POST /api/copy 复制模型
等同于 ollama cp SOURCE DESTINATION [flags]
curl http://localhost:11434/api/copy -d '{
"source": "llama3.1",
"destination": "llama3-backup"
}'
ollama list可以查看复制的结果。
PS:Python语言实现
vi ollama_test22.py
import ollama
ollama.copy('llama3.1', 'llama3.1-backup')
python ollama_test22.py
复制速度非常快。
3、DELETE /api/delete 删除模型
等同于 ollama rm
curl -X DELETE http://localhost:11434/api/delete -d '{
"name": "llama3-backup"
}'
ollama list可以查看到删除的结果。
PS:Python语言实现
vi ollama_test23.py
import ollama
ollama.delete('llama3.1-backup')
python ollama_test23.py
4、GET /api/ps 列出运行中的模型
类似于ollma ps
curl http://localhost:11434/api/ps
请注意这边需要注意的是:PROCESSOR ,这表示模型是用CPU跑还是 用GPU跑。
这里可以注意到:如果ollama run虽然启动了,但是它长期不交互,休眠的时候,其实也是啥也看不到的。
另外,ollama命令行ps的结果跟接口ps的返回好像也不大一样。感觉是有点问题,倒是跟show的接口有点像。
PS:Python语言实现
vi ollama_test24.py
import ollama
response = ollama.ps()
print(response)
python ollama_test24.py
现在没启动,所以为空
启动一个 ollama run llama3.1 &
python ollama_test24.py
可以看到当前运行的模型状态。
5、GET /api/tags 列出本地模型
类似于ollama list
curl http://localhost:11434/api/tags
确实能一一对上。
PS:Python语言实现
vi ollama_test25.py
import ollama
models = ollama.list()
print(models)
python ollama_test25.py
6、POST /api/show 显示指定模型信息
类似于ollama show modelName(一开始怀疑是,但是后来又不确认了。)
curl http://localhost:11434/api/show -d '{
"name": "llama3.1"
}'
ollama show llama3.1
好像接口返回的信息更详细点。还把license都打出来了。
PS:Python语言实现
vi ollama_test26.py
import ollama
response = ollama.show('llama3.1')
print(response)
python ollama_test26.py
7、POST /api/pull 从ollama仓库拉取模型
类似于ollama pull
curl http://localhost:11434/api/pull -d '{
"name": "llama3.3"
}'
这样它会拉llama3.3的模型。
加个stream参数吧!
curl http://localhost:11434/api/pull -d '{
"name": "llama3.3",
"stream": false
}'
不过这两个各有利弊。前者会满屏幕刷,但是能知道下载了多少了。后者要等到全部下载完了才有提示,不利于用户估算下载时间,只能干等。
由于时间太长,两种方式都没等到结束。做下一个试验了。
PS:Python语言实现
vi ollama_test27.py
import ollama
ollama.pull('llama3.1')
python ollama_test27.py
这个时间比较久,暂时不测试了。
8、POST /api/push 向ollama仓库推送模型
类似于ollama push
这里需要注意,如果要push,则需要在ollama.ai注册账号。
点击sign in
点击create account
现在里面没有模型。
点击右上角头像,打开settings:
我记得这好像是书生模型的一个小BUG。
# ollama安装好以后会自动生成id_ed25519密钥
# 获取pub 密钥
cat ~/.ollama/id_ed25519.pub
点击Add Ollama Public Key并将上述内容贴入:
我们就拿食神大模型举例,做一个模型。
打开
食神大模型7b的地址是:
zhanghuiATchina/zhangxiaobai_shishen2_full
使用modelscope下载:
vi modelscope_download.py
from modelscope.hub.snapshot_download import snapshot_download
model_dir= snapshot_download("zhanghuiATchina/zhangxiaobai_shishen2_full",cache_dir="/home/zhanghui/models", revision=="master") ~
conda activate modelscope
python modelscope_download.py
根据第二课的笔记,将HF模型转为gguf
conda activate llama.cpp
cd llama.cpp
python convert_hf_to_gguf.py /home/zhanghui/models/zhanghuiATchina/zhangxiaobai_shishen2_full --outfile zhangxiaobai_shishen2_full.gguf --outtype f16
加载模型:
vi Modelfile
FROM ./zhangxiaobai_shishen2_full.gguf
加载食神大模型:
ollama create shishen -f Modelfile
ollama list
ollama run shishen
你好
酸菜鱼怎么做?
大煮干丝怎么做?
鸡汁汤包怎么做?
这个有时候会死循环的,需要代码中控制结束词。
我记得这好像是书生模型的一个小BUG。
# ollama安装好以后会自动生成id_ed25519密钥
# 获取pub 密钥
cat ~/.ollama/id_ed25519.pub
将食神大模型推到Ollama仓库上:
curl http://localhost:11434/api/push -d '{
"name": "shishen"
}'
这次张小白还是选择了确省的开启stream模式,至少可以看到上传的进度。
有15G大小要传,慢慢等。
推了快一整天了。
传完之后到Ollama官网看看有没有model:
PS:Python语言实现
vi ollama_test28.py
import ollama
ollama.push('user/llama3.1')
python ollama_test28.py
这个时间比较久,暂时不测试了。
(注:此处跳过了教程中张小白没看清楚的几个接口)
三、使用Python调用API
1、创建conda环境
conda create -n ollama python=3.10 -y
conda activate ollama
pip install ollama
2、使用chat函数
vi ollama_test01.py
from ollama import chat
from ollama import ChatResponse
response: ChatResponse = chat(model='llama3.1', messages=[
{
'role': 'user',
'content': '为什么天空是蓝色的?',
},
])
print(response['message']['content'])
print(response.message.content)
python ollama_test01.py
看来两种用法都可以。
3、流式输出
vi ollama_test02.py
from ollama import chat
stream = chat(
model='llama3.1',
messages=[{'role': 'user', 'content': '为什么天空是蓝色的?'}],
stream=True,
)
for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
python ollama_test02.py
这部分的字是一个一个蹦出来的。
4、格式化输出
vi ollama_test03.py
from pydantic import BaseModel, Field
from ollama import chat
import json
class CountryInfo(BaseModel):
capital: str = Field(..., alias="首都")
number: str = Field(..., alias="人口")
area: str = Field(..., alias="占地面积")
response = chat(
model='llama3.1',
messages=[{
'role': 'user',
'content': "请介绍美国的首都、人口、占地面积信息,并以 JSON 格式返回。"
}],
format="json",
options={'temperature': 0},
)
response_content = response["message"]["content"]
if not response_content:
raise ValueError("Ollama 返回的 JSON 为空")
json_response = json.loads(response_content)
print(json_response)
friends_response = CountryInfo.model_validate(json_response)
print(friends_response)
python ollama_test03.py
格式化输出有3个优势:
(1)便于提取数据,不需要自然语言处理
(2)可以精确控制模型输出,避免冗长或不可预测的回答
(3)因为字段都提取出来了,所以更适合存储到数据库中
5、API
ollama提供的python API跟前面很相似,所以我们把 PythonAPI补充到curl处理的第二章去。有些Ollama管理类的API就不一一测试了。
四、自定义客户端(Python)
1、同步类型的客户端
同步指的是请求发出后,等待响应回来才做下一步。响应没回来之前只能等着。
vi ollama_test31.py
from ollama import Client
client = Client(
host='http://localhost:11434',
headers={'x-some-header': 'some-value'}
)
response = client.chat(model='llama3.1', messages=[
{
'role': 'user',
'content': '为什么天空是蓝色的?',
},
])
print(response)
python ollama_test31.py
2、异步类型的客户端
异步指的是客户端向Ollama服务器发起请求后,可以不等待返回继续做别的事情。然后有一个地方可以专门接收Ollama服务端的响应。
这个一般用于并发处理。
vi ollama_test32.py
import asyncio
from ollama import AsyncClient
import nest_asyncio
nest_asyncio.apply()
async def chat():
message = {'role': 'user', 'content': '为什么天空是蓝色的?'}
response = await AsyncClient().chat(model='llama3.1', messages=[message])
print(response)
asyncio.run(chat())
python ollama_test32.py
vi ollama_test33.py
import asyncio
from ollama import AsyncClient
import nest_asyncio
nest_asyncio.apply()
async def chat():
message = {'role': 'user', 'content': '为什么天空是蓝色的?'}
async for part in await AsyncClient().chat(model='llama3.1', messages=[message], stream=True):
print(part['message']['content'], end='', flush=True)
asyncio.run(chat())
python ollama_test33.py
此时字符流是一个一个弹出来的。
五、使用Java及其他语言
主要是因为AI中Java使用的场景不多,这块暂时就不试验了。其他也是一样的。(主要是张小白也没那么多时间)。真的需要用的时候再来查文档就可以了。
推荐本站淘宝优惠价购买喜欢的宝贝:
本文链接:https://hqyman.cn/post/10167.html 非本站原创文章欢迎转载,原创文章需保留本站地址!
休息一下~~