Как добавить работу с историей в 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), но после добавления логика чатбота видимо ломается, т.к. он перестаёт внятно отвечать (на запрос запомнить слово отправляет просто символ точки).
Вопрос: как его заставить работать с историей чата (чтобы допустим он мог запоминать что-то из чата и вспоминать когда я что-то спрашиваю о чем уже писал)