前言
在现代 AI 辅助开发工具中,如何高效地处理和展示工具执行结果,尤其是当输出内容极为庞大时,是提升用户体验和系统性能的关键。Gemini CLI 通过其智能摘要系统,将复杂的工具输出转化为简明、可读的内容。本文将深入解析 summarizer.ts
及其配套测试 summarizer.test.ts
,揭示其设计理念、技术细节和在整个项目中的作用。
1. 智能摘要系统的设计思想
1.1 分层摘要策略
Gemini CLI 摘要系统采用了分层摘要策略¹:
注解1 – 分层摘要策略:根据内容长度和复杂度,系统自动选择不同的摘要方式。短内容直接返回,长内容则调用 LLM(大语言模型)进行智能压缩。
- defaultSummarizer:直接 JSON 序列化工具输出,适合结构化或短内容。
- llmSummarizer:调用 Gemini 模型进行智能摘要,适合长文本或复杂内容。
export const defaultSummarizer: Summarizer = (
result, _geminiClient, _abortSignal
) => Promise.resolve(JSON.stringify(result.llmContent));
export const llmSummarizer: Summarizer = (result, geminiClient, abortSignal) =>
summarizeToolOutput(
partToString(result.llmContent),
geminiClient,
abortSignal,
);
1.2 智能长度检测与性能优化
系统通过智能长度检测²,避免不必要的 AI 调用:
注解2 – 智能长度检测:只有当内容长度超过阈值(默认2000字符)时,才会调用 LLM 进行摘要。这样既保证了性能,又避免了短内容被无意义地处理。
export async function summarizeToolOutput(
textToSummarize, geminiClient, abortSignal, maxLength = 2000
) {
if (!textToSummarize || textToSummarize.length < maxLength) {
return textToSummarize;
}
// ...调用 LLM 进行摘要
}
1.3 上下文感知的摘要提示词
系统设计了上下文感知的摘要提示词³,提升摘要质量:
注解3 – 上下文感知的摘要提示词:根据工具输出类型(目录列表、文本内容、Shell 命令),提示词会引导 LLM 采用不同的摘要策略,并保留错误和警告信息。
const SUMMARIZE_TOOL_OUTPUT_PROMPT = `
Summarize the following tool output to be a maximum of {maxLength} characters...
1. If the text is a directory listing...
2. If the text is text content...
3. If the text is the output of a shell command... include <error></error> and <warning></warning> tags.
Text to summarize:
"{textToSummarize}"
Return the summary string which should first contain an overall summarization of text followed by the full stack trace of errors and warnings in the tool output.
`;
2. 技术实现与核心算法
2.1 通用内容转换器
partToString
实现了通用内容转换器⁴:
注解4 – 通用内容转换器:支持字符串、数组、对象等多种格式的内容统一转为文本,确保摘要系统能处理各种工具输出。
function partToString(part: PartListUnion): string {
if (!part) return '';
if (typeof part === 'string') return part;
if (Array.isArray(part)) return part.map(partToString).join('');
if ('text' in part) return part.text ?? '';
return '';
}
2.2 健壮的响应解析与错误处理
getResponseText
和 try-catch 实现了健壮的响应解析与错误处理⁵:
注解5 – 健壮的响应解析与错误处理:无论 LLM 响应格式如何变化,系统都能安全提取文本内容。若摘要失败,则优雅回退到原始内容,并记录错误日志。
function getResponseText(response: GenerateContentResponse): string | null {
if (response.candidates && response.candidates.length > 0) {
const candidate = response.candidates[0];
if (candidate.content && candidate.content.parts && candidate.content.parts.length > 0) {
return candidate.content.parts.filter((part) => part.text).map((part) => part.text).join('');
}
}
return null;
}
try {
const parsedResponse = await geminiClient.generateContent(...);
return getResponseText(parsedResponse) || textToSummarize;
} catch (error) {
console.error('Failed to summarize tool output.', error);
return textToSummarize;
}
3. 配置驱动与模型管理
3.1 模型与参数集中管理
系统通过常量配置模型和参数,实现集中管理与灵活调优⁶:
注解6 – 集中管理与灵活调优:摘要模型和最大输出 token 数量均可统一配置,便于后续升级和性能优化。
const toolOutputSummarizerModel = DEFAULT_GEMINI_FLASH_MODEL;
const toolOutputSummarizerConfig: GenerateContentConfig = {
maxOutputTokens: 2000,
};
4. 测试驱动的质量保证
4.1 全面单元测试覆盖
summarizer.test.ts 提供了全面的单元测试覆盖⁷:
注解7 – 全面单元测试覆盖:涵盖短文本、长文本、异常处理、提示词构造等所有核心场景,确保摘要系统在各种边界条件下都能稳定运行。
- 短文本直接返回
- 长文本调用 LLM 并返回摘要
- 异常时回退原始内容
- 检查提示词构造是否正确
it('should return original text if it is shorter than maxLength', async () => { ... });
it('should call generateContent if text is longer than maxLength', async () => { ... });
it('should return original text if generateContent throws an error', async () => { ... });
it('should construct the correct prompt for summarization', async () => { ... });
5. 在项目架构中的作用
5.1 工具输出的统一处理
摘要系统作为工具输出的统一处理层⁸,连接工具执行与用户展示:
注解8 – 工具输出的统一处理层:无论是文件搜索、内容读取还是命令执行,所有工具的输出都可以通过摘要系统进行压缩和美化,极大提升了终端展示的可读性和信息密度。
5.2 与 GeminiClient 的协同
摘要系统与 GeminiClient 深度集成,实现AI驱动的内容优化⁹:
注解9 – AI驱动的内容优化:通过 GeminiClient 的 generateContent 方法,系统能够实时调用 LLM,对工具输出进行语义压缩和结构化处理。
5.3 配置与扩展性
通过类型定义和参数化设计,摘要系统支持高度可扩展¹⁰:
注解10 – 高度可扩展:用户和开发者可以自定义摘要器、调整模型参数、扩展内容类型,满足不同场景和需求。
6. 性能与用户体验优化
6.1 响应速度与资源管理
通过智能长度检测和异常回退,系统实现了高性能与稳定性¹¹:
注解11 – 高性能与稳定性:避免无谓的 AI 调用,保证响应速度;异常时优雅回退,确保用户体验不受影响。
6.2 内容完整性与安全性
无论摘要是否成功,系统都保证内容完整性与安全性¹²:
注解12 – 内容完整性与安全性:用户永远不会因为摘要失败而丢失信息,所有错误均有日志记录,便于后续排查。
总结
Gemini CLI 的智能摘要系统通过分层策略、AI驱动、健壮错误处理和全面测试,构建了一个高效、可靠、可扩展的工具输出处理平台。它不仅提升了终端用户的体验,也为整个 AI 工具生态系统的内容管理和展示提供了技术范例。
核心创新点
- 分层摘要策略 – 性能与智能兼顾
- 上下文感知提示词 – 提升摘要质量
- 健壮错误处理 – 保证系统稳定性
- 全面测试覆盖 – 质量保障
- 配置驱动与扩展性 – 灵活适应多场景
这种架构不仅让 Gemini CLI 在处理复杂工具输出时游刃有余,也为未来的 AI 工具平台内容压缩与展示奠定了坚实基础。
请将以下工具输出内容总结为最多 {maxLength} 个字符。摘要应简明扼要,抓住工具输出的主要信息点。
摘要应根据所提供的内容进行。请遵循以下基本规则:
1. 如果文本是目录列表或任何结构化输出,请结合对话历史理解上下文。利用这些上下文,判断我们需要从工具输出中获取哪些信息,并将其作为摘要返回。
2. 如果文本是普通内容且没有结构化信息,请对文本进行摘要。
3. 如果文本是 Shell 命令的输出,请结合对话历史理解上下文。利用这些上下文,判断我们需要从工具输出中获取哪些信息,并将其摘要返回,同时将任何错误的堆栈信息放在 标签内。堆栈信息应完整且不被截断。如果有警告,请在摘要中用 标签包含这些警告。
待总结文本:
“{textToSummarize}”
请返回一个摘要字符串,首先包含对文本的整体总结,然后在工具输出中附上完整的错误堆栈和警告信息。