Resouce Context 管理
之前的 Drive MCP 设计中提到了 Resource,这里记录一下在实际使用 Resource 过程中遇到的问题:在用户 Attach File 后,我们使用前面说的 MCP Client 获取 Resource,然后把上下文 attach 到 system prompt 中:
private async resolveResourceUris(
uris: string[],
_userId: string,
): Promise<string> {
const parts: string[] = [];
for (const uri of uris.slice(0, 5)) {
try {
const result = await this.mcpClient.readResource(uri);
const content = result.contents[0]?.text ?? "";
parts.push(
`--- Resource (${uri}) ---\n${content}\n--- End of resource ---`,
);
} catch (error) {
const msg = error instanceof Error ? error.message : "Unknown error";
logger.warn({ uri, error: msg }, "Failed to resolve resource URI");
parts.push(`--- ${uri}: [Error: ${msg}] ---`);
}
}
return parts.join("\n\n");
}
const resourceUris = request.resourceUris;
if (resourceUris && resourceUris.length > 0) {
const resolvedContent = await this.resolveResourceUris(resourceUris, userId);
if (resolvedContent) {
const resourceMessage: IMessage = {
role: "system",
content:
`[Attached Resources — the user has explicitly shared these for context]\n\n` +
resolvedContent,
timestamp: new Date(),
};
conversation.messages.push(resourceMessage);
}
}
然后就结束、测试 Agent 做 Summary,结果它发生了下面的问题:
- 如果我在一个 Folder 中 Attach 另一个 Folder,那么 Agent 会弄不清楚自己现在在处理哪个 Folder,会在当前的 Folder 查找 Attached Folder 的内容。
- backend 日志显示 Attach 内容后日志中会调用
check_index_status这些实际用不上的工具。
在排查具体问题是发现是上下文 Prompt 的问题,然后进行了如下策略修改:
- 我们把 System Prompt 加入到消息窗口中,不然 Agent 完全获取不到前面的 Resource 消息:
for (const msg of memoryState.recentMessages) {
if (msg.role === "user") {
messages.push({ role: "user", content: msg.content });
} else if (msg.role === "assistant") {
messages.push({ role: "assistant", content: msg.content });
} else if (msg.role === "system") {
// 注入的 system 消息(比如 Attached resource)
messages.push({ role: "system", content: msg.content });
}
}
- 然后对原先的 Agent,添加上针对 Attached 的上下文并取消原始的 Workspace 上下文注入,防止 Agent 弄不清楚到底该处理哪个 Folder,下面是一个例子:
简单回顾一下:这里的 Workspace Context 是 Agent 在 Drive 特定位置时注入的上下文,比如在某个 Folder 中时这个 Context 就是当前 folderId 和下面的文件。
const workspaceInfo = context.hasExplicitResources
? `\n\n## Context Mode: Resource-Focused\nThe user has explicitly attached specific files/folders as reference materials.\nTheir full content/structure is already provided in the conversation as system messages.\n**DO NOT** browse root directory, list folder contents, or explore surrounding folders — the data you need is already in the conversation.\nIf the task requires creating a result file, use folder ID "${context.folderId || "root"}" as the target.`
: context.workspaceSnapshot
? `\n\n## Current Workspace Snapshot\nThe user is currently in this folder:\n\`\`\`json\n${context.workspaceSnapshot}\n\`\`\`\nFolder path: ${context.folderPath || "/"}`
: "";