äžãåŒèš
å€§å®¶å¥œïŒææ¯äžäžªæºç ç±å¥œè ãåšäžäžç¯æç« äžïŒæä»¬äºè§£äº Claude Code çæŽäœæ¶æåå¯åšæµçšãä»å€©ïŒè®©æä»¬æ·±å ¥å°æ žå¿æš¡åââ对è¯åŒæçå®ç°ç»èã
çžä¿¡åŸå€äººéœå¥œå¥ïŒåœæä»¬åšç»ç«¯èŸå ¥äžäžªé®é¢æ¶ïŒClaude æ¯åŠäœç解并ç»åºåççïŒè¿äžªè¿çšèåéèçææ ·çææ¯ç»èïŒ
åšæ·±å ¥æºç ä¹åïŒææ³å享äžäžªä»€äººéæçåç°ïŒClaude Code ç对è¯åŒæç«ç¶å®ç°äºåå±å猩çç¥æ¥å€çé¿å¯¹è¯äžäžæïŒè¿æå³çå³äŸ¿æ¯é¿èŸŸæ°çŸèœ®ç对è¯ïŒç³»ç»ä¹èœä¿æé«æè¿è¡ã
äºã对è¯åŒæçæ žå¿æ¶æ
2.1 æŽäœæ¶ææŠè§
让æä»¬å æ¥çäžäžå¯¹è¯åŒæçæŽäœæ¶æïŒ
çšæ·èŸå
¥
â
âŒ
âââââââââââââââââââââââââââââââââââââââ
â QueryEngineïŒå¯¹è¯ç®¡çåšïŒ â
â - äŒè¯ç¶æç®¡ç â
â - æ¶æ¯æµèœ¬æ§å¶ â
â - SDK åè®®éé
â
âââââââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââ
â query()ïŒæ žå¿æ¥è¯¢åŸªç¯ïŒ â
â - æ¶æ¯å猩å€ç â
â - API è°çšç®¡ç â
â - å·¥å
·æ§è¡åè° â
â - é误æ¢å€æºå¶ â
âââââââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââ
â Anthropic API / MCP æå¡åš â
â - æš¡åè°çš â
â - å·¥å
·æ§è¡ â
â - æ¶æ¯æµå€ç â
âââââââââââââââââââââââââââââââââââââââ
2.2 QueryEngineïŒå¯¹è¯ç"倧è"
QueryEngine æ¯æŽäžªå¯¹è¯ç³»ç»çæ žå¿ïŒèŽèŽ£ç®¡ç对è¯ç宿ŽçåœåšæïŒ
export class QueryEngine {
private config: QueryEngineConfig; // é
眮信æ¯
private mutableMessages: Message[]; // æ¶æ¯å衚
private abortController: AbortController; // äžææ§å¶åš
private permissionDenials: SDKPermissionDenial[]; // æéæç»è®°åœ
private totalUsage: NonNullableUsage; // API 䜿çšç»è®¡
private readFileState: FileStateCache; // æä»¶è¯»åçŒå
}
è¿éæèž©äºäžªå€§åïŒ äžåŒå§æä»¥äžº QueryEngine åªæ¯äžäžªç®åçæ¶æ¯èœ¬ååšïŒäœæ·±å ¥ååç°å®å ¶å®æ¿æ äºïŒ
- äŒè¯ç¶æç®¡ç
- æé远螪
- èµæºæ¶èç»è®¡
- æä»¶çŒå管ç
è¿åäžªæ žå¿è莣ïŒ
äžãæ¶æ¯å€çæµçšæ·±åºŠåæ
3.1 æ¶æ¯åç±»äžå€ççç¥
QueryEngine å€çå€ç§æ¶æ¯ç±»åïŒæ¯ç§ç±»åéœæäžéšçå€çé»èŸïŒ
| æ¶æ¯ç±»å | å€ççç¥ | çšé |
|---|---|---|
assistant | æ åååèŸåº | AI 婿ååº |
user | å¢å ååè®¡æ° | çšæ·èŸå ¥ |
progress | ç«å³è®°åœ | å·¥å ·æ§è¡è¿åºŠ |
attachment | æåç»æåèŸåº | éä»¶åå æ°æ® |
stream_event | æŽæ°äœ¿çšç»è®¡ | æµåŒäºä»¶ |
system | å€çå猩蟹ç | ç³»ç»æ§å¶ä¿¡å· |
3.2 æ žå¿æ¹æ³ïŒsubmitMessage
è¿æ¯ QueryEngine çæ žå¿æ¹æ³ïŒå€ççšæ·èŸå ¥å¹¶è¿åååºïŒ
async *submitMessage(prompt, options) {
// 1. å
è£
æéæ£æ¥åœæ°
const wrappedCanUseTool = async (tool, input, ...) => {
const result = await canUseTool(tool, input, ...);
if (result.behavior !== 'allow') {
this.permissionDenials.push({
tool_name: tool.name,
tool_use_id: toolUseID
});
}
return result;
};
// 2. è·åç³»ç»æç€ºåäžäžæ
const { defaultSystemPrompt, userContext, systemContext } =
await fetchSystemPromptParts({ tools, mainLoopModel, ... });
// 3. å€ççšæ·èŸå
¥
const { messages: messagesFromUserInput, shouldQuery } =
await processUserInput({ input: prompt, mode: 'prompt', ... });
// 4. æä¹
åæ¶æ¯
if (persistSession && messagesFromUserInput.length > 0) {
await recordTranscript(messages);
}
// 5. æ§è¡æ¥è¯¢åŸªç¯
for await (const message of query({ messages, systemPrompt, ... })) {
// å€çåç±»æ¶æ¯...
}
}
å ³é®è®Ÿè®¡ç¹ïŒ
- 䜿çš
async*çæåšæš¡åŒïŒæ¯ææµåŒèŸåº - å è£ æéæ£æ¥åœæ°ïŒè®°åœæææéæç»
- æ¶æ¯æä¹ åç¡®ä¿äŒè¯å¯æ¢å€
åãåå±å猩çç¥ïŒå€çé¿å¯¹è¯çç§å¯æŠåš
4.1 åçŒ©å±æ¬¡ç»æ
è¿æ¯æåç°çæä»€äººæå¹ç讟计ïŒClaude Code å®ç°äºåå±å猩çç¥ïŒ
âââââââââââââââââââââââââââââââââââââââââââââââ
â 第1å±: Snip å猩ïŒå¿«éæž
çïŒ â
â - ç§»é€åµå°žæ¶æ¯åéæ§æ è®° â
â - 蜻é级ïŒå¿«éæ§è¡ â
âââââââââââââââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââ
â 第2å±: MicrocompactïŒçŒåäŒåïŒ â
â - åºäºçŒåçŒèŸçç»ç²åºŠå猩 â
â - ä¿æå¯¹è¯è¿èŽ¯æ§ â
âââââââââââââââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââ
â 第3å±: Context CollapseïŒäžäžææå ïŒ â
â - åºäºè§åŸæåœ±çæºèœæå â
â - ä¿æå¯¹è¯ç²åºŠ â
âââââââââââââââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââ
â 第4å±: AutocompactïŒèªåšåçŒ©ïŒ â
â - åºäºAIæ»ç»çéé级å猩 â
â - çææèŠæ¶æ¯ â
âââââââââââââââââââââââââââââââââââââââââââââââ
4.2 å猩å®ç°ä»£ç
// Snip å猩
if (feature('HISTORY_SNIP')) {
const snipResult = snipModule.snipCompactIfNeeded(messages);
messages = snipResult.messages;
}
// Microcompact
const microcompactResult = await deps.microcompact(messages, context);
messages = microcompactResult.messages;
// Context Collapse
if (feature('CONTEXT_COLLAPSE')) {
const collapseResult = await contextCollapse.applyCollapsesIfNeeded(messages);
messages = collapseResult.messages;
}
// Autocompact
const { compactionResult } = await deps.autocompact(messages, context, options);
if (compactionResult) {
const postCompactMessages = buildPostCompactMessages(compactionResult);
messages = postCompactMessages;
}
讟计äŒå¿ïŒ
- æžè¿åŒå猩ïŒä»å¿«éå°æ·±åºŠïŒæééæ©
- å¯é 眮æ§ïŒéè¿ feature flag æ§å¶å屿¯åŠå¯çš
- æºèœå³çïŒæ ¹æ®äžäžææ åµèªåšéæ©å猩çç¥
äºãAPI è°çšäžé误æ¢å€æºå¶
5.1 æµåŒå€çäžå·¥å ·æ§è¡
ç³»ç»æ¯æå·¥å ·çæµåŒæ§è¡ïŒæåçšæ·äœéªïŒ
for await (const message of deps.callModel({
messages: prependUserContext(messagesForQuery, userContext),
systemPrompt: fullSystemPrompt,
tools: toolUseContext.options.tools,
signal: toolUseContext.abortController.signal,
options: {
model: currentModel,
fallbackModel,
fastMode: appState.fastMode,
},
})) {
// æ£æµå·¥å
·äœ¿çš
if (message.type === 'assistant') {
const toolUseBlocks = message.message.content.filter(
content => content.type === 'tool_use'
);
if (toolUseBlocks.length > 0) {
needsFollowUp = true; // éèŠæ§è¡å·¥å
·
}
}
}
5.2 å€éé误æ¢å€çç¥
ç³»ç»å®ç°äºå€å±æ¬¡çé误æ¢å€ïŒ
çç¥äžïŒæš¡åé级
if (innerError instanceof FallbackTriggeredError && fallbackModel) {
currentModel = fallbackModel;
yield createSystemMessage(
`Switched to ${fallbackModel} due to high demand...`,
'warning'
);
continue;
}
çç¥äºïŒååºåŒå猩
if (isWithheld413 && reactiveCompact) {
const compacted = await reactiveCompact.tryReactiveCompact({
messages: messagesForQuery,
...
});
if (compacted) {
messages = buildPostCompactMessages(compacted);
continue;
}
}
çç¥äžïŒèŸåºtokenéå¶æ¢å€
if (maxOutputTokensRecoveryCount < MAX_OUTPUT_TOKENS_RECOVERY_LIMIT) {
const recoveryMessage = createUserMessage({
content: 'Output token limit hit. Resume directly...',
isMeta: true,
});
messages.push(recoveryMessage);
maxOutputTokensRecoveryCount++;
continue;
}
å ãäŒè¯æä¹ åäžæ°æ®å®å š
6.1 æ¶æ¯è®°åœæºå¶
äŒè¯æä¹ 忝ä¿è¯çšæ·äœéªçå ³é®ïŒ
// æ¶æ¯è®°åœçç¥
if (persistSession && messagesFromUserInput.length > 0) {
const transcriptPromise = recordTranscript(messages);
// Bare æš¡åŒäžéé»å¡åå
¥
if (isBareMode()) {
void transcriptPromise;
} else {
await transcriptPromise;
// 区å¶å·æ°åºæ¯
if (isEnvTruthy(process.env.CLAUDE_CODE_EAGER_FLUSH)) {
await flushSessionStorage();
}
}
}
è®°åœæ¶æºïŒ
- çšæ·æ¶æ¯æ¥æ¶åç«å³è®°åœ
- å©ææ¶æ¯åŒæ¥è®°åœ
- åçŒ©èŸ¹çæ¶å·æ°
6.2 å®å šæ§è®Ÿè®¡
// Windows è·¯åŸå«æé²æ€
process.env.NoDefaultCurrentDirectoryInExePath = '1';
// Git åœä»€å®å
𿣿¥
function prefetchSystemContextIfSafe() {
const hasTrust = checkHasTrustDialogAccepted();
if (hasTrust) {
void getSystemContext();
}
}
äžãæ»ç»äžæè
éè¿æ·±å ¥åæ Claude Code ç对è¯åŒæïŒææä»¥äžå ç¹æ·±å»äœäŒïŒ
- åå±è®Ÿè®¡çéèŠæ§ïŒQueryEngine äž query() çè莣å犻ïŒäœ¿åŸä»£ç æäºç»Žæ€åæ©å±
- å猩çç¥ç粟åŠïŒåå±å猩çç¥å Œé¡Ÿäºæ§èœå对è¯èŽšé
- é误æ¢å€ç宿޿§ïŒå€ç§æ¢å€çç¥ç¡®ä¿ç³»ç»ç鲿£æ§
- å®å šæ§çéè§ïŒå€å€å®å 𿣿¥äœç°äºäŒäžçº§åºçšç䞥谚æ§
äžäžç¯é¢åïŒ æä»¬å°æ·±å ¥åæ Claude Code çå·¥å ·ç³»ç»è®Ÿè®¡ïŒæç§å®æ¯åŠäœå®ç°ä»£ç æ§è¡ãæä»¶æäœçæ žå¿èœåçïŒ
å «ãäºåšäº€æµ
äœ ä»¬è§åŸè¿äžªåå±å猩çç¥è®Ÿè®¡åŸæä¹æ ·ïŒè¿æä»ä¹æŽå¥œçæ¹æ³æ¥å€çé¿å¯¹è¯äžäžæïŒæ¬¢è¿åšè¯è®ºåºäº€æµïŒ
åŠæè§åŸè¿ç¯æç« å¯¹äœ æåž®å©ïŒè¯·ç¹èµå ³æ³šæ¯æäžäžïŒæä»¬äžäžç¯è§ïŒð
ååäžæïŒç¹èµå ³æ³šæ¯æäžäžïŒ