跳转至

11. 项目驱动学习法

十一、项目驱动学习法

基于统一业务领域的双轨道实战系统设计

在高级后端与 AI 工程实践中,孤立地学习检索增强生成(RAG)或智能体(Agent)常导致认知碎片化。RAG 项目易停留在简单的“向量检索-生成拼装”阶段,忽视了底层的数据一致性与权限屏障;而 Agent 项目则易沉溺于概率性的工具编排,忽视了物理副作用的幂等性与长周期状态自愈。

本节引入校园业务领域(Campus Domain)下的双轨道实战系统设计。通过在统一的业务实体边界内并发部署“校园知识库问答系统”与“论坛求助治理 Agent”,深度演练“被动知识检索”与“主动状态干预”两种截然不同的工程手感,并在运行时将二者打通,实现高内聚的系统级协同。

flowchart TD subgraph RagTrack["轨道一:被动知识检索 (Campus RAG)"] A1["文档解析清洗"] --> A2["向量化与 pgvector 存储"] A2 --> A3["在线检索与多路融合"] A3 --> A4["流式生成与引用装配"] end subgraph AgentTrack["轨道二:主动状态干预 (Campus Agent)"] B1["事件扫描与信号提取"] --> B2["OODA 决策与行动规划"] B2 --> B3["校园 RAG 检索 (调用轨道一)"] B3 --> B4["物理副作用执行 (回帖/私信/任务)"] B4 --> B5["长周期状态自愈与语义压缩"] end A4 -. "提供精准依据" .-> B3

轨道一:多租户高并发校园知识库问答系统

1. 核心系统实体数据模型(Go 实现)

轨道一的系统核心目标是建立一个具备严格多租户隔离、版本追踪与流式可观测性的知识检索引擎。

type Document struct {
    ID        string    `json:"id" db:"id"`
    Title     string    `json:"title" db:"title"`
    Source    string    `json:"source" db:"source"`
    TenantID  string    `json:"tenant_id" db:"tenant_id"` // 多租户隔离标识
    Version   int       `json:"version" db:"version"`     // 文档版本号
    IsActive  bool      `json:"is_active" db:"is_active"` // 软失效标识,防止旧版本被检索
    RawText   string    `json:"raw_text" db:"raw_text"`
    CreatedAt time.Time `json:"created_at" db:"created_at"`
}

type Chunk struct {
    ID         string    `json:"id" db:"id"`
    DocumentID string    `json:"document_id" db:"document_id"`
    Position   int       `json:"position" db:"position"` // 切块物理顺序偏移
    Text       string    `json:"text" db:"text"`
    Embedding  []float32 `json:"embedding" db:"embedding"` // pgvector 高维向量
}

type ChatLog struct {
    ID           string    `json:"id" db:"id"`
    SessionID    string    `json:"session_id" db:"session_id"`
    Question     string    `json:"question" db:"question"`
    Answer       string    `json:"answer" db:"answer"`
    RetrievedIds []string  `json:"retrieved_ids" db:"retrieved_ids"` // 关联召回的 Chunk ID 集合,支持回溯审计
    P95LatencyMs int64     `json:"p95_latency_ms" db:"p95_latency_ms"`
    CreatedAt    time.Time `json:"created_at" db:"created_at"`
}

2. 系统执行流与物理拓扑

flowchart TD A["离线上传: POST /documents"] --> B["写入临时 S3 并生成异步解析任务"] B --> C["Worker 集群: 解析/智能切块/Embedding"] C --> D[("存储中台: pgvector (带 Tenant_ID 与 IsActive 索引)")] E["在线提问: POST /chat/stream"] --> F["网关层: 鉴权与租户范围绑定"] F --> G["检索层: Pre-filtering 元数据过滤 + 多路召回"] G --> H["Rerank 二次重排 (Top-5 块)"] H --> I["模型调度: 绑定 Context 优雅取消流式返回 (SSE)"] I --> J["写入 ChatLog 审计库"]

3. 核心设计痛点与系统级边界控制

  • 异步建库管线与状态反馈(Async Ingestion):上传接口仅负责接收文档元数据并写入对象存储,随即发布任务至 RabbitMQ。后台 Worker 并发执行文本抽取、OCR、清洗、按句义语义切块并批量向量化。通过在 Document 中维护 ProcessingReadyFailed 状态,实现对高时延 I/O 操作的物理隔离与错误重试。
  • 动态版本淘汰机制(Active-Version Pruning):系统在 Chunk 查询阶段引入硬性前置过滤。当教务处发布新版退选通知时,离线管线自动将旧版 DocumentIsActive 字段置为 false,向量数据库索引匹配时执行 WHERE is_active = true AND tenant_id = :tenant_id,杜绝历史过期数据导致的推理偏移。
  • 引用保真装配与防漂移(Reference Grounding):为了防止模型自由臆造引用来源,系统采用强绑定物理片段机制。模型生成的文本块中必须携带特定标识(如 [chunk_idx]),API 底座在 SSE 流式写回时,拦截标识并替换为真实的 Document.Source 与物理片段链接,确保每一句论断都有据可查。
  • 连接挂断信号传播(Cancel Propagation):在 Go 运行时,通过 r.Context() 监听客户端 TCP 断连事件。一旦触发断连,信号级联传递至下游底层连接池,立即熔断尚未完成的 LLM 流式通道与检索 goroutine,防止孤儿请求持续侵占系统资源。

轨道二:基于状态自愈与审计治理的论坛求助治理 Agent

1. 核心系统实体数据模型(Go 实现)

轨道二的核心目标是构建一个能够自动扫描、提取意图、建议动作流并实现长周期事务自愈的主动治理引擎。

type HelpPost struct {
    ID         string    `json:"id" db:"id"`
    Title      string    `json:"title" db:"title"`
    Body       string    `json:"body" db:"body"`
    AuthorID   string    `json:"author_id" db:"author_id"`
    IsResolved bool      `json:"is_resolved" db:"is_resolved"`
    CreatedAt  time.Time `json:"created_at" db:"created_at"`
}

type AgentRun struct {
    ID          string    `json:"id" db:"id"`
    PostID      string    `json:"post_id" db:"post_id"`
    Status      string    `json:"status" db:"status"` // queued, running, pending_approval, resolved, failed
    TraceID     string    `json:"trace_id" db:"trace_id"`
    HopCounter  int       `json:"hop_counter" db:"hop_counter"` // 环路断路器计数
    CurrentStep string    `json:"current_step" db:"current_step"`
    UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
}

type AgentAction struct {
    ID             string    `json:"id" db:"id"`
    RunID          string    `json:"run_id" db:"run_id"`
    Kind           string    `json:"kind" db:"kind"` // reply_post, send_dm, escalate_task
    IdempotencyKey string    `json:"idempotency_key" db:"idempotency_key"` // 强幂等键,防止动作重复触发
    TargetID       string    `json:"target_id" db:"target_id"`
    Status         string    `json:"status" db:"status"` // pending, executed, failed
    ResponseRaw    string    `json:"response_raw" db:"response_raw"`
    CreatedAt      time.Time `json:"created_at" db:"created_at"`
}

type MatchCandidate struct {
    ID        string    `json:"id" db:"id"`
    Kind      string    `json:"kind" db:"kind"` // student_helper, office_staff, resource_entity
    Score     float64   `json:"score" db:"score"`
    Reason    string    `json:"reason" db:"reason"`
    CreatedAt time.Time `json:"created_at" db:"created_at"`
}

type ConversationSummary struct {
    ThreadID    string    `json:"thread_id" db:"thread_id"`
    Facts       string    `json:"facts" db:"facts"` // 提炼后的硬事实骨架
    OpenIssues  string    `json:"open_issues" db:"open_issues"` // 悬而未决的待办项
    LastVersion int       `json:"last_version" db:"last_version"`
    UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
}

2. 系统执行流与物理拓扑

flowchart TD A["论坛扫描任务 / MQ 事件触发"] --> B["创建 AgentRun 实例 (分配 TraceID 与 HopCounter)"] B --> C["大模型提取求助信号与隐私分类检测"] C --> D{"判定动作风险等级"} D -->|只读低风险:查知识库| E["调用轨道一 RAG 获取流程说明"] D -->|高风险写副作用:发私信或创建跟进| F["校验 Action IdempotencyKey"] F --> G["写入 Checkpoint 并挂起 (Interrupt)"] G --> H["发送人工审批通知"] H -->|审批通过| I["反序列化恢复执行 (Resume)"] I --> J["触发物理 Side Effect"] J --> K["增量压缩对话事实至 ConversationSummary"]

3. 核心设计痛点与系统级边界控制

  • 强幂等性动作治理(Action Idempotency):为了防止扫描定时器多次拉起相同帖子导致 Agent 重复执行发私信或建任务等副作用,系统在执行任何 AgentAction 前必须生成唯一的 IdempotencyKey(通常基于 PostID + Kind + TargetID 的哈希)。底层执行引擎在事务内执行 INSERT INTO agent_actions,若触发唯一键冲突,则立即放弃物理执行,确保 side effect 的幂等安全性。
  • 多 Hop 环路断路器(Hop Counter & Circuit Breaker):为防止 Agent 在执行过程中由于意图抽取漂移,在多个 Specialist 智能体或工具之间陷入无限递归调用(如 Agent A 私信 Agent B,Agent B 触发回帖,回帖又被 Agent A 扫描),系统强制在 AgentRun 中染色传递 trace_idhop_counter。每流转一步,hop_counter 自增,一旦突破系统上限(如 > 6),底座强制执行熔断(Circuit Breaker),挂起任务并转人工接管。
  • 长周期会话压缩与语义降噪(Semantic Compaction):针对长周期的多轮求助跟进,若将冗长历史全量塞入模型,将迅速导致指令稀释与运行开销飙升。系统在每轮交互结束后,启动增量压缩管线,剥离语气词与寒暄,提炼出结构化的“已确立事实集”与“挂起问题列表”,更新至 ConversationSummary。下一轮循环时仅加载该摘要,保障决策模型的工作记忆高度纯净。
  • 环境与隐私安全屏障(Privacy Gate):学生发帖中可能夹带个人联系方式、学号等隐私字段。在 Agent 将数据提交至外部大模型前,底座沙箱必须运行本地过滤规则或轻量级 PII(Personally Identifiable Information)检测模型,脱敏后再行传输;在动作回帖前,系统也必须执行白名单词汇库与安全围栏校验,防止输出不当内容。

双轨道实战系统演进路线图

双轨实战系统绝非一次性构建的 Demo,而必须严格遵循分层迭代的演进路径,以防止开发路径过长导致项目失控崩溃。

迭代阶段 轨道一 (Campus RAG) 建设卡点 轨道二 (Campus Agent) 建设卡点 支撑系统核心指标与安全基准
v1 阶段 (骨架贯通) 1. 跑通同步文档上传、提取、切块。
2. 向量检索 Top-K 文本片段直接送入 LLM。
3. 实现基本的流式 HTTP SSE 接口。
1. 定期扫描论坛求助帖事件。
2. 大模型单步判定是否需要求助。
3. 只读调用 RAG 接口返回自动回帖建议。
核心目标:单次 OODA 受控循环跑通,无并发冲突,打通底座 Go 后端与 LLM 的基本连接。
v2 阶段 (边界治理) 1. 引入 RabbitMQ,将解析与向量化彻底异步化。
2. 实现 Pre-filtering 多租户与版本淘汰过滤。
3. 建立 Context 挂断信号的全链路传播回收。
1. 引入 IdempotencyKey 唯一索引限制,确保物理操作幂等。
2. 建立 Task Checkpoint 并支持 Durable Execution
3. 引入高风险写动作的人工介入卡点。
核心目标:实现系统确定性硬边界,防范数据串漏、重复调用及孤儿资源泄露,确保 side effect 完全受控。
v3 阶段 (性能与演进) 1. 部署 BM25 + pgvector 混合检索与 RRF 融合。
2. 接入 Rerank 服务调优 P95 延迟。
3. 部署 Query Cache 与 Embedding Cache。
1. 部署 ConversationSummary 增量压缩管线。
2. 建立 TraceID 跨应用追踪与 Hop 环路断路器。
3. 搭建离线 Golden 评测集与线上影子评测。
核心目标:在高并发大流量下保障亚秒级延迟与极低 Token 消耗,提供长周期事务的自愈与全面治理。

通过双轨道的深度配合与循序渐进的系统级重构,开发者将在同一套真实的系统边界内,切实掌握“高并发概率计算”与“分布式确定性架构”相交融的顶级工程设计艺术。