Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions s08_context_compact/README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,21 @@ def snip_compact(messages, max_messages=50):
if _is_tool_result_message(messages[tail_start]) and _message_has_tool_use(messages[tail_start - 1]):
tail_start -= 1
snipped = tail_start - head_end
placeholder = {"role": "user", "content": f"[snipped {snipped} messages from conversation middle]"}
return messages[:head_end] + [placeholder] + messages[tail_start:]

snip_text = f"\n\n[System Note: Snipped {snipped} history messages here for context compression]\n\n"

head_part = messages[:head_end]
tail_part = [msg.copy() for msg in messages[tail_start:]]

first_tail_msg = tail_part[0]

if isinstance(first_tail_msg["content"], str):
first_tail_msg["content"] = snip_text + first_tail_msg["content"]

elif isinstance(first_tail_msg["content"], list):
first_tail_msg["content"].insert(0, {"type": "text", "text": snip_text})

return head_part + tail_part
```

Messages are still trimmed directly; this just adds one boundary guard. `tool_result` content within remaining messages still keeps accumulating — message #34 may still hold 30KB of old file contents. → L2.
Expand Down
17 changes: 15 additions & 2 deletions s08_context_compact/README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,21 @@ def snip_compact(messages, max_messages=50):
if _is_tool_result_message(messages[tail_start]) and _message_has_tool_use(messages[tail_start - 1]):
tail_start -= 1
snipped = tail_start - head_end
placeholder = {"role": "user", "content": f"[snipped {snipped} messages from conversation middle]"}
return messages[:head_end] + [placeholder] + messages[tail_start:]

snip_text = f"\n\n[System Note: Snipped {snipped} history messages here for context compression]\n\n"

head_part = messages[:head_end]
tail_part = [msg.copy() for msg in messages[tail_start:]]

first_tail_msg = tail_part[0]

if isinstance(first_tail_msg["content"], str):
first_tail_msg["content"] = snip_text + first_tail_msg["content"]

elif isinstance(first_tail_msg["content"], list):
first_tail_msg["content"].insert(0, {"type": "text", "text": snip_text})

return head_part + tail_part
```

切り捨て自体は単純なままで、境界だけを保護する。残ったメッセージ内の `tool_result` 内容はまだ蓄積され続けている。34 番目のメッセージに 30KB の古いファイル内容が残っているかもしれない。→ L2。
Expand Down
23 changes: 21 additions & 2 deletions s08_context_compact/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,27 @@ def snip_compact(messages, max_messages=50):
if _is_tool_result_message(messages[tail_start]) and _message_has_tool_use(messages[tail_start - 1]):
tail_start -= 1
snipped = tail_start - head_end
placeholder = {"role": "user", "content": f"[snipped {snipped} messages from conversation middle]"}
return messages[:head_end] + [placeholder] + messages[tail_start:]

# 构造清晰的系统断层通知,告知 Claude 上下文有缺失,避免其产生幻觉
snip_text = f"\n\n[System Note: Snipped {snipped} history messages here for context compression]\n\n"

# 对后半段进行深拷贝(Deep Copy)或浅拷贝,防止直接修改和污染外部传入的原始 messages 数组
head_part = messages[:head_end]
tail_part = [msg.copy() for msg in messages[tail_start:]]

# 将提示信息“无损”合并到后半段第一条消息中,天然继承原有的角色交替和工具流结构
first_tail_msg = tail_part[0]

if isinstance(first_tail_msg["content"], str):
# 场景 A:普通的纯文本消息
first_tail_msg["content"] = snip_text + first_tail_msg["content"]

elif isinstance(first_tail_msg["content"], list):
# 场景 B:Claude 3 常见的多模态(含图片)或包含 tool_use/tool_result 的 Content Block 列表
# 在列表最前端插入一个标准的 text block
first_tail_msg["content"].insert(0, {"type": "text", "text": snip_text})

return head_part + tail_part
```

裁掉的是消息本身,只是在切口处多做一步保护;剩下的消息里 `tool_result` 内容仍在累积——第 34 条消息里可能躺着 30KB 的旧文件内容。→ L2。
Expand Down
21 changes: 20 additions & 1 deletion s08_context_compact/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,27 @@ def snip_compact(messages, max_messages=50):
if head_end >= tail_start:
return messages
snipped = tail_start - head_end
return messages[:head_end] + [{"role": "user", "content": f"[snipped {snipped} messages]"}] + messages[tail_start:]

# 构造清晰的系统断层通知,告知 Claude 上下文有缺失,避免其产生幻觉
snip_text = f"\n\n[System Note: Snipped {snipped} history messages here for context compression]\n\n"

# 对后半段进行深拷贝(Deep Copy)或浅拷贝,防止直接修改和污染外部传入的原始 messages 数组
head_part = messages[:head_end]
tail_part = [msg.copy() for msg in messages[tail_start:]]

# 将提示信息“无损”合并到后半段第一条消息中,天然继承原有的角色交替和工具流结构
first_tail_msg = tail_part[0]

if isinstance(first_tail_msg["content"], str):
# 场景 A:普通的纯文本消息
first_tail_msg["content"] = snip_text + first_tail_msg["content"]

elif isinstance(first_tail_msg["content"], list):
# 场景 B:Claude 3 常见的多模态(含图片)或包含 tool_use/tool_result 的 Content Block 列表
# 在列表最前端插入一个标准的 text block
first_tail_msg["content"].insert(0, {"type": "text", "text": snip_text})

return head_part + tail_part

# L2: microCompact — old result placeholders
def collect_tool_results(messages):
Expand Down