Зашифрованные эндпоинты, Tor и I2P
API также опубликован как onion-сервис Tor и eepsite I2P. Те же маршруты, тот же ключ; меняются только базовый URL и прокси.
Базовые URL
К одному и тому же API ведут четыре адреса. Используйте тот, который подходит вашей сети, с тем же API-ключом и теми же запросами.
| Сеть | Базовый URL | Как подключиться |
|---|---|---|
| Обычный веб | https://api.shannon-ai.com/v1 | Напрямую, по HTTPS. |
| Зашифрованное зеркало | https://api-encrypted.shannon-ai.com/v1 | Напрямую, по HTTPS. Второе имя хоста для того же API. |
| Tor (onion-сервис) | http://shannonmd773o5vxz75byha5rkea7nzr3srotw46uwythq3pjl6y4cad.onion/v1 | Через клиент Tor: SOCKS5-прокси, по умолчанию по адресу 127.0.0.1:9050. |
| I2P (eepsite) | http://acvnvkdea4xaczzjap7chysqqi4kkvp2eorfwkasindzmjpa47da.b32.i2p/v1 | Через маршрутизатор I2P: HTTP-прокси, по умолчанию по адресу 127.0.0.1:4444. |
- OpenAI SDK принимает базовый URL как показано, с
/v1. Anthropic SDK принимает его без/v1. - Чтобы проверить адрес, прочитайте заголовки ответа
https://api.shannon-ai.com:Onion-Locationсодержит onion-адрес, аX-I2P-Location— адрес I2P. Onion-адрес начинается сshannon.
Какие маршруты работают
Каждый маршрут /v1 отвечает на всех четырех адресах:
POST /v1/chat/completionsPOST /v1/responsesPOST /v1/messagesPOST /v1/messages/count_tokensPOST /v1/tokenizeGET /v1/models
GET /v1/models не требует ключа, поэтому это быстрая проверка того, что ваш прокси достигает API.
Что одинаково и что отличается
| Пункт | Одинаково? | Подробности |
|---|---|---|
| Маршруты, поля запросов, ответы, ошибки | Одинаково | Одинаково на любом адресе. Ни один маршрут не ведет себя иначе в зависимости от имени хоста. |
| API-ключ | Одинаково | Один ключ работает на любом адресе, как Authorization: Bearer или x-api-key. Cookie на /v1 никогда не читаются. |
| Баланс и лимиты | Одинаково | Тот же баланс и тот же лимит 120 запросов в минуту. Оба считаются на аккаунт, а не на адрес. |
| Размер запроса | Одинаково | До 32 MiB на тело запроса. |
| Схема | Отличается | https:// в обычном вебе и на зеркале. http:// на адресах .onion и .b32.i2p, где сама сеть шифрует соединение от конца до конца. |
| Прокси | Отличается | В обычном вебе не нужен. SOCKS5-прокси для Tor, HTTP-прокси для I2P. Имя должно разрешаться прокси, а не вашей машиной. |
| Скорость | Отличается | Обе сети добавляют задержку на каждый байт. I2P из двух медленнее. |
Баланс и лимиты описаны на отдельной странице. Лимиты и баланс
cURL через Tor
Запустите на своей машине клиент Tor. Он предоставляет SOCKS5-прокси на 127.0.0.1:9050. Параметр --socks5-hostname передает имя .onion этому прокси.
# 1. Is the onion service reachable? No key needed.
curl --socks5-hostname 127.0.0.1:9050 http://shannonmd773o5vxz75byha5rkea7nzr3srotw46uwythq3pjl6y4cad.onion/v1/models
# 2. A streamed chat call. -N prints the stream as it arrives.
curl -N --socks5-hostname 127.0.0.1:9050 http://shannonmd773o5vxz75byha5rkea7nzr3srotw46uwythq3pjl6y4cad.onion/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"stream": true,
"messages": [{"role": "user", "content": "Hello over Tor"}]
}' cURL через I2P
Запустите на своей машине маршрутизатор I2P. Он предоставляет HTTP-прокси на 127.0.0.1:4444, который принимает имя .b32.i2p как есть.
# 1. Is the eepsite reachable? No key needed.
curl --proxy http://127.0.0.1:4444 http://acvnvkdea4xaczzjap7chysqqi4kkvp2eorfwkasindzmjpa47da.b32.i2p/v1/models
# 2. A streamed chat call.
curl -N --proxy http://127.0.0.1:4444 http://acvnvkdea4xaczzjap7chysqqi4kkvp2eorfwkasindzmjpa47da.b32.i2p/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"stream": true,
"messages": [{"role": "user", "content": "Hello over I2P"}]
}' Базовый URL для SDK
SDK требует двух изменений: базового URL сети и HTTP-клиента, который идет через прокси. В Python оба официальных SDK принимают клиент httpx. Для SOCKS-прокси установите httpx[socks].
# pip install openai "httpx[socks]"
import httpx
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="http://shannonmd773o5vxz75byha5rkea7nzr3srotw46uwythq3pjl6y4cad.onion/v1",
http_client=httpx.Client(proxy="socks5h://127.0.0.1:9050", timeout=600),
)
stream = client.chat.completions.create(
model="shannon-3",
messages=[{"role": "user", "content": "Hello over Tor"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True) # pip install openai
import httpx
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="http://acvnvkdea4xaczzjap7chysqqi4kkvp2eorfwkasindzmjpa47da.b32.i2p/v1",
http_client=httpx.Client(proxy="http://127.0.0.1:4444", timeout=600),
)
stream = client.chat.completions.create(
model="shannon-3",
messages=[{"role": "user", "content": "Hello over I2P"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True) # pip install anthropic "httpx[socks]"
import anthropic
import httpx
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="http://shannonmd773o5vxz75byha5rkea7nzr3srotw46uwythq3pjl6y4cad.onion",
http_client=httpx.Client(proxy="socks5h://127.0.0.1:9050", timeout=600),
)
with client.messages.stream(
model="shannon-1.6-lite",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello over Tor"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True) Стриминг и keep-alive на медленных каналах
Стриминг работает в обеих сетях. Пока поток открыт и модели еще нечего отправить, API отправляет keep-alive, чтобы соединение не выглядело мертвым для прокси или вашего клиента.
| Эндпоинт | Keep-alive в открытом потоке | Отправляется для |
|---|---|---|
/v1/chat/completions | Строка-комментарий (начинается с :) каждые 15 секунд. | Все модели |
/v1/messages | event: ping или строка-комментарий каждые 15 секунд. | Все модели |
/v1/responses | Строка-комментарий каждые 15 секунд. | Размещенные модели с открытыми весами |
- Отправляйте
"stream": true. Потоковый ответ начинает приходить, как только модель пишет, а keep-alive показывает, что запрос еще обрабатывается. Ответ без стриминга ничего не отправляет, пока весь ответ не будет готов. - Задайте клиенту длинный таймаут чтения. В примерах используется 600 секунд. Таймаут короче 15 секунд может оборвать поток между двумя keep-alive.
- Пусть ваш SSE-читатель пропускает строки-комментарии и события
ping. SDK это уже делают. - Не отправляйте запрос повторно в тот момент, когда соединение оборвалось. Запрос, дошедший до API, выполняется до конца и учитывается, даже если соединения уже нет.
- Сначала проверьте путь запросом
GET /v1/models. Ключ ему не нужен, он возвращает короткий список JSON.
Проблемы с соединением
| Признак | Причина и решение |
|---|---|
Соединение с 127.0.0.1:9050 или 127.0.0.1:4444 отклонено | На вашей машине не запущен клиент Tor или маршрутизатор I2P либо он слушает другой порт. Tor Browser предоставляет свой SOCKS-прокси на порту 9150. |
Could not resolve host для имени .onion | Клиент попытался разрешить имя сам. Используйте --socks5-hostname в cURL и socks5h:// в URL прокси, чтобы имя разрешал клиент Tor. |
| Прокси I2P отвечает собственной страницей ошибки | Маршрутизатор еще не нашел адрес. После запуска ему нужно несколько минут. Повторите попытку. |
401 с Missing authentication | Запрос пришел без ключа. Отправьте тот же заголовок, что и в обычном вебе. |
Все остальные ошибки такие же, как в обычном вебе. Обработка ошибок
Ваш ключ без JavaScript
У Shannon есть также сайт без JavaScript, доступный в обычном вебе, как onion-сервис и как eepsite. Его страница /keys показывает ваш API-ключ и позволяет его заменить, так что получить ключ можно, не выходя из Tor или I2P. encrypted.shannon-ai.com/keys
Адреса этого сайта во всех трех сетях перечислены здесь: Зашифрованный доступ