LLM之调用智谱API实现问答

大语言模型(LLM)自从chatGPT发布以来,很多机构都发布了自己的大语言模型调用API,目前国内有百度的文心一言,阿里的通义千问,智谱,科大讯飞的讯飞星火等等。本文重点介绍如何应用智谱提供的API(申请较为容易),使用python语言进行调用。(最近也在整理相关的大模型基础理论,后面应该会发布,敬请期待!)

一、申请和使用

  登录智谱官网(https://open.bigmodel.cn/),点击右上角的“开发工作台”,如下图所示,查看自己的API key并进行复制。智谱默认注册会提供18元的调用额度。

LLM之调用智谱API实现问答_第1张图片

LLM之调用智谱API实现问答_第2张图片

  接下来就直接使用复制API,将python代码中的your zhipu api进行替换,记得先使用pip下载zhipuai包,具体安装命令如下:

pip install zhipuai -i https://pypi.tuna.tsinghua.edu.cn/simple

python整体调用代码如下:

import zhipuai
zhipuai.api_key = "your zhipu api"  # 引号内输入自己申请的智谱API
response = zhipuai.model_api.invoke(
     model="chatglm_pro",  # 官方模型有chatglm_pro, chatglm_std and chatglm_lite
     prompt=[
         {"role": "user", "content": "你好"}   # 提问的中文可以根据自己的想法进行修改
     ],
     temperature=0.95,
     top_p=0.7,
     incremental=True
 )  # 文中末尾已附上相关的参数说明
# print(response)
print(response["data"]["choices"][0]["content"].strip('"').strip(" "))

prompt是LLM中一种通用的说法,简单来说就是提问的问题。

二、测试效果

  测试效果如下图所示:

在这里插入图片描述

  当我修改prompt[{"role": "user", "content": "今天天气怎么样?"}]时,得到的结果却是:

在这里插入图片描述

从智谱官网的说明可以看出,用户可以准备一些训练数据,然后根据自己的实际需求生成(微调)一个对应任务的语言模型,最后将zhipuai.model_api.invoke函数中的model变量赋值为自己模型的名字即可调用。

  最后,再附上zhipuai.model_api.invoke的接口请求参数表(如果有兴趣了解的话):

参数名称 类型 是否必填 参数说明
prompt list 调用对话模型时,将当前对话信息列表作为提示输入给模型; 按照 {"role": "user", "content": "你好"} 的键值对形式进行传参; 总长度超过模型最长输入限制后会自动截断,需按时间由旧到新排序
temperature float 采样温度,控制输出的随机性,必须为正数 取值范围是:(0.0,1.0],不能等于 0,默认值为 0.95 值越大,会使输出更随机,更具创造性;值越小,输出会更加稳定或确定 建议您根据应用场景调整 top_ptemperature 参数,但不要同时调整两个参数
top_p float 用温度取样的另一种方法,称为核取样 取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果 例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取tokens 建议您根据应用场景调整 top_ptemperature 参数,但不要同时调整两个参数
request_id string 由用户端传参,需保证唯一性;用于区分每次请求的唯一标识,用户端不传时平台会默认生成。
incremental boolean SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回 - true 为增量返回 - false 为全量返回
return_type string 用于控制每次返回内容的类型,空或者没有此字段时默认按照json_string返回 - json_string 返回标准的 JSON 字符串 - text 返回原始的文本内容
ref object 用于控制请求时的外部信息引用,目前用于控制是否引用外部信息,空或者没有此字段时默认开启搜索,传参格式 {"enable": "true", "search_query": "历史"}

后面将其集成为一个类进行调用,代码如下

import os
from typing import Any, List, Optional, Dict, Iterator
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.llms.base import LLM
from langchain.schema.output import GenerationChunk
from langchain.utils import get_from_dict_or_env
from langchain.pydantic_v1 import Field, root_validator
from dotenv import find_dotenv, load_dotenv

# read zhipu api from .env file
def load_api():
    try:
        _ = load_dotenv(find_dotenv())
        api_key = os.environ["ZHIPUAI_API_KEY"]    #填写控制台中获取的 APIKey 信息
    except Exception as e:
        print(e)
        ValueError("Please input correct ZHIPUAI_API_KEY!")
    return api_key


# define LLM class for zhipuai 
class Zhipuai_LLM(LLM):
    model_kwargs: Dict[str, Any] = Field(default_factory=dict)
    client: Any

    # set default parameters
    model: str = "chatglm_std"
    """Model name in chatglm_pro, chatglm_std, chatglm_lite. """

    zhipuai_api_key: Optional[str] = None

    incremental: Optional[bool] = True
    """Whether to incremental the results or not."""

    streaming: Optional[bool] = False
    """Whether to streaming the results or not."""
    # streaming = -incremental

    request_timeout: Optional[int] = 60
    """request timeout for chat http requests"""

    top_p: Optional[float] = 0.8
    temperature: Optional[float] = 0.95
    request_id: Optional[float] = None

    # activate zhipuai enviroment
    @root_validator()
    def validate_enviroment(cls, values: Dict) -> Dict:

        values["zhipuai_api_key"] = get_from_dict_or_env(
            values,
            "zhipuai_api_key",
            "ZHIPUAI_API_KEY",
        )

        params = {
            "zhipuai_api_key": values["zhipuai_api_key"],
            "model": values["model"],
        }
        try:
            import zhipuai

            zhipuai.api_key = values["zhipuai_api_key"]
            values["client"] = zhipuai.model_api
        except ImportError:
            raise ValueError(
                "zhipuai package not found, please install it with "
                "`pip install zhipuai`"
            )
        return values
    
    @property
    def _llm_type(self) -> str:
        """Return type of llm."""
        return "zhipuai"

    @property
    def _default_params(self) -> Dict[str, Any]:
        """获取调用Ennie API的默认参数。"""
        normal_params = {
            "streaming": self.streaming,
            "top_p": self.top_p,
            "temperature": self.temperature,
            "request_id": self.request_id,
            }
        return {**normal_params}

    @property
    def _identifying_params(self) -> Dict[str, Any]:
        """Get the identifying parameters."""
        return {
            **{"model": self.model},
            **{**self._default_params},
        }
    
    def _convert_prompt_msg_params(
        self,
        prompt: str,
        **kwargs: Any,
    ) -> dict:
        return {
            **{"prompt": prompt, "model": self.model},
            **self._default_params,
            **kwargs,
        }
    
    def _stream(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> Iterator[GenerationChunk]:
        params = self._convert_prompt_msg_params(prompt, **kwargs)

        for res in self.client.invoke(**params):
            if res:
                chunk = GenerationChunk(text=res)
                yield chunk
                if run_manager:
                    run_manager.on_llm_new_token(chunk.text)

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        """Call out to an zhipuai models endpoint for each generation with a prompt.
        Args:
            prompt: The prompt to pass into the model.
        Returns:
            The string generated by the model.

        Example:
            .. code-block:: python
                response = zhipuai_model("Tell me a joke.")
        """
        if self.streaming:
            completion = ""
            for chunk in self._stream(prompt, stop, run_manager, **kwargs):
                completion += chunk.text
            return completion
        params = self._convert_prompt_msg_params(prompt, **kwargs)
        # print({**params})
        response_payload = self.client.invoke(**params)
        return response_payload["data"]["choices"][-1]["content"].strip('"').strip(" ")
    


api_key = load_api()
# print(api_key)
llm = Zhipuai_LLM(model="chatglm_pro", zhipuai_api_key=api_key)
print(llm("给我讲段笑话")) 

三、参考

[1] https://open.bigmodel.cn/dev/api#nosdk

[2] [https://github.com/datawhalechina/llm-universe](https://github.com/datawhalechina/llm-universe)

你可能感兴趣的:(人工智能)