通过调用讯飞星火api实现问答功能

一  .准备工作

首先要拿到讯飞的语言大模型的api,可以从以下链接的方式获取(讯飞星火大模型-AI大语言模型-星火大模型-科大讯飞讯飞星火大模型,是由科大讯飞推出的新一代认知智能大模型,拥有跨领域的知识和语言理解能力,能够基于自然对话方式理解与执行任务,提供语言理解、知识问答、逻辑推理、数学题解答、代码理解与编写等多种能力。icon-default.png?t=N7T8https://xinghuo.xfyun.cn/speechllm),目前这些都是免费。

二 . 演示

三 .代码

前端交互:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能回答</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
        }

        .container {
            max-width: 800px;
            margin: 20px auto;
            padding: 20px;
            background-color: #ffffff;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        .chat-header {
            display: flex;
            align-items: center;
            margin-bottom: 20px;
        }

        .chat-avatar {
            font-size: 24px;
            margin-right: 10px;
        }

        .chat-name {
            font-size: 20px;
            color: #333;
        }

        .chat-messages {
            list-style-type: none;
            padding: 0;
            margin: 0;
        }

        .chat-messages .message {
            display: flex;
            align-items: center;
            padding: 10px;
            margin-bottom: 10px;
            border-radius: 5px;
            word-wrap: break-word;
        }

        .chat-messages .message .message-avatar {
            font-size: 24px;
            margin-right: 10px;
        }

        .chat-messages .message .message-content {
            white-space: pre-wrap;
        }

        .chat-messages .message.right {
            justify-content: flex-end;
            background-color: #cfe8fc; 
        }

        .chat-messages .message.left {
            justify-content: flex-start;
            background-color: #e0e0e0; 
        }

        .chat-messages .message.right .message-avatar {
            margin-left: 10px;
            margin-right: 0;
        }

        .chat-messages .message.right .message-content {
            text-align: right;
        }

        .chat-messages .message.left .message-content {
            text-align: left;
        }

        .chat-input {
            display: flex;
            margin-top: 20px;
        }

        .chat-input input[type="text"] {
            flex: 1;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            margin-right: 10px;
        }

        .chat-input button {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        .chat-input button:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="chat-header">
            <div class="chat-avatar">
                🤖
            </div>
            <span class="chat-name">ChatBot</span>
        </div>

        <ul class="chat-messages" id="chatMessages">
          
        </ul>

        <form class="chat-input" id="myform">
            <input type="text" id="chat-message" placeholder="输入你的消息...">
            <button type="submit">发送</button>
        </form>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const form = document.getElementById('myform');
            const chatMessageInput = document.getElementById('chat-message');
            const chatAnswerDiv = document.getElementById('chatMessages');

            
            function createChatBubble(content, className, avatarClass) {
                const bubble = document.createElement('div');
                bubble.className = 'message ' + className;
                bubble.innerHTML = `
                    <div class="message-avatar ${avatarClass}"></div>
                    <div class="message-content">${content}</div>
                `;
                return bubble;
            }

           
            form.addEventListener('submit', async function(event) {
                event.preventDefault();

                const message = chatMessageInput.value.trim();
                if (!message) return;

                chatMessageInput.value = '';

                
                const userMessageElement = createChatBubble(message, 'right', 'user');
                chatAnswerDiv.appendChild(userMessageElement);

                const loadingMessage = createChatBubble('正在调用工作流...', 'left', 'assistant');
                chatAnswerDiv.appendChild(loadingMessage);

                try {
                    
                    const response = await fetch('/', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({ input: message, isNewConversation: true }) 
                    });

                    if (!response.ok) {
                        throw new Error(`Request failed with status ${response.status}`);
                    }

                    const data = await response.json();

                   
                    chatAnswerDiv.removeChild(loadingMessage);

                   
                    const assistantMessageText = data.response.replace(/\n/g, '<br>');
                    const assistantMessageElement = createChatBubble(assistantMessageText, 'left', 'assistant');

                    
                    chatAnswerDiv.appendChild(assistantMessageElement);
                } catch (error) {
                    console.error('Error:', error);
                    chatAnswerDiv.removeChild(loadingMessage);
                    const errorMessageElement = createChatBubble('Sorry, there was an error processing your request.', 'left', 'assistant');
                    chatAnswerDiv.appendChild(errorMessageElement);
                }
            });
        });
    </script>
</body>
</html>
后端flask框架
SparkApi.py
import _thread as thread
import base64
import datetime
import hashlib
import hmac
import json
import threading
from urllib.parse import urlparse
import ssl
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time

import websocket  # 使用websocket_client

answer = ""



class Ws_Param(object):
    # 初始化
    def __init__(self, APPID, APIKey, APISecret, gpt_url):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.host = urlparse(gpt_url).netloc
        self.path = urlparse(gpt_url).path
        self.gpt_url = gpt_url  # 注意这里使用 gpt_url

    # 生成url
    def create_url(self):
        # 生成RFC1123格式的时间戳
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        # 拼接字符串
        signature_origin = "host: " + self.host + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + self.path + " HTTP/1.1"

        # 进行hmac-sha256进行加密
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                 digestmod=hashlib.sha256).digest()

        signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')

        authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'

        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')

        # 将请求的鉴权参数组合为字典
        v = {
            "authorization": authorization,
            "date": date,
            "host": self.host
        }
        # 拼接鉴权参数,生成url
        url = self.gpt_url + '?' + urlencode(v)  # 注意这里使用 gpt_url
        return url


# 收到websocket错误的处理


def on_error(ws, error):
    print("### error:", error)





def on_close(ws, one, two):
    print(" ")


# 收到websocket连接建立的处理


def on_open(ws):
    thread.start_new_thread(run, (ws,))


def run(ws, *args):
    data = json.dumps(gen_params(appid=ws.appid, domain=ws.domain, question=ws.question))
    ws.send(data)


def run_websocket(ws):
    try:
        ws.run_forever()
    except websocket._exceptions.WebSocketConnectionClosedException:
        print("WebSocket connection closed")

def on_message(ws, message):
    print("Received message:", message)
    # 解析JSON消息并处理
    data = json.loads(message)
    code = data['header']['code']
    if code != 0:
        print(f'请求错误: {code}, {data}')
        ws.close()
    else:
        choices = data["payload"]["choices"]
        status = choices["status"]
        content = choices["text"][0]["content"]
        print(content, end="")
        global answer
        answer += content
     
        if status == 2:
            ws.close()


def gen_params(appid, domain, question):
  
    data = {
        # "header": {
        #     "app_id": appid,
        #     "uid": "1234"
        #
        # },
        "header": {
            "app_id": appid,
            "uid": "1234"

        },


        "parameter": {
            "chat": {
                "domain": domain,
                "temperature": 0.3,
                "max_tokens": 1000,
                # "top-k": 4
            }
        },
        "payload": {
            "message": {
                # "text": question
                "text": [
                    {"role": "system", "content": "我是一个抑郁症助手"},
                    {"role": "user", "content": "你要帮助患者判断是否患有抑郁症并且提出建议"},
                    {"role": "user", "content": question}]


            }

        }

    }

    return data


def main(appid, api_key, api_secret, Spark_url, domain, question):
    # print("星火:")
    wsParam = Ws_Param(appid, api_key, api_secret, Spark_url)
    websocket.enableTrace(False)
    wsUrl = wsParam.create_url()
    ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)
    ws.appid = appid
    ws.question = question
    ws.domain = domain
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})




def getText(role, content):
    text = []
    jsoncon = {}
    jsoncon["role"] = role
    jsoncon["content"] = content
    text.append(jsoncon)
    return text


def getlength(text):
    length = 0
    for content in text:
        # temp = content["content"]
        temp = content

        leng = len(temp)
        length += leng
    return length


def checklen(text):
    while (getlength(text) > 8000):
        del text[0]
    return text


def config():
    config = {}
    config["appid"] = "xxx"
    config["api_secret"] = "xxx"
    config["api_key"] = "xxx"
    config["domain"] = "xxx"
    config["Spark_url"] = "xxx"
    return config
注意:在config里面放入自己的appid及相关配置
main.py
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})


app.config.from_object('SparkEdit')





@app.route("/", methods=["GET", "POST"])
def xin_info():
    if request.method == "GET":
        return render_template('index.html')

    elif request.method == "POST":
        try:
            # 重置 SparkApi.answer 在每次请求开始时
            SparkApi.answer = ""

            # 获取请求的JSON数据
            req_data = request.get_json(silent=True)  # silent=True 避免请求体不是JSON时引发异常
            if not req_data or 'input' not in req_data:
                return jsonify({'error': 'Invalid request data'}), 400

            Input = req_data['input']

            # 获取配置信息
            appid = SparkApi.config()["appid"]
            api_secret = SparkApi.config()["api_secret"]
            api_key = SparkApi.config()["api_key"]
            domain = SparkApi.config()["domain"]
            Spark_url = SparkApi.config()["Spark_url"]

            # 处理请求并获取回答
            question = SparkApi.checklen(Input)
            SparkApi.main(appid, api_key, api_secret, Spark_url, domain, question)
            answer_txt = SparkApi.getText("assistant", SparkApi.answer)[0]["content"]

            # 返回JSON响应
            return jsonify({'response': answer_txt})

        except Exception as e:
            # 错误信息处理
            error_message = "An error occurred while processing your request."
            app.logger.error(f"Error processing request: {e}")  # 记录错误信息到日志
            return jsonify({'error': error_message}), 500

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哎呦☞ᨐ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值