Claude Code

关注公众号 jb51net

关闭
AI > Claude Code >

Qwen3.6-27B 本地私有化部署 + Claude Code 连接应用

小毕超

一、Qwen3.6-27B + Claude Code

Qwen3.6-27B 是阿里于 20264 月开源的多模态大模型,在主流智能体编程基准上取得了显著突破,全面超越前代旗舰 Qwen3.5-397B-A17B,参数量仅为其约 1/15,甚至在一些指标上和 Claude 4.5 Opus 相持平。

这里未展示出全部测评结果,更多介绍可以关注官方博客:

https://qwen.ai/blog?id=qwen3.6-27b

从上面的指标结果可以看出,Qwen3.6-27B 相比与上一代的 Qwen3.5-27B,在编程能力上有了大的飞跃,平常我们使用 Claude Code 做任务开发的时候,通常会消耗巨大的 Token 量,如果将一些常用重复性的开发任务使用本地私有化部署的 Qwen3.6-27B 来开发的话,是不是可以节省一些 Token 的使用量,而且还可以提高响应速度提高处理效率。再或者使用一些在线能力较强的模型,构建开发架构,使用 Qwen3.6-27B 来补充架子里面的具体实现,最后让能力强的模型验收结果,从而减少收费模型的输出量,毕竟收费模型的 output tokens 定价一般都比 input tokens 要贵,这样也可以实现优化开发成本和提升效率双丰收的结果。

因此本文主要介绍 Qwen3.6-27B 的本地私有化部署过程,部署采用vLLM 引擎,以及将 Claude Code 指向使用私有化部署的模型,并且开发一个五子棋的网页小游戏,以及针对开源项目 DeerFlow 2.0 进行源码分析的实践。

下面是本次实验主要的依赖版本:

torch==2.10.0
vllm>=0.17.0
transformers==4.57.6
modelscope==1.34.0

其中由于Claude Code 默认使用的 Anthropic 协议 ,vLLM0.17.0 版本才集成了 Anthropic 协议,因此 vLLM 的版本必须大于等于 v0.17.0

二、vLLM 私有化部署 Qwen3.6-27B

安装 vLLM,并且自动安装对应的 torch

uv pip install "vllm>=0.17.0" --torch-backend=auto --extra-index-url https://wheels.vllm.ai/nightly

下载 Qwen3.6-27B 模型,这里使用 modelscope 快速下载到本地:

modelscope download --model="Qwen/Qwen3.6-27B" --local_dir Qwen3.6-27B

使用 vLLM 启动 API 服务:

export CUDA_VISIBLE_DEVICES=0,1
vllm serve "Qwen3.6-27B" \
  --host 0.0.0.0 \
  --port 8000 \
  --dtype bfloat16 \
  --tensor-parallel-size 2 \
  --gpu-memory-utilization 0.8 \
  --api-key token-abc123 \
  --enable-prefix-caching \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_coder \
  --trust-remote-code

关键参数说明:

参数说明
export CUDA_VISIBLE_DEVICES=0,1指定使用的GPU设备,根据实际的GPU数量,这里我有两块GPU
dtype数据类型,其中 bfloat1616位浮点数
tensor-parallel-sizeTensor 并行的数量,当多 GPU 分布式推理时使用,建议和GPU的数量一致
gpu-memory-utilization设置 GPU 内存利用率的上限
api-keyAPI 认证密钥
enable-prefix-caching启用前缀缓存减少重复计算
reasoning-parser指定推理解析器
enable-auto-tool-choice启用自动工具选择
tool-call-parser工具调用解析器

启动后显存占用情况:

如果启动显存不足,可根据实际设备情况调整 gpu-memory-utilization 或者添加 max-model-len 参数,或通过 cpu-offload-gb 将部分模型权重卸载到内存中(影响运行效率)。

访问测试:

curl http://127.0.0.1:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
	-H "Authorization: Bearer token-abc123" \
    -d '{
        "model": "Qwen3.6-27B",
        "messages": [
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "你是谁,你认识小毕超吗?"}
        ]
    }'

运行结果:

使用 Anthropic 协议测试:

curl http://127.0.0.1:8000/v1/messages \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer token-abc123" \
    -d '{
        "model": "Qwen3.6-27B",
        "system": "You are a helpful assistant.",
        "messages": [
            {"role": "user", "content": "你是谁,你认识小毕超吗?"}
        ],
        "max_tokens": 1024
    }'

运行结果:

三、Claude Code 安装及配置私有化模型

3.1 安装 Claude Code

请提前安装好 Node 环境,版本最好 Node >=22

安装官方组件:

npm install -g @anthropic-ai/claude-code

安装好后,先输入 claude 看是否能正常进入cli

claude 

如果提示 Claude Code might not be available in your country ,可以在当前电脑用户目录下,找到 .claude.json 文件,在该文件中加入 "hasCompletedOnboarding": true 配置:

然后重新在控制台重新输入 claude 测试是否正常:

如果出现上述效果,则表示部署正常。

3.2 配置模型

cmd 控制中输入如下指令,配置系统环境变量:

setx ANTHROPIC_BASE_URL "http://127.0.0.1:8000"
setx ANTHROPIC_AUTH_TOKEN "token-abc123"
setx ANTHROPIC_MODEL "Qwen3.6-27B"
setx ANTHROPIC_SMALL_FAST_MODEL "Qwen3.6-27B"

然后最好关掉当前 cmd,重新打开cmd 进入 claude,测试连接是否正常:

如果看到使用的是 Qwen3.6-27B 模型,并且可以正常回答,就表示环境配置成功。

四、应用实践

4.1 开发一个H5五子棋小游戏

输入提示:

在当前根目录下创建一个H5五子棋游戏,单个HTML文件实现,包含:
- 15x15棋盘,黑白双方轮流落子
- 判断胜负(五子连珠)
- 显示当前回合和胜利提示
- 重新开始按钮
- 界面简洁美观

运行效果:

运行一切正常,并且所提需求均实现。

4.2 解读 DeerFlow2.0 源码设计过程

DeerFlow 2.0 是一个非常优秀的开源 Harness Agent 项目,这里让 Claude Code 分析其源码设计过程:

拉取项目:

git clone https://github.com/bytedance/deer-flow.git

然后进入项目中唤醒 claude, 首先使用 /init 指令,让 claude 了解下当前项目,并生成 Claude.md

/init

Claude.md 内容:

这里如果是我们自己的项目,可能就要看下 Claude.md 中梳理的具体内容了,判断内容是否完善,以及补充一些关键知识,这里主要让Claude分析其设计思路,这里不做任何修改,下面直接请 claude 帮助分析智能体的设计过程,输入提示:

请帮我分析这个项目的源码架构,我想了解:
1. Agent 的整体设计架构和核心模块划分。
2. Agent 的初始化和启动流程。
3. Agent 的任务接收、调度和执行的完整链路。
4. Agent 的状态管理和生命周期设计。
最后请将分析结果写入“设计过程.md”文件中。

分析结束,分析的结果不亚于收费模型!

以下是分析过程,其中为了方便展示 ```符号均替换为 ``:

# DeerFlow Agent 源码架构分析
## 一、整体设计架构和核心模块划分
DeerFlow 是一个基于 LangGraph 构建的 AI "超级代理"系统。其核心设计理念是:**一个 Lead Agent(主代理)作为任务编排器,可动态分解任务、派生 Sub-Agent(子代理),在隔离的沙箱环境中执行复杂的多步骤工作。**
### 1.1 系统层级架构
``
┌─────────────────────────────────────────────────────────────────┐
│                        接入层                                     │
│   Nginx (:2026) → Frontend(:3000) / Gateway(:8001) / LangGraph(:2024) │
├─────────────────────────────────────────────────────────────────┤
│                       应用层                                      │
│                                                                 │
│  ┌──────────────┐   ┌──────────────┐   ┌────────────────────┐  │
│  │ LangGraph    │   │ Gateway API  │   │ DeerFlowClient     │  │
│  │ Server       │   │ (FastAPI)    │   │ (嵌入式 Python 客户端)│  │
│  │ (:2024)      │   │ (:8001)      │   │                    │  │
│  └──────┬───────┘   └──────────────┘   └────────────────────┘  │
│         │                                                       │
│         ▼  (两者共享同一套 src/ 模块)                              │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                   Agent 核心层                            │    │
│  │                                                          │    │
│  │  ┌─────────────┐  ┌──────────────┐  ┌────────────────┐ │    │
│  │  │ Lead Agent  │  │ Middleware   │  │ Subagent       │ │    │
│  │  │ (主代理)     │──│ Chain (11个) │  │ System (子代理) │ │    │
│  │  └──────┬──────┘  └──────────────┘  └────────┬───────┘ │    │
│  │         │                                    │         │    │
│  │         ▼  ── 核心基础设施 ──                  ▼         │    │
│  │                                                          │    │
│  │  ┌──────────┐ ┌──────────┐ ┌───────┐ ┌──────────────┐  │    │
│  │  │ Sandbox  │ │  Tools   │ │ MCP   │ │ Skills System│  │    │
│  │  │ (沙箱)    │ │ (工具集)  │ │(外部) │ │ (技能系统)    │  │    │
│  │  └──────────┘ └──────────┘ └───────┘ └──────────────┘  │    │
│  │                                                          │    │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐                 │    │
│  │  │ Memory   │ │ Model    │ │Config    │                 │    │
│  │  │ (记忆)   │ │ Factory  │ │(配置)    │                 │    │
│  │  └──────────┘ └──────────┘ └──────────┘                 │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
``
### 1.2 核心模块划分
| 模块 | 路径 | 职责 |
|------|------|------|
| **Lead Agent** | `src/agents/lead_agent/` | 主代理工厂函数 + 动态系统提示词生成 |
| **Thread State** | `src/agents/thread_state.py` | 代理状态模式定义(继承 AgentState) |
| **Middleware** | `src/agents/middlewares/` | 11 个中间件,负责沙箱、记忆、标题、澄清等横切关注点 |
| **Memory** | `src/agents/memory/` | 跨会话持久记忆(事实提取、去抖队列、原子写入) |
| **Sandbox** | `src/sandbox/` | 沙箱执行系统(本地/Docker 两种实现 + 虚拟路径映射) |
| **Subagent** | `src/subagents/` | 子代理系统(注册表、双线程池执行引擎、超时控制) |
| **Tools** | `src/tools/` + `src/community/` | 工具装配(内置 + 沙箱 + MCP + 社区工具) |
| **MCP** | `src/mcp/` | Model Context Protocol 集成(懒加载、缓存、OAuth) |
| **Skills** | `src/skills/` | 技能发现、加载、解析(SKILL.md 渐进式加载) |
| **Model Factory** | `src/models/` | 模型工厂(thinking/vision 支持、动态反射创建) |
| **Config** | `src/config/` | 配置系统(config.yaml + extensions_config.json) |
| **Gateway** | `src/gateway/` | FastAPI 网关(models/skills/memory/uploads/artifacts/agents 路由) |
| **Client** | `src/client.py` | 嵌入式 Python 客户端(无需 HTTP 服务,直接调用 Agent) |
---
## 二、Agent 的初始化和启动流程
DeerFlow 的 Agent 初始化有两条路径:**LangGraph Server 路径**(HTTP 服务)和 **嵌入式 Client 路径**(纯 Python)。两者最终调用相同的 `make_lead_agent` 工厂函数。
### 2.1 LangGraph Server 路径
``
启动命令: uv run langgraph dev
                    │
                    ▼
           ┌─────────────────┐
           │ 读取 langgraph.json │
           │ graphs.lead_agent  │
           │ → src.agents:     │
           │   make_lead_agent  │
           └────────┬──────────┘
                    │
           LangGraph CLI 在收到
           第一个请求时懒调用该工厂函数
                    │
                    ▼
``
`langgraph.json` 配置:
``json
{
  "graphs": {
    "lead_agent": "src.agents:make_lead_agent"
  }
}
``
### 2.2 嵌入式 Client 路径
``
DeerFlowClient()
    │
    ▼  _ensure_agent(config)
    │
    ├── 创建 Model: create_chat_model()
    ├── 获取 Tools: get_available_tools()
    ├── 构建 Middleware: _build_middlewares()
    ├── 生成 Prompt: apply_prompt_template()
    └── 调用 LangChain: create_agent(...)
``
### 2.3 make_lead_agent 工厂函数详解
入口文件:`src/agents/lead_agent/agent.py:254`
``
make_lead_agent(config: RunnableConfig)
│
├── 1. 解析运行时参数 (从 config.configurable)
│   ├── thinking_enabled      → 是否启用扩展思考
│   ├── reasoning_effort      → 推理力度
│   ├── model_name / model    → 指定模型
│   ├── is_plan_mode          → 启用 TodoList
│   ├── subagent_enabled      → 启用子代理
│   ├── max_concurrent_subagents → 并发子代理上限
│   ├── is_bootstrap          → 启动引导模式
│   └── agent_name            → 自定义代理名
│
├── 2. 模型解析 (_resolve_model_name)
│   ├── 优先使用请求中指定的 model_name
│   ├── 其次使用 agent_config.model (自定义代理)
│   └── 回退到 config.yaml 中第一个模型
│
├── 3. 创建 LLM 实例 (create_chat_model)
│   ├── 根据 supports_thinking 决定是否启用思考模式
│   └── 根据 supports_reasoning_effort 注入推理力度参数
│
├── 4. 组装工具集 (get_available_tools)
│   ├── config.yaml 中定义的工具 (通过反射解析)
│   ├── MCP 工具 (懒加载 + mtime 缓存失效)
│   ├── 内置工具 (present_files, ask_clarification, view_image)
│   └── 子代理工具 (task, 仅在 subagent_enabled=True 时)
│
├── 5. 构建中间件链 (_build_middlewares) ← 见下方中间件链
│
├── 6. 生成系统提示词 (apply_prompt_template)
│   ├── 注入 Agent 角色和灵魂 (SOUL.md)
│   ├── 注入记忆上下文 (memory.json)
│   ├── 注入可用技能列表 (skills/)
│   ├── 注入子代理系统指令 (subagent_enabled 时)
│   ├── 注入工作目录说明
│   └── 附加当前日期
│
└── 7. 调用 LangChain create_agent()
    ├── model
    ├── tools
    ├── middleware
    ├── system_prompt
    └── state_schema = ThreadState
``
### 2.4 中间件链构建顺序(严格有序)
`_build_middlewares()` 函数按以下顺序组装 11 个中间件:
``
顺序  中间件                    条件        职责
────  ──────────────────────  ──────────  ──────────────────────────────
 1    ThreadDataMiddleware      始终        为 thread_id 创建本地数据目录
 2    UploadsMiddleware         始终        追踪并注入新上传的文件到对话
 3    SandboxMiddleware         始终        获取沙箱实例,存储 sandbox_id 到状态
 4    DanglingToolCallMiddleware 始终        为缺少响应的 tool_call 注入占位 ToolMessage
 5    SummarizationMiddleware   config.yaml  接近 token 上限时自动摘要对话
 6    TodoListMiddleware        is_plan_mode  提供 write_todos 工具,任务跟踪
 7    TitleMiddleware           始终        首次完整对话后自动生成线程标题
 8    MemoryMiddleware          config.yaml  过滤消息(user + 最终 AI),排队异步记忆更新
 9    ViewImageMiddleware       supports_vision 将图片转为 base64 注入状态
10    SubagentLimitMiddleware   subagent_enabled 截断超出并发上限的 task 调用
11    ClarificationMiddleware   始终(必须在最后) 拦截 ask_clarification 调用,中断执行 → Command(goto=END)
``
---
## 三、Agent 的任务接收、调度和执行的完整链路
### 3.1 完整请求链路(HTTP 模式)
``
用户输入消息
    │
    ▼
┌──────────────────────────────────────────────────┐
│ ① Frontend (Next.js)                             │
│    - 用户发送消息                                   │
│    - useThreadStream hook → LangGraph SDK 流式请求 │
│    - POST /api/langgraph/lead_agent/runs          │
└──────────────┬───────────────────────────────────┘
               │
               ▼
┌──────────────────────────────────────────────────┐
│ ② Nginx (:2026)                                  │
│    - 路由 /api/langgraph/* → LangGraph Server(:2024)│
└──────────────┬───────────────────────────────────┘
               │
               ▼
┌──────────────────────────────────────────────────┐
│ ③ LangGraph Server (:2024)                       │
│    - 收到请求,调用 make_lead_agent(config) 工厂函数  │
│    - 首次调用:创建 Agent 实例(模型 + 工具 + 中间件)  │
│    - 后续调用:复用缓存的 Agent 实例                  │
│    - 将请求包装为 Agent 输入状态                      │
│    - 调用 agent.stream(state, config, context)      │
└──────────────┬───────────────────────────────────┘
               │
               ▼
┌──────────────────────────────────────────────────┐
│ ④ Agent 执行循环 (LangGraph 内部)                  │
│                                                   │
│    for 每个中间件 (outer → inner):                 │
│        before_model(state)  ← 中间件前置处理        │
│        ▲                                          │
│        │                                          │
│    ┌───┴───┐                                      │
│    │ LLM   │ ← 系统提示词 + 对话历史 → 模型响应     │
│    │ 调用   │    (可能包含 tool_calls)              │
│    └───┬───┘                                      │
│        │                                          │
│        ▼                                          │
│    for 每个中间件 (inner → outer):                 │
│        after_model(state)  ← 中间件后置处理          │
│        │                                          │
│    for 每个 tool_call:                             │
│        执行工具 → 得到 ToolMessage → 追加到历史       │
│        │                                          │
│    if 还有 tool_calls: 回到开头继续                  │
│    else: 返回最终状态                                │
│                                                   │
│    每一步通过 SSE 流式输出到 Frontend                 │
└───────────────────────────────────────────────────┘
``
### 3.2 单轮 Agent 执行流程(详细)
``
输入: HumanMessage("分析腾讯股价下跌原因")
    │
    ▼
┌─ 中间件 before_model 链 ──────────────────────┐
│                                                │
│ ThreadDataMiddleware.before_model()             │
│   → 创建 .deer-flow/threads/{tid}/user-data/    │
│   → 写入 state.thread_data (workspace/uploads/  │
│     outputs 路径)                               │
│                                                │
│ UploadsMiddleware.before_model()                │
│   → 扫描 uploads/ 目录                          │
│   → 将新上传文件列表注入 state.uploaded_files    │
│                                                │
│ SandboxMiddleware.before_model()                │
│   → 获取沙箱实例 (本地/Docker)                    │
│   → 写入 state.sandbox = {sandbox_id: ...}      │
│                                                │
│ DanglingToolCallMiddleware.before_model()       │
│   → 检查消息历史中是否有未配对的 tool_call        │
│   → 注入占位 ToolMessage 防止模型重试             │
│                                                │
│ SummarizationMiddleware.before_model()          │
│   → 检查 token 数/消息数是否达到阈值              │
│   → 触发摘要:保留最近 N 条消息,压缩旧对话        │
│                                                │
│ TitleMiddleware.before_model()                  │
│   → 如果是首次完整交换,调用 LLM 生成标题          │
│   → 写入 state.title                            │
│                                                │
│ MemoryMiddleware.before_model()                 │
│   → 过滤出用户消息 + 最终 AI 响应                 │
│   → 加入去抖队列 (30s 后触发异步记忆更新)          │
│                                                │
│ ViewImageMiddleware.before_model()              │
│   → 将对话中的图片引用转为 base64 嵌入            │
│   → 写入 state.viewed_images                    │
│                                                │
│ SubagentLimitMiddleware.after_model()           │
│   → 截断 model_response 中超出 max_concurrent    │
│     的 task tool_calls                          │
│                                                │
│ ClarificationMiddleware.after_model()           │
│   → 检测 model_response 是否包含                 │
│     ask_clarification tool_call                 │
│   → 如果有 → return Command(goto=END) 中断      │
└────────────────────────────────────────────────┘
    │
    ▼
┌─ LLM 调用 ────────────────────────────────────┐
│                                                │
│  System Prompt (含角色/记忆/技能/子代理指令)      │
│  +                                              │
│  对话历史 (HumanMessage / AIMessage / ...)       │
│     │                                           │
│     ▼                                           │
│  模型返回:                                       │
│    - 文本响应 (简单问题)                           │
│    - 或多个 tool_calls (复杂任务)                  │
│    - 或 text + tool_calls (并行)                  │
└────────────────────┬───────────────────────────┘
                     │
                     ▼
            是否包含 tool_calls?
                     │
              ┌──────┴──────┐
              │ yes         │ no
              ▼             ▼
     ┌──────────────┐  ┌──────────────┐
     │ 工具执行阶段  │  │ 返回最终状态   │
     │              │  │ → SSE 输出   │
     │ for each     │  │ → 前端渲染   │
     │   tool_call: │  └──────────────┘
     │   执行工具    │
     │   → 生成     │
     │     ToolMsg  │
     │   → 追加到   │
     │     历史     │
     │              │
     │ → 回到开头   │
     │   继续循环   │
     └──────────────┘
``
### 3.3 子代理调度链路
当 Lead Agent 调用 `task` 工具时:
``
Lead Agent 返回 tool_calls: [task(...), task(...), task(...)]
    │
    ▼
┌───────────────────────────────────────────────────────┐
│ task_tool(description, prompt, subagent_type, ...)     │
│                                                        │
│ ① 从注册表获取子代理配置                                 │
│    get_subagent_config("general-purpose")              │
│    → SubagentConfig(name, tools, disallowed_tools,    │
│                     system_prompt, max_turns, timeout)  │
│                                                        │
│ ② 创建 SubagentExecutor                                │
│    - 过滤工具集 (根据 allowed/disallowed)               │
│    - 继承父代理的沙箱状态和 thread_data                  │
│    - 生成 trace_id 用于分布式追踪                        │
│                                                        │
│ ③ 异步执行 (execute_async)                              │
│    - 创建 SubagentResult(task_id, status=PENDING)       │
│    - 存入全局 _background_tasks 字典                     │
│    - 提交到 _scheduler_pool (3 个工作线程)               │
│    - 立即返回 task_id (非阻塞)                           │
│                                                        │
│ ④ 后台调度线程执行                                       │
│    - 状态 → RUNNING                                     │
│    - 提交到 _execution_pool (3 个工作线程)               │
│    - 等待 execution_future.result(timeout=900s)         │
│                                                        │
│ ⑤ 子代理执行线程                                         │
│    - _create_agent():                                   │
│      create_agent(model, filtered_tools,               │
│                   [ThreadDataMiddleware,                │
│                    SandboxMiddleware],                  │
│                   system_prompt, ThreadState)           │
│    - agent.stream(initial_state, config, context)       │
│    - 实时收集 AI 消息到 result.ai_messages               │
│    - 提取最终 AIMessage 内容作为 result.result            │
│                                                        │
│ ⑥ 调度线程回收结果                                       │
│    - 更新 _background_tasks[task_id]:                   │
│      status → COMPLETED / FAILED / TIMED_OUT            │
│      result, error, ai_messages                         │
└───────────────────────────────────────────────────────┘
    │
    ▼
┌───────────────────────────────────────────────────────┐
│ task_tool 轮询等待 (5s 间隔)                             │
│                                                        │
│  while True:                                           │
│      result = get_background_task_result(task_id)      │
│      if result.status in (COMPLETED, FAILED, TIMED_OUT):│
│          break                                         │
│      yield SSE event (task_started / task_running / ...)│
│      sleep(5)                                          │
│                                                        │
│  返回: ToolMessage(content=子代理最终结果)                │
└───────────────────────────────────────────────────────┘
    │
    ▼
Lead Agent 收到所有 task 的 ToolMessage → 继续下一轮循环
→ 综合所有子代理结果 → 生成最终回复 → 流式输出到用户
``
### 3.4 双线程池设计
``
┌─────────────────────┐         ┌─────────────────────┐
│  _scheduler_pool     │         │  _execution_pool     │
│  (3 workers)         │────────▶│  (3 workers)         │
│                      │         │                      │
│  职责:                │         │  职责:                │
│  - 状态管理           │         │  - 实际 Agent 执行    │
│  - 超时控制           │         │  - 流式消息收集       │
│  - 结果回收           │         │  - 提取最终结果       │
│  - 异常处理           │         │                      │
└─────────────────────┘         └─────────────────────┘
分离原因:
- 调度线程需要阻塞等待 (future.result(timeout))
- 执行线程需要流式处理 agent.stream()
- 分离后调度线程不会被执行阻塞,可以管理超时和清理
``
---
## 四、Agent 的状态管理和生命周期设计
### 4.1 ThreadState 状态模式
定义文件:`src/agents/thread_state.py`
``python
class ThreadState(AgentState):
    # ── 继承自 AgentState ──
    messages: list[BaseMessage]      # 对话消息历史 (append 模式)
    stack: list[...]                 # LangGraph 内部调用栈
    # ── DeerFlow 扩展字段 ──
    sandbox: SandboxState            # 沙箱状态 {sandbox_id: "local" | "container-xxx"}
    thread_data: ThreadDataState     # 线程数据 {workspace_path, uploads_path, outputs_path}
    title: str                       # 自动生成的对话标题
    artifacts: list[str]             # 产物文件列表 (merge_artifacts 去重归并)
    todos: list                      # 任务列表 (plan_mode 时)
    uploaded_files: list[dict]       # 上传文件信息
    viewed_images: dict              # 已查看图片 {path: {base64, mime_type}}
``
**自定义归并器 (Reducer)**:
- `merge_artifacts` — 合并去重(`dict.fromkeys` 保序去重)
- `merge_viewed_images` — 字典合并,空字典 `{}` 特殊处理为"清除所有"
### 4.2 生命周期状态图
``
                    ┌─────────────────────────────────────────────┐
                    │              Agent 实例生命周期                │
                    └─────────────────────────────────────────────┘
  ┌─────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────┐
  │  空闲    │────▶│  接收请求     │────▶│  执行中       │────▶│  完成     │
  │ (Standby)│     │ (make_...  ) │     │ (agent.     │     │ (SSE 结束)│
  └─────────┘     └──────────────┘     │  stream)    │     └──────────┘
                                       └──────────────┘
  首次请求时:
    make_lead_agent(config)
    ├── 解析模型 → create_chat_model()
    ├── 组装工具 → get_available_tools()
    ├── 构建中间件 → _build_middlewares()
    ├── 生成提示词 → apply_prompt_template()
    └── 创建代理 → create_agent(...)
  后续请求 (同配置):
    复用已缓存的 Agent 实例
  配置变化时:
    重新调用 make_lead_agent() 创建新实例
                    ┌─────────────────────────────────────────────┐
                    │            Thread (对话线程) 生命周期          │
                    └─────────────────────────────────────────────┘
  ┌────────┐  ┌──────────┐  ┌───────────┐  ┌──────────┐  ┌──────────┐
  │ 创建    │─▶│ ThreadData│─▶│ 每轮执行   │─▶│ 记忆更新  │─▶│ 持续/   │
  │ (新对话) │  │ 初始化    │  │ (中间件→   │  │ (异步,   │  │ 结束     │
  │        │  │ 创建目录  │  │  LLM→工具) │  │  30s去抖)│  │          │
  └────────┘  └──────────┘  └───────────┘  └──────────┘  └──────────┘
  每轮执行:
    ThreadDataMiddleware  → 确保线程目录存在
    UploadsMiddleware     → 扫描新上传文件
    SandboxMiddleware     → 获取/复用沙箱
    ... (其余中间件)
    TitleMiddleware       → 首次交换后生成标题 (仅一次)
    MemoryMiddleware      → 排队记忆更新 (每轮)
                    ┌─────────────────────────────────────────────┐
                    │           Sandbox (沙箱) 生命周期             │
                    └─────────────────────────────────────────────┘
  LocalSandbox:
    acquire() → 单例 (sandbox_id = "local")
    get(id)   → 返回同一实例
    release() → no-op (不销毁)
  AioSandbox (Docker):
    acquire() → 启动新容器 / 连接已有容器
    get(id)   → 返回容器客户端
    release() → 停止并清理容器
  沙箱复用:
    - 同一 thread_id 复用同一个沙箱实例
    - SandboxMiddleware 检查 state.sandbox 是否已有 sandbox_id
    - 如果有 → 直接 get() 复用,不再 acquire
                    ┌─────────────────────────────────────────────┐
                    │        Subagent (子代理) 生命周期             │
                    └─────────────────────────────────────────────┘
  PENDING ──▶ RUNNING ──▶ COMPLETED
                │
                ├──▶ FAILED    (执行异常)
                │
                └──▶ TIMED_OUT (超过 timeout_seconds,默认 900s)
  创建:
    task_tool() → SubagentExecutor(task, task_id)
                 → _scheduler_pool.submit(run_task)
  执行:
    run_task()  → _execution_pool.submit(execute)
                → agent.stream(state) 流式执行
                → 实时收集 AI 消息
  回收:
    调度线程等待 future.result(timeout)
    → 更新 _background_tasks[task_id] 状态
    → task_tool 轮询检测到终态 → 返回结果
``
### 4.3 配置驱动的条件化行为
Agent 的运行时行为由 `config.configurable` 中的参数动态控制:
``
config.configurable
├── model_name            → 切换 LLM 模型
├── thinking_enabled      → 启用/禁用扩展思考
├── reasoning_effort      → 推理力度 ("low" / "medium" / "high")
├── is_plan_mode          → 启用 TodoListMiddleware (任务追踪)
├── subagent_enabled      → 启用 task 工具 + SubagentLimitMiddleware
├── max_concurrent_subagents → 并发子代理数上限 (默认 3)
├── is_bootstrap          → 启动引导模式 (精简提示词 + setup_agent 工具)
└── agent_name            → 自定义代理 (加载对应 SOUL.md + 独立记忆)
``
### 4.4 记忆系统生命周期
``
用户发送消息
    │
    ▼
MemoryMiddleware.before_model()
    │ 过滤: 只保留 HumanMessage + 最后一个 AIMessage
    ▼
加入 MemoryQueue (去抖: 同一 thread_id 合并)
    │
    ▼  (30 秒后触发)
MemoryQueue.process()
    │
    ▼
LLM 事实提取
    ├── 分析对话内容
    ├── 提取用户上下文 (workContext, personalContext, topOfMind)
    ├── 提取离散事实 (id, content, category, confidence)
    └── 过滤: confidence < 0.7 的事实不存储
    │
    ▼
原子写入 memory.json
    ├── 写入临时文件
    ├── 原子替换 (os.replace)
    └── 失效内存缓存
    │
    ▼
下次对话时 → apply_prompt_template() → 读取 memory.json
    → 注入 top 15 事实 + 用户上下文到 <memory> 标签
    → 限制 max_injection_tokens (默认 2000 token)
``
---
## 五、关键设计模式总结
| 模式 | 体现 |
|------|------|
| **工厂模式** | `make_lead_agent(config)` 根据运行时参数创建完整 Agent 实例 |
| **中间件链** | 11 个中间件有序组装,before_model / after_model 钩子 |
| **策略模式** | SandboxProvider 接口,Local / Docker / K8s 三种实现 |
| **懒加载** | MCP 工具首次使用时才初始化;Agent 首次请求时才创建 |
| **缓存 + 失效** | MCP 工具按 mtime 缓存;memory.json 按修改时间缓存 |
| **对象池** | Subagent 双线程池 (_scheduler_pool + _execution_pool) |
| **事件驱动** | SSE 流式输出 (values / messages-tuple / end) |
| **渐进式加载** | Skills 只在系统提示词中列出路径,Agent 按需 read_file 加载 |
| **去抖队列** | Memory 更新去抖 (30s),避免每轮对话都触发 LLM 调用 |
| **原子写入** | memory.json 和 extensions_config.json 使用 temp + replace |

到此这篇关于Qwen3.6-27B 本地私有化部署 + Claude Code 连接应用的文章就介绍到这了,更多相关Qwen3.6-27B 本地部署+Claude Code内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!