Как добавить работу с историей в GIGACHAT API

Есть код отвечающий за логику (файл gigachatapi):

import streamlit as st 
import requests
import uuid
import json

from get_image import get_file_id
from requests.auth import HTTPBasicAuth

CLIENT_ID = st.secrets["CLIENT_ID"]
SECRET = st.secrets["SECRET"]


# Checking is token available or not
def get_access_token() -> str:
    url = "https://ngw.devices.sberbank.ru:9443/api/v2/oauth"
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
        'RqUID': str(uuid.uuid4()),
    }
    payload = {"scope": "GIGACHAT_API_PERS"}
    res = requests.post(
        url=url, 
        headers=headers, 
        auth=HTTPBasicAuth(CLIENT_ID, SECRET), 
        data=payload,
        verify=False)
    access_token = res.json()["access_token"]
    return access_token


# Generate images 
def get_image(access_token: str, file_id: str):
    url = f"https://gigachat.devices.sberbank.ru/api/v1/files/{file_id}/content"

    payload={}
    headers = {
    'Accept': 'image/jpg',
    'Authorization': f'Bearer {access_token}'
    }
    response = requests.get(url, headers=headers, data=payload, verify=False)
    return response.content

# Here you send prompt and configure settings
def send_prompt(msg: str, access_token: str):

    url = "https://gigachat.devices.sberbank.ru/api/v1/chat/completions"

    payload = json.dumps({
    "model": "GigaChat",
    "messages": [
        {
        "role": "user",
        "content": msg
        }
    ],
    "function_call": "auto",
    })
    headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': f'Bearer {access_token}'
    }

    response = requests.post(url, headers=headers, data=payload, verify=False)

    try:
        return response.json()["choices"][0]["message"]["content"]
    except Exception as e:
        return f"Ошибка: {e}"

# check: need to generate image or not
def sent_prompt_check(msg: str, access_token: str):
    res = send_prompt(msg, access_token)
    data, is_image = get_file_id(res)
    if is_image:
        data = get_image(file_id=data, access_token=access_token)
    return data, is_image

А также код отвечающий за интерфейс (файл main.py):

import streamlit as st 

from gigachatapi import get_access_token, send_prompt, sent_prompt_check

CLIENT_ID = st.secrets["CLIENT_ID"]
SECRET = st.secrets["SECRET"]

st.title("Persona GigaChat-bot")

if "access_token" not in st.session_state:
    try:
        st.session_state.access_token = get_access_token()
        st.toast("Токен получен")
    except Exception as e:
        st.toast(f"Токен не был получен: {e}")


if "messages" not in st.session_state:
    st.session_state.messages = [{"role": "ai", "content": "Привет"}]


for msg in st.session_state.messages:
    if msg.get("is_image"): # если был запрос на картинку
        st.chat_message(msg["role"]).image(msg["content"])
    else: # если на текст
        st.chat_message(msg["role"]).write(msg["content"])


if user_prompt := st.chat_input():
    st.chat_message("user").write(user_prompt)
    st.session_state.messages.append({"role": "user", "content": user_prompt})
    
    with st.spinner("Происходит магия..."):
        response, is_image = sent_prompt_check(user_prompt, st.session_state.access_token)
        if is_image:
            st.chat_message("ai").image(response)
            st.session_state.messages.append({"role": "ai", "content": response, "is_image": True})
        else:
            st.chat_message("ai").write(response)
            st.session_state.messages.append({"role": "ai", "content": response})

В документации к api сказано, что для работы с историей нужно обязательно передавать массив в запросе на генерацию, в сообщении с ролью assistant.

Попытался сделать что-то вроде этого:

import streamlit as st 
import requests
import uuid
import json

from get_image import get_file_id
from requests.auth import HTTPBasicAuth

CLIENT_ID = st.secrets["CLIENT_ID"]
SECRET = st.secrets["SECRET"]


# Checking is token available or not
def get_access_token() -> str:
    url = "https://ngw.devices.sberbank.ru:9443/api/v2/oauth"
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
        'RqUID': str(uuid.uuid4()),
    }
    payload = {"scope": "GIGACHAT_API_PERS"}
    res = requests.post(
        url=url, 
        headers=headers, 
        auth=HTTPBasicAuth(CLIENT_ID, SECRET), 
        data=payload,
        verify=False)
    access_token = res.json()["access_token"]
    return access_token


# Generate images 
def get_image(access_token: str, file_id: str):
    url = f"https://gigachat.devices.sberbank.ru/api/v1/files/{file_id}/content"

    payload={}
    headers = {
    'Accept': 'image/jpg',
    'Authorization': f'Bearer {access_token}'
    }
    response = requests.get(url, headers=headers, data=payload, verify=False)
    return response.content

# Here you send prompt and configure settings
def send_prompt(msg: str, access_token: str):

    url = "https://gigachat.devices.sberbank.ru/api/v1/chat/completions"

    payload = json.dumps({
    "model": "GigaChat",
    "messages": [
        {
        "role": "user",
        "content": msg,
        "data_for_context": [
            {"role": "assistant",
        "content": msg}
        ]
        }
    ],
    "function_call": "auto",
    })
    headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': f'Bearer {access_token}'
    }

    response = requests.post(url, headers=headers, data=payload, verify=False)

    try:
        return response.json()["choices"][0]["message"]["content"]
    except Exception as e:
        return f"Ошибка: {e}"

# check: need to generate image or not
def sent_prompt_check(msg: str, access_token: str):
    res = send_prompt(msg, access_token)
    data, is_image = get_file_id(res)
    if is_image:
        data = get_image(file_id=data, access_token=access_token)
    return data, is_image

(добавил массив как показано в документации, добавил роль assistant), но после добавления логика чатбота видимо ломается, т.к. он перестаёт внятно отвечать (на запрос запомнить слово отправляет просто символ точки).

Вопрос: как его заставить работать с историей чата (чтобы допустим он мог запоминать что-то из чата и вспоминать когда я что-то спрашиваю о чем уже писал)


Ответы (0 шт):