LLM API
Jako dodatkową usługę oferujemy możliwość korzystania z dużych modeli językowych. Są one dostępne przez API częściowo kompatybilne z OpenAI API oraz Anthropic Messages API.
Bazowy adres URL to:
https://llm.comtegra.cloud/v1
Umożliwiamy korzystanie z następujących zasobów:
- /v1/chat/completions
- /v1/completions — Completions API (legacy)
- /v1/models
- /v1/embeddings
- /v1/audio/transcriptions
- /v1/files/convert — konwersja PDF → Markdown
- /v1/messages — Anthropic Messages API
- /v1/responses — OpenAI Responses API
- /v1/systemone, /v1/decisions — decyzje typowane: format System One API na
/v1/systemone, format OpenAI Decisions na/v1/decisions
Uwierzytelnienie odbywa się za pomocą klucza. Aby rozpocząć korzystanie z API, wystarczy utworzyć klucz za pomocą klienta CGC.
Aktualną listę modelów otrzymasz, wywołując:
/v1/models
Typy modeli
Każdy model ma swój typ (type), który określa, z jakimi zasobami można go
używać:
type | Zasoby |
|---|---|
chat | /v1/chat/completions, /v1/completions, /v1/messages, /v1/responses |
embedding | /v1/embeddings |
transcription | /v1/audio/transcriptions |
conversion | /v1/files/convert |
decision | /v1/systemone (format System One API), /v1/decisions (format OpenAI Decisions) |
Typ każdego modelu jest podany w odpowiedzi /v1/models:
{"id": "gte-qwen2-7b", "object": "model", "created": null, "owned_by": null, "type": "embedding", "device": "a5000", "model_repo": null, "max_model_len": 8192}
Zapytanie, które używa modelu w zasobie innego typu (np. chat completions
z modelem do embeddingów), jest odrzucane z kodem HTTP 404 i
"code": "model_not_supported". Nieistniejący model lub zapytanie bez pola
model kończy się kodem HTTP 404 i "code": "model_not_found". Odrzucone
zapytania nie są rozliczane.
{"error": {"message": "The model 'gte-qwen2-7b' has type 'embedding' and is not supported on /v1/chat/completions.", "type": "invalid_request_error", "param": "model", "code": "model_not_supported"}}
W zasobie /v1/messages oba błędy mają format błędów Anthropic:
{"type": "error", "error": {"type": "not_found_error", "message": "The model 'gte-qwen2-7b' has type 'embedding' and is not supported on /v1/messages."}}
Przykłady użycia
Chat
- Python
- curl
from openai import OpenAI
client = OpenAI(base_url="https://llm.comtegra.cloud/v1",
api_key="YOUR-API-SECRET")
res = client.chat.completions.create(model="glm-53-nvfp4", max_completion_tokens=100,
messages=[{"role": "user", "content": "Hi"}])
print(res)
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-d '{"model": "glm-53-nvfp4", "messages": [{"role": "user", "content": "Hi"}]}' \
'https://llm.comtegra.cloud/v1/chat/completions'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Embeddings
- Python
- curl
from openai import OpenAI
client = OpenAI(base_url="https://llm.comtegra.cloud/v1",
api_key="YOUR-API-SECRET")
res = client.embeddings.create(model="gte-qwen2-7b", input="Mary had a little lamb")
print(res)
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-d '{"model": "gte-qwen2-7b","input": "Mary had a little lamb", "pooling": "mean"}' \
'https://llm.comtegra.cloud/v1/embeddings'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Transcriptions
- Python
- curl
from openai import OpenAI
client = OpenAI(base_url="https://llm.comtegra.cloud/v1",
api_key="YOUR-API-SECRET")
with open("recording.mp3", "rb") as f:
res = client.audio.transcriptions.create(model="whisper-1", file=f)
print(res)
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-F file=@'recording.mp3' \
-F model='whisper-1' \
'https://llm.comtegra.cloud/v1/audio/transcriptions'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Proxy zawsze zwraca format verbose_json, który zawiera długość nagrania
wykorzystywaną do rozliczeń. Formaty text, srt oraz vtt nie są obsługiwane.
Konwersja plików
Konwertuje PDF do Markdown. To rozszerzenie Comtegra (nie należy do API OpenAI
ani Anthropic). Użyj identyfikatora modelu pdf-to-markdown. Dostępne są dwa
tryby:
- Synchroniczny (domyślny): odpowiedź wraca po zakończeniu konwersji.
- W tle (
background=true): API od razu zwraca identyfikator konwersji, a wynik odbierasz, gdy jest gotowy. Używaj go dla skanów i długich dokumentów (OCR jednej zeskanowanej strony trwa kilkadziesiąt sekund) albo gdy agent ma w tym czasie pracować dalej.
Tryb synchroniczny
- Python
- curl
import requests
with open("document.pdf", "rb") as f:
res = requests.post(
"https://llm.comtegra.cloud/v1/files/convert",
headers={"Authorization": "Bearer YOUR-API-SECRET"},
files={"file": ("document.pdf", f, "application/pdf")},
data={"model": "pdf-to-markdown"},
)
print(res.json())
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-F file=@'document.pdf' \
-F model='pdf-to-markdown' \
'https://llm.comtegra.cloud/v1/files/convert'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Udane wywołanie zwraca JSON z "success": true, Markdown w polu "output",
"page_count" używane do rozliczeń oraz wyodrębnione obrazy w polu "images"
(base64, klucze to nazwy plików). Nieudane konwersje kończą się błędem i nie są
rozliczane. Plik większy niż 50 MB jest odrzucany z kodem 413.
Tryb w tle
Wyślij to samo zapytanie z background=true, a potem odpytuj konwersję, dopóki
jej status jest in_progress.
- Python
- curl
import time
import requests
API = "https://llm.comtegra.cloud/v1/files/convert"
HEADERS = {"Authorization": "Bearer YOUR-API-SECRET"}
with open("document.pdf", "rb") as f:
res = requests.post(
API,
headers=HEADERS,
files={"file": ("document.pdf", f, "application/pdf")},
data={"model": "pdf-to-markdown", "background": "true"},
)
res.raise_for_status()
conversion = res.json() # {"id": "fc_...", "status": "queued", ...}
while True:
res = requests.get(f"{API}/{conversion['id']}", headers=HEADERS)
res.raise_for_status()
conversion = res.json()
if conversion["status"] != "in_progress":
break
time.sleep(int(res.headers.get("Retry-After", 5)))
if conversion["status"] == "completed":
print(conversion["output"])
else:
print(conversion["error"])
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-F file=@'document.pdf' \
-F model='pdf-to-markdown' \
-F background=true \
'https://llm.comtegra.cloud/v1/files/convert'
# potem, z "id" z odpowiedzi:
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
'https://llm.comtegra.cloud/v1/files/convert/fc_...'
| Zapytanie | Odpowiedź |
|---|---|
POST z background=true | 202 Accepted z {"id", "object": "file.conversion", "model", "status": "queued"} oraz nagłówkami Location: /v1/files/convert/{id} i Retry-After: 5. |
GET /v1/files/convert/{id} w trakcie konwersji | 200 ze "status": "in_progress" i nagłówkiem Retry-After. |
GET po zakończeniu | 200 ze "status": "completed" i tymi samymi polami co odpowiedź synchroniczna: output, page_count, images, output_format. |
GET po nieudanej konwersji | 200 ze "status": "failed" i "error": {"message", "code"}. |
GET z nieznanym lub wygasłym identyfikatorem albo z innym kluczem API | 404 z kodem conversion_not_found. |
- Identyfikator konwersji działa tylko z kluczem API, który ją zlecił.
- Strony są rozliczane raz, przy pierwszym odebraniu wyniku; kolejne odebrania tego samego identyfikatora są bezpłatne. Nieudane konwersje nie są rozliczane.
- Wyniki są przechowywane przez 7 dni.
- Jeden klucz API może mieć naraz najwyżej 4 trwające odpytania; kolejne
dostają
429z nagłówkiemRetry-After. Odpytania nie wliczają się do limitów zapytań modelu. - Nagłówki
LocationiRetry-Aftersą wymienione wAccess-Control-Expose-Headers.
Messages
Zasób Anthropic Messages API umożliwia korzystanie z naszych modeli narzędziom agentowym, takim jak Claude Code oraz Anthropic SDK.
- Python
- curl
from anthropic import Anthropic
# Anthropic SDK samo dokleja "/v1/messages" do adresu bazowego, więc ustaw go na
# https://llm.comtegra.cloud (bez "/v1"). Uwierzytelniaj się przez auth_token,
# który wysyłany jest jako token bearer; argument api_key (x-api-key) nie jest
# obsługiwany.
client = Anthropic(base_url="https://llm.comtegra.cloud",
auth_token="YOUR-API-SECRET")
res = client.messages.create(model="glm-53-nvfp4", max_tokens=100,
messages=[{"role": "user", "content": "Hi"}])
print(res)
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-d '{"model": "glm-53-nvfp4", "max_tokens": 100, "messages": [{"role": "user", "content": "Hi"}]}' \
'https://llm.comtegra.cloud/v1/messages'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Anthropic SDK oraz narzędzia kompatybilne z Anthropic (takie jak Claude Code)
budują adres zapytania jako <adres bazowy>/v1/messages, dlatego ustaw ich adres
bazowy na https://llm.comtegra.cloud — bez /v1 używanego przez zasoby w stylu
OpenAI — i uwierzytelniaj się tokenem bearer (parametr auth_token w SDK).
Schemat x-api-key nie jest obsługiwany.
Responses
Zasób OpenAI Responses API obsługuje narzędzia agentowe, takie jak Codex CLI.
- Python
- curl
from openai import OpenAI
client = OpenAI(base_url="https://llm.comtegra.cloud/v1",
api_key="YOUR-API-SECRET")
res = client.responses.create(model="glm-53-nvfp4", input="Hi")
print(res)
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-d '{"model": "glm-53-nvfp4", "input": "Hi"}' \
'https://llm.comtegra.cloud/v1/responses'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Ten zasób jest bezstanowy: w każdym zapytaniu wysyłaj pełną historię rozmowy
w polu input. Stan rozmowy po stronie serwera (previous_response_id,
conversation oraz zapytania background) nie jest obsługiwany.
Decyzje
Zasoby decyzji serwują modele System One: zamiast generować tekst, model odpowiada na typowane pytania o dokument i podaje prawdopodobieństwa. Dokument przekazujesz raz, a potem zadajesz dowolną liczbę pytań na jego temat.
Obsługiwane są dwa formaty żądań:
/v1/systemone: format System One API (polestatei obiektquestions), do użycia zwykłym klientem HTTP;/v1/decisions: obsługiwany podzbiór formatu OpenAI Decisions, więc oficjalny klient OpenAI działa od razu - patrz poniżej.
Żądanie /v1/systemone przyjmuje pole state oraz obiekt questions.
Typy pytań:
type | Co odpowiada |
|---|---|
choice | Jedna opcja z podanych kryteriów, wraz z prawdopodobieństwami. |
noul | Odpowiedź tak/nie wraz z prawdopodobieństwem true. |
score | Poziom na uporządkowanej skali (np. Niski/Średni/Wysoki). |
multi | Zbiór pasujących etykiet z niezależnymi prawdopodobieństwami. |
act | Działanie o najniższym oczekiwanym koszcie; defer, gdy ryzyko jest zbyt duże. |
tool | Najlepiej dopasowane narzędzie spośród definicji w stylu OpenAI. |
noul, choice i score to podstawowe typy System One. multi, act i
tool to rozszerzenia, których nie każdy model decyzyjny obsługuje. Typy
obsługiwane przez dany model są podane w jego wpisie w /v1/models
(decision_capabilities.question_types).
- Python
- curl
import requests
res = requests.post(
"https://llm.comtegra.cloud/v1/systemone",
headers={"Authorization": "Bearer YOUR-API-SECRET"},
json={
"model": "basal-20-max",
"state": "The customer received a broken product and requests a refund.",
"questions": {
"category": {
"type": "choice",
"instructions": "Classify the message.",
"option_keys": "hide",
"criteria": {
"complaint": "Complaint",
"question": "Question",
"other": "Other",
},
}
},
},
)
print(res.json())
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-H 'Content-Type: application/json' \
-d '{"model": "basal-20-max", "state": "The customer received a broken product and requests a refund.", "questions": {"category": {"type": "choice", "instructions": "Classify the message.", "option_keys": "hide", "criteria": {"complaint": "Complaint", "question": "Question", "other": "Other"}}}}' \
'https://llm.comtegra.cloud/v1/systemone'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
Poprawna odpowiedź zachowuje natywny format: odpowiedź na każde pytanie
oraz obiekt usage:
{
"model": "basal-20-max",
"answers": {
"category": {
"type": "choice",
"choice": "complaint",
"probabilities": {"complaint": 0.9506, "question": 0.0059, "other": 0.0435},
"confidence": 0.9506
}
},
"usage": {
"input_tokens": 106,
"output_tokens": 0,
"questions": 1,
"branches": 1,
"latency_ms": 107.71,
"longest_prompt_tokens": 106
}
}
- Pole
output_tokensma zwykle wartość0: decyzja jest odczytywana z prawdopodobieństwów modelu, a nie generowana token po tokenie. - Kontekst modelu (
max_model_len, 32768 tokenów) obejmuje cały prompt: stan, pytanie i opcje razem. Stan, który się nie mieści, jest odrzucany z kodem HTTP422. - Streaming i parametry czatu (
messages,max_tokens,temperature) nie są obsługiwane na tym zasobie.
Użycie klienta OpenAI
Zasób /v1/decisions mówi obsługującym podzbiorem formatu OpenAI
Decisions, więc oficjalny klient OpenAI (openai>=3.26, z interfejsem
client.decisions) działa od razu:
- Python
- curl
from openai import OpenAI
client = OpenAI(base_url="https://llm.comtegra.cloud/v1",
api_key="YOUR-API-SECRET")
result = client.decisions.create(
model="basal-20-max",
input="The customer received a damaged product.",
questions=[
{
"type": "predicate",
"name": "complaint",
"instructions": "Is this a complaint?",
}
],
)
print(result.answers[0].probability)
curl \
-H 'Authorization: Bearer YOUR-API-SECRET' \
-H 'Content-Type: application/json' \
-d '{"model": "basal-20-max", "input": "The customer received a damaged product.", "questions": [{"type": "predicate", "name": "complaint", "instructions": "Is this a complaint?"}]}' \
'https://llm.comtegra.cloud/v1/decisions'
To polecenie jest przeznaczone do wykonania przez program curl. W Power Shellu curl to alias polecenia Invoke-WebRequest, które nie jest kompatybilne z curlem.
- Zasób
/v1/decisionsprzyjmuje polamodel,inputiquestions. Poleinputto tekst albo tablica wiadomości użytkownika, których treść jest tekstem lub częściamiinput_text; części są łączone znakami nowej linii, a wiadomości pustą linią. Obrazy, pliki audio i inne pliki, inne role oraz streaming są odrzucane z kodem HTTP400. - Obsługiwane typy pytań to
predicate,choiceiscore. Pytaniachoiceiscoreprzyjmują tablicę 2-255 unikalnych wartościchoices/levels(wartość lub etykieta plus opcjonalny opis). - Odpowiedzi zachowują kolejność pytań:
predicatezwraca prawdopodobieństwo,choicezwraca wybraną opcję wraz z pewnością i rozkładem prawdopodobieństw, ascorezwraca oczekiwany indeks poziomu liczony od zera. Odpowiedź nigdy nie dodaje ani nie pomija opcji, których nie zażądano. - Obiekt
usageużywa układu OpenAI; liczniki szczegółów (cache, reasoning) są zerowe, aoutput_tokensma zwykle wartość0. - Żądanie nie mieszczące się w kontekście modelu jest odrzucane z
"code": "context_length_exceeded". - Wpis modelu decyzyjnego w
/v1/modelswymienia obsługiwane zasoby i typy pytań w poludecision_capabilities.
Klucze API
cgc api-keys create --level LLM
Wypisany zostanie klucz z etykietą API secret. Zapisz go w wygodnym i bezpiecznym miejscu. Nie ma możliwości podejrzeć go drugi raz, więc jeśli go stracisz, usuń go i stwórz nowy. Nie ujawniaj swojego klucza, gdyż może to powodować naliczenie opłat za użycie API przez osoby trzecie.
Do kluczy, przypisanych do Twojego konta można dodać komentarze. Ułatwia to ich identyfikację.
cgc api-keys create --level LLM --comment "Klucz Michała"
Wszystkie dostępne opcje można zobaczyć, wykonując polecenie
cgc api-keys --help.
Billing
Zapytania do API doliczane są do rachunku Twojej organizacji.
Ich koszt zależy od liczby tokenów wejściowych i wyjściowych, modelu i GPU.
Wyjątki: transkrypcja audio jest rozliczana za każdą sekundę przetworzonego
nagrania; konwersja PDF → Markdown (/v1/files/convert) jest rozliczana za
każdą stronę (page_count w odpowiedzi); konwersja w tle jest rozliczana raz,
przy pierwszym odebraniu wyniku.
Cennik dostępny jest na stronie cgc.comtegra.cloud/pricing.
Zużycie tokenów i ich koszt można zobaczyć za pomocą polecenia
cgc billing status.
Przykład obliczenia kosztu zapytania:
Używasz modelu Meta-Llama 3.1-70B-Instruct-Q5_K_M, uruchomionego na GPU NVIDIA A100 GPU. Załóżmy, że tokeny wejściowe kosztują 19,78 zł / 1M tok. a tokeny wyjściowe -- 167,66 zł / 1M tok. Twoje zapytanie to: Write a haiku about ChatGPT. Jest ono długości 18 tokenów. Dostajesz następującą odpowiedź: Silicon whispers. ChatGPT's gentle responses. Knowledge at my door, której długość to 16 tokenów. To zapytanie będzie kosztować 19,78 zł * 18 / 1000000 + 167,66 zł * 16 / 1000000 = 0,003039 zł.
Oznaczanie treści generowanych przez AI
Akt o sztucznej inteligencji (rozporządzenie (UE) 2024/1689, art. 50 ust. 2) zobowiązuje dostawców generatywnych systemów AI do oznaczania ich wyników jako sztucznie wygenerowanych w formacie nadającym się do odczytu maszynowego. API spełnia ten wymóg, oznaczając każdą odpowiedź generatywną w momencie jej wytworzenia.
Każda pomyślna odpowiedź zasobów /v1/chat/completions, /v1/completions,
/v1/messages, /v1/responses, /v1/audio/transcriptions i
/v1/files/convert zawiera nagłówek X-AI-Generated: true. Odpowiedzi
niestrumieniowe zasobów /v1/chat/completions, /v1/completions,
/v1/messages i /v1/responses zawierają dodatkowo obiekt provenance na
najwyższym poziomie, obok standardowych pól odpowiedzi:
"provenance": {
"ai_generated": true,
"digital_source_type": "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia",
"legal_basis": "Regulation (EU) 2024/1689, Article 50(2)",
"generator": "comtegra-llmproxy",
"generator_version": "1.4.0",
"model_id": "glm-53-nvfp4",
"request_id": "4df57814-a195-467f-9d8a-294ce7796283",
"timestamp": "2026-08-24T14:08:02Z"
}
| Pole | Znaczenie |
|---|---|
ai_generated | Zawsze true. |
digital_source_type | Termin ze słownika IPTC Digital Source Type oznaczający treść w całości wygenerowaną przez wytrenowany model; tego samego słownika używa C2PA. |
legal_basis | Przepis, który oznaczenie realizuje. |
generator, generator_version | System, który dodał oznaczenie, i jego wersja. |
model_id | Wartość pola model z Twojego zapytania. |
request_id | Identyfikator zapytania, równy nagłówkowi odpowiedzi X-Request-ID. Podaj go, kontaktując się z pomocą techniczną w sprawie konkretnej odpowiedzi. |
timestamp | Czas wygenerowania (UTC, RFC 3339). |
W poniższych przypadkach oznaczenie ogranicza się do nagłówka:
- Odpowiedzi strumieniowe (
"stream": true). Strumień zdarzeń jest przekazywany bez zmian, więc klienty i SDK obsługujące strumieniowanie nie są dotknięte tą zmianą. /v1/audio/transcriptions. Treść transkrypcji jest przekazywana bez zmian./v1/files/convert(tryb synchroniczny i w tle). Wynik konwersji jest przekazywany tak, jak zwraca go konwerter; proxy nie dodaje opisanego wyżej obiektu.
Odpowiedzi /v1/embeddings i /v1/models oraz odpowiedzi z błędem nie są
oznaczane, ponieważ nie są treścią generowaną.
Oba nagłówki są wymienione w Access-Control-Expose-Headers, więc mogą je
odczytać również klienty przeglądarkowe z innych domen.
Obiekt provenance jest rozszerzeniem standardowych schematów odpowiedzi
OpenAI i Anthropic. Oficjalne SDK zachowują go jako dodatkowe pole — np.
res.model_extra["provenance"] w SDK OpenAI dla Pythona. Jeśli Twój klient
waliduje odpowiedzi według ścisłego schematu, dopuść to dodatkowe pole na
najwyższym poziomie.
Własna instancja LLM API
Jeśli używasz jednocześnie kilku modeli w swoim własnym namespace, możesz uruchomić własną instancję LLM API. Umożliwia ona kontrolę dostępu do modeli i gromadzenie informacji o użyciu tokenów przez każdego z użytkowników.
Działania administracyjne takie, jak zarządzanie użytkownikami i monitorowanie użycia wymagają dostępu SSH do własnego kontenera LLM API. Instrukcja konfiguracji dostępu SSH znajduje się tutaj.
Tworzenie własnej instancji
Najpierw utwórz wolumen, który będzie służył do przechowywania pliku konfiguracyjnego i bazy danych.
cgc volume create -s 1 -sc <storage_class> llm-api-data
Nastepnie uruchom swoją instancję LLM API.
cgc compute create -n llm-api -c 1 -m 2 -v llm-api-data llm-api
Domyślnie wolumen zostanie zamontowany pod ścieżką /media/api.
Kiedy aplikacja uruchomi się po raz pierwszy, utworzy ona plik konfiguracyjny
w /media/api/config.toml i zainicjalizuje bazę danych w /media/api/db.sqlite.
Domyślny plik konfiguracyjny zawiera komentarze, które tłumaczą dostepne opcje
i przykładowe fragmenty konfiguracji.
Każdy backend w pliku konfiguracyjnym musi mieć ustawione pole type na jedną
z wartości chat, embedding, transcription lub conversion (zob.
Typy modeli). Aplikacja nie uruchomi się, dopóki któryś backend
nie ma poprawnego type, dlatego przed aktualizacją istniejącej instancji
dopisz type do każdego backendu.
Do edycji pliku konfiguracyjnego polecamy użycie
File Browser.
Aby po edycji i zapisaniu pliku aplikacja przeładowała konfigurację można
zrestartować ją poleceniem cgc resource restart.
Alternatywną opcją jest wysłanie do aplikacji sygnału HUP, który spowoduje
przeładowanie konfiguracji backendów bez restartu aplikacji.
W tym celu należy zalogować się do kontenera aplikacji LLM API wykonać polecenie
kill -1 1.
Do polecenia cgc compute create llm-api można dodać argument
-e llmproxy_config=/ścieżka/do/pliku, aby wskazać niestandardową lokalizację pliku
konfiguracyjnego.
Zarządzanie użytkownikami
Dodanie nowego użytkownika sprowadza się do wygenerowania nowego klucza API. Zaloguj się przez SSH do swojego kontenera LLM API i wykonaj następujące polecenie.
llmproxyctl user create --comment 'John Smith' --expires '2030-01-01 13:37'
# z argumentami w krótszej postaci
llmproxyctl user create -t 'John Smith' -e '2030-01-01 13:37'
Program wypisze informacje o nowym użytkowniku i wygenerowany losowo klucz.
User created
Expires: 2030-01-01 12:37:00+00:00
Comment: John Smith
Hash: dd2a60b77cb2
Plain API key: 3FpwuzyXdU-u3bm8hg9ipA3ZB7JFWSqYHPRw1EMeQsB-XuV5cJ_...
Warto zauważyć, że nie ma możliwości ponownego wypisania klucza do API w tej postaci. Jest to spowodowane faktem, że klucze są przechowywane w bazie danych w postaci skróconej (hasz).
Listę wszystkich użytkowników można uzyskać następującym poleceniem.
llmproxyctl user list
Jest również możliwość edycji komentarza lub daty wygaśnięcia dostępu użytkownika. Zwróć uwagę na pierwszą kolumnę listy użytkowników (Hash). Wybór użytkownika do edycji odbywa się na podstawie kilku pierwszych znaków tego hasza, na przykład (tutaj: da):
llmproxyctl user list
Hash Expires Status Comment
------------ -------------------- ------- -------
dd2a60b77cb2 2030-01-01 12:37:00 active John Smith
a26a23f52cd8 - active Sam Altman
da7534bd88a0 2022-10-26 22:00:00 expired Jack Dorosey
llmproxyctl user update -t "Elon Musk" -e '2030-01-01 00:00' da
User updated
llmproxyctl user list
Hash Expires Status Comment
------------ -------------------- ------- -------
dd2a60b77cb2 2030-01-01 12:37:00 active John Smith
a26a23f52cd8 - active Sam Altman
da7534bd88a0 2030-01-01 00:00:00 active Elon Musk
Wyłączenie danego klucza odbywa się poprzez ustawienie jego daty wygaśnięcia na specjalną wartość now.
llmproxyctl user update -e now da