Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

s09: select_relevant_memories 的 "recent" 拼接顺序与切片不合理,不是真正的最近 2k 上下文

オープン 初心者向け
#517 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 15 日以内に返信

@siri666942 がすでに取り組んでいます。

2026年8月13日 から。

  • #518 @siri666942 による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
python
領域
ai

調査の方向性

s09_memory/code.py の recent_user_text から始め、特に 251-261 行を確認し、ユーザーメッセージがどのように収集され、結合され、切り出されているかを調べます。短い場合と長い場合の直近のターンで、選択した挙動を検証します。返されるコンテキストが時系列順を維持し、直近 4000 文字の末尾を含んでいれば完了です。

索引モデルが issue の本文から書いたものです。

説明

问题

s09_memory/code.py:251-261 recent_user_text returns a string claiming to be the most recent user context, but the join + slice order produces an unintuitive result.

def recent_user_text(messages: list, max_turns: int = 3) -> str:
    turns = []
    for message in reversed(messages):
        if message.get("role") != "user":
            continue
        text = message_text(message).strip()
        if text:
            turns.append(text)
        if len(turns) == max_turns:
            break
    return "\n".join(reversed(turns))[:4000]

Actual behavior

  1. reversed(messages) walks backwards; turns accumulates up to max_turns=3 user texts in turns = [latest, prev, prev2] order.
  2. reversed(turns) then flips it back to [prev2, prev, latest].
  3. Joined with \n, sliced to head 4000 chars.

Consequences:

  • If the latest user turn is short (e.g. "ok"), the head-4000 fills with older turns and the latest one is pushed past the slice window — the most relevant signal is dropped.
  • If the latest turn is long, older turns are pushed out entirely and the function degrades to "use only the latest turn" — but that intent is not expressed in the code.
  • The function is named recent_user_text but the implementation is "oldest of the recent few, then head-slice". Order is non-obvious.

Expected behavior

recent_user_text should mean "the last N characters of the most recent user context, in chronological order". A minimal fix:

def recent_user_text(messages: list, max_chars: int = 4000) -> str:
    chunks = []
    for message in messages:
        if message.get("role") != "user":
            continue
        text = message_text(message).strip()
        if text:
            chunks.append(text)
    joined = "\n".join(chunks)
    return joined[-max_chars:] if len(joined) > max_chars else joined

Or, if preserving the per-turn walk is desired, take only the tail of the result rather than the head:

result = "\n".join(reversed(turns))
return result[-4000:] if len(result) > 4000 else result

Either is fine — the important thing is that the slice direction matches the name: "recent" means tail, not head.


中文版本

问题

s09_memory/code.py:251-261 recent_user_text 的字面意思虽然是"最近的用户文本",但 join + 切片的顺序让它产出一个反直觉的结果。

```python
def recent_user_text(messages: list, max_turns: int = 3) -> str:
turns = []
for message in reversed(messages):
if message.get("role") != "user":
continue
text = message_text(message).strip()
if text:
turns.append(text)
if len(turns) == max_turns:
break
return "\n".join(reversed(turns))[:4000]
```

实际行为
  1. `reversed(messages)` 从末尾向前扫描,收集最多 3 条 user 文本,此时 `turns` 顺序为 `[最新, 次新, 更旧]`。
  2. `reversed(turns)` 又翻回 `[更旧, 次新, 最新]`。
  3. 用 `\n` 拼接后取头 4000 字符。

带来的问题:

  • 如果最新那条很短(比如 "ok"),头 4000 字符会被更旧的消息灌满,最新那条反而被切掉——最该被命中的信号反而丢
  • 如果最新那条够长,前面的消息直接被挤出窗口,函数退化成"只用最新一条"——这个意图代码里没体现
  • 函数名叫 `recent_user_text`,实现却是"最近几条里最旧的先出现 + 头切",顺序含义不明
期望行为

`recent_user_text` 应该是"按时间正序排列后,取末尾 N 个字符"。最小修复:

```python
def recent_user_text(messages: list, max_chars: int = 4000) -> str:
chunks = []
for message in messages:
if message.get("role") != "user":
continue
text = message_text(message).strip()
if text:
chunks.append(text)
joined = "\n".join(chunks)
return joined[-max_chars:] if len(joined) > max_chars else joined
```

或者保留逐条遍历的写法,但把切片方向反过来:

```python
result = "\n".join(reversed(turns))
return result[-4000:] if len(result) > 4000 else result
```

任选其一即可,关键是切片方向跟函数名一致——"recent" 是尾部,不是头部。

主要言語
Python
スター
79.5k
フォーク
12.7k
平均マージ
11日 19時間
マージ済み PR(30日)
5

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

shareAI-lab/learn-claude-code のほかの issue

shareAI-lab/learn-claude-code の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。