ವಿನಂತಿಯು ಯಶಸ್ವಿಯಾಯಿತು. ಪ್ರತಿಕ್ರಿಯೆಯು ಮಾನ್ಯವಾದ JSON ಆಗಿತ್ತು. SDK ಯಾವುದೇ ಎಚ್ಚರಿಕೆ ನೀಡಲಿಲ್ಲ. ಆದರೂ ಅಪ್ಲಿಕೇಶನ್ ಕುಸಿದುಹೋಯಿತು.
ನೀವು LLM ಪ್ರೊವೈಡರ್ ಬದಲಾವಣೆಯನ್ನು ಒಂದು ರಚನಾತ್ಮಕ ಅಪಾಯದ ಬದಲಿಗೆ ಕೇವಲ ಕಾನ್ಫಿಗರೇಶನ್ ಬದಲಾವಣೆಯೆಂದು ಪರಿಗಣಿಸಿದಾಗ ಏನಾಗುತ್ತದೆ ಎಂಬುದರ ಕಥೆ ಇದು. ಡಾಕ್ಯುಮೆಂಟೇಶನ್ ಒಂದು OpenAI-compatible ಎಂಡ್ಪಾಯಿಂಟ್ ಅನ್ನು ಭರವಸೆ ನೀಡುವ ಕಾರಣ, ನೀವು ಹೊಸ ಬೇಸ್ URL ಅನ್ನು ಪೇಸ್ಟ್ ಮಾಡುತ್ತೀರಿ, API ಕೀ ಅನ್ನು ಬದಲಾಯಿಸುತ್ತೀರಿ ಮತ್ತು ರಿಕ್ವೆಸ್ಟ್ ಬಾಡಿಯನ್ನು ಅಚ್ಚುಕಟ್ಟಾಗಿ ಹಾಗೆಯೇ ಇರಿಸುತ್ತೀರಿ. ಒಂದು ಸಾಮಾನ್ಯ "hello world" ಪ್ರಾಂಪ್ಟ್ಗೆ ಇದು ಕೆಲಸ ಮಾಡುತ್ತದೆ. ನೀವು ಸಂಭ್ರಮಿಸುತ್ತೀರಿ. ನಂತರ ನಿಜವಾದ ಟ್ರಾಫಿಕ್ ಬಂದಾಗ, ಸಮಸ್ಯೆಗಳು ಎದುರಾಗುತ್ತವೆ.
ವೈರ್ ಕಾಂಪ್ಯಾಟಿಬಿಲಿಟಿಯ ಭ್ರಮೆ
HTTP ಲೇಯರ್ನಲ್ಲಿನ ಕಾಂಪ್ಯಾಟಿಬಿಲಿಟಿ ಮೇಲ್ಮಟ್ಟದ್ದಾಗಿದೆ. 200 ಸ್ಟೇಟಸ್ ಕೋಡ್ ಮತ್ತು JSON ಬಾಡಿ ಎಂದರೆ ಸರ್ವರ್ ನಿಮ್ಮ ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸಿದೆ ಎಂದರ್ಥ. ಆದರೆ ಸರ್ವರ್ ಹಿಂದಿನ ಪ್ರೊವೈಡರ್ನಂತೆಯೇ ಯೋಚಿಸುತ್ತದೆ ಎಂದರ್ಥವಲ್ಲ. OpenAI-compatible ಎಂಡ್ಪಾಯಿಂಟ್ಗಳು ಒಂದೇ ರೀತಿಯ ರಿಕ್ವೆಸ್ಟ್ ರೂಪವನ್ನು ಹೊಂದಿರಬಹುದು, ಆದರೆ ಅವುಗಳ ವರ್ತನೆಯ ಒಪ್ಪಂದವನ್ನು (behavioral contract) ಹಂಚಿಕೊಳ್ಳುವುದಿಲ್ಲ. ಇಬ್ಬರು ಪ್ರೊವೈಡರ್ಗಳು ಒಂದೇ ರೀತಿಯ ಪೇಲೋಡ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು ಮತ್ತು ಅತ್ಯಂತ ಸೂಕ್ಷ್ಮ ಹಾಗೂ ವಿನಾಶಕಾರಿ ರೀತಿಯಲ್ಲಿ ಭಿನ್ನವಾದ ಉತ್ತರಗಳನ್ನು ನೀಡಬಹುದು.
ನಿಮ್ಮ ಕೋಡ್ ಕೆಲವು ಊಹೆಗಳನ್ನು ಮಾಡುತ್ತದೆ. message.content ಯಾವಾಗಲೂ ಸ್ಟ್ರಿಂಗ್ ಆಗಿರುವುದರಿಂದ, ಅದು ಸ್ಟ್ರಿಂಗ್ ಆಗಿರುತ್ತದೆ ಎಂದು ನೀವು ಊಹಿಸುತ್ತೀರಿ. ಟೂಲ್ ಕಾಲ್ (tool call) ಸ್ವಚ್ಛವಾದ, ಪಾರ್ಸ್ ಮಾಡಬಹುದಾದ JSON ನೊಂದಿಗೆ ಬರುತ್ತದೆ ಎಂದು ನೀವು ಭಾವಿಸುತ್ತೀರಿ. finish_reason ನೀವು ಭಾವಿಸಿದಂತೆ ಸಂಕೇತ ನೀಡುತ್ತದೆ ಎಂದು ನೀವು ಊಹಿಸುತ್ತೀರಿ. ಈ ಊಹೆಗಳು ಅಪಾಯಕಾರಿಯಾಗುವವರೆಗೆ ನಿಮಗೆ ತಿಳಿಯುವುದಿಲ್ಲ.
ಎಲ್ಲವನ್ನೂ ಪ್ರಾರಂಭಿಸಿದ ಆ ಕ್ರ್ಯಾಶ್ ಅನ್ನು ಗಮನಿಸಿ:
const text = response.choices[0].message.content.trim();
ಈ ಸಾಲು ನೋಡಲು ಮುಗ್ಧವಾಗಿ ಕಾಣುತ್ತದೆ. ಇದು ವಾರಗಟ್ಟಲೆ ಕೆಲಸ ಮಾಡಿತು. ನಂತರ ಹೊಸ ಪ್ರೊವೈಡರ್ ಒಂದು ಟೂಲ್ ಕಾಲ್ ಅನ್ನು ನೀಡಿತು. ಆ ಕ್ಷಣದಲ್ಲಿ, message.content ಖಾಲಿ ಸ್ಟ್ರಿಂಗ್ ಆಗಿರಲಿಲ್ಲ. ಅದು null ಆಗಿತ್ತು. ನಿಜವಾದ ಪೇಲೋಡ್ message.tool_calls ಒಳಗಿತ್ತು, ಆದರೆ ಪಾರ್ಸರ್ ಈಗಾಗಲೇ ಮುಂದೆ ಚಲಿಸಿತ್ತು ಮತ್ತು ಯಾವುದೂ ಇಲ್ಲದ ಜಾಗದಲ್ಲಿ .trim() ಅನ್ನು ಕರೆಯುತ್ತಿತ್ತು. API ಯಾವುದೇ ಎಚ್ಚರಿಕೆ ನೀಡಲಿಲ್ಲ. ನೆಟ್ವರ್ಕ್ ಲೇಯರ್ ದೂರು ನೀಡಲಿಲ್ಲ. ನಿಮ್ಮ ಸ್ವಂತ ಪಾರ್ಸರ್ ರಿಕ್ವೆಸ್ಟ್ ಅನ್ನು ಕೊನೆಗೊಳಿಸಿತು.
ಪ್ರೊವೈಡರ್ಗಳು ಎಲ್ಲಿ ಮೌನವಾಗಿ ಭಿನ್ನವಾಗುತ್ತವೆ
ಈ ವ್ಯತ್ಯಾಸಗಳು ಚೇಂಜ್ಲಾಗ್ಗಳಲ್ಲಿ (changelogs) ಪ್ರಕಟವಾಗುವುದಿಲ್ಲ. ಅವು ರೆಸ್ಪಾನ್ಸ್ ಆಬ್ಜೆಕ್ಟ್ನ ಅಂಚಿನಲ್ಲಿ ಕುಳಿತು ಎಡ್ಜ್ ಕೇಸ್ಗಳಿಗಾಗಿ (edge cases) ಕಾಯುತ್ತಿರುತ್ತವೆ.
ಟೂಲ್-ಕಾಲ್ ಫಾರ್ಮ್ಯಾಟಿಂಗ್ (Tool-call formatting). ಒಬ್ಬ ಪ್ರೊವೈಡರ್ ಟೂಲ್ ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳನ್ನು ಮೊದಲೇ ವ್ಯಾಲಿಡೇಟ್ ಮಾಡಿದ JSON ಆಬ್ಜೆಕ್ಟ್ ಆಗಿ ಕಳುಹಿಸುತ್ತಾನೆ. ಇನ್ನೊಬ್ಬರು ಅವುಗಳನ್ನು ಒಂದು ಫೀಲ್ಡ್ನ ಒಳಗಿರುವ ಎಸ್ಕೇಪ್ ಮಾಡಿದ ಸ್ಟ್ರಿಂಗ್ ಆಗಿ ಕಳುಹಿಸುತ್ತಾರೆ. ಮೂರನೆಯವರು ಉದ್ದವಾದ ಟೂಲ್ ಕಾಲ್ ಅನ್ನು ಹಲವಾರು ಸ್ಟ್ರೀಮಿಂಗ್ ಡೆಲ್ಟಾಗಳಾಗಿ ವಿಂಗಡಿಸಬಹುದು, ಇದರಿಂದ ರಚನೆಯು ಸರಿಯಾಗಿದೆಯೇ ಎಂದು ನೋಡುವ ಮೊದಲೇ ನೀವು ಚಂಕ್ಗಳನ್ನು ಬಫರ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಒಂದೇ ಪಾರ್ಸ್ ಮಾಡಬಹುದಾದ ಬ್ಲಾಬ್ ಅನ್ನು ನಿರೀಕ್ಷಿಸಿದರೆ, ಅದು ವಿಫಲವಾಗುತ್ತದೆ.
ಫಿನಿಶ್ ರಿಸನ್ಸ್ (Finish reasons). OpenAI "stop", "length", "tool_calls", ಮತ್ತು "content_filter" ನಂತಹ ನಿರ್ದಿಷ್ಟ ಸ್ಟ್ರಿಂಗ್ಗಳನ್ನು ಬಳಸುತ್ತದೆ. ಕಾಂಪ್ಯಾಟಿಬಲ್ ಪ್ರೊವೈಡರ್ ಮಾಡೆಲ್ ಟೋಕನ್ ಮಿತಿಯನ್ನು ತಲುಪಿದಾಗ "end_turn" ಅನ್ನು ನೀಡಬಹುದು ಅಥವಾ ಆ ಫೀಲ್ಡ್ ಅನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಬಿಡಬಹುದು. ನಿಮ್ಮ ರಿಟ್ರೈ (retry) ಅಥವಾ ಫಾಲ್ಬ್ಯಾಕ್ (fallback) ಲಾಜಿಕ್ ಕಡಿತವನ್ನು ಪತ್ತೆಹಚ್ಚಲು "length" ಗಾಗಿ ಕಾಯುತ್ತಿದ್ದರೆ, ಬಳಕೆದಾರರು ಅರ್ಧಕ್ಕೆ ನಿಂತ ಉತ್ತರವನ್ನು ನೋಡುತ್ತಿರುವಾಗ ನಿಮ್ಮ ಕೋಡ್ ಸುಮ್ಮನೆ ಕುಳಿತಿರುತ್ತದೆ.
ಬಳಕೆಯ ಫೀಲ್ಡ್ಗಳು (Usage fields). ಕೆಲವು ಪ್ರೊವೈಡರ್ಗಳು ಲೇಟೆನ್ಸಿಯನ್ನು (latency) ಕಡಿಮೆ ಮಾಡಲು ಸ್ಟ್ರೀಮಿಂಗ್ ರೆಸ್ಪಾನ್ಸ್ಗಳಿಂದ ಟೋಕನ್ ಸಂಖ್ಯೆಯನ್ನು ತೆಗೆದುಹಾಕುತ್ತಾರೆ. ಇತರರು ಕೇವಲ ಅಂತಿಮ ಚಂಕ್ನಲ್ಲಿ ಬಳಕೆಯನ್ನು ಸೇರಿಸುತ್ತಾರೆ ಅಥವಾ ನಾನ್-ಸ್ಟ್ರೀಮಿಂಗ್ ಕಾಲ್ಗಳಲ್ಲಿ ಅದನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಬಿಡುತ್ತಾರೆ. ನೀವು ಗ್ರಾಹಕರಿಗೆ ಪ್ರತಿ ಟೋಕನ್ಗೆ ಶುಲ್ಕ ವಿಧಿಸುವುದಾದರೆ ಮತ್ತು ನಿಮ್ಮ ಅಕೌಂಟಿಂಗ್ ಕೋಡ್ ಪ್ರತಿ ರೆಸ್ಪಾನ್ಸ್ ಆಬ್ಜೆಕ್ಟ್ನಲ್ಲಿ usage.total_tokens ಇರಬೇಕೆಂದು ನಿರೀಕ್ಷಿಸಿದರೆ, ನಿಮ್ಮ ಬಿಲ್ಲಿಂಗ್ ಪೈಪ್ಲೈನ್ ಮೌನವಾಗಿ ಶೂನ್ಯಗಳನ್ನು (zeros) ದಾಖಲಿಸುತ್ತದೆ.
ಸ್ಟ್ರೀಮಿಂಗ್ ವರ್ತನೆ (Streaming behavior). ಸರ್ವರ್-ಸೆಂಟ್ ಇವೆಂಟ್ಗಳು (Server-sent events) ಪ್ರಮಾಣಿತವಾಗಿರಬೇಕು, ಆದರೂ ಪ್ರೊವೈಡರ್ಗಳು ವಿಭಿನ್ನ ಫ್ರೀಕ್ವೆನ್ಸಿಗಳಲ್ಲಿ ಬಫರ್ಗಳನ್ನು ಫ್ಲಶ್ ಮಾಡುತ್ತಾರೆ. ಇವೆಂಟ್ ಬೌಂಡರಿಗಳು ಬದಲಾಗುತ್ತವೆ. ಒಬ್ಬ ಪ್ರೊವೈಡರ್ [DONE] ಸಿಗ್ನಲ್ನೊಂದಿಗೆ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಕೊನೆಗೊಳಿಸುತ್ತಾನೆ. ಇನ್ನೊಬ್ಬರು ಯಾವುದೇ ಸೆಂಟಿನಲ್ ಇಲ್ಲದೆ ಸಂಪರ್ಕವನ್ನು ಕಡಿತಗೊಳಿಸುತ್ತಾರೆ. ನಿಮ್ಮ ಕ್ಲೈಂಟ್ ನಿರ್ದಿಷ್ಟ ಕ್ಲೋಸಿಂಗ್ ಮಾರ್ಕರ್ಗಾಗಿ ಕಾಯುತ್ತಿದ್ದರೆ, ಅದು ಹ್ಯಾಂಗ್ ಆಗುತ್ತದೆ.
ಎರರ್ ಮತ್ತು ಟೈಮೌಟ್ಗಳು (Errors and timeouts). ರೇಟ್ ಲಿಮಿಟ್ (rate limit) ಒಬ್ಬ ಪ್ರೊವೈಡರ್ನಿಂದ retry-after ಹೆಡರ್ನೊಂದಿಗೆ 429 ಆಗಿ ಬರಬಹುದು ಮತ್ತು ಇನ್ನೊಬ್ಬರಿಂದ ಅಸ್ಪಷ್ಟ 502 ಆಗಿ ಬರಬಹುದು. ಕೆಲವು ಪ್ರೊವೈಡರ್ಗಳು ವಿನಂತಿಯನ್ನು ಸ್ವೀಕರಿಸುತ್ತಾರೆ ಮತ್ತು ನಂತರ ನೆಟ್ವರ್ಕ್ ಟೈಮೌಟ್ಗೆ ಮೊದಲು ಎರಡು ನಿಮಿಷಗಳ ಕಾಲ ಮೌನವಾಗಿರುತ್ತಾರೆ. OpenAI SDK ನಿಮ್ಮ ಲಾಗ್ಗಳು ನಿರೀಕ್ಷಿಸುವ ಎಕ್ಸೆಪ್ಶನ್ ಪ್ರಕಾರಗಳಿಗೆ (exception types) ಇವುಗಳನ್ನು ಮ್ಯಾಜಿಕ್ನಂತೆ ಬದಲಾಯಿಸುವುದಿಲ್ಲ.
ಅನಿರೀಕ್ಷಿತ ರೂಪಗಳಿಗಾಗಿ ಡಿಫೆನ್ಸಿವ್ ಪಾರ್ಸಿಂಗ್ (Defensive Parsing)
ಪರಿಹಾರವು ಸ್ಕೀಮಾವನ್ನು (schema) ನಂಬುವುದಲ್ಲ. ಪ್ರತಿ ರೆಸ್ಪಾನ್ಸ್ ಅನ್ನು ಸಂಶಯಾಸ್ಪದವೆಂದು ಪರಿಗಣಿಸುವುದೇ ನಿಜವಾದ ಪರಿಹಾರ.
content ಎಂಬುದು ಸ್ಟ್ರಿಂಗ್ ಎಂದು ಊಹಿಸಬೇಡಿ. ಅದನ್ನು ಬಳಸುವ ಮೊದಲು ಪರಿಶೀಲಿಸಿ.
const content = response.choices?.[0]?.message?.content;
const text = typeof content === "string" ? content.trim() : "";
ಟೂಲ್ ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳು ಮಾನ್ಯವಾದ JSON ಎಂದು ಊಹಿಸಬೇಡಿ. ಮಾಡೆಲ್ ಒಂದು ಕ್ರಿಯೆಯನ್ನು ಪ್ರಸ್ತಾಪಿಸುತ್ತದೆ. ಆ ಪ್ರಸ್ತಾಪವು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಸಾಕಷ್ಟು ಸುರಕ್ಷಿತವಾಗಿದೆಯೇ ಎಂದು ನಿರ್ಧರಿಸಬೇಕಾದ ಜವಾಬ್ದಾರಿ ನಿಮ್ಮ ಕೋಡ್ನದ್ದಾಗಿದೆ. ಪ್ರತಿಯೊಂದು ಟೂಲ್ ಆರ್ಗ್ಯುಮೆಂಟ್ ಪಾರ್ಸಿಂಗ್ ಅನ್ನು try-catch ನಲ್ಲಿ ಸುತ್ತಿ (wrap). ಒಂದು ವೇಳೆ JSON.parse ಎಡವುತ್ತರೆ (throws), ಆ ಟೂಲ್ ಕಾಲ್ ಅನ್ನು ತಪ್ಪಾದ ಡೇಟಾ ಎಂದು ಪರಿಗಣಿಸಿ ಫೇಲ್ಯೂರ್ ಹ್ಯಾಂಡ್ಲರ್ಗೆ (failure handler) ಕಳುಹಿಸಿ. ತಪ್ಪಾದ ಬ್ರಾಕೆಟ್ ಅಥವಾ ಮಿಸ್ಸಿಂಗ್ ಕೋಟ್ನಿಂದ ಉಂಟಾದ ಸಮಸ್ಯೆಗಳು ಅನ್ಹ್ಯಾಂಡಲ್ಡ್ ಎಕ್ಸೆಪ್ಶನ್ (unhandled exception) ಆಗಿ ಹೊರಬರಬಾರದು.
ಒಂದು ವೇಳೆ tool_calls ಇದ್ದು content ಇಲ್ಲದಿದ್ದರೆ, ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಿತಿ ಬದಲಾವಣೆಯನ್ನು (state transition) ಗುರುತಿಸಬೇಕು. ಬಳಕೆದಾರರಿಗೆ ಚಾಟ್ ಪ್ರತಿಕ್ರಿಯೆ ಸಿಗಲಿಲ್ಲ, ಬದಲಿಗೆ ಸಿಸ್ಟಮ್ಗೆ ಒಂದು ಕೆಲಸದ ಆದೇಶ (work order) ಸಿ
"hi" ಸಂದೇಶದೊಂದಿಗೆ ಎಂಡ್ಪಾಯಿಂಟ್ಗೆ (endpoint) ಪಿಂಗ್ ಮಾಡುವುದು ನೆಟ್ವರ್ಕ್ ಕೆಲಸ ಮಾಡುತ್ತದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸುತ್ತದೆ. ಆದರೆ ಇದು ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಬಗ್ಗೆ ಏನನ್ನೂ ಸಾಬೀತುಪಡಿಸುವುದಿಲ್ಲ.
ನೀವು ಪ್ರೊಡಕ್ಷನ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು (production traffic) ಮರುನಿರ್ದೇಶಿಸುವ ಮೊದಲು, ಹೊಸ ಪ್ರೊವೈಡರ್ ವಿರುದ್ಧ ಗುರಿ ಹೊಂದಿದ ವರ್ತನಾತ್ಮಕ ಪರೀಕ್ಷಾ ಸುಟ್ ಅನ್ನು (targeted behavioral test suite) ಚಲಾಯಿಸಿ:
- ಸಾಮಾನ್ಯ ಪಠ್ಯ ಪ್ರತಿಕ್ರಿಯೆ (Normal text response).
contentಅಸ್ತಿತ್ವದಲ್ಲಿದೆ, ಅದು ಸ್ಟ್ರಿಂಗ್ ಆಗಿದೆ ಮತ್ತು ಕ್ಯಾಸ್ಟಿಂಗ್ ದೋಷಗಳಿಲ್ಲದೆ (casting errors) ನಿಮ್ಮ ಸ್ಯಾನಿಟೈಸೇಶನ್ ಪೈಪ್ಲೈನ್ ಮೂಲಕ ಹಾದುಹೋಗಬಹುದು ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ. - ಫೋರ್ಸ್ಡ್ ಟೂಲ್ ಕಾಲ್ (Forced tool call).
tool_choiceಅನ್ನುrequiredಗೆ ಹೊಂದಿಸಿ. ಪ್ರೊವೈಡರ್ ಅದನ್ನು ಪಾಲಿಸುತ್ತದೆಯೇ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ ಮತ್ತುcontentಎಂಬುದುnull, ಖಾಲಿ ಸ್ಟ್ರಿಂಗ್ ಅಥವಾ ಮಿಸ್ಸಿಂಗ್ ಕೀ ಆಗಿ ಬರುತ್ತಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ. ಈ ಪ್ರತಿಯೊಂದು ಸ್ಥಿತಿಗೂ ತನ್ನದೇ ಆದ ಹ್ಯಾಂಡ್ಲರ್ (handler) ಅಗತ್ಯವಿದೆ. - ತಪ್ಪಾದ ಟೂಲ್ ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳು (Malformed tool arguments). ಮಾಡೆಲ್ ಟೂಲ್ ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳ ಒಳಗೆ ಮುರಿದುಹೋದ JSON ಅನ್ನು ಹಿಂತಿರುಗಿಸುವ ಸನ್ನಿವೇಶಗಳನ್ನು ಸೇರಿಸಿ. ನಿಮ್ಮ ಪಾರ್ಸರ್ (parser) ವರ್ಕರ್ ಕ್ರ್ಯಾಶ್ ಆಗುವ ಬದಲು ಅವುಗಳನ್ನು ಸುಗಮವಾಗಿ ತಿರಸ್ಕರಿಸುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.
- ಟೋಕನ್ ಮಿತಿಯ ಸಮೀಪವಿರುವ ಪ್ರತಿಕ್ರಿಯೆ (Response near the token limit). ಕಾಂಟೆಕ್ಸ್ಟ್ ವಿಂಡೋವನ್ನು (context window) ಪರೀಕ್ಷಿಸಿ.
finish_reasonಅನ್ನು ಪರಿಶೀಲಿಸಿ. ಟ್ರಂಕೇಶನ್ (truncation) ಸಂಭವಿಸಿದಾಗ ಪ್ರೊವೈಡರ್ ಅನಿರೀಕ್ಷಿತವಾದುದನ್ನು ನೀಡಿದರೆ, ನಿಮ್ಮ ಸಮ್ಮರೈಸೇಶನ್ ಅಥವಾ ರಿಟ್ರೈ ಲಾಜಿಕ್ (summarization or retry logic) ಹೇಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಬೇಕೆಂದು ತಿಳಿದಿರಬೇಕು.
ಇವು ಇಂಟಿಗ್ರೇಷನ್ ಟೆಸ್ಟ್ಗಳು (integration tests), ಯೂನಿಟ್ ಟೆಸ್ಟ್ಗಳಲ್ಲ (unit tests). ಇವು ನಿಮ್ಮ ಕೋಡ್ ಮತ್ತು ಪ್ರೊವೈಡರ್ನ ವ್ಯಕ್ತಿತ್ವದ ನಡುವಿನ ನೈಜ ಸಂಬಂಧವನ್ನು ಪರೀಕ್ಷಿಸುತ್ತವೆ. ನೀವು ಮೈಗ್ರೇಷನ್ (migration) ಪೂರ್ಣಗೊಂಡಿದೆ ಎಂದು ಹೇಳುವ ಮೊದಲು ಇವುಗಳನ್ನು ಪಾಸು ಮಾಡಿ.
ಒಂದು ಆಂತರಿಕ ಒಪ್ಪಂದವನ್ನು (Internal Contract) ನಿರ್ಮಿಸಿ
ಪ್ರೊವೈಡರ್ ವ್ಯತ್ಯಾಸಗಳು ನಿಮ್ಮ ನೆಟ್ವರ್ಕ್ ಗಡಿಯಲ್ಲಿಯೇ ನಿಲ್ಲಬೇಕು. ಅವುಗಳನ್ನು ಬಿಸಿನೆಸ್ ಲಾಜಿಕ್ (business logic) ಗೆ ಸೋರಿಯೊಡಬೇಡಿ.
ರೊ (raw) SDK ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಪಡೆದು, ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಹೊಂದಿರುವ ಒಂದು ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಹೊರತರುವ ನಾರ್ಮಲೈಸೇಶನ್ ಲೇಯರ್ ಅನ್ನು (normalization layer) ರಚಿಸಿ. ಪ್ರೊವೈಡರ್-ನಿರ್ದಿಷ್ಟ ವಿಚಿತ್ರತೆಗಳನ್ನು ಸ್ಥಿರವಾದ ಆಂತರಿಕ ಫಾರ್ಮ್ಯಾಟ್ಗೆ ಮ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರೊವೈಡರ್ A ಟೂಲ್ ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳನ್ನು ಸ್ಟ್ರಿಂಗ್ಗಳಾಗಿ ಮತ್ತು ಪ್ರೊವೈಡರ್ B ಆಬ್ಜೆಕ್ಟ್ಗಳಾಗಿ ನೀಡಿದರೆ, ನಿಮ್ಮ ಮ್ಯಾಪ್ಪರ್ ಎರಡನ್ನೂ ನಿಮ್ಮದೇ ಆದ ToolRequest ರಚನೆಗೆ ಸರಿಹೊಂದಿಸುತ್ತದೆ. ಬಳಕೆ (usage) ಇಲ್ಲದಿದ್ದರೆ, ನಿಮ್ಮ ಮ್ಯಾಪ್ಪರ್ ಅದನ್ನು ಅಂದಾಜಿಸುತ್ತದೆ ಅಥವಾ ಆ ಕೊರತೆಯನ್ನು ಸೂಚಿಸುತ್ತದೆ, ಆದರೆ ಅದು ಎಂದಿಗೂ undefined ಅನ್ನು ನಿಮ್ಮ ಕಾಸ್ಟ್-ಟ್ರ್ಯಾಕಿಂಗ್ ಮಾಡ್ಯೂಲ್ಗಳಿಗೆ (cost-tracking modules) ಸೇರಲು ಬಿಡುವುದಿಲ್ಲ.
ಒಂದು ವೇಳೆ finish_reason ಅಸಮಾನಿತವಾಗಿದ್ದರೆ (nonstandard), ಅದನ್ನು ನಿಮ್ಮದೇ ಆದ ಟರ್ಮಿನಲ್ ಸ್ಟೇಟ್ಗಳ (terminal states) ಎನಮ್ (enum) ಗೆ ಅನುವಾದಿಸಿ: COMPLETE, TRUNCATED, TOOL_CALL, FILTERED. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಈ ಸ್ವಚ್ಛ ಅಬ್ಸ್ಟ್ರಾಕ್ಷನ್ಗಳ (abstractions) ಆಧಾರದ ಮೇಲೆ ಏನು ಮಾಡಬೇಕೆಂದು ನಿರ್ಧರಿಸಬೇಕು, ಮೂರನೇ ವ್ಯಕ್ತಿಯ ಸರ್ವರ್ನಿಂದ ಬರುವ ರೊ ಸ್ಟ್ರಿಂಗ್ಗಳನ್ನು ಪತ್ತೆಹಚ್ಚುವ ಮೂಲಕ ಅಲ್ಲ.
ಈ ಲೇಯರ್ ಪ್ರೊವೈಡರ್ ಬದಲಾವಣೆಗಳನ್ನು ಅನಿರೀಕ್ಷಿತ ಸಮಸ್ಯೆಗಳ ಸುಳಿಯಿಂದ (whack-a-mole) ಕೇವಲ ಒಂದು ಫೈಲ್ ಬದಲಾವಣೆಯಾಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ. ನೀವು ಮ್ಯಾಪ್ಪರ್ ಅನ್ನು ಮರುಬರೆಯುತ್ತೀರಿ, ವರ್ತನಾತ್ಮಕ ಪರೀಕ್ಷೆಗಳನ್ನು ನಡೆಸುತ್ತೀರಿ ಮತ್ತು ಮುನ್ನಡೆಯುತ್ತೀರಿ. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಪೃಶ್ಯವಾಗಿ ಉಳಿಯುತ್ತದೆ.
ಇದು ಡಿಪೆಂಡೆನ್ಸಿ ಅಪ್ಗ್ರೇಡ್, ಕೇವಲ ಕಾನ್ಫಿಗರೇಶನ್ ಬದಲಾವಣೆಯಲ್ಲ
LLM ಪ್ರೊವೈಡರ್ಗಳನ್ನು ಬದಲಾಯಿಸುವುದು CDN ಎಂಡ್ಪಾಯಿಂಟ್ಗಳನ್ನು ಬದಲಾಯಿಸಿದಂತೆ ಅಲ್ಲ. ಇದು ನಿಮ್ಮ ಡೇಟಾಬೇಸ್ ಅನ್ನು PostgreSQL ನಿಂದ MySQL ಗೆ ಬದಲಾಯಿಸಿದಂತೆ ಹತ್ತಿರವಾಗಿದೆ. ಒಂದೇ ಕನೆಕ್ಷನ್ ಸ್ಟ್ರಿಂಗ್ (connection string) ಎಂದರೆ ಒಂದೇ ರೀತಿಯ ಕ್ವೆರಿ ವರ್ತನೆ ಎಂದರ್ಥ ಎಂದು ನೀವು ಎಂದಿಗೂ ಭಾವಿಸುವುದಿಲ್ಲ. ನೀವು ಲಾಕಿಂಗ್ ಸೆಮ್ಯಾಂಟಿಕ್ಸ್ (locking semantics), ಮೈಗ್ರೇಷನ್ ಪಥಗಳು ಮತ್ತು ಇಂಡೆಕ್ಸಿಂಗ್ ವಿಚಿತ್ರತೆಗಳನ್ನು ಪರೀಕ್ಷಿಸುತ್ತೀರಿ. LLM ಗಳು ಅಂತಹದೇ ಗೌರವಕ್ಕೆ ಅರ್ಹವಾಗಿವೆ. ಅವು ಸ್ಟ್ಯಾಂಡರ್ಡ್ APIಗಳಂತೆ ನಟಿಸುವ ಪ್ರೊಬಾಬಿಲಿಸ್ಟಿಕ್ ಸಿಸ್ಟಮ್ಗಳಾಗಿವೆ (probabilistic systems), ಮತ್ತು ಅವುಗಳ ಪ್ರತಿಕ್ರಿಯೆಗಳು ಫಾರ್ಮ್ಯಾಟಿಂಗ್, ಟ್ರಂಕೇಶನ್ ಮತ್ತು ಕಂಟ್ರೋಲ್ ಫ್ಲೋ ಬಗ್ಗೆ ಅಂತಹ ಕಲ್ಪನೆಗಳನ್ನು ಹೊಂದಿರುತ್ತವೆ, ಇವು ಒಂದೇ ಒಂದು ನೆಟ್ವರ್ಕ್ ದೋಷವನ್ನು ಎತ್ತದೆಯೇ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ತകർಬಲ್ಲವು.
ದೋಷವು ಎಂದಿಗೂ ಕನೆಕ್ಷನ್ನಲ್ಲಿ ಇರಲಿಲ್ಲ. ಹೊಂದಾಣಿಕೆ (compatibility) ಎಂದರೆ ಸಮಾನತೆ ಎಂದರ್ಥ ಎಂಬ ಕಲ್ಪನೆಯಲ್ಲಿದ್ದಿತು. ಅದು ಹಾಗಲ್ಲ. ಆಕಾರವನ್ನು (shape) ದೃಢೀಕರಿಸಿ. ಅಂಚುಗಳನ್ನು (edges) ಪರೀಕ್ಷಿಸಿ. ಒಪ್ಪಂದವನ್ನು (contract) ವಹಿಸಿಕೊಳ್ಳಿ.
Source: The Bug Only Happened After I Switched LLM Providers
Community: GyaanSetu AI on Telegram
