【Agent Harness 架构手册 #05】AI Agent 自进化经验蒸馏飞轮与 SSE 游标断点重连实战

Linux Swap 子系统:架构、内存管理与虚拟化 Swap Linux Swap机制通过将不活跃内存页移至磁盘或压缩内存,扩展系统有效内存容量,缓解内存压力。传统架构中,逻辑Swap槽与物理存储绑定,导致资源浪费,尤其在使用Zswap等压缩技术时。为此,Vswap与Xswap提出虚拟化方案:前者以XArray实现灵活映射,支持多后端迁移;后者采用稀疏映射,简化管理但容量固定。二者在架构设计、资源记账与动态扩展上各有权衡,反映了内核开发中对性能、可维护性与灵活性的深层考量。 阅读详情

玄同 765

AI Engineer


  中国传媒大学 | 数字媒体技术(游戏设计技术方向)

  ▍深耕领域  AI Agent 架构设计 Agent Harness 工程 Context Engineering 多智能体协同 & RAG
  ▍技术底座  Python TypeScript · LangChain MCP & Skills · FastAPI Milvus Docker
  ▍工程能力  专注 Agent 运行时架构、长上下文与 Prompt Cache 优化、LLM 全链路评测与工程化落地

     

「 让 AI 交互更智能,让技术落地更高效 」   |   欢迎技术探讨 / 项目合作,关注解锁大模型与智能交互的无限可能!

【Agent Harness 架构手册 #05】AI Agent 自进化“经验蒸馏飞轮(Knowledge Flywheel)”与 SSE 断点续传(Replayable Stream)架构实战

📚 《Agent Harness 架构手册:构建高可靠 AI 智能体运行时》五篇连载导航

欢迎来到本专栏的第 5 篇收官之作!在前四篇中,我们依次构建了 动态工具配额守卫(#01)、声明式 Action Feed 实时动态流(#02)、L1~L4 四级历史投影引擎(#03) 以及 三重零信任权限审计链与 AST 行级安全注入(#04)。

当你的 Agent 系统平稳运行起来后,要想从“能用的工具”蜕变为“越用越聪明的企业级智能体平台”,还必须攻克最后两个硬骨头:

  1. Agent 不会“吃一堑长一智”,每次都在同一个业务口径上摔跤:
    用户在对话里花了 5 轮才教会 Agent:“算华东区净毛利时必须剔除内部调拨单”。结果换了一个新会话,Agent 又忘了这回事!传统做法是让研发人员手动去改 Prompt 或写死知识库文档,不仅响应慢,还无法形成闭环。如何让 Agent 从用户的 点赞(Positive)、点踩纠错(Negative) 甚至 高频追问日志(Active) 中,自动提炼出可复用的 Skill(技能)、Knowledge(知识) 或 View Proposal(数据视图修订提案)?
  2. 浏览器一刷新或切后台,跑了一半的 SSE 流式任务就彻底断联:
    传统的 FastAPI StreamingResponse 将 Agent 的推理协程与 HTTP 请求生命周期死死绑在一起。一旦用户在 Agent 执行到第 8 步时不小心按了 F5 刷新页面,或者手机切了个 Wi-Fi,前端重连回来时流已经断了;更糟糕的是,当用户看 Agent 查错了方向,想在中途喊一句“别查去年了,改查今年 Q3!”时,只能硬生生点停止重来。

本文将带你完整实现 「三模自进化经验蒸馏飞轮(Sediment Policy Engine)」 与 「基于内存游标缓冲池的 SSE 断点续传 + 运行期动态控向(Replayable Stream & In-Flight Steer)」,为整套 Agent Harness 架构画上圆满句号!


一、为什么“静态知识库 + 绑定 HTTP 连接的流式推理”走不远?(原理拆解篇)

1.1 从“名医坐诊的医案整理本”与“高铁直播的云端录像回放”说起

为什么大多数团队做出来的 Agent 上线三个月后准确率和第一天一模一样,而且极其害怕网络抖动?

我们可以用两个非常直观的生活场景来拆解背后的架构缺陷:

  1. 为什么 Agent 不会自我进化?(缺少受控的“医案沉淀飞轮”):
    老中医每天看完病,到了晚上都会把白天 “一剂见效的疑难杂症(正向反馈 Positive)” 整理成标准方剂(register_sop_playbook / publish_doc_entry),把 “初诊开错药、复诊才修正过来的病例(负向反馈 Negative)” 记入错题本并修订诊疗指南(submit_schema_patch)。
    但在做自动化沉淀 Agent 时,如果不加工具白名单与单次交付门禁,沉淀 Agent 很容易失控——比如本来只是让它从点赞对话里总结一篇知识文档,它却自己连上生产库乱跑试探 SQL;或者一口气连建 5 个重复的碎片技能!因此,我们需要一套 按沉淀模式(positive / negative / active)严格收敛工具白名单与单次 Terminal 门禁的 ExperienceDistillMiddleware。
  2. 为什么刷新页面会丢流?(把“演播室摄像机”直接焊死在了“观众的电视机插头”上):
    传统 SSE 把 Agent 的 async for event in agent.run() 直接写在 FastAPI 的 StreamingResponse 生成器函数内部。这就好比观众家里一拔电视机插头(浏览器刷新断开 TCP),演播室的摄像机也当场断电停机!
    正确的 Replayable Stream(断点续传流) 架构是:将 Agent 运行在独立的后台异步任务(Detached Task)中,所有产出的事件按递增序号 seq = 0, 1, 2... 写入内存环形缓冲池(ReplayableEventBus)并同步落盘。无论前端断线重连多少次,只需带上 ?after=last_seq,就能瞬间补齐错过的事件并无缝接上实时流!

下面的全局架构图展示了 “自进化沉淀飞轮” 与 “可断点续传/可中途控向的流式运行时” 如何协同工作:

对话结束触发异步沉淀任务

沉淀出的新资产反哺下一轮在线问答

🔄 后台自进化闭环:三模经验蒸馏飞轮 (Knowledge Sediment Flywheel)

采集已完成对话轨迹与反馈信号
Positive(点赞) / Negative(纠错) / Active(主动巡检)

ExperienceDistillMiddleware 严格管控:
按模式裁剪工具箱 + 14步探索上限 + 单次交付锁

自动产出可复用 Skill / 知识文档
或提交数据视图修订提案供管理员一键确认

⚡ 在线流式运行时:解耦执行 + 断点续传 + 中途控向 (Replayable & Steerable)

独立异步任务运行 Agent
事件写入 ReplayableEventBus 缓冲池 (seq=0..N)

前端刷新重连 GET /stream?after=seq
先回放缺失事件,再无缝订阅实时增量

用户中途纠偏 POST /steer
在工具步边界注入新指令或优雅终止


1.2 三种经验蒸馏模式(Positive / Negative / Active)权限与策略全景对比

为了让自进化沉淀 Agent 既能精准提炼资产,又绝对不会越权乱改,我们将其划分为三种严格的运行模式:

沉淀模式 (DistillTriggerMode)触发时机与输入证据允许调用的探索工具 (Discovery Whitelist)允许调用的唯一交付工具 (Terminal Tools)无数据库连接器 (has_connector=False) 时的降级策略
positive(正向经验提炼)用户对某轮回答点赞,或一次多步分析成功解决复杂问题仅限轻量检索:search_tech_docs, fetch_doc_section, list_doc_index, search_data_catalog, load_sop_playbookregister_sop_playbook(主路径)、publish_doc_entry(辅助)完全不受影响(正向沉淀无需连接源库跑 SQL)
negative(负向错题修正)用户点踩、人工纠错,或对话中模型先查错后经用户指正才查对在 positive 基础上额外开放:inspect_table_schema, list_raw_tables, inspect_raw_tables, verify_sql_syntax, run_diagnostic_sqlsubmit_schema_patch、submit_schema_proposal、publish_doc_entry自动从白名单剔除沙箱探测工具与 submit_schema_proposal(因无法连库校验新 SQL),仅允许修订元数据或沉淀排障知识
active(主动日志巡检)定时任务批量扫描近期高频追问与未命中查询同 negative 全量探索集合并 positive 与 negative 全部交付工具自动剔除需连库校验的沙箱与新视图提案工具

💡 核心设计准则:
“单一事实来源(Single Source of Truth)+ 单次交付即锁死(Single-Terminal Lock)”——沉淀 Agent 在挂载工具(Engine 层)和运行时拦截(Middleware 层)共享同一套 resolve_active_toolset(mode, has_connector) 函数;且每轮沉淀最多只允许成功调用 1 次交付工具,彻底杜绝一次后台任务胡乱生成一堆垃圾文档!


二、基础篇:3 分钟实现受控自进化沉淀中间件(ExperienceDistillMiddleware)

我们先把自进化飞轮的核心控制层写出来。它需要保证三件事:

  1. 严格白名单拦截:任何不在当前 DistillTriggerMode 允许列表里的工具调用,直接拦截;
  2. 探索步数封顶(_MAX_DISCOVERY_STEPS = 14):在调用最终的交付工具前,最多允许查 14 次现有资产和知识库(防止重造轮子,但不能无限查下去);
  3. 单次交付锁(terminal_completed):一旦 register_sop_playbook 或 submit_schema_patch 成功执行 1 次,立即锁死本轮,禁止再顺手创建第二个产物。
2.1 完整可复用代码:ExperienceDistillMiddleware 策略引擎
from __future__ import annotations
import contextvars
from dataclasses import dataclass
from typing import Any, Literal
from langchain_core.messages import ToolMessage

DistillTriggerMode = Literal["positive", "negative", "active"]

_DISCOVERY_POSITIVE = frozenset({
    "search_tech_docs",
    "fetch_doc_section",
    "list_doc_index",
    "search_data_catalog",
    "load_sop_playbook",
})

_DISCOVERY_NEGATIVE_EXTRA = frozenset({
    "inspect_table_schema",
    "list_raw_tables",
    "inspect_raw_tables",
    "verify_sql_syntax",
    "run_diagnostic_sql",
})

_CONNECTOR_REQUIRED_TOOLS = frozenset({
    "list_raw_tables",
    "inspect_raw_tables",
    "verify_sql_syntax",
    "run_diagnostic_sql",
    "submit_schema_proposal",
})

_TERMINAL_POSITIVE = frozenset({"register_sop_playbook", "publish_doc_entry"})
_TERMINAL_NEGATIVE = frozenset({"submit_schema_patch", "submit_schema_proposal", "publish_doc_entry"})

ALLOWED_BY_MODE: dict[DistillTriggerMode, frozenset[str]] = {
    "positive": _DISCOVERY_POSITIVE | _TERMINAL_POSITIVE,
    "negative": _DISCOVERY_POSITIVE | _DISCOVERY_NEGATIVE_EXTRA | _TERMINAL_NEGATIVE,
    "active": _DISCOVERY_POSITIVE | _DISCOVERY_NEGATIVE_EXTRA | _TERMINAL_POSITIVE | _TERMINAL_NEGATIVE,
}

TERMINAL_BY_MODE: dict[DistillTriggerMode, frozenset[str]] = {
    "positive": _TERMINAL_POSITIVE,
    "negative": _TERMINAL_NEGATIVE,
    "active": _TERMINAL_POSITIVE | _TERMINAL_NEGATIVE,
}

_MAX_DISCOVERY_STEPS = 14
DISTILL_STEP_CUSHION = 8

def compute_distill_graph_limit() -> int:
    """计算与沉淀探索预算严格对齐的 LangGraph recursion_limit。"""
    return 2 * _MAX_DISCOVERY_STEPS + DISTILL_STEP_CUSHION

def resolve_active_toolset(mode: DistillTriggerMode, *, has_connector: bool) -> frozenset[str]:
    """根据沉淀模式与数据源连接状态,动态计算唯一合法的工具白名单。"""
    allowed = ALLOWED_BY_MODE[mode]
    if mode in {"negative", "active"} and not has_connector:
        return frozenset(allowed - _CONNECTOR_REQUIRED_TOOLS)
    return frozenset(allowed)

@dataclass
class _SedimentTurnState:
    discovery_calls: int = 0
    terminal_completed: bool = False

_sediment_state_ctx: contextvars.ContextVar[_SedimentTurnState | None] = contextvars.ContextVar(
    "sediment_state_ctx", default=None
)

class ExperienceDistillMiddleware:
    """自进化经验蒸馏 Agent 专用策略护栏:白名单隔离 + 14步查重上限 + 单次交付锁。"""

    def __init__(self, mode: DistillTriggerMode, *, has_connector: bool = True) -> None:
        self.mode: DistillTriggerMode = mode
        self.has_connector = has_connector
        self.allowed = resolve_active_toolset(mode, has_connector=has_connector)
        self.terminals = TERMINAL_BY_MODE[mode] & self.allowed

    async def awrap_tool_call(self, request: Any, handler: Any) -> ToolMessage:
        state = _sediment_state_ctx.get()
        if state is None:
            state = _SedimentTurnState()
            _sediment_state_ctx.set(state)

        op_name = request.tool_call["name"]
        call_id = request.tool_call["id"]

        # 1. 单次交付锁:一旦成功产出过 1 个沉淀提案/技能,禁止继续调用任何工具
        if state.terminal_completed:
            return ToolMessage(
                content="Error: 本轮沉淀已成功提交交付产物(单次交付锁生效),请直接输出总结结束本轮。",
                tool_call_id=call_id,
                name=op_name,
            )

        # 2. 模式白名单校验
        if op_name not in self.allowed:
            return ToolMessage(
                content=f"Error: 当前沉淀模式 ({self.mode}) 禁止调用工具 {op_name}。",
                tool_call_id=call_id,
                name=op_name,
            )

        # 3. 查重探索步数上限校验(放行最终的 Terminal 交付工具)
        if op_name not in self.terminals:
            if state.discovery_calls >= _MAX_DISCOVERY_STEPS:
                return ToolMessage(
                    content=(
                        f"Error: 沉淀前期查重探索步数已达上限 ({_MAX_DISCOVERY_STEPS} 步)。"
                        f"请立即调用交付工具 ({', '.join(sorted(self.terminals))}) 提交沉淀产物,或直接结束说明无需沉淀。"
                    ),
                    tool_call_id=call_id,
                    name=op_name,
                )
            state.discovery_calls += 1

        result = await handler(request)
        content = str(result.content or "") if isinstance(result, ToolMessage) else str(result or "")

        # 4. 若交付工具成功执行(未返回 Error),立即锁定本轮
        if op_name in self.terminals and not content.strip().startswith(("Error:", "[ERROR]")):
            state.terminal_completed = True

        return result

三、进阶篇:不怕刷新页面的 SSE 断点续传(ReplayableEventBus)与游标回放实战

解决了后台的自进化飞轮,我们再来攻克前端用户体验的头号顽疾:怎么让一个耗时 30 秒的 SSE 流式 Agent 任务,在用户任意刷新页面、切换标签页甚至断网重连时,100% 不中断后台执行,并且前端重连后能从断开的那一帧毫秒级续接?

3.1 全链路架构拆解:后台脱钩执行(Detached Task)+ asyncio.Condition 游标订阅

核心架构秘诀只有一句话:永远不要把 agent.run() 放在 HTTP 响应生成器里,而是用 asyncio.create_task() 启动独立的后台生产者往 ReplayableEventBus.events 列表里追加带序号 seq 的事件;HTTP SSE 接口只是一个拿着游标 cursor 来读取该列表的消费者!

3. 支持任意断线重连的 SSE 消费者 (GET /streams/{run_id}?after=K)

浏览器首次连接 after=0
收到 seq=1, 2 后用户按 F5 刷新页面!

后台 Producer 毫不受影响
继续写入 seq=3, 4

页面加载完毕重连 GET /streams/run_99?after=2
立即回放 seq=3, 4 并无缝挂起等待 seq=5!

2. 内存事件缓冲池 (ReplayableEventBus Ring/List Buffer)

events = [
{seq: 1, type: 'activity', ...},
{seq: 2, type: 'delta', ...},
{seq: 3, type: 'chart', ...}
]

1. 独立后台生产者协程 (Detached Agent Runner)

POST /qa/runs 启动后台 Task
立即返回 {run_id: 'run_99'}

Agent 持续产出流式事件
append_event 分配递增 seq = 1, 2, 3...

通过 asyncio.Condition.notify_all()
实时唤醒所有正在等待的 HTTP 消费者

3.2 完整可复用代码:支持多端同时订阅与断点续传的 ReplayableStreamHub

下面这段约 60 行的 Python 异步代码,仅用标准库 asyncio.Condition 就实现了一个工业级的 SSE 断点续传中心(支持任意多个客户端同时订阅同一个 run_id,支持 after_seq 历史补齐与实时流无缝切换):

import asyncio, json, time
from dataclasses import dataclass, field
from typing import Any, AsyncIterator

@dataclass
class ReplayableEventBus:
    """单次 Agent 运行的内存断点续传缓冲池。"""
    exec_ticket_id: str
    thread_key: str
    user_id: str
    created_at: float = field(default_factory=time.time)
    events: list[dict[str, Any]] = field(default_factory=list)
    done: bool = False
    error: str | None = None
    _cond: asyncio.Condition = field(default_factory=asyncio.Condition)

    async def publish(self, event_type: str, data: dict[str, Any]) -> int:
        """由后台 Agent 生产者调用:追加新事件并唤醒所有订阅者。"""
        async with self._cond:
            seq = len(self.events) + 1
            envelope = {"seq": seq, "type": event_type, "data": data, "ts": round(time.time(), 3)}
            self.events.append(envelope)
            self._cond.notify_all()
            return seq

    async def mark_finished(self, error: str | None = None) -> None:
        """标记本次运行已彻底结束(正常完成或异常终止),唤醒所有挂起的消费者退出循环。"""
        async with self._cond:
            self.error = error
            self.done = True
            self._cond.notify_all()

    async def subscribe(self, after_seq: int = 0, heartbeat_sec: float = 15.0) -> AsyncIterator[str]:
        """
        由 FastAPI StreamingResponse 调用:
        1. 先瞬间回放所有 seq > after_seq 的已缓存事件;
        2. 若运行尚未结束,则挂起等待新事件通知,期间定期发送 SSE 心跳防网关超时断开。
        """
        cursor = max(0, int(after_seq))
        while True:
            async with self._cond:
                while cursor >= len(self.events) and not self.done:
                    try:
                        await asyncio.wait_for(self._cond.wait(), timeout=heartbeat_sec)
                    except asyncio.TimeoutError:
                        # 发送标准 SSE 注释心跳帧,防止 Nginx / 负载均衡器 60s 切断空闲连接
                        yield ": heartbeat\n\n"
                        break

                batch = self.events[cursor:]
                cursor = len(self.events)
                is_done = self.done

            for item in batch:
                payload = json.dumps(item, ensure_ascii=False)
                yield f"id: {item['seq']}\nevent: {item['type']}\ndata: {payload}\n\n"

            if is_done and cursor >= len(self.events):
                break

四、高阶技巧:运行期动态控向(In-Flight Steer)与无 interrupt() 确定性提案确认

在流式运行时中,除了刷新重连,还有两个让架构师极易踩坑的高阶交互场景:

  1. 当 Agent 正在执行第 3 步工具时,用户看实时 Activity 流发现它查错了口径,想立刻发一条指令“别看含税价,改看未税价!”(In-Flight Steer),怎么在不强杀重开会话的前提下让 Agent 立刻拐弯?
  2. 当 Builder Agent 准备创建或修改一个生产数据视图时,必须先让管理员在界面上点击“确认采纳”才能写库。为什么我们强烈建议 不要用 LangGraph 的 interrupt() 挂起图状态,而改用 “终止型提案工具(Terminal Proposal Tool)”?
4.1 为什么“终止型提案工具(Terminal Proposal)”远胜 interrupt() 挂起?

很多教程教大家用 LangGraph 的 interrupt() 实现人工确认(Human-in-the-Loop):当工具跑一半时把整个图的内存 Checkpoint 冻结存进数据库,等用户点确认按钮时再 resume 恢复图执行。
但在真实的 Web 生产环境里,interrupt() 有三个致命痛点:

  1. 如果用户打开了提案卡片,却没有点“确认”也没有点“拒绝”,而是直接输入了一句新问题:“算了,先把昨天那个指标查一下”,处于 interrupted 悬挂状态的图 Checkpoint 就会直接报状态冲突!
  2. 升级代码或调整 Prompt 后,旧版本冻结在数据库里的二进制 Checkpoint 反序列化经常报错。

而 「终止型提案工具(submit_schema_proposal + return_direct=True)」 的设计极其清爽:

  • 当模型调用 submit_schema_proposal(name, sql, description) 时,工具内部只做参数与 SQL 合法性校验,然后将完整提案 JSON 作为 confirmation 事件推给前端,并正常结束本轮 Agent 运行(图状态 100% 干净完结,没有任何悬挂锁!);
  • 当用户在前端点击「确认创建」按钮时,前端直接调用一个纯确定性的 REST 接口 POST /api/views/confirm-proposal 落库即可,根本不需要再唤醒大模型花钱跑一轮!
4.2 运行期动态控向(In-Flight Steer)步边界注入流转图与代码实现

对于正在运行中的 Agent,我们为每个会话提供一个轻量的 SteerInbox(控向收件箱):

3. 模型在下一步丝滑拐弯

模型在第 k+1 步立即响应新指令
改调 2026 Q1 查询,无需作废重开!

2. 工具步边界无损拦截 (Agent Step Boundary)

当前正在执行的第 k 步工具正常跑完
保持 tool_calls -> ToolMessage 原子配对完整!

在进入下一轮 model 节点前
drain_steer_messages() 取走控向指令

作为最新 HumanMessage 追加至消息链尾部
(若指令为 action='stop' 则直接优雅收尾退出)

1. 用户在 Agent 运行中途发起控向 (POST /qa/steer)

看到 Activity 正在查 2025 年数据

用户点击『动态纠偏』输入:
'请改为查询 2026 年 Q1 数据'

下面是 SteerManager 运行期控向管理器的完整可复用实现:

from collections import deque
from dataclasses import dataclass, field
from langchain_core.messages import HumanMessage

@dataclass
class SteerCommand:
    """用户在 Agent 运行中途下发的实时控向指令。"""
    directive_kind: Literal["redirect", "stop"]
    guidance_note: str = ""
    submitted_at: float = field(default_factory=time.time)

class SteerManager:
    """按 thread_key 维护运行中 Agent 的实时控向收件箱。"""

    def __init__(self) -> None:
        self._inboxes: dict[str, deque[SteerCommand]] = {}

    def submit_steer(self, thread_key: str, directive_kind: Literal["redirect", "stop"], guidance_note: str = "") -> None:
        """供 POST /qa/steer/{thread_key} 路由调用:入队一条实时控向指令。"""
        box = self._inboxes.setdefault(thread_key, deque())
        box.append(SteerCommand(action=action, instruction=instruction.strip()))

    def drain_at_step_boundary(self, thread_key: str) -> tuple[bool, list[HumanMessage]]:
        """
        在每个工具步执行完毕、即将进入下一轮 model 推理前的步边界(Step Boundary)调用:
        返回 (should_stop_immediately, injected_human_messages)
        """
        box = self._inboxes.get(thread_key)
        if not box:
            return False, []

        injected: list[HumanMessage] = []
        should_stop = False
        while box:
            cmd = box.popleft()
            if cmd.directive_kind == "stop":
                should_stop = True
            elif cmd.instruction:
                injected.append(
                    HumanMessage(content=f"[用户运行中实时补充指令] 请立即按以下最新要求调整后续操作:{cmd.instruction}")
                )
        return should_stop, injected

五、实战避坑指南:高频报错与一键解决速查表

在落地自进化沉淀飞轮与 SSE 断点续传架构时,如果遇到以下典型问题,可直接对照下表快速排障:

序号遇到的报错或现象背后的真正原因一句话解决办法
01用户在 Agent 跑工具时点了“停止/纠偏”,结果下一轮对话报 400: An assistant message with tool_calls must be followed by tool messages在工具还没返回 ToolMessage 时就直接用 task.cancel() 硬劈了协程,导致半截 tool_calls 落库严禁在工具执行半空中强插消息或裸存半截状态!统一在当前工具步结束后的 步边界(Step Boundary) 消费 SteerManager 指令
02浏览器使用原生 EventSource 重连时,服务端没有收到上次断开的位置,又从第 1 条事件重复推了一遍既未解析请求参数 ?after=seq,也未读取浏览器 EventSource 自动附带的 Last-Event-ID 请求头在 SSE 帧中统一输出 id: {seq}\n,并在服务端入口用 after_seq = query_after or int(request.headers.get("Last-Event-ID", 0)) 双重兼容
03后台沉淀任务(Sediment Runner)在高并发下把在线问答的数据库连接池占满了离线/异步沉淀任务与在线实时问答共用了同一个数据库连接池且无并发上限为后台沉淀 Worker 配置独立的低优先级信号量(如 asyncio.Semaphore(2)),并在无源库连接时通过 resolve_active_toolset(has_connector=False) 自动剥离连库工具
04ReplayableEventBus 跑完后一直留在内存字典里,运行三天后 FastAPI 进程内存暴涨(OOM)缺少已完成运行缓冲池的 TTL 淘汰机制在 mark_finished 时将完整事件归档落盘至数据库,并为内存中的 ReplayableEventBus 设置 300 秒 TTL 惰性清理任务
05Nginx 反向代理下,当某个大数据分析工具耗时超过 60 秒无新事件产出时,前端 SSE 流被网关强行掐断报 504连接空闲时间超过了反向代理默认的 proxy_read_timeout(60s)在 ReplayableEventBus.subscribe 中将 wait_for 超时设为 15.0 秒,超时即刻输出一行标准 SSE 注释心跳 : heartbeat\n\n 保活连接

结语:五大核心支柱,铸就生产级 Agent Harness 架构闭环

至此,我们的 《Agent Harness 架构手册:构建高可靠 AI 智能体运行时》 五篇连载就全部圆满收官了!让我们用一张全景导图回顾这五大工程支柱如何环环相扣:

  1. 【#01 动态工具配额守卫(Dynamic Tool Quota Guard)】:用角色配额、沙箱连击锁、验证后单向锁与 Command(goto="model") 结束型工具报错自愈,管住 Agent 的“手脚”;
  2. 【#02 声明式实时活动流(Action Feed Engine)】:用 tool.metadata 声明式挂载与 Running/Done 双态确定性语义解析器,让 Agent 的“一举一动”清晰可读、零前端硬编码;
  3. 【#03 多轮历史四级预算投影(Context Engine v2)】:用不可变原始存储 + L1 预览 -> L2 结果卡片 -> L3 台账 -> L4 折叠 四级动态视图,管住 Agent 的“长期记忆与追问精度”;
  4. 【#04 零信任权限审计链与 AST 行级安全注入(Fail-Closed Security)】:用三重实时权限核验、跨代次(Grant Epoch)旧数据遮罩与 sqlglot AST 子查询重写,管住 Agent 的“安全底线”;
  5. 【#05 自进化沉淀飞轮与 SSE 断点续传(Flywheel & Replayable Stream)】:用受控的正负向经验蒸馏闭环、游标级断点续传与步边界实时控向,赋予 Agent “持续进化的生命力与丝滑交互体验”!

希望这套从真实大规模生产实践中提炼出的 Agent Harness 架构手册,能成为你打造下一代企业级 AI 智能体系统最趁手的工程蓝图!欢迎关注本专栏,我们下个系列再见!

SpringBoot实战教程-springboot概论 Spring Boot 是一个快速开发框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,以及自动配置。内置web容器,帮助开发者能够实现快速开发,简化了应用系统的初始搭建以及开发过程。 阅读详情

相关推荐

国产操作系统替换方案:3个避坑指南

坑核心误区避坑核心原则关键动作坑一:选型只看信创信创目录=唯一标准兼容性优先,信创是约束三维评估(兼容性+信创+生态),分场景选型坑二:迁移只管能跑功能能跑=迁移成功性能确认+运维回归适配-压测-回归三阶段,基线对比坑三:不防二次迁移解决停服=完成任务一步到位,两级兼容信创路线优先,双轨制发布,终态规划。

weixin_43524706的博客 294

【Agent Harness 架构手册 #02】AI Agent 实时动态流(Action Feed)与阶段性结论合成引擎实战

《Agent Harness 架构手册:构建高可靠 AI 智能体运行时》连载第02篇。本文详解如何告别满屏生硬JSON,从零构建双轨制可观测交互引擎:涵盖声明式工具元数据挂载、Running/Done双态语义转换器、每3步滑动窗口阶段性结论合成器(含嵌套流Tag静默隔离与确定性规则兜底)。

玄同765的AI应用开发博客 325

西门子PLC实战:基于1200/1500的工业物联网MQTT通讯全解析

本文详细解析了如何在西门子S7-1200/1500系列PLC上实现工业物联网MQTT通讯。通过从硬件准备、网络配置到TIA Portal中MQTT_Client功能块的实战编程,手把手指导工程师打通车间数据桥梁,解决信息孤岛问题,实现PLC数据高效上云或设备间互联。

whisky的博客 1089

【Agent Harness 架构手册 #01】LangGraph 动态工具配额守卫实战:根治无限探索与 return_direct 报错不自愈

《Agent Harness 架构手册:构建高可靠 AI 智能体运行时》连载第01篇。本文深入拆解生产级AI Agent工具调用配额控制核心难题,手把手教你实现支持四维探索配额、验证后锁定、return_direct结束工具报错自愈(Command回跳重试)与阶段性进展自动合成的动态工具配额守卫中间件。

玄同765的AI应用开发博客 303

手把手教你用树莓派蓝牙抓取小米温湿度计2代数据,接入HomeAssistant(附密钥获取避坑指南)

本文详细介绍了如何通过树莓派蓝牙抓取小米温湿度计2代数据并接入HomeAssistant的完整流程。重点解析了获取32位加密密钥的三种方法,包括使用Telink Flasher工具、米家APP抓包和开源工具ATC_MiThermometer,并提供了HomeAssistant集成配置和常见问题排查指南,帮助用户实现稳定可靠的温湿度监测。

一名菜鸟攻城师 777

深度学习batch、batch_size、epoch、iteration以及小样本中episode、support set、query set关系

训练整个数据集是epoch、把数据集分为多少小块就是batch,每个小块(batch)多少个数据就是batch_size,整个数据集需要训练多少轮是iteration

qq_42740834的博客 1610

【Agent Harness 架构手册 #03】多轮对话上下文引擎实战:L1~L4 四级预算投影与无损回放

《Agent Harness 架构手册:构建高可靠 AI 智能体运行时》连载第03篇。本文剖析多轮工具调用下的追问失忆难题,手把手实现四级无损历史投影引擎:原始消息不可变,按Token预算实时计算L1预览、L2结果卡片、L3结构化台账与L4折叠提问,削减85%开销且100%保留SQL筛选条件。

玄同765的AI应用开发博客 270

新手必看:瑞萨MCU选型时,QFP、QFN、BGA这些封装到底该怎么选?(附选型避坑指南)

本文详细解析了瑞萨MCU选型中QFP、QFN、BGA等封装的特点与适用场景,提供实战避坑指南。通过对比封装的空间占用、散热能力、焊接难度等核心维度,帮助工程师根据具体需求选择最合适的芯片封装,避免因选型不当导致的高成本与生产问题。

weixin_26965807的博客 421

【Agent Harness 架构手册 #04】企业级 Agent 零信任权限审计与 AST 行级安全注入:防止长对话中途撤权泄密

《Agent Harness 架构手册:构建高可靠 AI 智能体运行时》连载第04篇。本文构建企业级AI Agent零信任安全防线:实现模型调用前、工具执行前、结果发布前的三重实时权限核验、跨权限代次(Grant Epoch)旧数据遮罩以及基于sqlglot AST语法树的行级安全强制注入。

玄同765的AI应用开发博客 304

欧姆龙多PLC串行链接模式的应用

欧姆龙多PLC串行链接模式的应用 一、如何将两台CP1H进行串行PLC连接(PLC串行链接) 主机侧设定 从机侧设定 二、 如何实现编程通信 主机侧的【PC连接模式】为【全部】的时候 ① 主机会把自己的地址从3100开始,按照【链接字】设定的字数个数发送到每个从机的3100开始进行存储。 ② 从机会把自己的地址从31n0开始,按照主机侧参数【链接字】设定的字数个数发送到主机的31n0开始进行存储。 注:(n为从机的地址号,若从机号不连续,则该编号的地址将不被定义..

u014202847的博客 3081

拖动无标题栏的cef3窗口

拖动嵌入了cef3的无标题栏win32窗口,本质上就是拖动子窗口移动父窗口这么个事情,这个在自己创建窗口的程序上处理非常简单,cef封装较多,想修改的完善点步骤较多。         cef所用版本3.2623。         就用cefclient来做测试工程,首先建议在cefclient_win.cc的RunMain函数中的app = new ClientAppRenderer();前面

loveyong1990的专栏 6160

高危工业场景人员定位系统设计:四类场景的架构选型与部署要点

本文由航飞光电一线工程团队整理,重点讨论高危工业场景下人员定位系统的架构选型思路。覆盖危化、矿山、港口、电力四类场景,拆解技术路线分工、融合引擎跨区切换实现,以及私有化/本地化部署中的工程难点,供架构师与技术负责人参考。

HF17513371855的博客 335

手把手教你从入门到精通C# Modbus通信

本文是《Modbus通信从入门到精通》的导读,本专栏将会详细介绍ModusRTU 、ModbusASCII、ModbusTCP这三种协议的C#实现,由一个高级工程师多年实战经验总结而成,绝对干货!

qq_34059233的博客 1万+

【STM32】 ADC 完全指南:从模拟信号采样量化到五大架构原理

本文系统介绍ADC核心概念与五大主流架构。模拟信号具时间与幅值连续性,需经采样(满足奈奎斯特准则防混叠)、量化(引入±1/2LSB误差,SNR≈6.02N+1.76dB)、编码三步转为数字信号。重点解析Flash(并行高速但受限于比较器数量)、SAR(逐次逼近,低功耗适合MCU如STM32)、双积分(高精度抗工频,用于万用表)、流水线(高速吞吐)及Σ-Δ(高分辨率,靠过采样与噪声整形)五类架构原理、优缺点与应用场景。强调分辨率≠精度,选型本质是速度、精度、功耗与面积的权衡。

专注后端与底层技术,分享实战干货与学习笔记,梦想进入字节跳动,步履不停,热爱不止。 422

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

热管理系列之八:终局判断 - 浸没式冷却、混合架构与技术路线图

动力电池热管理三条路径的终局判断:液冷极致优化守住基盘,直冷在中高端渗透,浸没式冷却从概念到量产。附2026-2030技术路线图与关键产业信号分析。

weixin_54917114的博客 1102

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

零信任架构实战:基于天远运营商三要素详版V即时版构建自动化线上授信身份核验网关

破解线上信贷身份核验痛点:从离散证件图片审查到运营商三要素详版数据穿透直连 在互联网消费金融、小额循环信用贷款以及各类纯线上数字化授信平台的业务演进过程中,移动端进件的身份真实性校验是构筑整体合规风控体系的第一道关键屏障。随着移动互联网的高度普及,个人信贷申请全面向移动端 App、微信小程序以及轻量级 Web 门户迁移,“秒级审批、免抵押、纯线上放款”成为了

2501_94041864的博客 150

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

AI高密度算力推动冷却架构升级,全球数据中心高功率CDU市场CAGR达23.0%

QYResearch调研显示,2025年全球数据中心高功率CDU市场规模大约为2.04亿美元,预计2032年将达到9.97亿美元,2026-2032期间年复合增长率(CAGR)为23.0%。未来几年,本行业具有很大不确定性,本文的2026-2032年的预测数据是基于过去几年的历史发展、行业专家观点、以及本文分析师观点,综合给出的预测。

QYR_11的博客 187

数据不出域的 AI 分析方案如何选:企业 Data Agent 的三种部署架构与采购评估

选 Data Agent 翻车,表面看是功能不匹配,根子上是把部署架构当成了采购清单末尾的一个勾选项。拆开来看,有三个具体的翻车点。一是先被 SaaS 的体验打动,再回头找私有化,结果发现根本没有。很多 Data Agent 产品为了快速起量,只提供云服务。团队在公网环境里试用得很顺手,到了要落地的环节才发现,私有化版本要么不存在,要么是另一个定价体系、另一个功能子集。二是以为私有化只是把软件搬进内网,忽略了资产和权限的迁移成本。

Leo的博客 179

RDIMM、LRDIMM、UDIMM深度对比:寄存器架构、容量上限与平台适配

UDIMM、RDIMM与LRDIMM虽外形相同,但电气架构差异决定其性能与容量上限。UDIMM无缓冲,延迟低但容量受限;RDIMM通过RCD缓冲命令/地址,提升容量;LRDIMM进一步用数据缓冲器(DB)全链路减负,实现超大容量。三者互不兼容,平台适配严格,选型必须“平台先行”,类型错误无法通过降频或混插弥补。核心逻辑:先确认平台支持类型,再优化容量与频率,类型正确才是性能发挥的前提。

JGTX2706的博客 240

智能体架构之争:单Agent加Skills,还是多加几个Agent

Anthropic主张“一个Agent+Skills”取代多子智能体,以减少上下文丢失与成本;DeepSeek则提出“双层超智能体”架构,实现跨任务并行、主动响应。二者不矛盾:前者优化单任务内效率,后者突破多任务并发瓶颈。核心共识是:架构应由任务形态决定,而非组织或会话边界。未来关键在于量化拆分标准与防止Skills泛滥。

weixin_44592002的博客 246

蓝牙之通信架构

从应用、主机和控制器的分工入手,讲清 HCI、GAP、GATT、ATT、L2CAP 与安全协议如何配合,并通过一次温度读取理解蓝牙数据的完整传递过程。

2601_96393911的博客 205

Flux 架构:一个单向数据流库是怎么跑起来的

状态只有一份 + 数据单向流 + reducer 是纯函数 + 中间件链可组合 + 视图层声明式绑定。这 30 行就是这套思想的最小完整样本:两次useStore订阅、一次拿链式 dispatch、四个按钮对应四种 action(其中一种是 thunk 形态)。

sun_weitao的博客 104

《PCIe + BRAM架构(一):直接把DDR换成BRAM,只有读带宽没变》

本系列用同一块 XC7K325T 板卡、同一条 XDMA 通路,对比四种 PCIe 数据搬运架构:DDR 大缓存、Streaming、BRAM 轻缓存、多通道。本篇讲第三种:BRAM 架构。上一篇《PCIe + DDR架构(二):实测——更改上位机数据处理方式,带宽从1051.4 MB/s 涨到 1926.3 MB/s》

weixin_44017370的博客 326

区县外卖跑腿系统搭建:四端架构、订单链路与验收

区县同城配送系统先定业务边界和交付方式,再用四端跑通订单、支付、配送与结算,最后用真实订单验收。微订公开资料列有多种交付方式、多商户与跑腿业务范围,可作为候选方案,版本和报价以演示确认为准。

weixin_51117207的博客 101

从事件风暴到因果收敛:Mopheus多智能体协同事件触发架构与防循环实践

在构建生产级多智能体协同引擎的过程中,我们总结了三条核心工程准则:1.不可变因果链优于事后关系反查在高度并发且异步的多智能体网络中,因果关系的追溯绝不能依赖事后查库反查关联;将只增的因果祖先链显式封装在事件载荷与任务上下文中,以O(1)的内存检查实现确定性极高的闭环防范。2.生产端纯粹广播与消费端前置极速过滤是高吞吐的基石遵循严格的Pub/Sub模式,让核心业务实体与下游智能体编排解耦;通过调度层内存条件字典求值(conditions),在纳秒级内过滤掉99%的无关事件,保障零业务侵入与极高的系统吞吐。

weixin_54551388的博客 234

政企AI会议纪要系统如何实现内网部署?从语音转写到智能纪要的完整架构

在私有化部署模式下,这些模块可以运行在单位内部的服务器或AI一体机上,通过内部服务接口完成数据交换。

shxjnpl的博客 162
上一篇: 【Agent Harness 架构手册 #04】企业级 Agent 零信任权限审计与 AST 行级安全注入:防止长对话中途撤权泄密
下一篇: 【RAG 架构与评测实战 #01】确定性文档切分、受控 LLM 摘要增强与防注入预览输出
玄同765
玄同765 新星创作者: 人工智能技术领域 新星创作者: 人工智能技术领域
博客等级 码龄6年 1万+粉丝 262原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值