diff --git a/.env.template b/.env.template index db821d37..4fecc16e 100644 --- a/.env.template +++ b/.env.template @@ -34,10 +34,6 @@ YUXI_INSTANCE_ID= # # MinerU # MINERU_API_KEY= -# LightRag llm 并发限制 -# MAX_ASYNC=5 -# EMBEDDING_FUNC_MAX_ASYNC=8 - # Sandbox (deerFlow-style provisioner) # SANDBOX_PROVIDER=provisioner # SANDBOX_PROVISIONER_URL=http://sandbox-provisioner:8002 @@ -48,7 +44,6 @@ YUXI_INSTANCE_ID= # SANDBOX_IDLE_TIMEOUT_SECONDS=120 # SANDBOX_IDLE_CHECK_INTERVAL_SECONDS=10 # # sandbox-provisioner backend: memory | docker | kubernetes -# # `local` 仍兼容,但只是 `docker` 的历史别名,不再推荐继续配置 # SANDBOX_PROVISIONER_BACKEND=docker # sandbox-provisioner 通用配置 @@ -59,7 +54,7 @@ YUXI_INSTANCE_ID= # SANDBOX_HTTP_PROXY=http://host.docker.internal:7897 # SANDBOX_HTTPS_PROXY=http://host.docker.internal:7897 -# Docker backend 专用 (used when SANDBOX_PROVISIONER_BACKEND=docker/local) +# Docker backend 专用 (used when SANDBOX_PROVISIONER_BACKEND=docker) # 注意:网络名称已在 docker-compose.yml 中固定为 yuxi-know_app-network # SANDBOX_DOCKER_NETWORK=yuxi-know_app-network # SANDBOX_DOCKER_THREADS_HOST_PATH= @@ -71,4 +66,4 @@ YUXI_INSTANCE_ID= # SANDBOX_NODE_HOST=host.docker.internal # KUBECONFIG_PATH=/root/.kube/config # THREAD_PVC=yuxi-thread -# SKILLS_PVC=yuxi-skills # 当前代码会读取,但 Pod 挂载实际仍只使用 THREAD_PVC \ No newline at end of file +# SKILLS_PVC=yuxi-skills # 当前代码会读取,但 Pod 挂载实际仍只使用 THREAD_PVC diff --git a/README.en.md b/README.en.md index 4e2abe19..bc08554d 100644 --- a/README.en.md +++ b/README.en.md @@ -22,13 +22,13 @@ ## Introduction -Yuxi is an LLM-powered platform for building knowledge-base and knowledge-graph agents. It unifies **RAG retrieval**, **LightRAG knowledge graphs**, and **LangGraph multi-agent orchestration** into a single multi-tenant workspace: administrators configure knowledge bases, models, and permissions, while users chat — in a ChatGPT-like interface — with agents that can mount Skills, MCPs, sub-agents, and sandbox tools, and receive answers with cited sources, graph-based reasoning, and deliverable artifacts. +Yuxi is an LLM-powered platform for building knowledge-base and knowledge-graph agents. It unifies **RAG retrieval**, **Milvus-backed in-knowledge-base graphs**, and **LangGraph multi-agent orchestration** into a single multi-tenant workspace: administrators configure knowledge bases, models, and permissions, while users chat — in a ChatGPT-like interface — with agents that can mount Skills, MCPs, sub-agents, and sandbox tools, and receive answers with cited sources, graph-based reasoning, and deliverable artifacts. ## Core Features - 🤖 **Agent development** — Built on LangGraph, with sub-agents (SubAgents), Skills, MCPs, Tools, and middleware; long-running tasks run asynchronously on a background worker, backed by a sandbox file system for persisting, previewing, and downloading tool artifacts. - 📚 **Knowledge base (RAG)** — Multi-format document parsing (MinerU / PaddleX / OCR), configurable Embedding and Rerank models, knowledge base evaluation, in-app PDF / image preview, and retrieval sources backfilled as chat citations. -- 🕸️ **Knowledge graph** — Graph construction and visualization based on LightRAG, with property graph support that feeds directly into agent reasoning. +- 🕸️ **Knowledge graph** — Build, visualize, and retrieve entity-relation graphs inside Milvus knowledge bases, then fuse graph hits with chunk retrieval for agent reasoning. - 🏢 **Multi-tenancy & permissions** — User / department-level access control, unified model provider configuration, and API Key authentication for external system integration. - ⚙️ **Platform & engineering** — Vue + FastAPI architecture, ready-to-run Docker Compose deployment, dark mode, a lightweight LITE startup mode, and production-grade orchestration. @@ -49,7 +49,7 @@ Yuxi is an LLM-powered platform for building knowledge-base and knowledge-graph **1. Clone and initialize** ```bash -git clone --branch v0.7.0.dev0 --depth 1 https://github.com/xerrors/Yuxi.git +git clone --branch v0.7.0.dev1 --depth 1 https://github.com/xerrors/Yuxi.git cd Yuxi # Linux/macOS diff --git a/README.md b/README.md index f1fb902f..eac269e4 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,13 @@ ## 简介 -语析(Yuxi)是一个基于大模型的智能知识库与知识图谱智能体开发平台。它把 **RAG 检索**、**LightRAG 知识图谱** 与 **LangGraph 多智能体编排** 整合进统一的多租户工作台:管理员配置知识库、模型与权限,用户在类 ChatGPT 的界面中与可挂载 Skills、MCP、子智能体和沙盒工具的智能体对话,并获得带引用来源、知识图谱推理与可交付产物的回答。 +语析(Yuxi)是一个基于大模型的智能知识库与知识图谱智能体开发平台。它把 **RAG 检索**、**Milvus 知识库内知识图谱** 与 **LangGraph 多智能体编排** 整合进统一的多租户工作台:管理员配置知识库、模型与权限,用户在类 ChatGPT 的界面中与可挂载 Skills、MCP、子智能体和沙盒工具的智能体对话,并获得带引用来源、知识图谱推理与可交付产物的回答。 ## 核心特性 - 🤖 **智能体开发** —— 基于 LangGraph 构建,支持子智能体(SubAgents)、Skills、MCP、Tools 与中间件机制;长耗时任务由后台 worker 异步执行,配套沙盒文件系统支持工具产物落盘、预览与下载。 - 📚 **知识库(RAG)** —— 多格式文档解析(MinerU / PaddleX / OCR),可配置 Embedding 与 Rerank 模型,支持知识库评估与 PDF / 图片在线预览,检索来源回填到对话引用。 -- 🕸️ **知识图谱** —— 基于 LightRAG 的图谱构建与可视化,支持属性图谱,并作为检索增强直接参与智能体推理。 +- 🕸️ **知识图谱** —— 在 Milvus 知识库内构建、展示和检索实体关系图谱,并与 chunk 检索结果融合参与智能体推理。 - 🏢 **多租户与权限** —— 用户 / 部门级权限管理,模型供应商统一配置,支持 API Key 认证供外部系统集成调用。 - ⚙️ **平台与工程化** —— Vue + FastAPI 架构,开箱即用的 Docker Compose 部署,支持暗黑模式、LITE 轻量启动与生产级编排。 @@ -84,7 +84,7 @@ - 新增内置 Skills `deep-reporter`,用于指导生成科研报告、行业调研和其他深度分析类长报告 - 重构内置 Skills/MCP/Subagents 安装/添加/移除机制:内置 skill 支持按需安装、基于 `version + content_hash` 的更新提示与覆盖确认,不再使用服务器级开关切换 - 新增知识库 PDF、图片的预览功能 -- 重构后端测试目录结构:按 `unit / integration / e2e` 分层迁移现有测试,拆分全局 `conftest.py`,统一测试入口为 `uv run --group test pytest`,并新增独立测试规范文档 `docs/vibe/testing-guidelines.md` +- 重构后端测试目录结构:按 `unit / integration / e2e` 分层迁移现有测试,拆分全局 `conftest.py`,统一测试入口为 `uv run --group test pytest`,并新增独立测试规范文档 `docs/develop-guides/testing-guidelines.md` ### 修复 @@ -124,7 +124,7 @@ **1. 克隆代码并初始化** ```bash -git clone --branch v0.7.0.dev0 --depth 1 https://github.com/xerrors/Yuxi.git +git clone --branch v0.7.0.dev1 --depth 1 https://github.com/xerrors/Yuxi.git cd Yuxi # Linux/macOS diff --git a/REFACTOR.md b/REFACTOR.md index 8da6bf5a..a87fe73a 100644 --- a/REFACTOR.md +++ b/REFACTOR.md @@ -24,10 +24,10 @@ - [x] add model retry times to agent context config - [x] 添加用户级别的 Skills 的安装 - [x] Skill 卡片优化 -- [ ] 拓展 Skill 安装方法 +- [x] 拓展 Skill 安装方法 - [x] MCP 部分,未添加情况下无法获取工具 -- [ ] 添加 MCP 移除 JSON 模式 -- [ ] 工作区允许上传多个文件 +- [x] 添加 MCP 移除 JSON 模式 +- [x] 工作区允许上传多个文件 - [x] 子智能体的消息渲染与可视化 - [x] 子智能体的优化,参考 PR 的方案。 - [x] 附件上传能够支持转换为 PDF,待办:查看 OCR 模型的状态,样式优化,保存的文件名不对 @@ -51,5 +51,14 @@ - [x] parser 从plugins 移动到 knowledge 里面,guard 移动到services 里面 - [x] neo4j 相关的服务,可以移动到 storage 里面 - [ ] 点开对话的时候要能够自动定位到尾部,而不是最开始。 +- [x] 评估要支持填写评估的名称,默认是时间戳加 hash 类似于 eval-20240918-xxxxxx +- [x] 优化评估综合评分 +- [ ] 优化思维导图构建的接口设计,支持增量构建和更新 +- [ ] 如何将 PWD 修改为 user-data - [x] 将 Qwen-Image 修改为 Skill - [x] 现在输入区域对于不同 mention 的渲染的 ICON 和 human-message 里面的渲染的 ICON; +- [x] 节点的颜色按照 label 的分类来 + +# bug + +- [ ] 知识库、知识图谱、评估基准的空状态是不一样的,需要统一 diff --git a/docs/advanced/api-key-integration.md b/docs/advanced/api-key-integration.md index 2c8331e2..46a17a01 100644 --- a/docs/advanced/api-key-integration.md +++ b/docs/advanced/api-key-integration.md @@ -4,7 +4,7 @@ Yuxi 平台提供了 API Key 认证机制,允许外部系统在无需用户登 ## API Key 概述 -API Key 是一种用于身份验证的密钥字符串,外部系统可以通过它在请求头中携带凭据来访问 Yuxi 的对话接口。与传统的用户名密码登录方式相比,API Key 更加适合用于系统间的自动化调用场景。Yuxi 的 API Key 以 `yxkey_` 为前缀,长度为 56 个字符,采用 SHA-256 哈希存储,确保密钥本身不会在数据库中明文保存。系统会记录每个 API Key 的最后使用时间,方便管理员追踪使用情况。 +API Key 是一种用于身份验证的密钥字符串,外部系统可以通过它在请求头中携带凭据来访问 Yuxi 的对话接口。与传统的用户名密码登录方式相比,API Key 更加适合用于系统间的自动化调用场景。Yuxi 的 API Key 以 `yxkey_` 为前缀,长度为 54 个字符,采用 SHA-256 哈希存储,确保密钥本身不会在数据库中明文保存。系统会记录每个 API Key 的最后使用时间,方便管理员追踪使用情况。 ## 创建 API Key @@ -12,42 +12,116 @@ API Key 是一种用于身份验证的密钥字符串,外部系统可以通过 需要特别注意的是,创建 API Key 时返回的完整密钥(secret)只会显示一次,务必在创建时将其安全保存。如果遗失,需要通过"重新生成"功能生成新的密钥,原有的密钥将立即失效。 +管理接口同样走通用认证: + +- `GET /api/user/apikey/`:列出当前用户可见的 API Key +- `POST /api/user/apikey/`:创建 API Key +- `PUT /api/user/apikey/{api_key_id}`:更新名称、状态或过期时间 +- `POST /api/user/apikey/{api_key_id}/regenerate`:重新生成密钥 +- `DELETE /api/user/apikey/{api_key_id}`:删除密钥 + ## 接口调用方式 -外部系统通过 HTTP 请求调用 Yuxi 的对话接口,需要在请求头中携带 API Key。流式接口地址为 `POST /api/agent/chat`,非流式接口地址为 `POST /api/agent/chat/sync`(不支持 HITL)。请求头需要包含 `Authorization` 字段,值格式为 `Bearer `,其中 `` 是创建 API Key 时获取的完整密钥。请求体为 JSON 格式,必填字段为 `query` 和 `agent_id`,可选字段为 `thread_id`、`image_content` 和 `meta`。 +外部系统通过 HTTP 请求调用 Yuxi 接口时,需要在请求头中携带 API Key: + +```http +Authorization: Bearer yxkey_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + +当前智能体对话采用 run + SSE 流程: + +1. 创建对话线程:`POST /api/chat/thread` +2. 创建运行任务:`POST /api/agent/runs` +3. 订阅事件流:`GET /api/agent/runs/{run_id}/events` + +`POST /api/agent/runs` 请求体必填 `query`、`agent_id` 和 `thread_id`,可选字段包括 `meta`、`image_content`、`resume`、`parent_run_id`、`resume_request_id`。接口返回 `run_id`、`thread_id`、`status`、`request_id` 和 `stream_url`。 以下是一个典型的 Python 调用示例: ```python -import requests import json +import requests -url = "http://your-yuxi-server/api/agent/chat" +base_url = "http://your-yuxi-server" headers = { "Authorization": "Bearer yxkey_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "Content-Type": "application/json" -} -payload = { - "query": "你好,请介绍一下你自己", - "agent_id": "default-chatbot", - "meta": {} + "Content-Type": "application/json", } -response = requests.post(url, headers=headers, json=payload, stream=True) -for line in response.iter_lines(): - if line: - print(line.decode('utf-8')) +thread_resp = requests.post( + f"{base_url}/api/chat/thread", + headers=headers, + json={ + "agent_id": "default-chatbot", + "title": "外部系统会话", + "metadata": {}, + }, +) +thread_resp.raise_for_status() +thread_id = thread_resp.json()["id"] + +run_resp = requests.post( + f"{base_url}/api/agent/runs", + headers=headers, + json={ + "query": "你好,请介绍一下你自己", + "agent_id": "default-chatbot", + "thread_id": thread_id, + "meta": {"request_id": "external-request-001"}, + }, +) +run_resp.raise_for_status() +run = run_resp.json() + +with requests.get(f"{base_url}{run['stream_url']}", headers=headers, stream=True) as response: + response.raise_for_status() + event_type = None + data_lines = [] + + for line in response.iter_lines(decode_unicode=True): + if line is None: + continue + if line.startswith(":"): + continue + + if line == "": + if event_type and data_lines: + payload = json.loads("\n".join(data_lines)) + print(event_type, payload) + if event_type == "end": + break + event_type = None + data_lines = [] + continue + + if line.startswith("event:"): + event_type = line.removeprefix("event:").strip() + elif line.startswith("data:"): + data_lines.append(line.removeprefix("data:").strip()) ``` -该接口返回的是流式响应(Server-Sent Events),每个事件是一行 JSON 数据,包含对话的增量内容。客户端需要逐行解析并处理这些事件来构建完整的对话结果。 +如果已经有会话线程,可以复用已有 `thread_id` 直接创建 run: + +```json +{ + "query": "继续上一轮话题", + "agent_id": "default-chatbot", + "thread_id": "existing-thread-id", + "meta": {} +} +``` ## 响应格式 -接口返回的流式响应采用 JSON Lines 格式,每行代表一个事件。常见的事件类型包括: +运行事件流采用 Server-Sent Events 格式,响应头为 `text/event-stream`。每个事件包含: -`event: data` 表示数据事件,携带实际的对话内容。`event: error` 表示错误事件,当对话过程中发生错误时会收到此类事件。`event: done` 表示完成事件,标志对话结束。 +- `event`:事件类型,可能是模型输出、工具调用、子智能体输出等语义事件,也可能是 `error` 或终止事件 `end` +- `data`:JSON 编码的事件 envelope,包含 `run_id`、`thread_id`、事件载荷等字段 +- `id`:Redis Stream 序号,可作为断线重连游标 -每次调用都会在响应中包含 `request_id`,这是本次对话的唯一标识符,可用于日志追踪和问题排查。如果需要在多轮对话中使用同一个会话,可以通过 `thread_id` 参数指定线程 ID,系统会将同一线程的消息串联起来形成连贯的对话上下文。 +服务端还会定期发送以 `:` 开头的 heartbeat 注释,客户端应忽略。断线重连时,可以在请求头中传 `Last-Event-ID`,或在 query 参数中传 `after_seq`,服务端会从该序号后继续回放事件。 + +每次创建 run 都会返回 `request_id`,可用于日志追踪和问题排查。如果需要在多轮对话中使用同一个会话,请复用 `thread_id`,系统会将同一线程的消息串联起来形成连贯的对话上下文。 ## 认证方式 diff --git a/docs/advanced/configuration.md b/docs/advanced/configuration.md index cd270d3e..f8c3a049 100644 --- a/docs/advanced/configuration.md +++ b/docs/advanced/configuration.md @@ -13,7 +13,7 @@ ## 模型配置 -由网页统一管理,详见 [模型配置](./intro/model-config.md)。 +由网页统一管理,详见 [模型配置](../intro/model-config.md)。 ## 应用配置 diff --git a/docs/advanced/document-processing.md b/docs/advanced/document-processing.md index 3464b867..9147b826 100644 --- a/docs/advanced/document-processing.md +++ b/docs/advanced/document-processing.md @@ -8,8 +8,9 @@ Yuxi 支持多种文档格式的智能解析,从简单的文本文件到复杂 | 类型 | 格式 | 说明 | |------|------|------| -| 文本 | .txt, .md, .html | 直接提取内容 | +| 文本 | .txt, .md, .html, .htm | 直接提取内容 | | Word | .docx | 保留格式和结构 | +| PowerPoint | .pptx | 保留主要文本结构 | | PDF | .pdf | 支持文本和图片 PDF | | 表格 | .csv, .xls, .xlsx | 识别表格结构 | | JSON | .json | 结构化数据 | @@ -17,7 +18,7 @@ Yuxi 支持多种文档格式的智能解析,从简单的文本文件到复杂 ### 图片文件 对于图片文件,需要启用 OCR 才能提取文字: -- .jpg, .jpeg, .png, .bmp, .tiff, .tif, .gif, .webp +- .jpg, .jpeg, .png, .bmp, .tiff, .tif ### 压缩包 diff --git a/docs/advanced/third-party-auth.md b/docs/advanced/third-party-auth.md index d6a1df1c..e169880c 100644 --- a/docs/advanced/third-party-auth.md +++ b/docs/advanced/third-party-auth.md @@ -69,7 +69,7 @@ Yuxi 支持以OIDC接入第三方登录认证,方便企业用户集成现有 # OIDC_NAME_CLAIM=name # 是否使用原始用户名(不带 oidc: 前缀),允许映射到 Yuxi 已有的本地账号 (true/false,默认: false) -# 开启后,OIDC 返回的 username 会直接作为 user_id 登录,需要管理员提前创建好用户账号 +# 开启后,OIDC 返回的 username 会直接作为业务登录标识 uid 登录,需要管理员提前创建好用户账号 # OIDC_USE_RAW_USERNAME=false # 是否从OIDC userinfo 中获取部门信息并自动创建关联部门 (true/false,默认: false) @@ -78,8 +78,8 @@ Yuxi 支持以OIDC接入第三方登录认证,方便企业用户集成现有 # 部门名称字段映射 (默认: department) # OIDC_DEPARTMENT_CLAIM=department -# OIDC 登录时是否强制提示用户重新登录 (添加 prompt=login 参数,true/false,默认: false) -# OIDC_FORCE_PROMPT_LOGIN=false +# OIDC 登录时是否强制提示用户重新登录 (添加 prompt=login 参数,true/false,默认: true) +# OIDC_FORCE_PROMPT_LOGIN=true ``` ### 3. 重启Yuxi服务使配置生效 @@ -93,11 +93,11 @@ docker restart api-dev web-dev 当你需要将 Yuxi 系统中已有的本地账号与 OIDC SSO 绑定,可以开启此选项。 **绑定原理**(无需修改数据库): -系统会创建一个标记为删除的占位用户 `oidc:{sub}:{target_user_id}` 来记录 OIDC sub 与 Yuxi 用户的绑定关系,确保只有绑定过的 OIDC 身份才能登录对应的账号,**防止账号冒用**。 +系统会创建一个标记为删除的占位用户 `oidc:{sub}:{target_user_id}` 来记录 OIDC sub 与 Yuxi 用户的绑定关系,确保只有绑定过的 OIDC 身份才能登录对应的账号,**防止账号冒用**。其中 `target_user_id` 是数据库中的数值 `users.id`;用户登录标识仍使用字符串 `uid`。 ### 自动获取部门信息(OIDC_FETCH_DEPARTMENT_INFO=true) 开启后,系统会从 OIDC userinfo 中读取部门名称和描述,自动在 Yuxi 中创建部门并将用户关联到该部门。 - 对从 OIDC 获取的部门名称会自动做 `strip()` 去空格,并截断到 50 字符 - 部门描述会自动截断到 255 字符 -- 如果部门名称处理后为空,会回退到使用 `OIDC_DEFAULT_DEPARTMENT` 默认部门 \ No newline at end of file +- 如果部门名称处理后为空,会回退到使用 `OIDC_DEFAULT_DEPARTMENT` 默认部门 diff --git a/docs/agents/agents-config.md b/docs/agents/agents-config.md index 79f0d6f0..67355ea5 100644 --- a/docs/agents/agents-config.md +++ b/docs/agents/agents-config.md @@ -232,21 +232,20 @@ config_json.context + runtime ids -> context_schema instance - `_prompt_skills`:需要注入提示词的 Skill 闭包 - `_readable_skills`:`/home/gem/skills` 和沙盒可读的 Skill 闭包 -中间件通过 `request.runtime.context` 或 `runtime.context` 继续读取这些结果。 +随后 Graph 构建会直接使用这份 Context: -例如: +- `load_chat_model(context.model)` 选择主模型 +- `build_prompt_with_context(context)` 生成系统提示词 +- `resolve_configured_runtime_tools(context)` 组装已配置的内置工具和 MCP 工具 +- `KnowledgeBaseMiddleware` 根据 `_visible_knowledge_bases` 暴露知识库工具 +- `SkillsMiddleware` 根据 `_prompt_skills` 注入 Skill 提示段,并在 Skill 被激活后按需挂载工具与 MCP 依赖 +- `save_attachments_to_fs` 将线程附件转换为运行时可读的文件提示 -- `RuntimeConfigMiddleware` - - 读取 `model`、`system_prompt`、`tools`、`mcps` - - 动态覆盖模型、系统提示词和工具列表 -- `SkillsMiddleware` - - 读取 `_prompt_skills` 注入 skills 提示段 - - 读取 `_readable_skills` 校验可激活 Skill - - 根据 `activated_skills` 按需挂载工具和 MCP 依赖 -- 文件系统与沙盒接入 - - 普通 Agent 默认使用当前 `thread_id` 作为文件与 Skills 作用域 - - 子智能体使用 child `thread_id` 做 checkpoint,`file_thread_id` 指向父会话 uploads/outputs,`skills_thread_id` 指向子智能体自身 Skills 作用域 - - 通过 `_readable_skills` 决定 `/home/gem/skills` 的可读范围 +文件系统与沙盒接入同样读取这些运行时字段: + +- 普通 Agent 默认使用当前 `thread_id` 作为文件与 Skills 作用域 +- 子智能体使用 child `thread_id` 做 checkpoint,`file_thread_id` 指向父会话 uploads/outputs,`skills_thread_id` 指向子智能体自身 Skills 作用域 +- 通过 `_readable_skills` 决定 `/home/gem/skills` 的可读范围 所以 Context 既是输入配置,也是 Graph 创建前整理出的运行时资源上下文。 diff --git a/docs/agents/middleware.md b/docs/agents/middleware.md index 6ec41273..76a9aa26 100644 --- a/docs/agents/middleware.md +++ b/docs/agents/middleware.md @@ -4,28 +4,32 @@ ## 核心中间件 -### RuntimeConfigMiddleware +### 运行时配置准备 -这是系统的默认中间件,负责在每次模型调用前注入运行时配置: +当前版本不再使用单独的旧版运行时配置中间件。内置 Agent 在创建 Graph 前完成运行时配置准备: -- 自动注入当前时间到系统提示词 -- 根据配置动态加载工具列表 -- 处理模型选择和加载 +- `prepare_agent_runtime_context`:按当前用户权限过滤工具、知识库、MCP 和 Skills,并派生 `_visible_knowledge_bases`、`_prompt_skills`、`_readable_skills` +- `build_prompt_with_context`:基于 Context 生成系统提示词 +- `load_chat_model(context.model)`:加载主模型 +- `resolve_configured_runtime_tools(context)`:加载已配置的内置工具和 MCP 工具 -### inject_attachment_context +### save_attachments_to_fs 支持文件上传功能的中间件。如果智能体需要处理用户上传的文档,可以启用此中间件: ```python -from yuxi.agents.middlewares import inject_attachment_context +from yuxi.agents.middlewares import save_attachments_to_fs +from yuxi.agents.middlewares.knowledge_base import KnowledgeBaseMiddleware +from yuxi.agents.middlewares.skills import SkillsMiddleware async def get_graph(self): graph = create_agent( model=load_chat_model("..."), tools=tools, middleware=[ - inject_attachment_context, # 启用附件处理 - context_aware_prompt, # 其他中间件 + save_attachments_to_fs, + KnowledgeBaseMiddleware(), + SkillsMiddleware(), ], checkpointer=await self._get_checkpointer(), ) @@ -37,7 +41,19 @@ async def get_graph(self): 启用文件上传能力需要两步: 1. 在智能体类中声明 `capabilities = ["file_upload"]` -2. 添加上述中间件 +2. 在 Graph 的 `middleware` 列表中加入 `save_attachments_to_fs` + +### KnowledgeBaseMiddleware + +根据运行时 `_visible_knowledge_bases` 暴露知识库工具,包括 `list_kbs`、`query_kb`、`find_kb_document`、`open_kb_document` 和 `get_mindmap`。知识库可见范围已经在 Graph 创建前按当前用户和 Agent 配置过滤。 + +### SkillsMiddleware + +负责 Skills 的请求级提示词注入、Skill 激活校验,以及激活后按需加载 `tool_dependencies` 和 `mcp_dependencies`。它读取 `prepare_agent_runtime_context` 派生出的 `_prompt_skills` 与 `_readable_skills`,不会把 Skills 提示永久写回 Context。 + +### 子智能体与摘要 + +主 Agent 在配置了子智能体时会挂载 Yuxi task middleware,用真实子 Agent graph 执行任务;子智能体自身不会继续挂载下一层子智能体。长对话压缩使用 DeepAgents 的 SummarizationMiddleware,由 Yuxi 的 `create_summary_middleware` 封装接入。 ## 自定义中间件 diff --git a/docs/agents/skills-management.md b/docs/agents/skills-management.md index 5eaebae7..bc2f42e1 100644 --- a/docs/agents/skills-management.md +++ b/docs/agents/skills-management.md @@ -24,7 +24,10 @@ Skills 系统采用「文件系统存内容,数据库存索引」的分离架 │ │ └── prompts/ │ - name │ │ │ └── skill-b/ │ - description│ │ │ ├── SKILL.md │ - dir_path │ │ -│ └── ... │ - deps... │ │ +│ └── ... │ - source_type│ │ +│ │ - share_config │ +│ │ - enabled │ │ +│ │ - deps... │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ @@ -33,21 +36,23 @@ Skills 系统采用「文件系统存内容,数据库存索引」的分离架 ### 存储结构 - **文件系统**:`/app/saves/skills` 目录下,每个 Skill 占用一个子目录 -- **数据库索引**:`skills` 表存储元数据(slug、name、description、依赖关系等) +- **数据库索引**:`skills` 表存储元数据(slug、name、description、来源、共享范围、启用状态、依赖关系等) - **关联机制**:通过 `dir_path` 字段关联文件系统目录与数据库记录 ::: tip 不能直接在文件系统创建 -由于 Skills 的元数据需要写入数据库,因此不能直接在文件系统中创建 Skill。必须通过系统的导入功能或在线创建功能来完成,系统会自动处理数据库记录的创建。 +由于 Skills 的元数据需要写入数据库,因此不能直接在文件系统中创建 Skill。必须通过系统的导入或安装功能来完成,系统会自动处理数据库记录的创建。 ::: ## 创建方式 -系统提供四种方式创建 Skills: +系统提供以下方式创建或安装 Skills: -1. **ZIP 导入(推荐)**:将 Skill 目录打包成 ZIP,通过管理界面上传导入 -2. **在线创建**:通过 Skills 管理页面在线创建目录和文件 -3. **远程仓库安装**:在 Skills 管理页面填写 skills 仓库地址和 skill 名称,由后端调用 `npx skills` 下载后再导入系统 -4. **手动导入**:直接操作数据库(不推荐,需要手动同步文件系统和数据库) +1. **ZIP / SKILL.md 上传(推荐)**:上传后先解析为安装草稿,确认共享范围后再写入正式 Skills 存储和数据库 +2. **远程仓库安装**:填写 skills 仓库地址和 skill 名称,后端调用 `npx skills` 下载并解析为安装草稿,确认后导入系统 +3. **在线编辑**:对已有且可管理的 Skill 在线创建目录、编辑文件和维护依赖 +4. **Agent 内安装**:主智能体可通过 `install_skill` 工具,从沙盒路径或 Git 来源安装当前用户私有 Skill;子智能体禁用该工具 + +不建议直接操作数据库或文件系统导入 Skill。直接写文件不会自动生成 `skills` 表记录,也无法参与权限、依赖和沙盒挂载。 ## Skills 来源 @@ -108,34 +113,40 @@ description: 这是一个用于处理特定任务的技能 有三种方式可以导入 Skill: -**方式一:通过 ZIP 包导入(推荐)** +**方式一:通过 ZIP 包或 SKILL.md 上传(推荐)** 1. 将 Skill 目录打包成 ZIP 文件(注意:ZIP 的根目录就是 Skill 目录) 2. 在系统设置的「Skills 管理」页面,点击「导入 Skill」 -3. 上传 ZIP 文件即可 +3. 上传 ZIP 文件或单个 `SKILL.md` +4. 系统解析上传内容并返回安装草稿 +5. 确认共享范围后完成安装;也可以放弃草稿 系统会自动: - 校验 ZIP 内容和路径安全性 - 检查 slug 冲突(如有冲突会自动追加 `-v2` 等后缀) - 解析 SKILL.md 的 frontmatter 并存储到数据库 +- 按当前用户角色校验可选择的共享范围 -**方式二:在线创建** +**方式二:在线编辑已有 Skill** 在 Skills 管理页面,你可以: - 新建目录或文件 - 在线编辑文本文件(支持 .md、.py、.js、.json 等格式) -- 直接在网页上编写 SKILL.md 内容 +- 直接在网页上修改 SKILL.md 内容 + +只有具备 `can_manage` 权限的用户才能编辑文件、依赖、共享范围和启用状态。 **方式三:从远程 skills 仓库安装** 1. 在 Skills 管理页面的“远程安装”面板中填写仓库来源,例如 `anthropics/skills` 或完整 GitHub URL 2. 点击“查看可安装 Skills”获取该仓库中可发现的 skills 列表 -3. 选择或输入目标 skill 名称后点击“安装” +3. 选择或输入目标 skill 名称后点击“解析” +4. 系统返回安装草稿,确认共享范围后正式安装 系统会在后端: - 调用 `npx skills add --list` 校验来源并发现可安装的 skills - 使用隔离的临时 `HOME` 执行 `npx skills add --skill -g -y --copy` -- 从临时目录中提取对应 skill,再按现有导入流程写入 `/app/saves/skills` 与数据库 +- 从临时目录中提取对应 skill,再按现有导入流程生成草稿;确认后写入 `/app/saves/skills` 与数据库 ::: tip 远程安装不会把 ~/.agents/skills 作为系统主存储 远程安装只把 `skills.sh` CLI 作为“下载器”使用。Yuxi 仍然以 `/app/saves/skills + skills 表` 作为正式来源,这样才能与现有的权限、线程可见性和沙盒挂载机制保持一致。 @@ -199,15 +210,29 @@ Skills 之间可以建立依赖关系,形成一个松耦合的技能网络。 ## 权限管理 -Skills 管理采用基于角色的权限控制: +Skills 使用 `source_type`、`share_config` 和 `enabled` 控制来源、共享范围和启用状态。 -| 角色 | 权限 | +| 字段 | 说明 | |------|------| -| 超级管理员 | 完全控制:导入、导出、编辑、删除、配置依赖 | -| 管理员 | 只读:查看 Skills 列表(用于 Agent 配置) | -| 普通用户 | 无访问权限 | +| `source_type` | `builtin`、`upload` 或 `remote` | +| `share_config.access_level` | `global`、`department` 或 `user` | +| `enabled` | 是否允许在 Agent 配置与运行时使用 | -管理员可以在创建或编辑 Agent 时,从 Skills 列表中选择需要的能力。 +访问与管理规则: + +| 用户 | 可见 / 可用 | 可管理 | +|------|-------------|--------| +| 超级管理员 / 管理员 | 可查看可管理或已启用且可访问的 Skills | 可管理所有非内置 Skills;可启停内置 Skills | +| 普通用户 | 可查看已启用且对自己可访问的 Skills,也可安装自己的私有 Skill | 可管理自己创建的非内置 Skills | +| 内置 Skills | 默认全局共享并启用 | 管理员可启停;不允许删除或直接编辑文件 | + +共享范围限制: + +- `global`:所有用户可访问 +- `department`:指定部门用户可访问 +- `user`:指定用户可访问;普通用户安装时只能选择个人范围 + +管理员和普通用户在创建或编辑 Agent 时,都只能从自己可访问且启用的 Skills 中选择能力。 ## 运行时行为 @@ -292,7 +317,7 @@ A:请检查以下几点: A:可以通过以下方式: 1. 导出当前 Skill,修改后重新导入 2. 在 Skills 管理页面在线编辑文件 -3. 直接修改文件系统中的内容(需要重启服务使缓存失效) +3. 远程来源的 Skill 可重新解析并确认安装,形成新的导入结果 **Q:Skill 依赖的工具/MCP 不存在怎么办?** diff --git a/docs/agents/tools-system.md b/docs/agents/tools-system.md index b68f4b4e..1a556a6c 100644 --- a/docs/agents/tools-system.md +++ b/docs/agents/tools-system.md @@ -11,9 +11,9 @@ Yuxi 的工具系统采用 `@tool` 装饰器注册机制,核心位于 `backend ```python from yuxi.agents.toolkits.registry import tool -@tool(category="buildin", tags=["计算"], display_name="计算器") -def calculator(a: float, b: float, operation: str) -> float: - """计算器:对给定的2个数字进行基本数学运算""" +@tool(category="buildin", tags=["示例"], display_name="示例工具") +def example_tool(text: str) -> str: + """示例工具:返回处理后的文本""" ... ``` @@ -39,9 +39,9 @@ from yuxi.agents.toolkits import buildin, mysql # 触发 @tool 装饰器执行 | 工具 | 说明 | |------|------| -| `calculator` | 计算器,支持加减乘除 | | `ask_user_question` | 向用户发起交互式提问 | | `present_artifacts` | 展示 Agent 沙盒 outputs 目录下的产物文件 | +| `install_skill` | 从沙盒路径或 Git 来源安装当前用户私有 Skill,并激活当前主智能体会话;子智能体禁用 | | `tavily_search` | Tavily 网页搜索(需配置 `TAVILY_API_KEY`) | Qwen-Image 生成能力已迁移为内置 Skill `image-gen`。模型调用与图片下载在 Agent 沙盒中完成,生成后的图片保存到 `/home/gem/user-data/outputs/`,再通过 `present_artifacts` 展示。 @@ -75,28 +75,19 @@ kb_tools = get_common_kb_tools() ## 工具组装 -工具组装在 `RuntimeConfigMiddleware` 中完成。根据上下文配置筛选工具: +工具组装在 Graph 创建阶段完成。内置 Agent 会先调用 `prepare_agent_runtime_context` 过滤当前用户可用资源,再调用 `resolve_configured_runtime_tools(context)` 加载已配置工具: 1. **基础工具**:从 `context.tools` 中按名称筛选 2. **MCP 工具**:根据 `context.mcps` 加载 MCP 服务器工具 3. **知识库工具**:由 `KnowledgeBaseMiddleware` 独立处理 +4. **Skill 依赖工具**:由 `SkillsMiddleware` 在 Skill 激活后按需追加 ```python -# 中间件中的工具筛选逻辑 -async def get_tools_from_context(self, context) -> list: - selected_tools = [] +from yuxi.agents.context import prepare_agent_runtime_context +from yuxi.agents.toolkits.service import resolve_configured_runtime_tools - # 1. 基础工具 - for tool_name in context.tools or []: - if tool_name in tools_map: - selected_tools.append(tools_map[tool_name]) - - # 2. MCP 工具 - for server_name in context.mcps or []: - mcp_tools = await get_enabled_mcp_tools(server_name) - selected_tools.extend(mcp_tools) - - return selected_tools +context = await prepare_agent_runtime_context(context, user=current_user, db=db) +tools = await resolve_configured_runtime_tools(context) ``` ## Skills 集成 diff --git a/docs/develop-guides/changelog.md b/docs/develop-guides/changelog.md index c36fe1aa..8791518d 100644 --- a/docs/develop-guides/changelog.md +++ b/docs/develop-guides/changelog.md @@ -2,6 +2,61 @@ 本页用于记录各版本发布说明(新增、修复与破坏性变更)。 +## v0.7.0 (开发中) + +### 破坏性变更 + +- Provider 与模型配置收敛:移除旧版 v1 模型配置与 Ollama 支持,运行时模型统一使用 `provider_id:model_id` 与独立 provider 模块;自定义 provider 实现逻辑从文件移动到数据库,并从 config 文件迁移到 provider 模块。 +- 智能体运行时语义收敛:用户可见的 `AgentConfig` 收敛为数据库持久化的一级 `Agent`,内置 Python Agent 改为智能体后端;聊天、运行任务、恢复审批和文件预览均从线程绑定的 Agent 解析运行时上下文,前端只提交 `agent_id`。 +- 知识库能力边界收敛:移除 Upload 与 LightRAG 知识库/图谱能力,知识库类型收敛为 Milvus 与只读连接器;知识库 API 统一使用 `/databases/{kb_id}/xxx` 形式,并整合 mindmap / eval 等子接口。 +- Agent 资源默认选择与权限过滤:未显式配置工具、知识库、MCP、Skills 时默认启用当前用户可访问/可用的全部资源,子智能体默认不启用,显式保存空列表仍表示不启用对应资源;Agent 创建前统一完成最终资源权限过滤、知识库 `kb_id` 可见范围派生和 Skill prompt/readable 依赖闭包派生。 +- Skill 安装与权限模型收敛:Skill 元数据使用 `source_type/share_config/enabled` 表达来源、生效范围与启用状态;内置 Skill 启动或同步时自动写入数据库并默认全局启用,上传和远程添加统一改为解析草稿后确认安装,不保留旧直接安装兼容路径。 +- 历史兼容层精简:移除 sandbox provisioner `local` 后端别名、ask_user_question 单问题旧协议、JWT 历史默认密钥特殊判断、内置 Skill `SKILLS.md` 文件名回退、运行事件数字 seq 兼容和前端旧字段回退。 +- 用户身份命名收敛:原业务登录标识统一改为 `uid`,Agent/LangGraph runtime、conversation、agent_run、sandbox 路径和前端用户态均使用字符串 `uid`;`user_id` 仅保留给外部响应中的数值 `users.id` 或真实外键场景。 + +### 开发记录 + +- 收敛 MCP 创建与编辑入口:前端移除整段配置文本入口和模式切换器,仅保留表单字段提交;后端 MCP 创建/更新请求拒绝额外配置字段,避免绕过表单约束。 +- 调整内置 MCP 默认项:移除 `sequentialthinking` 的系统内置同步,启动同步时清理历史系统内置记录,保留用户手动创建的同名 MCP。 +- 图片生成能力迁移为 Skill:Qwen-Image 从内置 Python 生成工具迁移到内置 Skill `image-gen`,模型调用与图片下载在 Agent 沙盒中完成,生成结果保存到 outputs 并通过 `present_artifacts` 展示,为多图片生成模型接入复用同一产物展示链路。 +- 降低知识库路由与工具模块复杂度:示例问题生成迁移到知识库 utils,文件上传统一 100 MB 限制,URL 预处理入库路径与旧 `content_type=url` 行为收敛,并修复 uid、导出 MIME 与异常透传等路由问题。 +- 重构智能体配置语义:用户可见的 `AgentConfig` 收敛为数据库持久化的一级 `Agent`,内置 Python Agent 改为智能体后端;新增 `/api/agent` 管理与运行接口,聊天、运行任务、恢复审批和文件预览均从线程绑定的 Agent 解析运行时上下文,前端只提交 `agent_id`,并在模型配置页新增“智能体”管理页签。 +- 删除 Upload 与 LightRAG 图谱/知识库能力:知识库类型收敛为 Milvus 与 Dify,只保留 Milvus 知识库内图谱构建/展示/检索,移除独立 `/graph` 页面和默认上传图谱工具。 +- 收敛只读知识源连接器:新增 `ReadOnlyConnectors` 基类,Dify 改为声明自身创建参数与校验规则,新增 Notion Data Source 只读知识库并支持 Search/Find/Open;知识库类型接口返回创建参数 schema,前端新建表单按类型动态渲染非 Milvus 配置并统一保存到 `additional_params`。 +- 新增知识库 Chunk 持久化:Milvus 知识库索引/更新流程会将 chunks 双写到 PostgreSQL `knowledge_chunks` 表与 Milvus,文件内容查看优先查询 PostgreSQL,并为位置信息、图谱实体关联、标签和抽取结果预留结构化字段。 +- 完善 Milvus 知识库图谱构建:修复 Chunk 图谱写入返回值、Neo4j 同步写入阻塞事件循环、重复构建任务竞态、图谱查询提前终止、Neo4j 连接复用、LLM 抽取超时重试和前端错误详情展示等问题;图谱构建会将 entity/triple 本体与 chunk 引用写入 PostgreSQL,并为唯一 entity/triple 建立 Milvus 语义索引,单文件删除时同步清理图谱引用和孤儿向量。 +- 优化图谱抽取器配置:未配置时在图谱中心展示配置入口,抽取方案收敛为 LLM,前端仅保留“更多拓展中”占位;LLM 抽取器使用固定 Prompt + 自定义 Schema,并支持模型参数与并发队列数;已配置后允许修改参数并提示重置重抽风险。修复上传并入库新文件时旧内存 metadata 覆盖数据库图谱配置的问题。 +- 新增 Milvus 图谱检索链路:Query 可召回图谱实体和三元组,结合 Chunk 命中实体构造 seed entity,读取 Neo4j 2-hop 子图后用 igraph 执行 PPR,最终以 Chunk 为产物并通过 RRF 与原 Chunk 召回融合;检索配置改为 dataclass 元数据生成,支持 `depend_on` 控制重排序和图检索参数展示。 +- 收紧用户管理部门隔离:普通管理员创建用户时固定归属本部门,用户列表、访问选项、详情、更新和删除接口均限制在本部门范围内。 +- 调整 Agent 资源默认选择与运行时上下文:未显式配置工具、知识库、MCP、Skills 时默认启用当前用户可访问/可用的全部资源,子智能体默认不启用,显式保存空列表仍表示不启用对应资源;Agent 创建前统一完成最终资源权限过滤、知识库 `kb_id` 可见范围派生和 Skill prompt/readable 依赖闭包派生,聊天运行时与文件系统预览复用同一结果。 +- 重构 Skills 权限与安装流程:Skill 增加 `source_type/share_config/enabled`,内置 Skill 作为启动同步入库的全局资源,不再保留前端安装/更新状态,支持启停但不允许删除;上传和远程添加统一为解析草稿后确认生效范围,安装 slug 优先读取 `SKILL.md` 的 `slug` 字段并保留 `name` 展示名,压缩包名称不参与 slug 校验;管理端支持编辑生效范围与启停;Agent 运行时按当前用户可访问 Skills 派生 prompt/readable 依赖闭包并限制挂载/激活,Skills prompt 改为模型请求级注入以避免污染 runtime context;主智能体恢复 `install_skill` 工具,允许当前用户安装私有 Skill 并激活当前会话,子智能体配置和运行态均禁用该工具。 +- 精简历史兼容层:移除 sandbox provisioner `local` 后端别名、ask_user_question 单问题旧协议、JWT 历史默认密钥特殊判断、内置 Skill `SKILLS.md` 文件名回退、运行事件数字 seq 兼容和前端若干旧字段回退。 +- 重构知识库共享权限:`share_config` 改为全局共享、部门共享、指定人可访问三档,部门共享必须包含当前用户部门,指定人可访问必须包含当前用户,并补充权限过滤测试。 +- 移除知识库沙盒文件系统映射:不再通过 `/home/gem/kbs` 暴露知识库文件树,Agent 继续使用 `query_kb` 与 `open_kb_document` 访问知识库内容。 +- 规范 Agent 知识库 Search/Find/Open 工具协议:`resource_id` 统一表示知识库 `kb_id`,Search 返回结构化 `resource_id/file_id/chunk` 结果,新增 `find_kb_document` 在已知文件内做关键词或正则定位,Open 默认窗口扩大到 1800 行。 +- 收敛知识库分块配置:分块预设仅表达策略选择,通用分块参数统一通过 `chunk_parser_config` 传递;移除 `chunk_size`、`chunk_overlap`、`qa_separator` 等旧 root 字段兼容。 +- 收敛知识库文件解析参数:文件级 `processing_params` 统一保存 `ocr_engine` 与 `ocr_engine_config`,解析阶段直接使用该结构并保留分块参数快照。 +- 修复知识库文件大小显示为 0 的问题:文件上传时 `file_sizes` 参数未正确传播或历史数据缺失导致 DB 中 `file_size` 为 `None`;新增 `MinIOClient.stat_file/astat_file` 获取文件大小方法,`add_file_record` 在 `size` 缺失时从 MinIO 回补,`_load_metadata` 加载元数据后自动为缺少 `size` 的文件从 MinIO 补全并持久化。 +- 优化评估基准自动生成:生成任务支持配置队列并发数,默认 10,范围 1-20。 +- 重梳理知识库评估存储:评估数据集、题目、评估运行和逐题结果统一入库,JSONL 仅作为导入/导出格式;后端和前端 API 统一使用 dataset/run 语义;评估运行支持用户命名,历史记录按名称展示,综合评分只聚合检索指标。 +- 扩展知识库上传来源:添加“从工作区上传”模式,后端将当前用户工作区文件预处理上传到 MinIO,前端沿用现有 `addDocuments` 入库链路提交 MinIO URL、内容哈希和文件大小。 +- 重构知识库详情页布局:`DatabaseInfo` 改为顶部详情 header + 左侧功能 tab 侧边栏 + 右侧内容区,Milvus 默认进入文件管理,并将检索测试、知识图谱、知识导图、检索配置、RAG 评估和评估基准统一纳入侧边栏导航;只读连接器保留检索测试与检索配置。 +- 整合知识导图接口:移除独立 mindmap router 与前端 API 模块,思维导图生成、查询和文件列表接口统一收敛到知识库 API 下。 +- 收敛独立模型配置模块运行时:运行时 chat / embedding / rerank 均统一从 provider 模块与模型缓存读取 `provider_id:model_id`;旧版静态模型配置、v1 slash spec、旧模型列表接口和 Ollama 适配已移除;内置 provider 模板补充 XiaomiMiMo、XiaomiMiMo Token Plan CN 与 Kimi Code(`kimi-for-coding`)。 +- 调整智能体配置归属与字段权限:`AgentConfig` 从部门共享改为按 `uid` 隔离,所有登录用户可管理自己的配置;`BaseContext` 支持字段级 `auth` 元数据,后端按用户角色过滤可见与可保存的配置项。 +- 新增用户级沙盒环境变量:增加 `agent_envs` 表与 `/api/user/agent-env` 接口,设置面板支持当前用户维护 Agent 沙盒环境变量;创建新沙盒时与全局 `sandbox.env` 合并注入,用户变量优先。 +- 收敛用户身份命名:原业务登录标识统一改为 `uid`,Agent/LangGraph runtime、conversation、agent_run、sandbox 路径和前端用户态均使用字符串 `uid`;`user_id` 仅保留给外部响应中的数值 `users.id` 或真实外键场景。 +- 工作区知识库分类显示:知识库侧边栏按创建者分组为“我的知识库”和“共享知识库”,自己创建的知识库显示在“我的知识库”下,非自己创建的显示在“共享知识库”下;`knowledge_bases` 表新增 `created_by` 字段记录创建者 uid。 +- 工作区文件上传支持多选:`/workspace/upload` 与 Viewer 工作区上传统一使用 `files` 多文件字段,一次最多上传 50 个文件,批量上传失败时清理本次已写入文件。 +- 聊天附件新增 MinIO tmp 临时上传、可选 PDF/图片解析、确认后加入线程附件的流程;前端改为弹窗内上传、解析与确认。 +- 标准化 Agent run/SSE 执行链路:run 创建时持久化输入消息并提交后入队,worker 统一写入 Redis Stream envelope,SSE 输出 `event/data/id`、心跳注释、`Last-Event-ID` 回放和终止 `end` 事件;前端强制使用 run API 并支持 ask_user_question 中断后以 resume run 恢复;事件 envelope 构造收敛到统一 helper,前端优先使用 envelope 一级 `thread_id` 路由。 +- 收敛后端模块边界:文档解析从 `plugins.parser` 移动到 `knowledge.parser`,内容审查从 `plugins.guard` 移动到 `services.guard`。 +- 收敛文件服务边界:文件预览判断抽为独立服务,Viewer 文件系统的 workspace 分支复用用户 workspace 服务,线程运行时上下文解析从泛化 `filesystem_service` 拆出为 agent runtime helper。 +- 升级 DeepAgents 到 0.6.7 并适配新版文件系统协议:SubAgentMiddleware 改为显式 subagent spec,Skills prompt 补齐新版占位符;sandbox/skills backend 复用新版 `ReadResult`、`GlobResult`、`GrepResult` 等协议类型,文件权限在 backend 层明确区分 skills、uploads、outputs 与 workspace,保留最小 `CustomCompositeBackend` 以避免非 route glob 误扫其他 route;Agent 上下文压缩改为复用 DeepAgents SummarizationMiddleware,历史摘要与大工具结果统一 offload 到 outputs。 +- 优化聊天输入 @ 文件提及:未创建 Thread 时可搜索用户 workspace,创建 Thread 后按当前对话文件优先、workspace 兜底的来源顺序搜索,并拆分 workspace/thread 缓存避免假 thread 与跨用户缓存污染;输入框与用户消息支持将 raw mention 渲染为带类型图标的引用单元,文件仅显示文件名且保留原始沙盒路径文本。 +- 重构子智能体为 Agent-backed 形态:移除旧 `subagents` 表与 `/api/system/subagents` 管理链路,子智能体改为 `agents.is_subagent=true` 且使用 `SubAgentBackend`,创建/编辑统一走 Agent 管理入口;内置后端收敛为 `ChatbotAgent` 与 `SubAgentBackend`,Context 分为 `BaseContext`、`ChatBotContext` 与 `SubAgentContext`;主 Agent 通过 Yuxi task middleware 启动真实子 Agent graph,子智能体不再嵌套调用子智能体。沙盒挂载同步拆分为 child checkpoint thread、父对话 uploads/outputs、用户级 workspace 与子 Agent skills scope;主线程状态记录 `subagent_runs` 并在前端 task 工具中展示子智能体名称、执行状态、child thread 和产物,task 工具结果会暴露 child thread ID 且支持传回 `thread_id` 继续既有子智能体线程;子智能体执行复用 `agent_runs(run_type=subagent)` 记录父 run、child thread 与状态,child thread state 查询以 `agent_runs` 关系为准,不再解析 thread ID 反推父线程;真实流式 E2E 覆盖子智能体输出文件可由父线程文件/Viewer API 读取。流式链路参考 DeepAgents event streaming,后端将 LangGraph v3 raw event 归一化为 Yuxi semantic stream event,按父/子线程归属隔离 run SSE chunk,并支持通过 child thread state 拉取子智能体中间过程。 +- 修正评估综合得分计算:`overall_score` 改为有答案准确率时取各题准确率平均,否则取各题 `recall@10` 平均,不再把 recall/f1/各 k 检索指标混合平均;历史已存运行不回填。 + ## v0.6.2 (2026-05-22) ### 新增 @@ -85,7 +140,7 @@ - 新增内置 Skills `deep-reporter`,用于指导生成科研报告、行业调研和其他深度分析类长报告 - 重构内置 Skills/MCP/Subagents 安装/添加/移除机制:内置 skill 支持按需安装、基于 `version + content_hash` 的更新提示与覆盖确认,不再使用服务器级开关切换 - 新增知识库 PDF、图片的预览功能 -- 重构后端测试目录结构:按 `unit / integration / e2e` 分层迁移现有测试,拆分全局 `conftest.py`,统一测试入口为 `uv run --group test pytest`,并新增独立测试规范文档 `docs/vibe/testing-guidelines.md` +- 重构后端测试目录结构:按 `unit / integration / e2e` 分层迁移现有测试,拆分全局 `conftest.py`,统一测试入口为 `uv run --group test pytest`,并新增独立测试规范文档 `docs/develop-guides/testing-guidelines.md` - 新增工具元数据 `config_guide` 字段:后端工具列表接口现在可返回“给人看的配置说明”,前端工具详情页会展示该说明,用于提示工具使用前需要配置的环境变量或入口;首批为 MySQL 工具和 `Qwen-Image` 补充了配置指引 - 补充 Langfuse 集成方案文档:明确采用“云端优先、先 tracing 后 feedback”的接入路径,并约定 Yuxi 的 `user/thread` 到 Langfuse `user_id/session_id` 的映射关系 - 新增面向用户的 Langfuse 集成文档:在“智能体开发”分组中说明 Langfuse 的定位、能力、配置方式与查看路径,并与当前 `LANGFUSE_BASE_URL` 配置保持一致 diff --git a/docs/develop-guides/contributing.md b/docs/develop-guides/contributing.md index 0d188bb7..36a2f348 100644 --- a/docs/develop-guides/contributing.md +++ b/docs/develop-guides/contributing.md @@ -141,7 +141,7 @@ make lint - 通用开发文档位于 `docs/` - 文档导航定义在 `docs/.vitepress/config.mts` -- 若本次改动值得记录,请更新 [roadmap.md](./roadmap.md) +- 未完成规划、未来里程碑或已知问题更新 [roadmap.md](./roadmap.md);已完成的用户可见变更或发布说明更新 [changelog.md](./changelog.md) - 若确需新增仅开发者可见的说明文档,放在 `docs/vibe/` ## 提交信息规范 diff --git a/docs/intro/knowledge-base.md b/docs/intro/knowledge-base.md index 2b9db944..3bdab138 100644 --- a/docs/intro/knowledge-base.md +++ b/docs/intro/knowledge-base.md @@ -99,11 +99,11 @@ Neo4j 连接信息可以在 `.env` 中配置: ```bash # 1. 上传文件 -POST /api/knowledge/files/upload?db_id=<知识库ID> +POST /api/knowledge/files/upload?kb_id=<知识库ID> # 返回 file_path 和 content_hash # 2. 解析并入库 -POST /api/knowledge/databases/{db_id}/documents +POST /api/knowledge/databases/{kb_id}/documents # 返回 status=queued 和 task_id ``` diff --git a/docs/intro/model-config.md b/docs/intro/model-config.md index 63c4e47a..d29a816f 100644 --- a/docs/intro/model-config.md +++ b/docs/intro/model-config.md @@ -25,19 +25,35 @@ ## 供应商管理 -### 内置供应商 +### 内置供应商模板 -部分供应商默认启用,首次使用需配置 API 凭证: +系统启动时会同步一组内置 provider 模板。模板只提供 Provider ID、Base URL、凭证环境变量和远端模型发现地址;实际是否可用仍取决于你是否配置凭证、启用供应商并添加模型。 -| 供应商 | Provider ID | 支持类型 | 备注 | -|--------|-------------|----------|------| -| SiliconFlow | `siliconflow-cn` | chat, embedding, rerank | 默认启用 | -| OpenAI | `openai` | chat | | -| DeepSeek | `deepseek` | chat | | -| 阿里云百炼 | `alibaba` | chat | | -| 智谱清言 | `zhipuai` | chat | | -| MiniMax | `minimax-cn` | chat | | -| OpenRouter | `openrouter` | chat, embedding | | +| 供应商 | Provider ID | 支持类型 | 凭证环境变量 | +|--------|-------------|----------|--------------| +| OpenAI | `openai` | chat | `OPENAI_API_KEY` | +| DeepSeek | `deepseek` | chat | `DEEPSEEK_API_KEY` | +| DashScope | `alibaba` | chat, embedding, rerank | `DASHSCOPE_API_KEY` | +| Aliyun Coding Plan | `alibaba-coding-plan-cn` | chat | `DASHSCOPE_API_KEY` | +| Aliyun Coding Plan International | `alibaba-coding-plan` | chat | `DASHSCOPE_API_KEY` | +| Zhipu BigModel | `zhipuai` | chat | `ZHIPUAI_API_KEY` | +| Zhipu BigModel Coding Plan | `zhipuai-coding-plan` | chat | `ZHIPUAI_API_KEY` | +| Z.AI | `zai` | chat | `ZAI_API_KEY` | +| Z.AI Coding Plan | `zai-coding-plan` | chat | `ZAI_API_KEY` | +| XiaomiMiMo Token Plan | `xiaomi-token-plan-cn` | chat | `XIAOMI_MIMO_TOKEN_PLAN_API_KEY` | +| XiaomiMiMo | `xiaomi` | chat | `XIAOMI_MIMO_API_KEY` | +| Kimi Code | `kimi-for-coding` | chat | `KIMI_CODE_API_KEY` | +| Moonshot | `moonshotai-cn` | chat | `MOONSHOT_API_KEY` | +| Moonshot International | `moonshotai` | chat | `MOONSHOT_API_KEY` | +| MiniMax | `minimax-cn` | chat | `MINIMAX_API_KEY` | +| MiniMax International | `minimax` | chat | `MINIMAX_API_KEY` | +| OpenRouter | `openrouter` | chat, embedding | `OPENROUTER_API_KEY` | +| ModelScope | `modelscope` | chat | `MODELSCOPE_ACCESS_TOKEN` | +| OpenCode | `opencode` | chat | 无默认环境变量 | +| SiliconFlow | `siliconflow-cn` | chat, embedding, rerank | `SILICONFLOW_API_KEY` | +| SiliconFlow International | `siliconflow` | chat, embedding, rerank | `SILICONFLOW_GLOBAL_API_KEY` | + +其中 `alibaba`、`siliconflow-cn` 预置了部分 embedding / rerank 模型;其他供应商通常需要进入详情页通过「获取远程模型」或「手动添加」补充模型。 ### 操作流程 diff --git a/docs/intro/quick-start.md b/docs/intro/quick-start.md index 2b699b2b..db71a4bb 100644 --- a/docs/intro/quick-start.md +++ b/docs/intro/quick-start.md @@ -20,7 +20,7 @@ ```bash # 克隆最新版本 -git clone --branch v0.7.0.dev0 --depth 1 https://github.com/xerrors/Yuxi.git +git clone --branch v0.7.0.dev1 --depth 1 https://github.com/xerrors/Yuxi.git cd Yuxi ```