教程

工具收集

prompt 收集

claude code 逆向工程博客

参考:

  1. system_prompt

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    SYSTEM_PROMPT = """You are a helpful coding agent that assists with programming tasks and file operations.
    
    When responding to requests:
    1. Analyze what the user needs
    2. Use the minimum number of tools necessary to accomplish the task
    3. After using tools, provide a concise summary of what was done
    
    IMPORTANT: Once you've completed the requested task, STOP and provide your final response. Do not continue creating additional files or performing extra actions unless specifically asked.
    
    Examples of good behavior:
    - User: "Create a file that adds numbers" → Create ONE file, then summarize
    - User: "Create files for add and subtract" → Create ONLY those two files, then summarize
    - User: "Create math operation files" → Ask for clarification on which operations, or create a reasonable set and stop
    
    After receiving tool results:
    - If the task is complete, provide a final summary
    - Only continue with more tools if the original request is not yet fulfilled
    - Do not interpret successful tool execution as a request to do more
    
    Be concise and efficient. Complete the requested task and stop."""

构建 Agent 的要点

历史对话管理

历史数据的持久化

  • 保存历史
  • 加载历史

最大对话历史长度

因为对话历史长度的限制,需要限定 max_history_count,

messages = self.messages[max_history_count:]

ReAct tool 调用

Reason –> Action –> Observe

  • Reason: 是否/使用哪些工具
  • Action: 调用工具
  • Observe: 观察工具调用结果

工具调用

两种调用方式

Human In the loop

获取人工授权,然后执行工具调用

自动调用

要点:

  1. 注意避免死循环,需要设置 最大自动调用次数

伪代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def auto_tool_use(self, user: str, max_tool_auto_call: int):

    n = 0
    while n < max_tool_auto_call:
        # 1) 整理 messages
        messages = self.messages[max_history_count:]
        # 2) llm 调用 :::: Reason
        ret = self.llm.invode(user)

        n += 1
        # 3) 判断是否需要 tool 调用
        if "tool_use" not in ret:
            msg = ret.content
            messages.append({"role": "user", "content": user})
            messages.append({"role": "assistant", "content": msg})
            break

        # 4) 执行 tool 调用 :::: Action
        tool_calls = ret.tool_calls
        tool_results: list[dict] = self._execute__tools(tool_calls)
        # 5) 保存 tool 调用结果 :::: Observe
        self.messages.extend(
            [
                {
                    "role": "user",
                    # 注意:这里content不再是str, 而是一个 list[dict]
                    "content": [
                        {
                            "type": "tool_result",
                            "tool_use_id": t["tool_use_id"],
                            "content": t["content"],
                        }
                        for t in tool_results
                    ],
                }
            ]
        )
        # 6) 下一轮 Reasoning --> Action --> Oberve
        #    根据 tool 调用的结果判断是否已经结果问题,如果没有结果,LLM 根据需要再次触发 tool 调用
    return messages

Context Engineering

FAQ

context 污染

无效 context

  1. 通过 网络搜索获取的(召回)内容,可能和对话主题无关

    • 这种内容可能会导致对话偏离主题

Content Engineering 案例

Claude Code

参考:

Claude Code 包括了三层 context (three-layout context)

  1. 第一层: Cluade.md

    • persistent layer

      • 长期记忆
    • 在初始化一个项目任务时,Cluade 会先扫描项目的重要文件(requirements.txt, README,项目结构等等),然后创建 Cluade.md
    • 包括内容:

      • projtect convention 项目风格
      • commit 规范
      • architecture decisions
      • coding standards
      • 已经你个人规定的其他要求
  2. 第二层: dynamic layer

    • 根据用户的 query 命令,去获取项目中的相关内容来增强 context
    • 比如:用户提取修复 auth bug, 它会

      1. 查找和认证相关的文件和代码,理解代码逻辑,查找相关 codebase,比如 middleware, config, tests
      2. 扩充 context
      3. 制定修复 bug 的方案
      4. 让用户确定是否采用
  3. 第三层:conversation

    • 对话本身

      1. user query
      2. tools used
      3. content retrieved

Claude Code 如何压缩对话历史?

langchain Middleware

定义:Middleware(中间件)= Agent 执行过程中自动运行的"拦截器",在特定时机自动执行特定逻辑,对 AI 模型透明。

langchain MiddleWare Vs Tool

  • todolist 作为 middleware 实现,而不是 tool

    • https://claude.ai/share/a7ddb21d-e9c2-4276-8af9-a48190e39585
    • 如果使用 tool 实现,潜在的问题

      1. ❌ 模型可能**忘记**使用 todo 工具
      2. ❌ 模型需要**主动决定**何时添加任务
      3. ❌ 在 prompt 中占用 token(所有工具都会被列出)
      4. ❌ 没有强制规划流程
    • 使用 middleware 的好处

      1. 模型无感知
      2. 强制调用
  • 使用 middleware 实现,底层调用逻辑顺序

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    from langchain.agents import create_agent
    from langchain.agents.middleware import TodoListMiddleware
    
    # ✅ 用 Middleware 实现(自动执行)
    agent = create_agent(
    model="gpt-4o",
    tools=[search_web, send_email],  # 不需要添加 todo 工具
    middleware=[TodoListMiddleware()]
    )
    
    agent.invoke("Help me plan my day and send emails")
    ```
    
    ,**优势**
    1.  **自动执行**模型在思考前会自动更新待办
    2.  **不占用工具槽**不会在模型的工具列表中
    3.  **强制规划**系统提示会要求模型维护任务列表
    4.  **透明管理**模型无需关心实现细节
    
    ,**实际执行**
    ```
    [before_model 钩子自动触发]
    System: "Use write_todos to plan your tasks..."
    
    AI calls: write_todos([
    {content: "Search for weather", status: "pending"},
    {content: "Draft email", status: "pending"},
    {content: "Send email", status: "pending"}
    ])
    
    AI: Let me start by searching the weather...
    [执行工具]
    
    [after_model 钩子自动更新状态]
    write_todos([
    {content: "Search for weather", status: "completed"},
    {content: "Draft email", status: "in_progress"},
    ...
    ])