स्किप करके मेन कंटेंट पर जाऍं
OpenAI

23 जनवरी 2026

इंजीनियरिंग

Codex एजेंट लूप को खोलना

माइकल बोलिन, तकनीकी स्टाफ के सदस्य

लोड किया जा रहा है...

Codex CLI(एक नई विंडो में खुलेगा) हमारा क्रॉस-प्लेटफ़ॉर्म लोकल सॉफ़्टवेयर एजेंट है, जो तुम्हारी मशीन पर सुरक्षित और कुशलता से काम करते हुए उच्च-गुणवत्ता और भरोसेमंद सॉफ़्टवेयर परिवर्तन तैयार करने के लिए डिज़ाइन किया गया है। हमने यह जानने के लिए बहुत कुछ सीखा है कि एक विश्व-स्तरीय सॉफ़्टवेयर एजेंट कैसे बनाया जाए जब से हमने अप्रैल में पहली बार CLI लॉन्च किया। उन इनसाइट्स को समझने के लिए, यह एक चल रही श्रृंखला की पहली पोस्ट है, जिसमें हम Codex के काम करने के विभिन्न पहलुओं और मेहनत से सीखे गए सबक को भी खोजेंगे। (Codex CLI के निर्माण की और भी गहन जानकारी के लिए, हमारी ओपन सोर्स रिपॉज़िटरी https://github.com/openai/codex(एक नई विंडो में खुलेगा) पर देखो। अगर तुम और जानना चाहो, तो हमारे डिज़ाइन निर्णयों के कई बारीक विवरण GitHub इश्यूज़ और पुल रिक्वेस्ट में दर्ज हैं।)

शुरुआत में, हम एजेंट लूप पर ध्यान केंद्रित करेंगे, जो Codex CLI में मुख्य तर्क है और उपयोगकर्ता, मॉडल, और उन उपकरणों के बीच बातचीत को व्यवस्थित करने के लिए जिम्मेदार है जिन्हें मॉडल सार्थक सॉफ़्टवेयर कार्य करने के लिए सक्रिय करता है। हमें उम्मीद है कि यह पोस्ट आपको LLM का उपयोग करने में हमारे एजेंट (या “हार्नेस”) की भूमिका का अच्छा दृष्टिकोण देती है।

आगे बढ़ने से पहले, शब्दावली पर एक त्वरित नोट: OpenAI में, “Codex” सॉफ़्टवेयर एजेंट ऑफ़रिंग्स के एक समूह को संदर्भित करता है, जिसमें Codex CLI, Codex Cloud, और Codex VS Code एक्सटेंशन शामिल हैं। यह पोस्ट Codex हार्नेस पर केंद्रित है, जो कोर एजेंट लूप और निष्पादन तर्क प्रदान करता है, जो सभी Codex अनुभवों के आधार में है और Codex CLI के माध्यम से प्रस्तुत होता है। यहां आसानी के लिए, हम “Codex” और “Codex CLI” शब्दों का परस्पर उपयोग करेंगे।

एजेंट लूप

हर AI एजेंट के केंद्र में 'एजेंट लूप' नामक एक तत्व होता है। एजेंट लूप का एक सरल चित्रण इस प्रकार है:

“Agent loop” शीर्षक वाला आरेख, जो दिखाता है कि एक AI प्रणाली उपयोगकर्ता अनुरोध को कैसे संसाधित करती है, उपकरणों को कॉल करती है, परिणामों का अवलोकन करती है, अपनी योजना को अपडेट करती है, और आउटपुट लौटाती है। तीर यूज़र इनपुट, मॉडल रीज़निंग, टूल क्रियाएँ, और अंतिम प्रतिक्रिया जैसे चरणों को जोड़ते हैं।

शुरुआत में, एजेंट उपयोगकर्ता से इनपुट लेता है ताकि इसे उन पाठ निर्देशों के सेट में शामिल किया जा सके, जिसे वह मॉडल के लिए तैयार करता है, जिसे प्रॉम्प्ट कहा जाता है।

अगला कदम मॉडल को हमारे निर्देश भेजकर और उससे प्रतिक्रिया उत्पन्न करने के लिए कहना है, जिसे इन्फ़रेंस कहा जाता है। इन्फ़रेंस के दौरान, टेक्स्ट प्रॉम्प्ट को पहले इनपुट टोकन(एक नई विंडो में खुलेगा)—जो मॉडल की शब्दावली में इंडेक्स करने वाले पूर्णांक होते हैं—के अनुक्रम में बदला जाता है। इन टोकन का उपयोग मॉडल को सैंपल करने के लिए किया जाता है, जिससे आउटपुट टोकन का एक नया अनुक्रम उत्पन्न होता है।

आउटपुट टोकन को वापस टेक्स्ट में अनुवादित किया जाता है, जो मॉडल की प्रतिक्रिया बन जाता है। क्योंकि टोकन क्रमिक रूप से उत्पन्न होते हैं, यह अनुवाद मॉडल के चलते ही हो सकता है, यही कारण है कि कई LLM-आधारित एप्लिकेशन स्ट्रीमिंग आउटपुट प्रदर्शित करते हैं। व्यवहार में, इन्फ़रेंस आमतौर पर एक API के पीछे छिपा होता है जो टेक्स्ट पर काम करता है, और टोकनाइज़ेशन के विवरणों को छुपा देता है।

इन्फ़रेंस चरण के परिणामस्वरूप, मॉडल या तो (1) उपयोगकर्ता के मूल इनपुट के लिए एक अंतिम प्रतिक्रिया उत्पन्न करता है, या (2) एक टूल कॉल का अनुरोध करता है जिसे एजेंट को पूरा करने की अपेक्षा की जाती है (उदाहरण के लिए, “ls चलाएं और आउटपुट रिपोर्ट करें”). (2) के मामले में, एजेंट टूल कॉल को निष्पादित करता है और उसके आउटपुट को मूल प्रॉम्प्ट में जोड़ता है। इस आउटपुट का उपयोग एक नया इनपुट बनाने के लिए किया जाता है, जिसका उपयोग मॉडल को फिर से क्वेरी करने के लिए किया जाता है; एजेंट फिर इस नई जानकारी को ध्यान में रख सकता है और दोबारा प्रयास कर सकता है।

यह प्रक्रिया तब तक दोहराई जाती है जब तक कि मॉडल टूल कॉल्स जारी करना बंद कर देता है और इसके बजाय उपयोगकर्ता के लिए एक संदेश तैयार करता है (जिसे OpenAI मॉडल्स में सहायक संदेश कहा जाता है)। कई मामलों में, यह संदेश सीधे यूज़र के मूल अनुरोध का उत्तर देता है, लेकिन यह यूज़र के लिए एक अनुवर्ती प्रश्न भी हो सकता है।

क्योंकि एजेंट टूल कॉल्स को निष्पादित कर सकता है जो स्थानीय वातावरण को संशोधित करते हैं, इसका “आउटपुट” केवल सहायक संदेश तक सीमित नहीं है। कई मामलों में, एक सॉफ़्टवेयर एजेंट का मुख्य आउटपुट वह कोड होता है जिसे वह तुम्हारी मशीन पर लिखता या संपादित करता है। फिर भी, हर टर्न हमेशा एक सहायक संदेश के साथ समाप्त होता है—जैसे “मैंने वह architecture.md जोड़ दिया है, जो तुमने मांगा था”—जो एजेंट लूप में एक समाप्ति स्थिति का संकेत देता है। एजेंट के दृष्टिकोण से, उसका काम पूरा हो गया है और नियंत्रण वापस यूज़र को लौट आता है।

डायग्राम में दिखाया गया यूज़र इनपुट से एजेंट रिस्पॉन्स तक का सफर बातचीत के एक टर्न के रूप में जाना जाता है (Codex में इसे एक थ्रेड कहा जाता है). हालाँकि इस कन्वर्सेशन टर्न में मॉडल इन्फरेंस और टूल कॉल्स के बीच कई इटरेशन शामिल हो सकते हैं. हर बार जब आप किसी मौजूदा बातचीत में नया मैसेज भेजते हैं, तो कन्वर्सेशन हिस्ट्री नए टर्न के लिए प्रॉम्प्ट का हिस्सा बन जाती है, जिसमें पिछले टर्न्स के मैसेज और टूल कॉल्स शामिल होते हैं:

“Multi-turn agent loop” शीर्षक वाला आरेख दिखाता है कि कैसे एक AI एजेंट क्रमिक रूप से उपयोगकर्ता इनपुट लेता है, क्रियाएँ उत्पन्न करता है, उपकरणों से परामर्श करता है, स्थिति को अपडेट करता है, और परिणाम लौटाता है। एजेंट के रीज़निंग चक्र को दर्शाने वाले लेबल किए गए चरण, तीर, और उदाहरण टूल आउटपुट शामिल हैं।

इसका मतलब है कि जैसे-जैसे बातचीत बढ़ती है, वैसे-वैसे मॉडल को सैंपल करने के लिए उपयोग किए जाने वाले प्रॉम्प्ट की लंबाई भी बढ़ती जाती है। यह लंबाई महत्वपूर्ण है क्योंकि प्रत्येक मॉडल की एक संदर्भ विंडो होती है, जो एक इन्फ़रेंस कॉल के लिए उपयोग किए जा सकने वाले टोकन की अधिकतम संख्या है। ध्यान दें कि इस विंडो में इनपुट और आउटपुट टोकन दोनों शामिल होते हैं। जैसा कि तुम कल्पना कर सकते हो, एक एजेंट एक ही टर्न में सैकड़ों टूल कॉल करने का निर्णय ले सकता है, जिससे कॉन्टेक्स्ट विंडो संभावित रूप से समाप्त हो सकती है। इसी कारण, संदर्भ विंडो प्रबंधन एजेंट की कई जिम्मेदारियों में से एक है। अब, चलिए देखते हैं कि Codex एजेंट लूप को कैसे संचालित करता है।

मॉडल अनुमान

Codex CLI HTTP अनुरोध Responses API(एक नई विंडो में खुलेगा) को मॉडल इन्फ़रेंस चलाने के लिए भेजता है। हम यह देखेंगे कि Codex के माध्यम से जानकारी कैसे प्रवाहित होती है, जो एजेंट लूप को चलाने के लिए Responses API का उपयोग करता है।

Codex CLI जिस Responses API एंडपॉइंट का उपयोग करता है, वह कॉन्फ़िगर करने योग्य(एक नई विंडो में खुलेगा) है, इसलिए इसे किसी भी ऐसे एंडपॉइंट के साथ उपयोग किया जा सकता है जो Responses API को लागू करता है(एक नई विंडो में खुलेगा):

आइए देखें कि Codex बातचीत में पहले इन्फ़रेंस कॉल के लिए प्रॉम्प्ट कैसे तैयार करता है।

प्रारंभिक प्रॉम्प्ट तैयार करना

एक अंतिम उपयोगकर्ता के रूप में, जब तुम Responses API को क्वेरी करते हो, तो तुम मॉडल को सैंपल करने के लिए उपयोग किए गए प्रॉम्प्ट को शब्दशः निर्दिष्ट नहीं करते हो। इसके बजाय, तुम अपनी क्वेरी के हिस्से के रूप में विभिन्न इनपुट प्रकार निर्दिष्ट करते हो, और Responses API सर्वर यह तय करता है कि इस जानकारी को एक प्रॉम्प्ट में कैसे संरचित किया जाए जिसे मॉडल उपभोग करने के लिए डिज़ाइन किया गया है। तुम प्रॉम्प्ट को 'आइटम्स की एक सूची' के रूप में सोच सकते हो; यह खंड बताएगा कि तुम्हारी क्वेरी उस सूची में कैसे परिवर्तित होती है।

प्रारंभिक प्रॉम्प्ट में, सूची के प्रत्येक आइटम को एक भूमिका के साथ जोड़ा गया है। भूमिका यह दर्शाती है कि संबंधित सामग्री को कितना महत्व दिया जाना चाहिए और यह निम्नलिखित मानों में से एक होता है (प्राथमिकता के घटते क्रम में): system, developer, user, assistant.

Responses API(एक नई विंडो में खुलेगा) एक JSON payload को कई पैरामीटर के साथ लेता है। हम इन तीन पर ध्यान देंगे:

Codex में, निर्देश फ़ील्ड को model_instructions_file(एक नई विंडो में खुलेगा) से ~/.codex/config.toml में पढ़ा जाता है, अगर निर्दिष्ट किया गया हो; अन्यथा, मॉडल से जुड़े base_instructions का उपयोग किया जाता है(एक नई विंडो में खुलेगा) । मॉडल-विशिष्ट निर्देश Codex रिपो में होते हैं और CLI में बंडल किए जाते हैं (उदाहरण के लिए, gpt-5.2-codex_prompt.md(एक नई विंडो में खुलेगा))।

टूल्स फ़ील्ड टूल परिभाषाओं की एक सूची है जो Responses API द्वारा परिभाषित स्कीमा के अनुरूप है। Codex के लिए, इसमें Codex CLI द्वारा प्रदान किए गए टूल, Responses API द्वारा प्रदान किए गए टूल जो Codex के लिए उपलब्ध होने चाहिए, और यूज़र द्वारा प्रदान किए गए टूल शामिल हैं, जो आमतौर पर MCP सर्वर के माध्यम से आते हैं:

JavaScript

1
[
2
// Codex's default shell tool for spawning new processes locally.
3
{
4
"type": "function",
5
"name": "shell",
6
"description": "Runs a shell command and returns its output...",
7
"strict": false,
8
"parameters": {
9
"type": "object",
10
"properties": {
11
"command": {"type": "array", "description": "The command to execute", ...},
12
"workdir": {"description": "The working directory...", ...},
13
"timeout_ms": {"description": "The timeout for the command...", ...},
14
...
15
},
16
"required": ["command"],
17
}
18
}
19

20
// Codex's built-in plan tool.
21
{
22
"type": "function",
23
"name": "update_plan",
24
"description": "Updates the task plan...",
25
"strict": false,
26
"parameters": {
27
"type": "object",
28
"properties": {"plan":..., "explanation":...},
29
"required": ["plan"]
30
}
31
},
32

33
// Web search tool provided by the Responses API.
34
{
35
"type": "web_search",
36
"external_web_access": false
37
},
38

39
// MCP server for getting weather as configured in the
40
// user's ~/.codex/config.toml.
41
{
42
"type": "function",
43
"name": "mcp__weather__get-forecast",
44
"description": "Get weather alerts for a US state",
45
"strict": false,
46
"parameters": {
47
"type": "object",
48
"properties": {"latitude": {...}, "longitude": {...}},
49
"required": ["latitude", "longitude"]
50
}
51
}
52
]

अंत में, JSON पेलोड का इनपुट फ़ील्ड आइटम्स की सूची है। Codex यूज़र मेसेज जोड़ने(एक नई विंडो में खुलेगा) से पहले इनपुट में निम्नलिखित आइटम्स डालता है:

1. role=developer के साथ एक संदेश जो उस सैंडबॉक्स का वर्णन करता है जो सिर्फ Codex द्वारा प्रदान किए गए shell टूल पर लागू होता है और टूल्स सेक्शन में परिभाषित है। यानी, अन्य टूल्स, जैसे कि MCP सर्वर्स से प्रदान किए गए हैं, Codex द्वारा सैंडबॉक्स नहीं किए जाते हैं और अपने स्वयं के गार्डरेल्स लागू करने के लिए ज़िम्मेदार होते हैं।

संदेश एक टेम्पलेट से तैयार किया गया है, जिसमें मुख्य सामग्री के टुकड़े Codex CLI में शामिल Markdown स्निपेट्स से आते हैं, जैसे workspace_write.md(एक नई विंडो में खुलेगा) और on_request.md(एक नई विंडो में खुलेगा):

प्लेन टेक्स्ट

1
<permissions instructions>
2
- description of the sandbox explaining file permissions and network access
3
- instructions for when to ask the user for permissions to run a shell command
4
- list of folders writable by Codex, if any
5
</permissions instructions>

2. (वैकल्पिक) role=developer वाला एक संदेश, जिसकी सामग्री उपयोगकर्ता की config.toml फ़ाइल से पढ़ा गया developer_instructions मान है।

3. (वैकल्पिक) role=user वाला एक संदेश, जिसकी सामग्री “user instructions” होती है, जो किसी एक फ़ाइल से नहीं ली जाती, बल्कि कई स्रोतों से एकत्रित की जाती है(एक नई विंडो में खुलेगा)। आम तौर पर, अधिक विशिष्ट निर्देश बाद में आते हैं:

4. role=user के साथ एक संदेश जो उस स्थानीय वातावरण का वर्णन करता है जिसमें एजेंट वर्तमान में काम कर रहा है। यह वर्तमान कार्यशील निर्देशिका और उपयोगकर्ता के शेल को निर्दिष्ट करता है(एक नई विंडो में खुलेगा):

प्लेन टेक्स्ट

1
<environment_context>
2
<cwd>/Users/mbolin/code/codex5</cwd>
3
<shell>zsh</shell>
4
</environment_context>

जब Codex input को इनिशियलाइज़ करने के लिए सभी आवश्यक गणनाएँ पूरी कर लेता है, तो वह बातचीत शुरू करने के लिए उपयोगकर्ता संदेश जोड़ता है।

पिछले उदाहरणों में प्रत्येक संदेश की सामग्री पर ध्यान केंद्रित किया गया था, लेकिन ध्यान दें कि input का प्रत्येक तत्व एक JSON ऑब्जेक्ट है, जिसमें type, role(एक नई विंडो में खुलेगा), और content निम्नलिखित होते हैं:

JSON

1
{
2
"type": "message",
3
"role": "user",
4
"content": [
5
{
6
"type": "input_text",
7
"text": "Add an architecture diagram to the README.md"
8
}
9
]
10
}

जब Codex Responses API को भेजने के लिए पूरा JSON पेलोड तैयार कर लेता है, तो वह ~/.codex/config.toml में Responses API एंडपॉइंट की कॉन्फ़िगरेशन के अनुसार Authorization हेडर के साथ HTTP POST अनुरोध करता है (यदि निर्दिष्ट किया गया हो, तो अतिरिक्त HTTP हेडर और क्वेरी पैरामीटर जोड़े जाते हैं)।

जब OpenAI Responses API सर्वर को अनुरोध प्राप्त होता है, तो यह JSON का उपयोग करके मॉडल के लिए प्रॉम्प्ट को इस प्रकार व्युत्पन्न करता है (हालांकि, Responses API का कस्टम कार्यान्वयन एक अलग विकल्प चुन सकता है):

AI एजेंट लूप में एक चरण दिखाने वाला स्नैपशॉट आरेख. एक उपयोगकर्ता का अनुरोध मॉडल में प्रवेश करता है, जो एक विचार, एक टूल नाम के साथ एक क्रिया, और एक टूल इनपुट उत्पन्न करता है। डायग्राम टूल कॉल होने से पहले इस मध्यवर्ती रीज़निंग चरण को हाइलाइट करता है।

जैसा कि आप देख सकते हैं, प्रॉम्प्ट में पहले तीन आइटम्स का क्रम सर्वर द्वारा निर्धारित किया जाता है, न कि क्लाइंट द्वारा। फिर भी, उन तीन वस्तुओं में से, केवल सिस्टम संदेश की सामग्री सर्वर द्वारा नियंत्रित होती है, क्योंकि उपकरण और निर्देश क्लाइंट द्वारा निर्धारित किए जाते हैं। प्रॉम्प्ट को पूरा करने के लिए input JSON पेलोड से आता है।

अब जब हमारे पास अपना प्रॉम्प्ट है, हम मॉडल को सैंपल करने के लिए तैयार हैं।

पहला टर्न

यह HTTP अनुरोध Responses API को Codex में बातचीत के पहले “टर्न” की शुरुआत करता है। सर्वर एक Server-Sent Events (SSE(एक नई विंडो में खुलेगा)) स्ट्रीम के साथ प्रतिक्रिया करता है। प्रत्येक इवेंट का data एक JSON पेलोड होता है जिसमें "type" होता है जो "response" से शुरू होता है, जो कुछ इस तरह हो सकता है (इवेंट्स की पूरी सूची हमारे API दस्तावेज़(एक नई विंडो में खुलेगा) में उपलब्ध है):

प्लेन टेक्स्ट

1
data: {"type":"response.reasoning_summary_text.delta","delta":"ah ", ...}
2
data: {"type":"response.reasoning_summary_text.delta","delta":"ha!", ...}
3
data: {"type":"response.reasoning_summary_text.done", "item_id":...}
4
data: {"type":"response.output_item.added", "item":{...}}
5
data: {"type":"response.output_text.delta", "delta":"forty-", ...}
6
data: {"type":"response.output_text.delta", "delta":"two!", ...}
7
data: {"type":"response.completed","response":{...}}

Codex इवेंट्स की स्ट्रीम को ग्रहण करता है(एक नई विंडो में खुलेगा) और उन्हें आंतरिक इवेंट ऑब्जेक्ट्स के रूप में पुनः प्रकाशित करता है, जिनका उपयोग क्लाइंट कर सकता है। response.output_text.delta जैसे इवेंट्स का उपयोग UI में स्ट्रीमिंग को समर्थन देने के लिए किया जाता है, जबकि response.output_item.added जैसे अन्य इवेंट्स को ऑब्जेक्ट्स में परिवर्तित किया जाता है जिन्हें बाद की Responses API कॉल्स के लिए input में जोड़ा जाता है।

मान लीजिए कि Responses API के पहले अनुरोध में दो response.output_item.done इवेंट शामिल हैं: एक type=reasoning के साथ और एक type=function_call के साथ। जब हम टूल कॉल के उत्तर के साथ मॉडल को फिर से क्वेरी करते हैं, तो इन घटनाओं को JSON के input फ़ील्ड में प्रदर्शित किया जाना चाहिए: 

JavaScript

1
[
2
/* ... original 5 items from the input array ... */
3
{
4
"type": "reasoning",
5
"summary": [
6
"type": "summary_text",
7
"text": "**Adding an architecture diagram for README.md**\n\nI need to..."
8
],
9
"encrypted_content": "gAAAAABpaDWNMxMeLw..."
10
},
11
{
12
"type": "function_call",
13
"name": "shell",
14
"arguments": "{\"command\":\"cat README.md\",\"workdir\":\"/Users/mbolin/code/codex5\"}",
15
"call_id": "call_8675309..."
16
},
17
{
18
"type": "function_call_output",
19
"call_id": "call_8675309...",
20
"output": "<p align=\"center\"><code>npm i -g @openai/codex</code>..."
21
}
22
]

बाद की क्वेरी के हिस्से के रूप में मॉडल को सैंपल करने के लिए उपयोग किया गया परिणामी प्रॉम्प्ट इस प्रकार होगा:

“Snapshot 2” लेबल वाला डायग्राम, जो एक टूल कॉल के बाद AI एजेंट को दिखाता है. मॉडल एक उपकरण अवलोकन प्राप्त करता है और एक नया विचार और क्रिया उत्पन्न करता है। तीर इनपुट, अवलोकन और आउटपुट को जोड़ते हैं ताकि यह दिखाया जा सके कि एजेंट अपने रीज़निंग चक्र को कैसे दोहराता है।

विशेष रूप से ध्यान दें कि पुराना प्रॉम्प्ट नए प्रॉम्प्ट का एक सटीक उपसर्ग है । यह जानबूझकर किया गया है, क्योंकि इससे बाद के अनुरोध अधिक कुशल हो जाते हैं, क्योंकि यह हमें प्रॉम्प्ट कैशिंग का लाभ उठाने में सक्षम बनाता है (जिस पर हम प्रदर्शन के अगले खंड में चर्चा करेंगे)।

एजेंट लूप के हमारे पहले डायग्राम को देखते हुए, हम देख सकते हैं कि इन्फ़रेंस और टूल कॉलिंग के बीच कई पुनरावृत्तियाँ हो सकती हैं। प्रॉम्प्ट तब तक बढ़ता रह सकता है जब तक हमें अंततः एक सहायक संदेश प्राप्त नहीं होता, जो टर्न के अंत का संकेत देता है:

प्लेन टेक्स्ट

1
data: {"type":"response.output_text.done","text": "I added a diagram to explain...", ...}
2
data: {"type":"response.completed","response":{...}}

Codex CLI में, हम उपयोगकर्ता को सहायक संदेश दिखाते हैं और कंपोज़र पर ध्यान केंद्रित करते हैं ताकि उपयोगकर्ता को संकेत मिले कि बातचीत जारी रखने की अब उनकी बारी है। यदि उपयोगकर्ता जवाब देता है, तो पिछले टर्न से सहायक का संदेश और उपयोगकर्ता का नया संदेश, दोनों को नए टर्न की शुरुआत करने के लिए Responses API अनुरोध के input में जोड़ा जाना चाहिए:

JavaScript

1
[
2
/* ... all items from the last Responses API request ... */
3
{
4
"type": "message",
5
"role": "assistant",
6
"content": [
7
{
8
"type": "output_text",
9
"text": "I added a diagram to explain the client/server architecture."
10
}
11
]
12
},
13
{
14
"type": "message",
15
"role": "user",
16
"content": [
17
{
18
"type": "input_text",
19
"text": "That's not bad, but the diagram is missing the bike shed."
20
}
21
]
22
}
23
]

एक बार फिर, क्योंकि हम बातचीत जारी रख रहे हैं, हम जो input Responses API को भेजते हैं, उसकी लंबाई बढ़ती जा रही है:

“Snapshot 3” लेबल वाला डायग्राम जो AI एजेंट लूप के अंतिम चरण को दिखाता है। टूल के परिणाम प्राप्त करने के बाद, मॉडल एक निष्कर्षात्मक विचार और उपयोगकर्ता को लौटाया गया अंतिम उत्तर उत्पन्न करता है। तीर टूल आउटपुट से पूर्ण प्रतिक्रिया तक के परिवर्तन को दर्शाते हैं।

आइए देखें कि यह लगातार बढ़ता हुआ प्रॉम्प्ट प्रदर्शन के लिए क्या मायने रखता है।

प्रदर्शन संबंधी विचार

तुम शायद सोच रहे हो, “रुको, क्या बातचीत के दौरान Responses API को भेजे गए JSON की मात्रा के हिसाब से एजेंट लूप quadratic नहीं है?” और तुम सही हो। हालांकि Responses API इस समस्या को कम करने के लिए एक वैकल्पिक previous_response_id(एक नई विंडो में खुलेगा) पैरामीटर का समर्थन करता है, Codex आज इसका उपयोग नहीं करता है, मुख्य रूप से अनुरोधों को पूरी तरह से स्टेटलेस रखने और ज़ीरो डेटा रिटेंशन (ZDR) कॉन्फ़िगरेशन का समर्थन करने के लिए।

previous_response_id से बचने से Responses API के प्रदाता के लिए चीज़ें सरल हो जाती हैं, क्योंकि यह सुनिश्चित करता है कि हर अनुरोध stateless हो। यह ज़ीरो डेटा रिटेंशन (ZDR)(एक नई विंडो में खुलेगा) को चुनने वाले ग्राहकों को समर्थन देना भी सरल बनाता है, क्योंकि previous_response_id का समर्थन करने के लिए आवश्यक डेटा को संग्रहीत करना ZDR के विपरीत होगा। ध्यान दें कि ZDR ग्राहक पिछले टर्न्स के प्रोप्राइटरी रीज़निंग संदेशों से लाभ उठाने की क्षमता का त्याग नहीं करते हैं, क्योंकि संबंधित encrypted_content को सर्वर पर डिक्रिप्ट किया जा सकता है। (OpenAI ZDR ग्राहक की डिक्रिप्शन कुंजी को बनाए रखता है, लेकिन उनके डेटा को नहीं.) ZDR को सपोर्ट करने के लिए Codex में संबंधित बदलावों के लिए PRs #642(एक नई विंडो में खुलेगा) और #1641(एक नई विंडो में खुलेगा) देखें।

आमतौर पर, मॉडल का सैंपलिंग करने की लागत नेटवर्क ट्रैफ़िक की लागत से अधिक होती है, जिससे सैंपलिंग हमारे दक्षता प्रयासों का मुख्य लक्ष्य बन जाती है। यही कारण है कि प्रॉम्प्ट कैशिंग इतनी महत्वपूर्ण है, क्योंकि यह हमें पिछले इन्फ़रेंस कॉल से की गई गणना को पुनः उपयोग करने की अनुमति देती है। जब हमें cache hits मिलते हैं, मॉडल का सैंपलिंग चतुर्भुज की बजाय रैखिक होता है। हमारे प्रॉम्प्ट कैशिंग (एक नई विंडो में खुलेगा)डॉक्यूमेंटेशन में इसे और विस्तार से समझाया गया है:

कैश हिट्स केवल प्रॉम्प्ट के अंदर सटीक प्रीफ़िक्स मैच के लिए ही संभव हैं। कैशिंग के लाभों को समझने के लिए, अपने प्रॉम्प्ट की शुरुआत में निर्देशों और उदाहरणों जैसी स्थिर सामग्री रखें, और अंत में उपयोगकर्ता-विशिष्ट जानकारी जैसी परिवर्तनीय सामग्री रखें। यह इमेज और टूल्स पर भी लागू होता है, जिन्हें अनुरोधों के बीच समान होना चाहिए।

इसे ध्यान में रखते हुए, आइए विचार करें कि Codex में कौन से प्रकार के ऑपरेशन “cache miss” का कारण बन सकते हैं:

  • बातचीत के दौरान मॉडल के लिए उपलब्ध tools को बदलना।
  • Responses API अनुरोध के लक्ष्य मॉडल को बदलना (व्यवहार में, यह मूल प्रॉम्प्ट के तीसरे आइटम को बदलता है, क्योंकि इसमें मॉडल-विशिष्ट निर्देश होते हैं)।
  • सैंडबॉक्स कॉन्फ़िगरेशन, अनुमोदन मोड, या वर्तमान कार्यशील निर्देशिका बदलना।

Codex टीम को Codex CLI में नए फीचर्स पेश करते समय सतर्क रहना चाहिए जो प्रॉम्प्ट कैशिंग को प्रभावित कर सकते हैं। उदाहरण के लिए, MCP टूल्स के लिए हमारी प्रारंभिक सहायता में एक बग था, जिसमें हम टूल्स को एक सुसंगत क्रम में सूचीबद्ध करने में असफल रहे(एक नई विंडो में खुलेगा), जिससे कैश मिस हो रहे थे। ध्यान दें कि MCP टूल्स विशेष रूप से जटिल हो सकते हैं क्योंकि MCP सर्वर notifications/tools/list_changed(एक नई विंडो में खुलेगा) नोटिफिकेशन के माध्यम से तुरंत ही वे जिन टूल्स की सूची प्रदान करते हैं, उसे बदल सकते हैं। लंबी बातचीत के दौरान इस नोटिफ़िकेशन को मान्यता देना एक महंगा कैश मिस उत्पन्न कर सकता है।

जब संभव हो, हम बातचीत के बीच में होने वाले कॉन्फ़िगरेशन बदलावों को किसी पहले संदेश में बदलाव करने के बजाय बदलाव को दर्शाने के लिए input में एक नया संदेश जोड़कर संभालते हैं:

  • यदि सैंडबॉक्स कॉन्फ़िगरेशन या अनुमोदन मोड बदलता है, तो हम insert(एक नई विंडो में खुलेगा) करते हैं एक नया role=developer संदेश, जिसका प्रारूप मूल आइटम के समान होता है।
  • यदि वर्तमान कार्यशील निर्देशिका बदलती है, तो हम insert(एक नई विंडो में खुलेगा) करते हैं एक नया role=user संदेश, जो मूल के समान प्रारूप में होता है।

हम प्रदर्शन के लिए कैश हिट सुनिश्चित करने के लिए बहुत प्रयास करते हैं। हमें प्रबंधित करने के लिए एक और प्रमुख संसाधन है: कॉन्टेक्स्ट विंडो।

कॉन्टेक्स्ट विंडो खत्म होने से बचने के लिए हमारी सामान्य रणनीति यह है कि टोकन की संख्या किसी सीमा से अधिक होने पर हम बातचीत को संक्षिप्त कर देते हैं। विशेष रूप से, हम input को बातचीत का प्रतिनिधित्व करने वाली नई, छोटी सूची से बदलते हैं, जिससे एजेंट अब तक की घटनाओं की समझ के साथ आगे बढ़ सके। कॉम्पैक्शन के एक शुरुआती इम्प्लीमेंटेशन(एक नई विंडो में खुलेगा) में उपयोगकर्ता को /compact कमांड को मैन्युअली इनवोक करना पड़ता था, जो मौजूदा बातचीत के साथ सारांश(एक नई विंडो में खुलेगा) के लिए कस्टम निर्देशों का उपयोग करके Responses API को क्वेरी करता था। Codex ने सारांश युक्त परिणामी सहायक संदेश को नए इनपुट(एक नई विंडो में खुलेगा) के रूप में बाद के वार्तालाप चरणों के लिए उपयोग किया।

तब से, Responses API ने एक विशेष /responses/compact एंडपॉइंट(एक नई विंडो में खुलेगा) का समर्थन करना शुरू कर दिया है, जो कॉम्पैक्शन को अधिक कुशलता से करता है। यह आइटमों की एक सूची(एक नई विंडो में खुलेगा) लौटाता है, जिसका उपयोग पिछले input की जगह बातचीत जारी रखने के लिए किया जा सकता है, और इस दौरान कॉन्टेक्स्ट विंडो को खाली कर देता है. इस सूची में एक विशेष type=compaction आइटम शामिल है, जिसमें एक अपारदर्शी encrypted_content आइटम होता है जो मूल बातचीत के बारे में मॉडल की छिपी हुई समझ को बनाए रखता है। अब, जब auto_compact_limit(एक नई विंडो में खुलेगा) पार हो जाता है, Codex अपने आप इस एंडपॉइंट का उपयोग करके बातचीत को संक्षिप्त करता है।

आने वाला है

हमने Codex एजेंट लूप का परिचय दिया है और यह समझाया है कि Codex किसी मॉडल से क्वेरी करते समय अपने संदर्भ को कैसे तैयार और प्रबंधित करता है। रास्ते में, हमने उन व्यावहारिक विचारों और सर्वोत्तम प्रथाओं को उजागर किया जो Responses API के ऊपर एक एजेंट लूप बनाने वाले किसी भी व्यक्ति पर लागू होती हैं।

हालाँकि एजेंट लूप Codex के लिए नींव रखता है, यह केवल शुरुआत भर है। आने वाली पोस्ट्स में, हम CLI के आर्किटेक्चर में गहराई से जाएंगे, टूल के उपयोग को कैसे लागू किया जाता है, इसे एक्सप्लोर करेंगे, और Codex के सैंडबॉक्सिंग मॉडल पर एक करीबी नज़र डालेंगे।

लेखक

Michael Bolin

स्वीकृतियां

Codex CLI बनाने वाली पूरी टीम को विशेष धन्यवाद।