文章目录
***絮絮叨叨:
最近新手开始接需求,妈的还是全栈开发!让我摸最后一天写完这个文档吧。
大模型真得很受欢迎。最近leader开会要求大家每天花一小时进行大模型学习分享讨论;当然我的科研导师也叫我干这个方向,就是我真的无法兼顾。那便舍科研而取实习吧~
参考智谱AI平台,自行登录注册充钱哈哈
一.sdk和http两种调用方式的区别
SDK 是 "Software Development Kit" 的缩写,中文通常称为“软件开发工具包”。它是一系列用于开发软件应用程序的工具、API 库、文档和示例代码的集合。
SDK 提供了更高级的抽象和封装,使得开发者可以更容易地调用 API,而无需处理底层的 HTTP 请求和响应。
使用原生 HTTP 请求可以完全控制请求的细节,包括请求头、请求体、超时设置等。
原生 HTTP 请求通常更接近底层,可以提供更好的性能和更低的开销。
总之SDK 更易用,http更灵活。
二、SDK调用
同步调用:调用后即可一次性获得最终结果。是阻塞式的,调用者等待调用完成。
异步调用:是非阻塞式的,调用者不等待调用完成,适用于不需要立即获取结果的场景。
SSE调用:调用后可以流式的实时获取到结果直到结束
#以上是官方提供的,可以根据需求决定哪种方式。
流式调用:允许数据逐步传输,适用于处理大量或实时数据。
函数调用:是执行特定任务的操作,可以是同步或异步的。
1.官方 SDK
1.java版
<dependency>
<groupId>cn.bigmodel.openapi</groupId>
<artifactId>oapi-java-sdk</artifactId>
<version>release-V4-2.0.2</version>
</dependency>
/**
* 同步调用
*/
private static void testInvoke() {
List<ChatMessage> messages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), "作为一名营销专家,请为智谱开放平台创作一个吸引人的slogan");
messages.add(chatMessage);
String requestId = String.format(requestIdTemplate, System.currentTimeMillis());
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(Constants.ModelChatGLM4)
.stream(Boolean.FALSE)
.invokeMethod(Constants.invokeMethod)
.messages(messages)
.requestId(requestId)
.build();
ModelApiResponse invokeModelApiResp = client.invokeModelApi(chatCompletionRequest);
try {
System.out.println("model output:" + mapper.writeValueAsString(invokeModelApiResp));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
/**
* 异步调用
*/
private static String testAsyncInvoke() {
List<ChatMessage> messages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), "作为一名营销专家,请为智谱开放平台创作一个吸引人的slogan");
messages.add(chatMessage);
String requestId = String.format(requestIdTemplate, System.currentTimeMillis());
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(Constants.ModelChatGLM4)
.stream(Boolean.FALSE)
.invokeMethod(Constants.invokeMethodAsync)
.messages(messages)
.requestId(requestId)
.build();
ModelApiResponse invokeModelApiResp = client.invokeModelApi(chatCompletionRequest);
System.out.println("model output:" + JSON.toJSONString(invokeModelApiResp));
return invokeModelApiResp.getData().getTaskId();
}
/**
* sse调用
*/
private static void testSseInvoke() {
List<ChatMessage> messages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), "作为一名营销专家,请为智谱开放平台创作一个吸引人的slogan");
messages.add(chatMessage);
String requestId = String.format(requestIdTemplate, System.currentTimeMillis());
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(Constants.ModelChatGLM4)
.stream(Boolean.TRUE)
.messages(messages)
.requestId(requestId)
.build();
ModelApiResponse sseModelApiResp = client.invokeModelApi(chatCompletionRequest);
if (sseModelApiResp.isSuccess()) {
AtomicBoolean isFirst = new AtomicBoolean(true);
ChatMessageAccumulator chatMessageAccumulator = mapStreamToAccumulator(sseModelApiResp.getFlowable())
.doOnNext(accumulator -> {
{
if (isFirst.getAndSet(false)) {
System.out.print("Response: ");
}
if (accumulator.getDelta() != null && accumulator.getDelta().getTool_calls() != null) {
String jsonString = mapper.writeValueAsString(accumulator.getDelta().getTool_calls());
System.out.println("tool_calls: " + jsonString);
}
if (accumulator.getDelta() != null && accumulator.getDelta().getContent() != null) {
System.out.print(accumulator.getDelta().getContent());
}
}
})
.doOnComplete(System.out::println)
.lastElement()
.blockingGet();
Choice choice = new Choice(chatMessageAccumulator.getChoice().getFinishReason(), 0L, chatMessageAccumulator.getDelta());
List<Choice> choices = new ArrayList<>();
choices.add(choice);
ModelData data = new ModelData();
data.setChoices(choices);
data.setUsage(chatMessageAccumulator.getUsage());
data.setId(chatMessageAccumulator.getId());
data.setCreated(chatMessageAccumulator.getCreated());
data.setRequestId(chatCompletionRequest.getRequestId());
sseModelApiResp.setFlowable(null);
sseModelApiResp.setData(data);
}
System.out.println("model output:" + JSON.toJSONString(sseModelApiResp));
}
2.python版
from zhipuai import ZhipuAI
client = ZhipuAI(api_key="xxxx") # 请填写您自己的APIKey
#同步 调用
response1= client.chat.completions.create(
model="glm-4", # 填写需要调用的模型名称
messages=[
{"role": "user", "content": "作为一名动画片专家,请为沸羊羊和美羊羊写一个爱情故事"},
{"role": "user", "content": "请加入角色喜羊羊"},
{"role": "user", "content": "加入角色懒羊羊"}
],
)
print(response1)
#异步 调用
#看不到结果正常。因为他需要拿到id后不断查询,但是使用http很好查询网上可搜到。
#至于sdk怎么才能控制等到异步结果,欢迎和我讨论。
response2 = client.chat.asyncCompletions.create(
model="glm-4", # 填写需要调用的模型名称
messages=[
{
"role": "user",
"content": "请你作为童话故事大王,写一篇短篇童话故事,故事的主题是要永远保持一颗善良的心,要能够激发儿童的学习兴趣和想象力,同时也能够帮助儿童更好地理解和接受故事中所蕴含的道理和价值观。"
}
],
)
print(response2)
#SSE 调用
response3 = client.chat.completions.create(
model="glm-4", # 填写需要调用的模型名称
messages=[
{"role": "system", "content": "你是一个乐于解答各种问题的助手,你的任务是为用户提供专业、准确、有见地的建议。"},
{"role": "user", "content": "我对太阳系的行星非常感兴趣,特别是土星。请提供关于土星的基本信息,包括其大小、组成、环系统和任何独特的天文现象。"},
],
stream=True,#和同步调用的区别
)
for chunk in response3:
print(chunk.choices[0].delta)
2.OpenAI SDK
from openai import OpenAI
client = OpenAI(
api_key="your api key",
base_url="https://open.bigmodel.cn/api/paas/v4/"
)
completion = client.chat.completions.create(
model="glm-4",
messages=[
{"role": "system", "content": "你是一个聪明且富有创造力的小说作家"},
{"role": "user", "content": "请你作为童话故事大王,写一篇短篇童话故事,故事的主题是要永远保持一颗善良的心,要能够激发儿童的学习兴趣和想象力,同时也能够帮助儿童更好地理解和接受故事中所蕴含的道理和价值观。"}
],
top_p=0.7,
temperature=0.9
)
print(completion.choices[0].message)
3.Langchain SDK
import os
from langchain_openai import ChatOpenAI
from langchain.prompts import (
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
llm = ChatOpenAI(
temperature=0.95,
model="glm-4",
openai_api_key="your api key",
openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)
prompt = ChatPromptTemplate(
messages=[
SystemMessagePromptTemplate.from_template(
"You are a nice chatbot having a conversation with a human."
),
MessagesPlaceholder(variable_name="chat_history"),
HumanMessagePromptTemplate.from_template("{question}")
]
)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
conversation = LLMChain(
llm=llm,
prompt=prompt,
verbose=True,
memory=memory
)
conversation.invoke({"question": "tell me a joke"})
三、http调用
import requests
import urllib3
import time
import jwt
def generate_token(apikey: str, exp_seconds: int):
try:
id, secret = apikey.split(".")
except Exception as e:
raise Exception("invalid apikey", e)
payload = {
"api_key": id,
"exp": int(round(time.time() * 1000)) + exp_seconds * 1000,
"timestamp": int(round(time.time() * 1000)),
}
return jwt.encode(
payload,
secret,
algorithm="HS256",
headers={"alg": "HS256", "sign_type": "SIGN"},
)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
base_url = "https://open.bigmodel.cn/api/paas"
def get_response(**kwargs):
data = kwargs
#本代码按理来说只要改这个apikey成你自己的就可以跑了,不能跑可能是没缴费
token = generate_token('yourapikey', 3600)
print("token:", token)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
#更改使用你访问模型的API地址基址
response = requests.post(f"{base_url}/v4/chat/completions", headers=headers, json=data, stream=data["stream"],
verify=False)
decoded_line = response.json()
return decoded_line
def run_conversation(query: str, stream=False, max_retry=5):
#可以尝试更改你用的模型
params = dict(model="glm-4", messages=[{"role": "user", "content": query}], stream=stream)
response = get_response(**params)
print("Response:", response)
if __name__ == "__main__":
query = "假如你是魔镜,魔镜魔镜,谁是天底下最聪明的人" #
print(run_conversation(query, stream=False))