Pamięć¶
Pamięć OpenClaw to zwykły Markdown w obszarze roboczym agenta. Pliki są źródłem prawdy; model „pamięta” tylko to, co zostanie zapisane na dysku.
Narzędzia wyszukiwania pamięci są dostarczane przez aktywną wtyczkę pamięci (domyślnie:
memory-core). Wtyczki pamięci można wyłączyć za pomocą plugins.slots.memory = "none".
Pliki pamięci (Markdown)¶
Domyślny układ obszaru roboczego używa dwóch warstw pamięci:
memory/YYYY-MM-DD.md- Dziennik dzienny (tylko dopisywanie).
- Odczytywany jest dzień bieżący + wczorajszy na początku sesji.
MEMORY.md(opcjonalne)- Kuratorowana pamięć długoterminowa.
- Ładowana wyłącznie w głównej, prywatnej sesji (nigdy w kontekstach grupowych).
Pliki te znajdują się w obszarze roboczym (agents.defaults.workspace, domyślnie
~/.openclaw/workspace). Pełny układ opisano w Agent workspace.
Kiedy zapisywać pamięć¶
- Decyzje, preferencje i trwałe fakty trafiają do
MEMORY.md. - Codzienne notatki i bieżący kontekst trafiają do
memory/YYYY-MM-DD.md. - Jeśli ktoś mówi „zapamiętaj to”, zapisz to (nie trzymaj w RAM-ie).
- Ten obszar wciąż się rozwija. Pomaga przypominanie modelowi o zapisywaniu wspomnień; będzie wiedział, co zrobić.
- Jeśli chcesz, aby coś się utrwaliło, poproś bota o zapisanie tego w pamięci.
Automatyczne opróżnianie pamięci (ping przed kompakcją)¶
Gdy sesja jest bliska automatycznej kompakcji, OpenClaw uruchamia cichy,
agentowy krok, który przypomina modelowi o zapisaniu trwałej pamięci zanim
kontekst zostanie skompaktowany. Domyślne prompty wyraźnie mówią, że model może odpowiedzieć,
ale zazwyczaj NO_REPLY jest poprawną odpowiedzią, dzięki czemu użytkownik nigdy nie widzi tego kroku.
Jest to kontrolowane przez agents.defaults.compaction.memoryFlush:
{
agents: {
defaults: {
compaction: {
reserveTokensFloor: 20000,
memoryFlush: {
enabled: true,
softThresholdTokens: 4000,
systemPrompt: "Session nearing compaction. Store durable memories now.",
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store.",
},
},
},
},
}
Szczegóły:
- Miękki próg: opróżnianie uruchamia się, gdy estymacja tokenów sesji przekroczy
contextWindow - reserveTokensFloor - softThresholdTokens. - Cisza domyślna: prompty zawierają
NO_REPLY, więc nic nie jest dostarczane. - Dwa prompty: prompt użytkownika oraz prompt systemowy dołączają przypomnienie.
- Jedno opróżnienie na cykl kompakcji (śledzone w
sessions.json). - Obszar roboczy musi być zapisywalny: jeśli sesja działa w sandboxie z
workspaceAccess: "ro"lub"none", opróżnianie jest pomijane.
Pełny cykl życia kompakcji opisano w Session management + compaction.
Wyszukiwanie pamięci wektorowej¶
OpenClaw może zbudować niewielki indeks wektorowy nad MEMORY.md i memory/*.md, aby
zapytania semantyczne mogły znajdować powiązane notatki nawet przy różnym brzmieniu.
Ustawienia domyślne:
- Włączone domyślnie.
- Obserwuje pliki pamięci pod kątem zmian (z opóźnieniem).
- Domyślnie używa zdalnych embeddingów. Jeśli
memorySearch.providernie jest ustawione, OpenClaw automatycznie wybiera: 1.local, jeśli skonfigurowanomemorySearch.local.modelPathi plik istnieje. 2.openai, jeśli można rozwiązać klucz OpenAI. 3.gemini, jeśli można rozwiązać klucz Gemini. 4.voyage, jeśli można rozwiązać klucz Voyage. 5. W przeciwnym razie wyszukiwanie pamięci pozostaje wyłączone do czasu konfiguracji. - Tryb lokalny używa node-llama-cpp i może wymagać
pnpm approve-builds. - Używa sqlite-vec (gdy dostępne) do przyspieszenia wyszukiwania wektorowego w SQLite.
Zdalne embeddingi wymagają klucza API dostawcy embeddingów. OpenClaw
rozwiązuje klucze z profili uwierzytelniania, models.providers.*.apiKey lub zmiennych
środowiskowych. OAuth Codex obejmuje tylko czat/uzupełniania i nie spełnia
wymagań embeddingów do wyszukiwania pamięci. Dla Gemini użyj GEMINI_API_KEY lub
models.providers.google.apiKey. Dla Voyage użyj VOYAGE_API_KEY lub
models.providers.voyage.apiKey. Przy użyciu niestandardowego endpointu zgodnego z OpenAI
ustaw memorySearch.remote.apiKey (oraz opcjonalnie memorySearch.remote.headers).
Backend QMD (eksperymentalny)¶
Ustaw memory.backend = "qmd", aby zastąpić wbudowany indeksator SQLite przez
QMD: lokalny sidecar wyszukiwania łączący
BM25 + wektory + reranking. Markdown pozostaje źródłem prawdy; OpenClaw wywołuje
QMD do pobierania wyników. Kluczowe punkty:
Wymagania wstępne
- Domyślnie wyłączone. Włączane per-konfiguracja (
memory.backend = "qmd"). - Zainstaluj osobno CLI QMD (
bun install -g https://github.com/tobi/qmdlub pobierz wydanie) i upewnij się, że binarkaqmdznajduje się naPATHgateway’a. - QMD wymaga kompilacji SQLite ze wsparciem rozszerzeń (
brew install sqlitena macOS). - QMD działa w pełni lokalnie przez Bun +
node-llama-cppi automatycznie pobiera modele GGUF z HuggingFace przy pierwszym użyciu (nie jest wymagany osobny daemon Ollama). - Gateway uruchamia QMD w samodzielnym katalogu XDG pod
~/.openclaw/agents/<agentId>/qmd/, ustawiającXDG_CONFIG_HOMEorazXDG_CACHE_HOME. - Wsparcie OS: macOS i Linux działają od razu po zainstalowaniu Bun + SQLite. Windows najlepiej wspierany przez WSL2.
Jak działa sidecar
- Gateway zapisuje samodzielny katalog domowy QMD pod
~/.openclaw/agents/<agentId>/qmd/(konfiguracja + cache + baza sqlite). - Kolekcje są tworzone przez
qmd collection addzmemory.qmd.paths(plus domyślne pliki pamięci obszaru roboczego), następnieqmd update+qmd embedsą uruchamiane przy starcie oraz w konfigurowalnym interwale (memory.qmd.update.interval, domyślnie 5 min). - Odświeżanie przy starcie działa teraz domyślnie w tle, aby nie blokować uruchomienia czatu;
ustaw
memory.qmd.update.waitForBootSync = true, aby zachować poprzednie blokujące zachowanie. - Wyszukiwania są wykonywane przez
qmd query --json. Jeśli QMD zawiedzie lub brakuje binarki, OpenClaw automatycznie wraca do wbudowanego menedżera SQLite, dzięki czemu narzędzia pamięci nadal działają. - OpenClaw nie udostępnia obecnie strojenia rozmiaru batcha embeddingów QMD; zachowanie batcha kontroluje samo QMD.
- Pierwsze wyszukiwanie może być wolne: QMD może pobrać lokalne modele GGUF
(reranker/rozszerzanie zapytań) przy pierwszym uruchomieniu
qmd query. - OpenClaw automatycznie ustawia
XDG_CONFIG_HOME/XDG_CACHE_HOME, gdy uruchamia QMD. -
Jeśli chcesz wstępnie pobrać modele ręcznie (i rozgrzać ten sam indeks, którego używa OpenClaw), uruchom jednorazowe zapytanie z katalogami XDG agenta.
Stan QMD OpenClaw znajduje się w Twoim katalogu stanu (domyślnie
~/.openclaw). Możesz wskazaćqmdna dokładnie ten sam indeks, eksportując te same zmienne XDG, których używa OpenClaw:```bash
Pick the same state dir OpenClaw uses¶
STATE_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}" if [ -d "$HOME/.moltbot" ] && [ ! -d "$HOME/.openclaw" ] \ && [ -z "${OPENCLAW_STATE_DIR:-}" ]; then STATE_DIR="$HOME/.moltbot" fi
export XDG_CONFIG_HOME="$STATE_DIR/agents/main/qmd/xdg-config" export XDG_CACHE_HOME="$STATE_DIR/agents/main/qmd/xdg-cache"
(Optional) force an index refresh + embeddings¶
qmd update qmd embed
Warm up / trigger first-time model downloads¶
qmd query "test" -c memory-root --json >/dev/null 2>&1 ```
Powierzchnia konfiguracji (memory.qmd.*)
command(domyślnieqmd): nadpisanie ścieżki do pliku wykonywalnego.includeDefaultMemory(domyślnietrue): automatyczne indeksowanieMEMORY.md+memory/**/*.md.paths[]: dodanie dodatkowych katalogów/plików (path, opcjonalniepattern, opcjonalnie stabilnename).sessions: włączenie indeksowania JSONL sesji (enabled,retentionDays,exportDir).update: kontrola kadencji odświeżania i wykonywania utrzymania: (interval,debounceMs,onBoot,waitForBootSync,embedInterval,commandTimeoutMs,updateTimeoutMs,embedTimeoutMs).limits: ograniczenie ładunku przywołań (maxResults,maxSnippetChars,maxInjectedChars,timeoutMs).scope: ten sam schemat cosession.sendPolicy. Domyślnie tylko DM-y (denywszystkie,allowczaty bezpośrednie); poluzuj, aby ujawniać trafienia QMD w grupach/kanałach.- When
scopedenies a search, OpenClaw logs a warning with the derivedchannel/chatTypeso empty results are easier to debug. - Fragmenty pochodzące spoza obszaru roboczego pojawiają się jako
qmd/<collection>/<relative-path>w wynikachmemory_search;memory_getrozumie ten prefiks i czyta z skonfigurowanego katalogu głównego kolekcji QMD. - Gdy
memory.qmd.sessions.enabled = true, OpenClaw eksportuje zanonimizowane transkrypty sesji (tury Użytkownik/Asystent) do dedykowanej kolekcji QMD pod~/.openclaw/agents/<id>/qmd/sessions/, dzięki czemumemory_searchmoże przywoływać ostatnie rozmowy bez dotykania wbudowanego indeksu SQLite. - Fragmenty
memory_searchzawierają teraz stopkęSource: <path#line>, gdymemory.citationsma wartośćauto/on; ustawmemory.citations = "off", aby zachować metadane ścieżki jako wewnętrzne (agent nadal otrzymuje ścieżkę domemory_get, ale tekst fragmentu pomija stopkę, a prompt systemowy ostrzega agenta, aby jej nie cytował).
Przykład
memory: {
backend: "qmd",
citations: "auto",
qmd: {
includeDefaultMemory: true,
update: { interval: "5m", debounceMs: 15000 },
limits: { maxResults: 6, timeoutMs: 4000 },
scope: {
default: "deny",
rules: [{ action: "allow", match: { chatType: "direct" } }]
},
paths: [
{ name: "docs", path: "~/notes", pattern: "**/*.md" }
]
}
}
Cytowania i fallback
memory.citationsobowiązuje niezależnie od backendu (auto/on/off).- Gdy działa
qmd, oznaczamystatus().backend = "qmd", aby diagnostyka pokazywała, który silnik obsłużył wyniki. Jeśli podproces QMD zakończy się lub wyjście JSON nie może zostać sparsowane, menedżer wyszukiwania loguje ostrzeżenie i zwraca wbudowanego dostawcę (istniejące embeddingi Markdown), dopóki QMD się nie podniesie.
Dodatkowe ścieżki pamięci¶
Jeśli chcesz indeksować pliki Markdown poza domyślnym układem obszaru roboczego, dodaj jawne ścieżki:
agents: {
defaults: {
memorySearch: {
extraPaths: ["../team-docs", "/srv/shared-notes/overview.md"]
}
}
}
Uwagi:
- Ścieżki mogą być bezwzględne lub względne względem obszaru roboczego.
- Katalogi są skanowane rekurencyjnie w poszukiwaniu plików
.md. - Indeksowane są tylko pliki Markdown.
- Dowiązania symboliczne są ignorowane (pliki lub katalogi).
Embeddingi Gemini (natywne)¶
Ustaw dostawcę na gemini, aby używać bezpośrednio API embeddingów Gemini:
agents: {
defaults: {
memorySearch: {
provider: "gemini",
model: "gemini-embedding-001",
remote: {
apiKey: "YOUR_GEMINI_API_KEY"
}
}
}
}
Uwagi:
remote.baseUrljest opcjonalne (domyślnie bazowy URL API Gemini).remote.headerspozwala dodać dodatkowe nagłówki, jeśli są potrzebne.- Domyślny model:
gemini-embedding-001.
Jeśli chcesz użyć niestandardowego endpointu zgodnego z OpenAI (OpenRouter, vLLM lub proxy),
możesz użyć konfiguracji remote z dostawcą OpenAI:
agents: {
defaults: {
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
baseUrl: "https://api.example.com/v1/",
apiKey: "YOUR_OPENAI_COMPAT_API_KEY",
headers: { "X-Custom-Header": "value" }
}
}
}
}
Jeśli nie chcesz ustawiać klucza API, użyj memorySearch.provider = "local" lub ustaw
memorySearch.fallback = "none".
Fallbacki:
memorySearch.fallbackmoże mieć wartośćopenai,gemini,locallubnone.- Dostawca fallback jest używany tylko wtedy, gdy podstawowy dostawca embeddingów zawiedzie.
Indeksowanie wsadowe (OpenAI + Gemini):
- Włączone domyślnie dla embeddingów OpenAI i Gemini. Ustaw
agents.defaults.memorySearch.remote.batch.enabled = false, aby wyłączyć. - Domyślne zachowanie czeka na zakończenie batcha; dostrój
remote.batch.wait,remote.batch.pollIntervalMsiremote.batch.timeoutMinutes, jeśli potrzeba. - Ustaw
remote.batch.concurrency, aby kontrolować liczbę równoległych zadań batch (domyślnie: 2). - Tryb batch obowiązuje, gdy
memorySearch.provider = "openai"lub"gemini"i używa odpowiadającego klucza API. - Zadania batch Gemini używają asynchronicznego endpointu batch embeddingów i wymagają dostępności Gemini Batch API.
Dlaczego batch OpenAI jest szybki i tani:
- Dla dużych uzupełnień wstecznych OpenAI jest zwykle najszybszą wspieraną opcją, ponieważ możemy wysyłać wiele żądań embeddingów w jednym zadaniu batch i pozwolić OpenAI przetwarzać je asynchronicznie.
- OpenAI oferuje obniżone ceny dla obciążeń Batch API, więc duże przebiegi indeksowania są zwykle tańsze niż wysyłanie tych samych żądań synchronicznie.
- Szczegóły w dokumentacji i cenniku OpenAI Batch API:
- https://platform.openai.com/docs/api-reference/batch
- https://platform.openai.com/pricing
Przykład konfiguracji:
agents: {
defaults: {
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
fallback: "openai",
remote: {
batch: { enabled: true, concurrency: 2 }
},
sync: { watch: true }
}
}
}
Narzędzia:
memory_search— zwraca fragmenty z plikiem + zakresami linii.memory_get— odczyt zawartości pliku pamięci po ścieżce.
Tryb lokalny:
- Ustaw
agents.defaults.memorySearch.provider = "local". - Podaj
agents.defaults.memorySearch.local.modelPath(GGUF lub URIhf:). - Opcjonalnie: ustaw
agents.defaults.memorySearch.fallback = "none", aby uniknąć zdalnego fallbacku.
Jak działają narzędzia pamięci¶
memory_searchprzeszukuje semantycznie fragmenty Markdown (~400 tokenów docelowo, 80-tokenowa nakładka) zMEMORY.md+memory/**/*.md. Zwraca tekst fragmentu (limit ~700 znaków), ścieżkę pliku, zakres linii, wynik, dostawcę/model oraz informację, czy nastąpił fallback z lokalnych → zdalnych embeddingów. Nie jest zwracana pełna zawartość pliku.memory_getodczytuje konkretny plik Markdown pamięci (względny względem obszaru roboczego), opcjonalnie od wskazanej linii i przez N linii. Ścieżki pozaMEMORY.md/memory/są odrzucane.- Oba narzędzia są włączone tylko wtedy, gdy
memorySearch.enabledrozwiązuje się jako true dla agenta.
Co jest indeksowane (i kiedy)¶
- Typ pliku: tylko Markdown (
MEMORY.md,memory/**/*.md). - Przechowywanie indeksu: SQLite per-agent w
~/.openclaw/memory/<agentId>.sqlite(konfigurowalne przezagents.defaults.memorySearch.store.path, obsługuje token{agentId}). - Świeżość: watcher na
MEMORY.md+memory/oznacza indeks jako brudny (debounce 1,5 s). Synchronizacja jest planowana na start sesji, przy wyszukiwaniu lub w interwale i działa asynchronicznie. Transkrypty sesji używają progów delta do wyzwalania synchronizacji w tle. - Wyzwalacze reindeksacji: indeks przechowuje dostawcę/model embeddingów + odcisk endpointu + parametry chunkowania. Jeśli którekolwiek z nich się zmieni, OpenClaw automatycznie resetuje i reindeksuje cały magazyn.
Wyszukiwanie hybrydowe (BM25 + wektor)¶
Gdy włączone, OpenClaw łączy:
- Podobieństwo wektorowe (dopasowanie semantyczne, brzmienie może się różnić)
- Trafność słów kluczowych BM25 (dokładne tokeny, jak identyfikatory, zmienne środowiskowe, symbole kodu)
Jeśli pełnotekstowe wyszukiwanie jest niedostępne na Twojej platformie, OpenClaw wraca do wyszukiwania tylko wektorowego.
Dlaczego hybryda?¶
Wyszukiwanie wektorowe świetnie radzi sobie z „to znaczy to samo”:
- „Mac Studio gateway host” vs „maszyna uruchamiająca gateway”
- „debounce aktualizacje plików” vs „unikać indeksowania przy każdym zapisie”
Może jednak być słabe dla dokładnych, wysoko-sygnałowych tokenów:
- identyfikatory (
a828e60,b3b9895a…) - symbole kodu (
memorySearch.query.hybrid) - ciągi błędów („sqlite-vec unavailable”)
BM25 (pełnotekst) jest odwrotnością: silne dla dokładnych tokenów, słabsze dla parafraz. Wyszukiwanie hybrydowe to pragmatyczny środek: używa obu sygnałów pobierania, aby uzyskać dobre wyniki zarówno dla zapytań „języka naturalnego”, jak i „igła w stogu siana”.
Jak łączymy wyniki (obecny projekt)¶
Szkic implementacji:
- Pobierz pulę kandydatów z obu stron:
- Wektor: top
maxResults * candidateMultiplierwedług podobieństwa cosinusowego. - BM25: top
maxResults * candidateMultiplierwedług rangi FTS5 BM25 (niżej = lepiej).
- Przekształć rangę BM25 w wynik ~0..1:
textScore = 1 / (1 + max(0, bm25Rank))
- Połącz kandydatów po id fragmentu i oblicz wynik ważony:
finalScore = vectorWeight * vectorScore + textWeight * textScore
Uwagi:
vectorWeight+textWeightjest normalizowane do 1,0 podczas rozwiązywania konfiguracji, więc wagi zachowują się jak procenty.- Jeśli embeddingi są niedostępne (lub dostawca zwraca wektor zerowy), nadal uruchamiamy BM25 i zwracamy dopasowania słów kluczowych.
- Jeśli FTS5 nie może zostać utworzone, pozostajemy przy wyszukiwaniu tylko wektorowym (bez twardej awarii).
To nie jest „idealne według teorii IR”, ale jest proste, szybkie i zwykle poprawia recall/precyzję na rzeczywistych notatkach. Jeśli później będziemy chcieli pójść dalej, typowe kolejne kroki to Reciprocal Rank Fusion (RRF) lub normalizacja wyników (min/max lub z-score) przed mieszaniem.
Konfiguracja:
agents: {
defaults: {
memorySearch: {
query: {
hybrid: {
enabled: true,
vectorWeight: 0.7,
textWeight: 0.3,
candidateMultiplier: 4
}
}
}
}
}
Cache embeddingów¶
OpenClaw może buforować embeddingi fragmentów w SQLite, aby reindeksowanie i częste aktualizacje (zwłaszcza transkrypty sesji) nie wymagały ponownego embedowania niezmienionego tekstu.
Konfiguracja:
agents: {
defaults: {
memorySearch: {
cache: {
enabled: true,
maxEntries: 50000
}
}
}
}
Wyszukiwanie pamięci sesji (eksperymentalne)¶
Opcjonalnie możesz indeksować transkrypty sesji i udostępniać je przez memory_search.
Funkcja jest ukryta za flagą eksperymentalną.
agents: {
defaults: {
memorySearch: {
experimental: { sessionMemory: true },
sources: ["memory", "sessions"]
}
}
}
Uwagi:
- Indeksowanie sesji jest opcjonalne (domyślnie wyłączone).
- Aktualizacje sesji są debouncowane i indeksowane asynchronicznie po przekroczeniu progów delta (best-effort).
memory_searchnigdy nie blokuje na indeksowaniu; wyniki mogą być lekko nieaktualne do czasu zakończenia synchronizacji w tle.- Wyniki nadal zawierają tylko fragmenty;
memory_getpozostaje ograniczone do plików pamięci. - Indeksowanie sesji jest izolowane per agent (indeksowane są tylko logi sesji tego agenta).
- Logi sesji znajdują się na dysku (
~/.openclaw/agents/<agentId>/sessions/*.jsonl). Każdy proces/użytkownik z dostępem do systemu plików może je odczytać, więc granicą zaufania jest dostęp do dysku. Dla ostrzejszej izolacji uruchamiaj agentów pod oddzielnymi użytkownikami systemu lub hostami.
Progi delta (pokazane wartości domyślne):
agents: {
defaults: {
memorySearch: {
sync: {
sessions: {
deltaBytes: 100000, // ~100 KB
deltaMessages: 50 // JSONL lines
}
}
}
}
}
Przyspieszenie wektorów SQLite (sqlite-vec)¶
Gdy rozszerzenie sqlite-vec jest dostępne, OpenClaw przechowuje embeddingi w
wirtualnej tabeli SQLite (vec0) i wykonuje zapytania odległości wektorów w
bazie danych. Utrzymuje to szybkie wyszukiwanie bez ładowania każdego embeddingu do JS.
Konfiguracja (opcjonalna):
agents: {
defaults: {
memorySearch: {
store: {
vector: {
enabled: true,
extensionPath: "/path/to/sqlite-vec"
}
}
}
}
}
Uwagi:
enableddomyślnie ma wartość true; po wyłączeniu wyszukiwanie wraca do obliczania podobieństwa cosinusowego w procesie nad zapisanymi embeddingami.- Jeśli rozszerzenie sqlite-vec jest niedostępne lub nie uda się go załadować, OpenClaw loguje błąd i kontynuuje z fallbackiem JS (bez tabeli wektorowej).
extensionPathnadpisuje dołączoną ścieżkę sqlite-vec (przydatne dla niestandardowych buildów lub niestandardowych lokalizacji instalacji).
Automatyczne pobieranie lokalnych embeddingów¶
- Domyślny lokalny model embeddingów:
hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf(~0,6 GB). - Gdy
memorySearch.provider = "local",node-llama-cpprozwiązujemodelPath; jeśli GGUF brakuje, jest automatycznie pobierany do cache (lublocal.modelCacheDir, jeśli ustawione), a następnie ładowany. Pobieranie jest wznawiane przy ponownej próbie. - Wymaganie natywnej kompilacji: uruchom
pnpm approve-builds, wybierznode-llama-cpp, następniepnpm rebuild node-llama-cpp. - Fallback: jeśli lokalna konfiguracja się nie powiedzie i
memorySearch.fallback = "openai", automatycznie przełączamy się na zdalne embeddingi (openai/text-embedding-3-small, o ile nie nadpisano) i zapisujemy powód.
Przykład niestandardowego endpointu zgodnego z OpenAI¶
agents: {
defaults: {
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
baseUrl: "https://api.example.com/v1/",
apiKey: "YOUR_REMOTE_API_KEY",
headers: {
"X-Organization": "org-id",
"X-Project": "project-id"
}
}
}
}
}
Uwagi:
remote.*ma pierwszeństwo przedmodels.providers.openai.*.remote.headersłączą się z nagłówkami OpenAI; zdalne wygrywają przy konfliktach kluczy. Pomińremote.headers, aby użyć domyślnych ustawień OpenAI.