OpenCSG AI Gateway: auto Model Guide
💡 Note: In the following examples,
$AIGWrepresents the entry point URL of your AI Gateway instance. Please replace it with your actual gateway domain or endpoint (e.g., the SaaS public URL or self-hosted service endpoint).
1. Role of Request Headers
| Header | Description | Format Requirement |
|---|---|---|
CSG-Router-Session-Id | Router Session ID, used to maintain session context consistency for model ranking | Must be ses_<32-hex-characters> |
CSG-Router-Turn-Id | Turn ID within the same conversation turn, reusing saved ranking results to keep the model fixed | Must be turn_<32-hex-characters>, and must be accompanied by Session ID |
X-Session-ID | ① Upstream affinity: pins requests to the same upstream via consistent hashing to reuse KV/prefix cache; ② If the value matches the ses_ format, also acts as an alias for Router Session | Any string for ①; only ses_ format takes effect for ② |
Key Rules:
- These IDs are generated by the Router; clients must not fabricate them. The gateway returns
CSG-Router-Session-IdandCSG-Router-Turn-Idin the response headers. The client should save them and send them back in subsequent requests. - Invalid formats are silently dropped without raising errors; Router will treat the request as a new session and generate fresh IDs. If only
Turn-Idis provided withoutSession-Id,Turn-Idis also discarded. - The gateway strips
CSG-Router-*headers before forwarding requests to the upstream model;X-Session-IDis preserved because upstream affinity requires it.
2. Recommended Invocation Flow (Agent Multi-Turn Example)
Turn 1, User Prompt: Do not include any Router headers.
curl -i $AIGW/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"Help me write quicksort"}],"tools":[...]}'
# Response headers:
# CSG-Router-Session-Id: ses_8f3a... (32-hex)
# CSG-Router-Turn-Id: turn_1c9e... (32-hex)
Tool call loop within the same turn (tool_call → tool result → next request): Include both Session and Turn.
curl $AIGW/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "CSG-Router-Session-Id: ses_8f3a..." \
-H "CSG-Router-Turn-Id: turn_1c9e..." \
-d '{"model":"auto","messages":[ user, assistant(tool_calls), tool(result) ],"tools":[...]}'
The Router returns the saved ranking result for this turn, ensuring the model is not switched mid-loop.
Turn 2, User sends a new message: Include Session only, omit Turn.
curl -i $AIGW/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "CSG-Router-Session-Id: ses_8f3a..." \
-d '{"model":"auto","messages":[ ...history..., {"role":"user","content":"Now change it to non-recursive"}]}'
# Router re-evaluates ranking with conversation context and returns a new Turn-Id
Python (OpenAI SDK) Example:
from openai import OpenAI
client = OpenAI(base_url=f"{AIGW}/v1", api_key=KEY)
sid = tid = None
def call(messages, new_turn):
global sid, tid
headers = {}
if sid:
headers["CSG-Router-Session-Id"] = sid
if not new_turn and tid:
headers["CSG-Router-Turn-Id"] = tid
raw = client.chat.completions.with_raw_response.create(
model="auto", messages=messages, extra_headers=headers)
sid = raw.headers.get("CSG-Router-Session-Id") or sid
tid = raw.headers.get("CSG-Router-Turn-Id") or tid
return raw.parse()
# User sends new message -> call(msgs, new_turn=True)
# Tool execution result returned -> call(msgs, new_turn=False)
3. Header Presence Comparison
| Scenario | Behavior | Consequence |
|---|---|---|
| Omit all headers | Each request is treated as a new session with independent ranking | Fine for single-turn Q&A. In Agent scenarios, the model may change across iterations within the same tool loop, causing inconsistent tool_call formats and reasoning styles, plus higher latency from repeated ranking |
| Session only (New turn) | Re-evaluates ranking within the same session and generates a new Turn | Recommended for every new user question |
| Session + Turn (Within same turn) | Reuses the turn's saved ranking result; model remains unchanged | Recommended for tool loops and retries |
| Turn only | Gateway drops Turn; equivalent to omitting headers | No error, but silently loses session stickiness |
| Fabricated / Invalid ID format | Silently dropped; treated as a new session | Same as above; hard to detect during debugging |
X-Session-ID: <arbitrary> | Not treated as Router Session, only used for upstream affinity; disables capacity-aware upstream re-selection and pins to the hash-selected upstream | No stickiness across models, but upstream affinity is maintained, improving cache hit rates |
X-Session-ID: ses_xxx | Acts as both Router Session and upstream affinity key | Convenient for legacy clients already sending X-Session-ID; overridden by CSG-Router-Session-Id if both are present |
Responses API with previous_response_id | Session already bound to an upstream; reuses model owning that upstream without invoking Router | No ranking, no fallback candidates, returns no Router headers; fails immediately if the bound upstream is unavailable |
Summary
Set model to auto. Extract Session and Turn from response headers: include both within the same turn, and include only Session when starting a new turn. Never fabricate IDs on the client side.
Related Documents
Connect and Call Models · Routing and Reliability · Performance and Cost Optimization