Harness Academy
Tài liệu gốc 10 15 phútTiếng Việt + English
docs/en/s07-memory-system.mdXem bản gốc
Ngôn ngữ bài đọc
Bản dịch tiếng Việt

Bản dịch đầy đủ theo đúng cấu trúc tài liệu; code, liên kết và định danh kỹ thuật được giữ nguyên.

s07: Hệ thống bộ nhớ

s00 > s01 > s02 > s03 > s04 > s05 > s06 > [ s07 ] > s08 > s09 > s10 > s11 > s12 > s13 > s14 > s15 > s16 > s17 > s18 > s19 > s20 > s21 > s22 > s23 > s24 > s25 > s26 > s27

Không phải mọi thứ đều thuộc về bộ nhớ; chỉ những thông tin có giá trị qua các phiên mới đáng được lưu giữ.

Chương này giải quyết vấn đề gì

Nếu một tổng đài viên bắt đầu hoàn toàn lại từ đầu trong mỗi phiên mới, thì nó sẽ tiếp tục quên những thứ như:

  • Kiểu mã nào người dùng thích
  • Những lỗi người dùng đã sửa nhiều lần
  • Các quy ước của dự án không rõ ràng ngay từ chính mã
  • Nơi có thể tìm thấy các nguồn lực bên ngoài nhất định

Điều này khiến hệ thống có cảm giác như "mọi tương tác đều là cuộc gặp gỡ đầu tiên".

Đó là lý do tại sao bộ nhớ là cần thiết.

Nhưng trước tiên, một ranh giới: bộ nhớ không phải để lưu trữ mọi thứ

Đây là nơi chương này dễ bị lạc lối nhất.

Trí nhớ không phải là "ghi lại mọi thứ hữu ích". Nếu bạn làm điều đó, hai vấn đề sẽ xuất hiện nhanh chóng:

  1. Trí nhớ trở thành ngăn kéo rác, ngày càng lộn xộn theo thời gian
  2. agent bắt đầu dựa vào những ký ức cũ thay vì đọc sự thật cơ bản hiện tại

Vì vậy chương này trước tiên phải thiết lập một nguyên tắc:

Chỉ những thông tin còn giá trị qua các phiên và không thể dễ dàng suy ra từ trạng thái dự án hiện tại mới được lưu trữ trong bộ nhớ.

MEMORY.md so với USER.md

Giải thích các thuật ngữ chính

NHỚ.md là gì

Sổ ghi chép làm việc của agent. Khi được đưa vào dấu nhắc hệ thống, nó sẽ có tiêu đề:

MEMORY (your personal notes) [62% -- 1,364/2,200 chars]

Nó lưu trữ thông tin mà agent đã học được trong quá trình làm việc về môi trường và dự án. Không phải về người dùng là ai mà là về "môi trường làm việc này trông như thế nào".

Ví dụ cụ thể:

$ Project uses pytest, not unittest. Run tests with pytest -x for fail-fast
$ This machine is macOS ARM; Homebrew path is /opt/homebrew
$ Auth module rewrite is driven by compliance, not tech debt
$ CI config is at .github/workflows/ci.yml; must pass lint before merge
$ Do not use asyncio.run(); this project has a persistent event loop, use bridge_async()

Trong một câu: MEMORY.md ghi lại "cách hoạt động của dự án/môi trường này."

NGƯỜI DÙNG.md là gì

Hồ sơ người dùng. Khi được đưa vào dấu nhắc hệ thống, nó sẽ có tiêu đề:

USER PROFILE (who the user is) [48% -- 660/1,375 chars]

Nó lưu trữ thông tin mà agent đã tìm hiểu được về cá nhân người dùng. Không phải về dự án mà là về "người này là ai, họ thích gì và họ không thích gì".

Ví dụ cụ thể:

$ Name is Zhang San, backend engineer, 10 years of Go, 2 years of Python
$ Hates mock tests -- last time mocks diverged from production and caused an outage
$ Keep answers concise; do not add a summary of what was just done at the end
$ Prefers tabs for indentation, snake_case for variables
$ Timezone UTC+8, typical working hours 10:00-22:00

Trong một câu: USER.md ghi lại "người này là ai và làm thế nào để cộng tác với họ một cách suôn sẻ."

Tại sao hai tập tin riêng biệt

Trong mã nguồn, cả hai tệp đều được vận hành thông qua cùng một memory công cụ, được phân biệt bởi target tham số:

# Write to MEMORY.md
memory(action="add", target="memory", content="Project uses pytest for testing")

# Write to USER.md
memory(action="add", target="user", content="User prefers tabs for indentation")

Lý do cốt lõi của việc chia tách là các vòng đời khác nhau:

BỘ NHỚ.mdNGƯỜI DÙNG.md
Về aiDự án và môi trườngCá nhân người dùng
Giới hạn ký tự2.2001.375
Khi chuyển đổi dự ánChủ yếu cần phải được xây dựng lạiTái sử dụng trực tiếp
Khi chuyển đổi người dùngHầu hết vẫn hữu íchCần được xây dựng lại

Ví dụ: khi bạn chuyển từ Dự án A sang Dự án B, các mục nhập USER.md như "người dùng thích tab" và "giữ câu trả lời ngắn gọn" vẫn được giữ nguyên. Nhưng các mục MEMORY.md như "dự án sử dụng pytest" có thể sai -- dự án mới sử dụng vitest.

Hệ thống hồ sơ agent Hermes (s11) cung cấp cho mỗi hồ sơ riêng memories/ thư mục, vì vậy cả hai tập tin có thể độc lập khi chuyển đổi cấu hình.

Một quy tắc đơn giản để quyết định sử dụng tập tin nào

Hãy tự hỏi: "Nếu tôi chuyển sang một dự án hoàn toàn khác, liệu thông tin này có còn hữu ích không?"

  • Yes -> USER.md (vì nó mô tả người dùng chứ không phải dự án)
  • Không -> MEMORY.md (vì nó mô tả môi trường hiện tại)

Trường hợp cạnh: "Người dùng ghét các bài kiểm tra giả" -> lưu trữ trong USER.md. Mặc dù nó liên quan đến thử nghiệm nhưng nó mô tả ưu tiên của người dùng được áp dụng bất kể dự án.

"ảnh chụp nhanh bị đóng băng" là gì

agent Hermes đọc MEMORY.md và USER.md khi bắt đầu phiên và đóng băng chúng như một phần của lời nhắc hệ thống.

Những thay đổi vào bộ nhớ giữa phiên được ghi vào đĩa ngay lập tức, nhưng chúng không làm thay đổi lời nhắc hệ thống của phiên hiện tại.

Tại sao? Bởi vì việc thay đổi lời nhắc hệ thống sẽ phá vỡ bộ đệm nhắc nhở của Anthropic. Những ký ức mới có hiệu lực khi phiên tiếp theo bắt đầu.

Những gì nên lưu trữ và những gì không nên lưu trữ

Điều này quan trọng hơn “làm thế nào để thực hiện nó”.

Lưu trữ những gì

LoạiVí dụ
Sở thích của người dùng"Ưu tiên các tab thụt lề," "Giữ câu trả lời ngắn gọn"
Chỉnh sửa của người dùng"Không giả lập cơ sở dữ liệu; hãy sử dụng cơ sở dữ liệu thử nghiệm thực"
Công ước dự án"Việc viết lại xác thực được thúc đẩy bởi sự tuân thủ chứ không phải nợ công nghệ"
Nguồn lực bên ngoài"Theo dõi lỗi nằm trong dự án INGEST trên Linear"

Những gì KHÔNG nên lưu trữ

Không lưu trữTại sao
Cấu trúc file, chữ ký hàm, bố cục thư mụcCó thể được khám phá lại bằng cách đọc mã
Tiến độ nhiệm vụ hiện tạiĐây là nhiệm vụ/kế hoạch, không phải ký ức
Tên chi nhánh hiện tại, số PR hiện tạiĐi cũ nhanh chóng
Mã cụ thể để sửa lỗiMã và lịch sử cam kết là nguồn chính xác
Bí mật, mật khẩuRủi ro bảo mật

Ranh giới này phải được giữ vững. Nếu không, bộ nhớ sẽ chuyển từ "giúp hệ thống thông minh hơn theo thời gian" sang "giúp hệ thống bị ảo giác theo thời gian".

Mô hình tinh thần tối thiểu

Session 1: User says "I hate mock tests"
   |
   v
Agent calls the memory tool, writes to MEMORY.md
   |
   v
Session ends; MEMORY.md is on disk

------ time passes ------

Session 2 starts
   |
   v
Read MEMORY.md -> freeze as part of the system prompt
   |
   v
Agent knows not to use mocks -> writes real tests directly

Điểm mấu chốt: Việc ghi được thực hiện ngay lập tức (đĩa), nhưng hiệu lực sẽ bị trì hoãn (phiên tiếp theo). Thiết kế này bảo vệ bộ nhớ đệm nhanh chóng.

Cấu trúc dữ liệu chính

1. Nhập bộ nhớ

Bộ nhớ của agent Hermes không phải là một cơ sở dữ liệu có cấu trúc. Nó chỉ đơn giản là các mục trong một tệp đánh dấu, được phân cách bằng $:

$ User prefers tabs over spaces for indentation
$ Project uses pytest, not unittest. Run with `pytest -x` for fail-fast
$ Auth rewrite is driven by legal/compliance, not tech debt

Mỗi mục là một câu hoặc đoạn văn ngắn. Đơn giản, dễ đọc và có thể đọc/ghi trực tiếp bởi agent.

2. Giới hạn ký tự

MEMORY.md mặc định có tối đa 2200 ký tự. USER.md mặc định có tối đa 1375 ký tự.

Sao chặt thế? Bởi vì bộ nhớ được đưa vào dấu nhắc hệ thống cho mỗi phiên. Nếu bộ nhớ phát triển không giới hạn, nó sẽ chiếm ngày càng nhiều cửa sổ ngữ cảnh.

Khi sắp hết dung lượng, nhân viên phải quyết định loại bỏ các mục cũ nào để nhường chỗ. Điều này buộc agent phải giữ bộ nhớ ngắn gọn.

3. Ảnh chụp nhanh đông lạnh

snapshot = {
    "memory": "$ User prefers tabs...\n$ Project uses pytest...",
    "user": "$ Senior engineer, prefers concise answers...",
}

Được tạo khi phiên bắt đầu và không bao giờ thay đổi sau đó. Cuộc gọi công cụ trả về trạng thái thời gian thực từ đĩa, nhưng lời nhắc hệ thống sử dụng ảnh chụp nhanh bị đóng băng.

Thực hiện tối thiểu

Bước 1: Xác định định dạng lưu trữ

ENTRY_DELIMITER = "$"

def parse_entries(text):
    return [e.strip() for e in text.split(ENTRY_DELIMITER) if e.strip()]

def render_entries(entries):
    return "\n".join(f"{ENTRY_DELIMITER} {e}" for e in entries)

Bước 2: Đọc và ghi vào đĩa

def load_memory(path):
    if not path.exists():
        return []
    return parse_entries(path.read_text())

def save_memory(path, entries):
    path.write_text(render_entries(entries))

Bước 3: Cung cấp công cụ bộ nhớ

Thông số tối thiểu: action (thêm/thay thế/xóa/đọc) + content.

def handle_memory(action, content=None, target="memory"):
    entries = load_memory(path_for(target))
    
    if action == "add":
        entries.append(content)
        # If over the character limit, require the agent to clean up
        save_memory(path_for(target), entries)
        return f"Added. {len(entries)} entries, {char_count} chars."
    
    if action == "remove":
        # Use substring matching to find the entry to delete
        entries = [e for e in entries if content not in e]
        save_memory(path_for(target), entries)
        return f"Removed. {len(entries)} entries remaining."
    
    if action == "read":
        return render_entries(entries)

Bước 4: Đóng băng ảnh chụp nhanh khi phiên bắt đầu

# Inside _build_system_prompt()
memory_block = memory_store.format_for_system_prompt("memory")
user_block = memory_store.format_for_system_prompt("user")
if memory_block:
    prompt_parts.append(memory_block)
if user_block:
    prompt_parts.append(user_block)

Bước này kết nối với s04 (lắp ráp prompt). Bộ nhớ là một trong những nguồn cho lời nhắc hệ thống.

Lựa chọn thiết kế độc đáo của agent Hermes tại đây

1. Ảnh chụp nhanh đông lạnh + đĩa thời gian thực

Hầu hết bộ nhớ của agent đều có hiệu lực ngay sau khi sửa đổi. agent Hermes cố tình tách ra hai lớp:

  • Ghi đĩa ngay lập tức (bền)
  • Hệ thống nhắc nhở bị đóng băng (ổn định)

Điều này là dành cho bộ nhớ đệm nhanh chóng. Nếu lời nhắc hệ thống được cập nhật mỗi khi bộ nhớ thay đổi, tiền tố bộ đệm của Anthropic sẽ bị vô hiệu và lời nhắc đầy đủ sẽ cần được gửi lại trong mỗi lệnh gọi API.

2. Khóa tập tin

Trong trường hợp Cổng, nhiều phiên có thể ghi đồng thời vào MEMORY.md. agent Hermes sử dụng khóa tập tin (fcntl.flock) để đảm bảo tính nguyên tử.

3. Nhà cung cấp bộ nhớ ngoài

Ngoài MEMORY.md / USER.md tích hợp sẵn, Hermes Agent còn hỗ trợ cắm các nhà cung cấp bộ nhớ ngoài (chẳng hạn như cơ sở dữ liệu vectơ) thông qua plugin.

Nội dung bộ nhớ ngoài không đi vào dấu nhắc hệ thống (điều đó sẽ làm hỏng bộ nhớ đệm). Thay vào đó, nó được đưa vào tin nhắn của người dùng. Điều này giúp lời nhắc hệ thống ổn định trong khi nội dung động của bộ nhớ ngoài có một đường dẫn riêng.

4. Nhắc nhở bộ nhớ định kỳ (hai cơ chế kích hoạt)

Hermes Agent có hai cơ chế kích hoạt bộ nhớ độc lập nhằm giải quyết các tình huống khác nhau:

Cơ chế A: Đánh giá lý lịch định kỳ (thúc đẩy)

self._memory_nudge_interval = 10   # Trigger every 10 user turns by default
self._turns_since_memory = 0       # Counter

Mỗi khi người dùng gửi tin nhắn, bộ đếm sẽ tăng thêm 1. Khi đạt đến nudge_interval:

User turn 1 -> counter 1
User turn 2 -> counter 2
...
User turn 10 -> counter 10 -> triggered! Counter resets to zero

Sau khi kích hoạt, hệ thống sẽ tạo một "agent đánh giá" độc lập trong chuỗi nền sau khi phản hồi đã được trả lại cho người dùng:

# In the background thread
review_agent = AIAgent(
    model=self.model,
    max_iterations=8,       # Only 8 turns; a quick review
    quiet_mode=True,        # Completely silent; no user-visible output
)
review_agent._memory_store = self._memory_store    # Shares the same memory store
review_agent._memory_nudge_interval = 0            # Review agent does not trigger nudges itself

review_agent.run_conversation(
    user_message=MEMORY_REVIEW_PROMPT,              # Review prompt
    conversation_history=messages_snapshot,          # Snapshot of the current conversation
)

Lời nhắc đánh giá trông như thế này:

Review the conversation above and consider saving to memory if appropriate.

Focus on:
1. Has the user revealed things about themselves -- their persona, desires,
   preferences, or personal details worth remembering?
2. Has the user expressed expectations about how you should behave, their
   work style, or ways they want you to operate?

If something stands out, save it using the memory tool.
If nothing is worth saving, just say 'Nothing to save.' and stop.

Các quyết định thiết kế chính:

  • Chạy sau phản hồi -- không cạnh tranh với nhiệm vụ chính của người dùng để thu hút sự chú ý của model
  • agent độc lập -- stdout/stderr được chuyển hướng đến /dev/null; hoàn toàn vô hình với người dùng
  • repository bộ nhớ dùng chung -- bộ nhớ do agent đánh giá ghi sẽ được lưu vào đĩa ngay lập tức
  • Giới hạn ở 8 lượt -- đánh giá là quét nhanh, không phải phân tích sâu

Cơ chế B: Xả khẩn cấp trước khi nén

Khi một cuộc trò chuyện sắp bị nén (s05) hoặc phiên sắp được đặt lại, hệ thống thực hiện "lưu bộ nhớ khẩn cấp":

self._memory_flush_min_turns = 6   # Only trigger flush after at least 6 user turns

Thao tác nhắc nhở hoạt động khác với nhắc nhở -- đó không phải là đánh giá cơ bản mà là thông báo được đưa trực tiếp vào cuộc trò chuyện hiện tại:

flush_content = (
    "[System: The session is being compressed. "
    "Save anything worth remembering -- prioritize user preferences, "
    "corrections, and recurring patterns over task-specific details.]"
)

Sau khi nhìn thấy thông báo này, mô hình sẽ gọi trực tiếp công cụ bộ nhớ trong ngữ cảnh hiện tại để lưu thông tin. Sau khi lưu xong, hệ thống sẽ xóa tất cả các thông báo liên quan đến xóa khỏi lịch sử (không để lại dấu vết).

Phân công lao động giữa hai cơ chế

Cú huých định kỳXả nén trước
Khi được kích hoạtMỗi N người dùng quayTrước khi nén/đặt lại phiên
Nó chạy như thế nàoChủ đề nền, agent độc lậpCuộc trò chuyện hiện tại, tin nhắn được chèn
Nhận thức của người dùngHoàn toàn vô hìnhHoàn toàn vô hình (tin nhắn bị xóa sau)
Ngưỡng mặc định10 lượt6 lượt
Mục đíchTích lũy thường xuyênCơ hội cuối cùng để ngăn ngừa mất mát
Phím cấu hìnhmemory.nudge_intervalmemory.flush_min_turns

Ranh giới giữa bộ nhớ, phiên, SOUL.md và HERMES.md

trí nhớphiênSOUL.mdHERMES.md
Nó là gìKiến thức được tuyển chọn qua các buổi họcBản ghi đầy đủ của một cuộc trò chuyệnĐịnh nghĩa cá tínhQuy tắc dự án
Ai viết nóagentHệ thống (tự động)Người dùngNhà phát triển
Tần suất thay đổiThường xuyênMọi cuộc trò chuyệnHiếmĐã sửa cho mỗi dự án
Kích thướcNhỏ (có giới hạn)Lớn (toàn bộ lịch sử)NhỏTrung bình

Những lỗi thường gặp của người mới bắt đầu

1. Lưu cấu trúc mã vào bộ nhớ

"Dự án này có src/ và test/" -- không được lưu trữ; hệ thống có thể đọc lại hệ thống tập tin.

2. Lưu tiến độ công việc hiện tại vào bộ nhớ

"Tôi hiện đang sửa đổi mô-đun xác thực" -- đây là nhiệm vụ/kế hoạch, không phải bộ nhớ.

3. Coi ký ức là sự thật tuyệt đối

Bộ nhớ có thể trở nên cũ kỹ. Sử dụng nó để định hướng chứ không phải để thay thế cho việc quan sát hiện tại. Nếu bộ nhớ xung đột với mã hiện tại, hãy tin vào sự thật cơ bản trước mặt bạn.

4. Không đặt giới hạn ký tự

Nếu bộ nhớ tăng lên không giới hạn, dấu nhắc hệ thống sẽ tiếp tục mở rộng và chiếm hết cửa sổ ngữ cảnh.

5. Mong đợi những thay đổi bộ nhớ giữa phiên sẽ có hiệu lực ngay lập tức

Theo mô hình ảnh chụp nhanh cố định, các thay đổi sẽ có hiệu lực trong phiên tiếp theo. Đây là do thiết kế, không phải lỗi.

Ranh giới giảng dạy

Điều quan trọng nhất trong chương này không phải là bộ nhớ tự động hay tinh vi cuối cùng có thể trở thành như thế nào, mà trước hết là thiết lập ranh giới lưu trữ rõ ràng:

  • Điều gì đáng lưu giữ qua các phiên
  • Điều gì chỉ là trạng thái nhiệm vụ hiện tại và không được đưa vào bộ nhớ
  • Mỗi bộ nhớ, phiên, SOUL.md và HERMES.md chịu trách nhiệm gì

Trì hoãn có chủ ý: kiến trúc plugin đầy đủ cho các nhà cung cấp bộ nhớ ngoài, tích hợp cơ sở dữ liệu vector, chiến lược hợp nhất bộ nhớ tự động và chống trùng lặp.

Nếu người đọc có thể yêu cầu agent "ghi nhớ các tùy chọn của người dùng từ phiên trước khi bắt đầu phiên mới", thì chương này đã đạt được mục tiêu.

Sau khi kết thúc chương này, bạn sẽ có thể trả lời

  • Tại sao bộ nhớ không nên lưu trữ "mọi thứ"?
  • Tại sao MEMORY.md và USER.md được giữ riêng biệt?
  • Loại thông tin nào thích hợp cho việc lưu trữ chéo phiên? Cái gì không phải?
  • Tại sao những thay đổi bộ nhớ giữa phiên không ảnh hưởng ngay đến lời nhắc hệ thống?
  • Ranh giới giữa bộ nhớ, phiên, SOUL.md và HERMES.md là gì?

Một dòng cần nhớ: Bộ nhớ lưu trữ thông tin "có thể vẫn có giá trị trong tương lai nhưng không thể dễ dàng lấy lại từ cơ sở mã hiện tại." Hermes Agent sử dụng các ảnh chụp nhanh bị đóng băng để bảo vệ bộ đệm nhắc nhở -- việc ghi được thực hiện ngay lập tức nhưng có hiệu lực khi có độ trễ.

Mục lục nguồn