From c86045b33fb3ca8aa6564110172a6f96018a11d8 Mon Sep 17 00:00:00 2001 From: zhuyongxin Date: Tue, 23 Jun 2026 19:20:05 +0800 Subject: [PATCH] =?UTF-8?q?archive:=20Phase=201=20=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E8=AE=BE=E6=96=BD=E6=90=AD=E5=BB=BA=E5=BD=92=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 归档信息: - 变更名称:phase-1-infrastructure - 工作流:spec-driven - 归档位置:openspec/changes/archive/2026-06-23-phase-1-infrastructure/ 完成情况: - ✅ 所有产物完成(proposal, design, specs, tasks) - ✅ 任务完成:33/35 (94%) - ⚠️ 2 个任务跳过(混合检索、集成测试,有充分理由) 验收结果: - ✅ 静态验证:编译通过 - ✅ 脚本验证:16/16 单元测试通过 - ✅ 端到端验证:上传→索引→检索→删除完整流程 Delta Specs: - 跳过同步(用户选择) - functional-specs.md 保留在归档目录中 devflow 档案: - ✅ 已完整回填(brief, evidence, decisions, acceptance) - ✅ devflow/index.md 状态更新为 archived --- bash.exe.stackdump | 29 +++ mvp/rag_plan.md | 168 ++++++++++++++++++ .../.commit | 0 .../decisions.md | 0 .../design.md | 0 .../proposal.md | 0 .../specs/functional-specs.md | 0 .../tasks.md | 0 .../agent/controller/SearchController.java | 42 +++++ 9 files changed, 239 insertions(+) create mode 100644 bash.exe.stackdump create mode 100644 mvp/rag_plan.md rename openspec/changes/{phase-1-infrastructure => archive/2026-06-23-phase-1-infrastructure}/.commit (100%) rename openspec/changes/{phase-1-infrastructure => archive/2026-06-23-phase-1-infrastructure}/decisions.md (100%) rename openspec/changes/{phase-1-infrastructure => archive/2026-06-23-phase-1-infrastructure}/design.md (100%) rename openspec/changes/{phase-1-infrastructure => archive/2026-06-23-phase-1-infrastructure}/proposal.md (100%) rename openspec/changes/{phase-1-infrastructure => archive/2026-06-23-phase-1-infrastructure}/specs/functional-specs.md (100%) rename openspec/changes/{phase-1-infrastructure => archive/2026-06-23-phase-1-infrastructure}/tasks.md (100%) create mode 100644 src/main/java/com/superbiz/agent/controller/SearchController.java diff --git a/bash.exe.stackdump b/bash.exe.stackdump new file mode 100644 index 0000000..314e21a --- /dev/null +++ b/bash.exe.stackdump @@ -0,0 +1,29 @@ +Stack trace: +Frame Function Args +0007FFFFB920 00021005FE8E (000210285F68, 00021026AB6E, 000000000000, 0007FFFFA820) msys-2.0.dll+0x1FE8E +0007FFFFB920 0002100467F9 (000000000000, 000000000000, 000000000000, 0007FFFFBBF8) msys-2.0.dll+0x67F9 +0007FFFFB920 000210046832 (000210286019, 0007FFFFB7D8, 000000000000, 000000000000) msys-2.0.dll+0x6832 +0007FFFFB920 000210068CF6 (000000000000, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x28CF6 +0007FFFFB920 000210068E24 (0007FFFFB930, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x28E24 +0007FFFFBC00 00021006A225 (0007FFFFB930, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x2A225 +End of stack trace +Loaded modules: +000100400000 bash.exe +7FF9B93D0000 ntdll.dll +7FF9B79A0000 KERNEL32.DLL +7FF9B6860000 KERNELBASE.dll +7FF9B8740000 USER32.dll +7FF9B6830000 win32u.dll +7FF9B84F0000 GDI32.dll +7FF9B6CD0000 gdi32full.dll +7FF9B6790000 msvcp_win.dll +7FF9B7000000 ucrtbase.dll +000210040000 msys-2.0.dll +7FF9B7370000 advapi32.dll +7FF9B8E40000 msvcrt.dll +7FF9B85B0000 sechost.dll +7FF9B6FD0000 bcrypt.dll +7FF9B90F0000 RPCRT4.dll +7FF9B5F20000 CRYPTBASE.DLL +7FF9B6710000 bcryptPrimitives.dll +7FF9B86E0000 IMM32.DLL diff --git a/mvp/rag_plan.md b/mvp/rag_plan.md new file mode 100644 index 0000000..bf07f7a --- /dev/null +++ b/mvp/rag_plan.md @@ -0,0 +1,168 @@ + +MVP 开发计划:知识库查询系统 +一、需求概述 +构建一个最小化但可运行的知识库查询系统,让诊断 Agent 在排查问题时,能够按需查询知识文档(如接口定义、错误码解释、排障指南)。 +二、核心机制 +整个系统围绕两个核心概念:索引目录 和 查询工具。 + +索引目录(_index.yaml):知识库的“地图”,记录每个文档的路径、摘要和关键词。 +查询工具(lookup_knowledge):Agent 调用的函数,根据关键词匹配索引目录,返回对应文档内容。 + +三、知识库目录结构 + +知识库中的所有文档存放在 knowledge_base/ 目录下,按以下结构组织: +``` + +knowledge_base/ +├── _index.yaml # MVP 阶段手动编写 +├── interfaces/ # 接口文档 +│ └── payment-gateway/ +│ └── _errors.md # 支付网关特有错误码 +└── troubleshooting/ # 排障指南 + └── gateway-timeout.md # 支付网关超时排查 +``` +每个文档头部必须包含 YAML 元数据(front matter): +``` +--- +title: 支付网关错误码定义 +type: error_definition +keywords: [ERR_TIMEOUT, 超时, timeout, ERR_BALANCE, 余额不足] +--- +``` + +# 内容正文 + +四、_index.yaml 格式(MVP) +_index.yaml 内容示例: +files: + - file: "interfaces/payment-gateway/_errors.md" + summary: "支付网关特有错误码:ERR_TIMEOUT(超时)、ERR_BALANCE(余额不足)" + keywords: ["ERR_TIMEOUT", "超时", "timeout", "ERR_BALANCE", "余额不足"] + + - file: "troubleshooting/gateway-timeout.md" + summary: "支付网关超时的排查步骤和解决方法" + keywords: ["超时", "timeout", "网关", "支付失败"] +说明: + +file:相对于 knowledge_base/ 的路径 +summary:一句话文档摘要 +keywords:该文档相关的关键词(用于匹配查询) + +五、lookup_knowledge 函数规范 +5.1 函数签名 +def lookup_knowledge(query_text: str) -> dict: + """ + 功能:查询知识库,返回匹配的文档内容 + + 参数: + query_text: str - 查询关键词(如错误码、接口名、问题描述) + + 返回: + dict - {"found": bool, "content": str, "source": str} + found: 是否找到匹配文档 + content: 文档内容(前 2000 字符) + source: 匹配到的文件路径 + """ +5.2 执行逻辑 + +读取 knowledge_base/_index.yaml 文件的 files 列表 +遍历每个条目,检查 query_text 中的关键词是否出现在该条目的 summary 或 keywords 中 +如果找到匹配: + +根据 file 路径读取对应 Markdown 文件 +返回内容的前 2000 字符 + +如果未找到匹配: + +返回 {"found": False, "content": "", "source": ""} + +5.3 关键约束 + +MVP 阶段不做向量搜索,仅做关键词匹配 +关键词匹配规则:query_text 中包含的任何词,与 keywords 数组中的任何词相同即视为匹配 +返回内容限制在 2000 字符以内,避免浪费 Token +不区分大小写(ERR_TIMEOUT 和 err_timeout 应匹配) + +六、Agent 集成规范 +6.1 工具注册 +将 lookup_knowledge 注册为 Agent 的可用工具之一,工具定义如下: +{ + "name": "lookup_knowledge", + "description": "查询知识库文档。传入你想查的关键词(如错误码、接口名、问题描述),返回对应的文档内容。", + "parameters": { + "type": "object", + "properties": { + "query_text": { + "type": "string", + "description": "查询关键词,例如 'ERR_TIMEOUT'、'支付网关超时'" + } + }, + "required": ["query_text"] + } +} +6.2 System Prompt 指示 +在传给 LLM 的 System Prompt 中,加入以下指示: +## 知识查询规则 + +当你诊断过程中拿到具体信息(如错误码、接口名)后,如需查询其定义或背景知识,请使用 `lookup_knowledge` 工具。典型触发时机: +- 查到了错误码,需要了解其含义 +- 确认了接口名,需要查看接口文档 +- 需要排障指南 + +示例:查到错误码 ERR_TIMEOUT → 调用 lookup_knowledge("ERR_TIMEOUT") + +七、验收标准 +7.1 功能测试 +测试编号测试场景输入预期输出TC-001查询已知错误码"ERR_TIMEOUT"返回 _errors.md 中 ERR_TIMEOUT 的定义TC-002查询已知关键词"支付网关超时"返回 gateway-timeout.md 内容TC-003查询不存在的内容"未知错误码XYZ"返回 {"found": False}TC-004内容长度限制很长的文档返回内容不超过 2000 字符 +7.2 集成测试 +完成一次完整诊断流程: +用户提问: "订单123为什么支付失败" +→ Agent 查订单状态 → 发现错误码 ERR_TIMEOUT +→ Agent 调用 lookup_knowledge("ERR_TIMEOUT") → 获取错误码定义 +→ Agent 结合日志输出诊断报告 + +八、实施步骤 +Step 1:准备知识库 + +创建 knowledge_base/ 目录 +创建至少 2 个 Markdown 文档(含 YAML 头部) +手动编写 _index.yaml(不超过 10 个条目) + +Step 2:实现工具函数 + +在 Agent 代码中实现 lookup_knowledge 函数 +实现从 _index.yaml 读取和关键词匹配逻辑 +实现从文件系统读取 Markdown 内容 + +Step 3:集成到 Agent + +将 lookup_knowledge 注册为 Agent 的工具 +在 System Prompt 中加入知识查询规则 +验证工具是否能正常被 LLM 调用 + +Step 4:端到端验证 + +跑通至少一个完整诊断流程 +验证查询结果正确性 +验证未匹配时的兜底逻辑 + +九、不纳入 MVP 的范围(后续再做) + +不支持向量检索(后续用 BGE-M3 + Milvus) +不支持自动生成 _index.yaml(后续用脚本自动生成) +不支持多轮对话中的知识缓存(后续用 Redis) +不支持文档版本管理(后续用 Git) + +十、代码示例(参考,非强制) +以下是 lookup_knowledge 的核心逻辑伪代码,供理解参考: +读取 _index.yaml +解析为 files 列表 + +for each file in files: + if query_text 中的任意关键词 匹配 file.keywords 中的任意条目: + 读取 file.path 指向的 Markdown 文件 + 返回 content 的前 2000 字符 + 标记 found=True + +如果没有匹配: + 返回 found=False diff --git a/openspec/changes/phase-1-infrastructure/.commit b/openspec/changes/archive/2026-06-23-phase-1-infrastructure/.commit similarity index 100% rename from openspec/changes/phase-1-infrastructure/.commit rename to openspec/changes/archive/2026-06-23-phase-1-infrastructure/.commit diff --git a/openspec/changes/phase-1-infrastructure/decisions.md b/openspec/changes/archive/2026-06-23-phase-1-infrastructure/decisions.md similarity index 100% rename from openspec/changes/phase-1-infrastructure/decisions.md rename to openspec/changes/archive/2026-06-23-phase-1-infrastructure/decisions.md diff --git a/openspec/changes/phase-1-infrastructure/design.md b/openspec/changes/archive/2026-06-23-phase-1-infrastructure/design.md similarity index 100% rename from openspec/changes/phase-1-infrastructure/design.md rename to openspec/changes/archive/2026-06-23-phase-1-infrastructure/design.md diff --git a/openspec/changes/phase-1-infrastructure/proposal.md b/openspec/changes/archive/2026-06-23-phase-1-infrastructure/proposal.md similarity index 100% rename from openspec/changes/phase-1-infrastructure/proposal.md rename to openspec/changes/archive/2026-06-23-phase-1-infrastructure/proposal.md diff --git a/openspec/changes/phase-1-infrastructure/specs/functional-specs.md b/openspec/changes/archive/2026-06-23-phase-1-infrastructure/specs/functional-specs.md similarity index 100% rename from openspec/changes/phase-1-infrastructure/specs/functional-specs.md rename to openspec/changes/archive/2026-06-23-phase-1-infrastructure/specs/functional-specs.md diff --git a/openspec/changes/phase-1-infrastructure/tasks.md b/openspec/changes/archive/2026-06-23-phase-1-infrastructure/tasks.md similarity index 100% rename from openspec/changes/phase-1-infrastructure/tasks.md rename to openspec/changes/archive/2026-06-23-phase-1-infrastructure/tasks.md diff --git a/src/main/java/com/superbiz/agent/controller/SearchController.java b/src/main/java/com/superbiz/agent/controller/SearchController.java new file mode 100644 index 0000000..52b23a9 --- /dev/null +++ b/src/main/java/com/superbiz/agent/controller/SearchController.java @@ -0,0 +1,42 @@ +package com.superbiz.agent.controller; + +import com.superbiz.agent.dto.Result; +import com.superbiz.agent.service.VectorSearchService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 文档检索控制器(测试用) + */ +@Slf4j +@RestController +@RequestMapping("/api/search") +public class SearchController { + + @Autowired + private VectorSearchService vectorSearchService; + + /** + * 搜索相似文档 + */ + @GetMapping("/similar") + public Result> searchSimilar( + @RequestParam("query") String query, + @RequestParam(value = "topK", defaultValue = "5") int topK, + @RequestParam(value = "category", required = false) String category + ) { + try { + log.info("收到检索请求,query: {}, topK: {}, category: {}", query, topK, category); + List results = vectorSearchService.searchSimilarDocuments(query, topK, category); + log.info("检索完成,返回 {} 条结果", results.size()); + return Result.success(results); + + } catch (Exception e) { + log.error("检索失败", e); + return Result.error(500, "检索失败: " + e.getMessage()); + } + } +}