From 12497a2fea061d2aa0caafdc3b0b7aba87a33030 Mon Sep 17 00:00:00 2001 From: wizardchen Date: Tue, 2 Dec 2025 22:47:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E7=BB=93=E6=9E=84=E4=BD=93=EF=BC=8C=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E5=9D=97=E3=80=81=E6=B6=88=E6=81=AF=E3=80=81=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E5=92=8C=E7=A7=9F=E6=88=B7=E6=A8=A1=E5=9E=8B=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0API=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/chunk.go | 40 ++-- client/message.go | 27 +++ client/session.go | 61 +++--- client/tenant.go | 6 +- docs/API.md | 17 +- docs/api/README.md | 72 ++++++++ docs/api/chat.md | 104 +++++++++++ docs/api/chunk.md | 95 ++++++++++ docs/api/evaluation.md | 154 +++++++++++++++ docs/api/faq.md | 310 +++++++++++++++++++++++++++++++ docs/api/knowledge-base.md | 370 +++++++++++++++++++++++++++++++++++++ docs/api/knowledge.md | 313 +++++++++++++++++++++++++++++++ docs/api/message.md | 180 ++++++++++++++++++ docs/api/model.md | 271 +++++++++++++++++++++++++++ docs/api/session.md | 361 ++++++++++++++++++++++++++++++++++++ docs/api/tag.md | 150 +++++++++++++++ docs/api/tenant.md | 243 ++++++++++++++++++++++++ 17 files changed, 2728 insertions(+), 46 deletions(-) create mode 100644 docs/api/README.md create mode 100644 docs/api/chat.md create mode 100644 docs/api/chunk.md create mode 100644 docs/api/evaluation.md create mode 100644 docs/api/faq.md create mode 100644 docs/api/knowledge-base.md create mode 100644 docs/api/knowledge.md create mode 100644 docs/api/message.md create mode 100644 docs/api/model.md create mode 100644 docs/api/session.md create mode 100644 docs/api/tag.md create mode 100644 docs/api/tenant.md diff --git a/client/chunk.go b/client/chunk.go index 6ed514818..b48fc4072 100644 --- a/client/chunk.go +++ b/client/chunk.go @@ -14,23 +14,28 @@ import ( // Chunk represents the information about a document chunk // Chunks are the basic units of storage and indexing in the knowledge base type Chunk struct { - ID string `json:"id"` // Unique identifier of the chunk - KnowledgeID string `json:"knowledge_id"` // Identifier of the parent knowledge - TenantID uint `json:"tenant_id"` // Tenant ID - Content string `json:"content"` // Text content of the chunk - Embedding []float32 `json:"embedding"` // Vector embedding representation - ChunkIndex int `json:"chunk_index"` // Index position of chunk in the document - TotalChunks int `json:"total_chunks"` // Total number of chunks in the document - IsEnabled bool `json:"is_enabled"` // Whether this chunk is enabled - StartAt int `json:"start_at"` // Starting position in original text - EndAt int `json:"end_at"` // Ending position in original text - VectorStoreID string `json:"vector_store_id"` // Vector storage ID - KeywordStoreID string `json:"keyword_store_id"` // Keyword storage ID - EmbeddingStatus int `json:"embedding_status"` // Embedding status: 0-unprocessed, 1-processing, 2-completed - ChunkType string `json:"chunk_type"` - ImageInfo string `json:"image_info"` - CreatedAt string `json:"created_at"` // Creation time - UpdatedAt string `json:"updated_at"` // Last update time + ID string `json:"id"` // Unique identifier of the chunk + KnowledgeID string `json:"knowledge_id"` // Identifier of the parent knowledge + KnowledgeBaseID string `json:"knowledge_base_id"` // ID of the knowledge base + TenantID uint64 `json:"tenant_id"` // Tenant ID + TagID string `json:"tag_id"` // Optional tag ID for categorization + Content string `json:"content"` // Text content of the chunk + ChunkIndex int `json:"chunk_index"` // Index position of chunk in the document + IsEnabled bool `json:"is_enabled"` // Whether this chunk is enabled + Status int `json:"status"` // Status of the chunk + StartAt int `json:"start_at"` // Starting position in original text + EndAt int `json:"end_at"` // Ending position in original text + PreChunkID string `json:"pre_chunk_id"` // Previous chunk ID + NextChunkID string `json:"next_chunk_id"` // Next chunk ID + ChunkType string `json:"chunk_type"` // Chunk type (text, image_ocr, etc.) + ParentChunkID string `json:"parent_chunk_id"` // Parent chunk ID + RelationChunks any `json:"relation_chunks"` // Relation chunk IDs + IndirectRelationChunks any `json:"indirect_relation_chunks"` // Indirect relation chunk IDs + Metadata any `json:"metadata"` // Metadata for the chunk + ContentHash string `json:"content_hash"` // Content hash for quick matching + ImageInfo string `json:"image_info"` // Image information + CreatedAt string `json:"created_at"` // Creation time + UpdatedAt string `json:"updated_at"` // Last update time } // ChunkResponse represents the response for a single chunk @@ -59,6 +64,7 @@ type UpdateChunkRequest struct { IsEnabled bool `json:"is_enabled"` // Whether enabled StartAt int `json:"start_at"` // Start position EndAt int `json:"end_at"` // End position + ImageInfo string `json:"image_info"` // Image information } // ListKnowledgeChunks lists all chunks under a knowledge document diff --git a/client/message.go b/client/message.go index b59d691f2..575bb8f6a 100644 --- a/client/message.go +++ b/client/message.go @@ -12,6 +12,32 @@ import ( "time" ) +// ToolResult represents the result of a tool execution +type ToolResult struct { + Success bool `json:"success"` // Whether the tool executed successfully + Output string `json:"output"` // Human-readable output + Data map[string]interface{} `json:"data,omitempty"` // Structured data for programmatic use + Error string `json:"error,omitempty"` // Error message if execution failed +} + +// ToolCall represents a single tool invocation within an agent step +type ToolCall struct { + ID string `json:"id"` // Function call ID from LLM + Name string `json:"name"` // Tool name + Args map[string]interface{} `json:"args"` // Tool arguments + Result *ToolResult `json:"result"` // Execution result + Reflection string `json:"reflection,omitempty"` // Agent's reflection on this tool call result + Duration int64 `json:"duration"` // Execution time in milliseconds +} + +// AgentStep represents one iteration of the ReAct loop +type AgentStep struct { + Iteration int `json:"iteration"` // Iteration number (0-indexed) + Thought string `json:"thought"` // LLM's reasoning/thinking (Think phase) + ToolCalls []ToolCall `json:"tool_calls"` // Tools called in this step (Act phase) + Timestamp time.Time `json:"timestamp"` // When this step occurred +} + // Message message information type Message struct { ID string `json:"id"` @@ -20,6 +46,7 @@ type Message struct { Content string `json:"content"` Role string `json:"role"` KnowledgeReferences []*SearchResult `json:"knowledge_references"` + AgentSteps []AgentStep `json:"agent_steps,omitempty"` // Agent execution steps (only for assistant messages) IsCompleted bool `json:"is_completed"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` diff --git a/client/session.go b/client/session.go index b89c49b1e..7b9de4ee6 100644 --- a/client/session.go +++ b/client/session.go @@ -49,41 +49,52 @@ type SummaryConfig struct { MaxCompletionTokens int `json:"max_completion_tokens"` } -// AgentConfig defines session-level agent configuration (matches server struct). -type AgentConfig struct { +// SessionAgentConfig defines session-level agent configuration (matches server struct). +// Sessions only store Enabled and KnowledgeBases; other configs are read from Tenant at runtime +type SessionAgentConfig struct { AgentModeEnabled bool `json:"agent_mode_enabled"` // Whether agent mode is enabled for this session WebSearchEnabled bool `json:"web_search_enabled"` // Whether web search is enabled for this session - KnowledgeBases []string `json:"knowledge_bases"` // Accessible knowledge base IDs + KnowledgeBases []string `json:"knowledge_bases"` // Accessible knowledge base IDs for this session } // CreateSessionRequest session creation request type CreateSessionRequest struct { - KnowledgeBaseID string `json:"knowledge_base_id"` // Associated knowledge base ID (optional in agent mode) - SessionStrategy *SessionStrategy `json:"session_strategy"` // Session strategy - AgentConfig *AgentConfig `json:"agent_config"` // Agent configuration (optional, for agent mode) + KnowledgeBaseID string `json:"knowledge_base_id"` // Associated knowledge base ID (optional in agent mode) + SessionStrategy *SessionStrategy `json:"session_strategy"` // Session strategy + AgentConfig *SessionAgentConfig `json:"agent_config"` // Agent configuration (optional, for agent mode) +} + +// ContextConfig configures LLM context management +type ContextConfig struct { + MaxTokens int `json:"max_tokens"` // Maximum tokens allowed in LLM context + CompressionStrategy string `json:"compression_strategy"` // Compression strategy: "sliding_window" or "smart" + RecentMessageCount int `json:"recent_message_count"` // Number of recent messages to keep + SummarizeThreshold int `json:"summarize_threshold"` // Number of messages before summarization } // Session session information type Session struct { - ID string `json:"id"` - TenantID uint `json:"tenant_id"` - KnowledgeBaseID string `json:"knowledge_base_id"` - Title string `json:"title"` - MaxRounds int `json:"max_rounds"` - EnableRewrite bool `json:"enable_rewrite"` - FallbackStrategy string `json:"fallback_strategy"` - FallbackResponse string `json:"fallback_response"` - EmbeddingTopK int `json:"embedding_top_k"` - KeywordThreshold float64 `json:"keyword_threshold"` - VectorThreshold float64 `json:"vector_threshold"` - RerankModelID string `json:"rerank_model_id"` - RerankTopK int `json:"rerank_top_k"` - RerankThreshold float64 `json:"reranking_threshold"` // Reranking threshold - SummaryModelID string `json:"summary_model_id"` - SummaryParameters *SummaryConfig `json:"summary_parameters"` - AgentConfig *AgentConfig `json:"agent_config"` // Agent configuration (optional) - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + ID string `json:"id"` + TenantID uint64 `json:"tenant_id"` + KnowledgeBaseID string `json:"knowledge_base_id"` + Title string `json:"title"` + Description string `json:"description"` + MaxRounds int `json:"max_rounds"` + EnableRewrite bool `json:"enable_rewrite"` + FallbackStrategy string `json:"fallback_strategy"` + FallbackResponse string `json:"fallback_response"` + EmbeddingTopK int `json:"embedding_top_k"` + KeywordThreshold float64 `json:"keyword_threshold"` + VectorThreshold float64 `json:"vector_threshold"` + RerankModelID string `json:"rerank_model_id"` + RerankTopK int `json:"rerank_top_k"` + RerankThreshold float64 `json:"rerank_threshold"` // Reranking threshold + SummaryModelID string `json:"summary_model_id"` + SummaryParameters *SummaryConfig `json:"summary_parameters"` + AgentConfig *SessionAgentConfig `json:"agent_config"` // Agent configuration (optional) + ContextConfig *ContextConfig `json:"context_config"` // Context management configuration (optional) + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` } // SessionResponse session response diff --git a/client/tenant.go b/client/tenant.go index 1e22327e2..b7b9bbff3 100644 --- a/client/tenant.go +++ b/client/tenant.go @@ -24,7 +24,7 @@ type RetrieverEngineParams struct { // Tenant represents tenant information in the system type Tenant struct { - ID uint `yaml:"id" json:"id" gorm:"primaryKey"` + ID uint64 `yaml:"id" json:"id" gorm:"primaryKey"` // Tenant name Name string `yaml:"name" json:"name"` // Tenant description @@ -37,6 +37,10 @@ type Tenant struct { RetrieverEngines RetrieverEngines `yaml:"retriever_engines" json:"retriever_engines" gorm:"type:json"` // Business/department information Business string `yaml:"business" json:"business"` + // Storage quota (Bytes), default is 10GB + StorageQuota int64 `yaml:"storage_quota" json:"storage_quota" gorm:"default:10737418240"` + // Storage used (Bytes) + StorageUsed int64 `yaml:"storage_used" json:"storage_used" gorm:"default:0"` // Creation timestamp CreatedAt time.Time `yaml:"created_at" json:"created_at"` // Last update timestamp diff --git a/docs/API.md b/docs/API.md index d608467b1..3dcef43cd 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1311,12 +1311,14 @@ curl --location 'http://localhost:8080/api/v1/chunks/4c4e7c1a-09cf-485b-a7b5-24b "data": [ { "id": "df10b37d-cd05-4b14-ba8a-e1bd0eb3bbd7", - "tenant_id": 0, + "tenant_id": 1, "knowledge_id": "4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5", "knowledge_base_id": "kb-00000001", + "tag_id": "", "content": "彗星xxxx", "chunk_index": 0, "is_enabled": true, + "status": 2, "start_at": 0, "end_at": 964, "pre_chunk_id": "", @@ -1325,9 +1327,11 @@ curl --location 'http://localhost:8080/api/v1/chunks/4c4e7c1a-09cf-485b-a7b5-24b "parent_chunk_id": "", "relation_chunks": null, "indirect_relation_chunks": null, + "metadata": null, + "content_hash": "", "image_info": "", - "created_at": "0001-01-01T00:00:00Z", - "updated_at": "0001-01-01T00:00:00Z", + "created_at": "2025-08-12T11:52:36.168632+08:00", + "updated_at": "2025-08-12T11:52:53.376871+08:00", "deleted_at": null } ], @@ -1928,6 +1932,8 @@ curl --location 'http://localhost:8080/api/v1/sessions' \ "seed": 0, "max_completion_tokens": 2048 }, + "agent_config": null, + "context_config": null, "created_at": "2025-08-12T12:26:19.611616669+08:00", "updated_at": "2025-08-12T12:26:19.611616919+08:00", "deleted_at": null @@ -1981,6 +1987,8 @@ curl --location 'http://localhost:8080/api/v1/sessions/ceb9babb-1e30-41d7-817d-f "seed": 0, "max_completion_tokens": 2048 }, + "agent_config": null, + "context_config": null, "created_at": "2025-08-12T10:24:38.308596+08:00", "updated_at": "2025-08-12T10:25:41.317761+08:00", "deleted_at": null @@ -2322,6 +2330,7 @@ curl --location --request GET 'http://localhost:8080/api/v1/messages/ceb9babb-1e "knowledge_source": "" } ], + "agent_steps": [], "is_completed": true, "created_at": "2025-08-12T10:24:38.370548+08:00", "updated_at": "2025-08-12T10:25:40.416382+08:00", @@ -2334,6 +2343,7 @@ curl --location --request GET 'http://localhost:8080/api/v1/messages/ceb9babb-1e "content": "彗尾的形状", "role": "user", "knowledge_references": [], + "agent_steps": [], "is_completed": true, "created_at": "2025-08-12T14:30:39.732246+08:00", "updated_at": "2025-08-12T14:30:39.733277+08:00", @@ -2389,6 +2399,7 @@ curl --location --request GET 'http://localhost:8080/api/v1/messages/ceb9babb-1e "knowledge_source": "" } ], + "agent_steps": [], "is_completed": true, "created_at": "2025-08-12T14:30:39.735108+08:00", "updated_at": "2025-08-12T14:31:17.829926+08:00", diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 000000000..7803030d3 --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1,72 @@ +# WeKnora API 文档 + +## 目录 + +- [概述](#概述) +- [基础信息](#基础信息) +- [认证机制](#认证机制) +- [错误处理](#错误处理) +- [API 概览](#api-概览) + +## 概述 + +WeKnora 提供了一系列 RESTful API,用于创建和管理知识库、检索知识,以及进行基于知识的问答。本文档详细描述了这些 API 的使用方式。 + +## 基础信息 + +- **基础 URL**: `/api/v1` +- **响应格式**: JSON +- **认证方式**: API Key + +## 认证机制 + +所有 API 请求需要在 HTTP 请求头中包含 `X-API-Key` 进行身份认证: + +``` +X-API-Key: your_api_key +``` + +为便于问题追踪和调试,建议每个请求的 HTTP 请求头中添加 `X-Request-ID`: + +``` +X-Request-ID: unique_request_id +``` + +### 获取 API Key + +在 web 页面完成账户注册后,请前往账户信息页面获取您的 API Key。 + +请妥善保管您的 API Key,避免泄露。API Key 代表您的账户身份,拥有完整的 API 访问权限。 + +## 错误处理 + +所有 API 使用标准的 HTTP 状态码表示请求状态,并返回统一的错误响应格式: + +```json +{ + "success": false, + "error": { + "code": "错误代码", + "message": "错误信息", + "details": "错误详情" + } +} +``` + +## API 概览 + +WeKnora API 按功能分为以下几类: + +| 分类 | 描述 | 文档链接 | +|------|------|----------| +| 租户管理 | 创建和管理租户账户 | [tenant.md](./tenant.md) | +| 知识库管理 | 创建、查询和管理知识库 | [knowledge-base.md](./knowledge-base.md) | +| 知识管理 | 上传、检索和管理知识内容 | [knowledge.md](./knowledge.md) | +| 模型管理 | 配置和管理各种AI模型 | [model.md](./model.md) | +| 分块管理 | 管理知识的分块内容 | [chunk.md](./chunk.md) | +| 标签管理 | 管理知识库的标签分类 | [tag.md](./tag.md) | +| FAQ管理 | 管理FAQ问答对 | [faq.md](./faq.md) | +| 会话管理 | 创建和管理对话会话 | [session.md](./session.md) | +| 聊天功能 | 基于知识库和 Agent 进行问答 | [chat.md](./chat.md) | +| 消息管理 | 获取和管理对话消息 | [message.md](./message.md) | +| 评估功能 | 评估模型性能 | [evaluation.md](./evaluation.md) | diff --git a/docs/api/chat.md b/docs/api/chat.md new file mode 100644 index 000000000..3b9a3c1fd --- /dev/null +++ b/docs/api/chat.md @@ -0,0 +1,104 @@ +# 聊天功能 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ---- | ----------------------------- | ------------------------ | +| POST | `/knowledge-chat/:session_id` | 基于知识库的问答 | +| POST | `/agent-chat/:session_id` | 基于 Agent 的智能问答 | +| POST | `/knowledge-search` | 基于知识库的搜索知识 | + +## POST `/knowledge-chat/:session_id` - 基于知识库的问答 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-chat/ceb9babb-1e30-41d7-817d-fd584954304b' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "query": "彗尾的形状" +}' +``` + +**响应格式**: +服务器端事件流(Server-Sent Events,Content-Type: text/event-stream) + +**响应**: + +``` +event: message +data: {"id":"3475c004-0ada-4306-9d30-d7f5efce50d2","response_type":"references","content":"","done":false,"knowledge_references":[{"id":"c8347bef-127f-4a22-b962-edf5a75386ec","content":"彗星xxx。","knowledge_id":"a6790b93-4700-4676-bd48-0d4804e1456b","chunk_index":0,"knowledge_title":"彗星.txt","start_at":0,"end_at":2760,"seq":0,"score":4.038836479187012,"match_type":3,"sub_chunk_id":["688821f0-40bf-428e-8cb6-541531ebeb76","c1e9903e-2b4d-4281-be15-0149288d45c2","7d955251-3f79-4fd5-a6aa-02f81e044091"],"metadata":{},"chunk_type":"text","parent_chunk_id":"","image_info":"","knowledge_filename":"彗星.txt","knowledge_source":""},{"id":"fa3aadee-cadb-4a84-9941-c839edc3e626","content":"# 文档名称\n彗星.txt\n\n# 摘要\n彗星是由冰和尘埃构成的太阳系小天体,接近太阳时会释放气体形成彗发和彗尾。其轨道周期差异大,来源包括柯伊伯带和奥尔特云。彗星与小行星的区别逐渐模糊,部分彗星已失去挥发物质,类似小行星。目前已知彗星数量众多,且存在系外彗星。彗星在古代被视为凶兆,现代研究揭示其复杂结构与起源。","knowledge_id":"a6790b93-4700-4676-bd48-0d4804e1456b","chunk_index":6,"knowledge_title":"彗星.txt","start_at":0,"end_at":0,"seq":6,"score":0.6131043121858466,"match_type":3,"sub_chunk_id":null,"metadata":{},"chunk_type":"summary","parent_chunk_id":"c8347bef-127f-4a22-b962-edf5a75386ec","image_info":"","knowledge_filename":"彗星.txt","knowledge_source":""}]} + +event: message +data: {"id":"3475c004-0ada-4306-9d30-d7f5efce50d2","response_type":"answer","content":"表现为","done":false,"knowledge_references":null} + +event: message +data: {"id":"3475c004-0ada-4306-9d30-d7f5efce50d2","response_type":"answer","content":"结构","done":false,"knowledge_references":null} + +event: message +data: {"id":"3475c004-0ada-4306-9d30-d7f5efce50d2","response_type":"answer","content":"。","done":false,"knowledge_references":null} + +event: message +data: {"id":"3475c004-0ada-4306-9d30-d7f5efce50d2","response_type":"answer","content":"","done":true,"knowledge_references":null} +``` + +## POST `/agent-chat/:session_id` - 基于 Agent 的智能问答 + +Agent 模式支持更智能的问答,包括工具调用、网络搜索、多知识库检索等能力。 + +**请求参数**: +- `query`: 查询文本(必填) +- `knowledge_base_ids`: 知识库 ID 数组,可动态指定本次查询使用的知识库(可选) +- `agent_enabled`: 是否启用 Agent 模式(可选,默认 false) +- `web_search_enabled`: 是否启用网络搜索(可选,默认 false) +- `summary_model_id`: 覆盖会话默认的摘要模型 ID(可选) +- `mcp_service_ids`: MCP 服务白名单(可选) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/agent-chat/ceb9babb-1e30-41d7-817d-fd584954304b' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "query": "帮我查询今天的天气", + "agent_enabled": true, + "web_search_enabled": true, + "knowledge_base_ids": ["kb-00000001"] +}' +``` + +**响应格式**: +服务器端事件流(Server-Sent Events,Content-Type: text/event-stream) + +**响应类型说明**: + +| response_type | 描述 | +|---------------|------| +| `thinking` | Agent 思考过程 | +| `tool_call` | 工具调用信息 | +| `tool_result` | 工具调用结果 | +| `references` | 知识库检索引用 | +| `answer` | 最终回答内容 | +| `reflection` | Agent 反思内容 | +| `error` | 错误信息 | + +**响应示例**: + +``` +event: message +data: {"id":"agent-001","response_type":"thinking","content":"用户想查询天气,我需要使用网络搜索工具...","done":false,"knowledge_references":null} + +event: message +data: {"id":"agent-001","response_type":"tool_call","content":"","done":false,"knowledge_references":null,"data":{"tool_name":"web_search","arguments":{"query":"今天天气"}}} + +event: message +data: {"id":"agent-001","response_type":"tool_result","content":"搜索结果:今天晴,气温25°C...","done":false,"knowledge_references":null} + +event: message +data: {"id":"agent-001","response_type":"answer","content":"根据查询结果,今天天气晴朗,气温约25°C。","done":false,"knowledge_references":null} + +event: message +data: {"id":"agent-001","response_type":"answer","content":"","done":true,"knowledge_references":null} +``` diff --git a/docs/api/chunk.md b/docs/api/chunk.md new file mode 100644 index 000000000..15ac564cf --- /dev/null +++ b/docs/api/chunk.md @@ -0,0 +1,95 @@ +# 分块管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | --------------------------- | ------------------------ | +| GET | `/chunks/:knowledge_id` | 获取知识的分块列表 | +| DELETE | `/chunks/:knowledge_id/:id` | 删除分块 | +| DELETE | `/chunks/:knowledge_id` | 删除知识下的所有分块 | + +## GET `/chunks/:knowledge_id?page=&page_size=` - 获取知识的分块列表 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/chunks/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5?page=1&page_size=1' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "df10b37d-cd05-4b14-ba8a-e1bd0eb3bbd7", + "tenant_id": 1, + "knowledge_id": "4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5", + "knowledge_base_id": "kb-00000001", + "tag_id": "", + "content": "彗星xxxx", + "chunk_index": 0, + "is_enabled": true, + "status": 2, + "start_at": 0, + "end_at": 964, + "pre_chunk_id": "", + "next_chunk_id": "", + "chunk_type": "text", + "parent_chunk_id": "", + "relation_chunks": null, + "indirect_relation_chunks": null, + "metadata": null, + "content_hash": "", + "image_info": "", + "created_at": "2025-08-12T11:52:36.168632+08:00", + "updated_at": "2025-08-12T11:52:53.376871+08:00", + "deleted_at": null + } + ], + "page": 1, + "page_size": 1, + "success": true, + "total": 5 +} +``` + +## DELETE `/chunks/:knowledge_id/:id` - 删除分块 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/chunks/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5/df10b37d-cd05-4b14-ba8a-e1bd0eb3bbd7' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "message": "Chunk deleted", + "success": true +} +``` + +## DELETE `/chunks/:knowledge_id` - 删除知识下的所有分块 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/chunks/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "message": "All chunks under knowledge deleted", + "success": true +} +``` diff --git a/docs/api/evaluation.md b/docs/api/evaluation.md new file mode 100644 index 000000000..b111262bd --- /dev/null +++ b/docs/api/evaluation.md @@ -0,0 +1,154 @@ +# 评估功能 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ---- | ------------- | --------------------- | +| GET | `/evaluation` | 获取评估任务 | +| POST | `/evaluation` | 创建评估任务 | + +## GET `/evaluation` - 获取评估任务 + +**请求参数**: +- `task_id`: 从 `POST /evaluation` 接口中获取到的任务 ID +- `X-API-Key`: 用户 API Key + +**请求**: + +```bash +curl --location 'http://localhost:8080/api/v1/evaluation?task_id=c34563ad-b09f-4858-b72e-e92beb80becb' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": { + "task": { + "id": "c34563ad-b09f-4858-b72e-e92beb80becb", + "tenant_id": 1, + "dataset_id": "default", + "start_time": "2025-08-12T14:54:26.221804768+08:00", + "status": 2, + "total": 1, + "finished": 1 + }, + "params": { + "session_id": "", + "knowledge_base_id": "2ef57434-8c8d-4442-b967-2f7fc578a2fc", + "vector_threshold": 0.5, + "keyword_threshold": 0.3, + "embedding_top_k": 10, + "vector_database": "", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "rerank_top_k": 5, + "rerank_threshold": 0.7, + "chat_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_config": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。", + "context_template": "你是一个专业的智能信息检索助手", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "fallback_strategy": "", + "fallback_response": "抱歉,我无法回答这个问题。" + }, + "metric": { + "retrieval_metrics": { + "precision": 0, + "recall": 0, + "ndcg3": 0, + "ndcg10": 0, + "mrr": 0, + "map": 0 + }, + "generation_metrics": { + "bleu1": 0.037656734016532384, + "bleu2": 0.04067392145167686, + "bleu4": 0.048963321289052536, + "rouge1": 0, + "rouge2": 0, + "rougel": 0 + } + } + }, + "success": true +} +``` + +## POST `/evaluation` - 创建评估任务 + +**请求参数**: +- `dataset_id`: 评估使用的数据集,暂时只支持官方测试数据集 `default` +- `knowledge_base_id`: 评估使用的知识库 +- `chat_id`: 评估使用的对话模型 +- `rerank_id`: 评估使用的重排序模型 + +**请求**: + +```bash +curl --location 'http://localhost:8080/api/v1/evaluation' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "dataset_id": "default", + "knowledge_base_id": "kb-00000001", + "chat_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "rerank_id": "b30171a1-787b-426e-a293-735cd5ac16c0" +}' +``` + +**响应**: + +```json +{ + "data": { + "task": { + "id": "c34563ad-b09f-4858-b72e-e92beb80becb", + "tenant_id": 1, + "dataset_id": "default", + "start_time": "2025-08-12T14:54:26.221804768+08:00", + "status": 1 + }, + "params": { + "session_id": "", + "knowledge_base_id": "2ef57434-8c8d-4442-b967-2f7fc578a2fc", + "vector_threshold": 0.5, + "keyword_threshold": 0.3, + "embedding_top_k": 10, + "vector_database": "", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "rerank_top_k": 5, + "rerank_threshold": 0.7, + "chat_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_config": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。", + "context_template": "你是一个专业的智能信息检索助手,xxx", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "fallback_strategy": "", + "fallback_response": "抱歉,我无法回答这个问题。" + } + }, + "success": true +} +``` diff --git a/docs/api/faq.md b/docs/api/faq.md new file mode 100644 index 000000000..993a06e0f --- /dev/null +++ b/docs/api/faq.md @@ -0,0 +1,310 @@ +# FAQ管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | ------------------------------------------- | ------------------------ | +| GET | `/knowledge-bases/:id/faq/entries` | 获取FAQ条目列表 | +| POST | `/knowledge-bases/:id/faq/entries` | 批量导入FAQ条目 | +| POST | `/knowledge-bases/:id/faq/entry` | 创建单个FAQ条目 | +| PUT | `/knowledge-bases/:id/faq/entries/:entry_id`| 更新单个FAQ条目 | +| PUT | `/knowledge-bases/:id/faq/entries/status` | 批量更新FAQ启用状态 | +| PUT | `/knowledge-bases/:id/faq/entries/tags` | 批量更新FAQ标签 | +| DELETE | `/knowledge-bases/:id/faq/entries` | 批量删除FAQ条目 | +| POST | `/knowledge-bases/:id/faq/search` | 混合搜索FAQ | + +## GET `/knowledge-bases/:id/faq/entries` - 获取FAQ条目列表 + +**查询参数**: +- `page`: 页码(默认 1) +- `page_size`: 每页条数(默认 20) +- `tag_id`: 按标签ID筛选(可选) +- `keyword`: 关键字搜索(可选) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entries?page=1&page_size=10' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": { + "total": 100, + "page": 1, + "page_size": 10, + "data": [ + { + "id": "faq-00000001", + "chunk_id": "chunk-00000001", + "knowledge_id": "knowledge-00000001", + "knowledge_base_id": "kb-00000001", + "tag_id": "tag-00000001", + "is_enabled": true, + "standard_question": "如何重置密码?", + "similar_questions": ["忘记密码怎么办", "密码找回"], + "negative_questions": ["如何修改用户名"], + "answers": ["您可以通过点击登录页面的'忘记密码'链接来重置密码。"], + "index_mode": "hybrid", + "chunk_type": "faq", + "created_at": "2025-08-12T10:00:00+08:00", + "updated_at": "2025-08-12T10:00:00+08:00" + } + ] + }, + "success": true +} +``` + +## POST `/knowledge-bases/:id/faq/entries` - 批量导入FAQ条目 + +**请求参数**: +- `mode`: 导入模式,`append`(追加)或 `replace`(替换) +- `entries`: FAQ条目数组 +- `knowledge_id`: 关联的知识ID(可选) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entries' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "mode": "append", + "entries": [ + { + "standard_question": "如何联系客服?", + "similar_questions": ["客服电话", "在线客服"], + "answers": ["您可以通过拨打400-xxx-xxxx联系我们的客服。"], + "tag_id": "tag-00000001" + }, + { + "standard_question": "退款政策是什么?", + "answers": ["我们提供7天无理由退款服务。"] + } + ] +}' +``` + +**响应**: + +```json +{ + "data": { + "task_id": "task-00000001" + }, + "success": true +} +``` + +注:批量导入为异步操作,返回任务ID用于追踪进度。 + +## POST `/knowledge-bases/:id/faq/entry` - 创建单个FAQ条目 + +同步创建单个FAQ条目,适用于单条录入场景。会自动检查标准问和相似问是否与已有FAQ重复。 + +**请求参数**: +- `standard_question`: 标准问(必填) +- `similar_questions`: 相似问数组(可选) +- `negative_questions`: 反例问题数组(可选) +- `answers`: 答案数组(必填) +- `tag_id`: 标签ID(可选) +- `is_enabled`: 是否启用(可选,默认true) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entry' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "standard_question": "如何联系客服?", + "similar_questions": ["客服电话", "在线客服"], + "answers": ["您可以通过拨打400-xxx-xxxx联系我们的客服。"], + "tag_id": "tag-00000001", + "is_enabled": true +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "faq-00000001", + "chunk_id": "chunk-00000001", + "knowledge_id": "knowledge-00000001", + "knowledge_base_id": "kb-00000001", + "tag_id": "tag-00000001", + "is_enabled": true, + "standard_question": "如何联系客服?", + "similar_questions": ["客服电话", "在线客服"], + "negative_questions": [], + "answers": ["您可以通过拨打400-xxx-xxxx联系我们的客服。"], + "index_mode": "hybrid", + "chunk_type": "faq", + "created_at": "2025-08-12T10:00:00+08:00", + "updated_at": "2025-08-12T10:00:00+08:00" + }, + "success": true +} +``` + +**错误响应**(标准问或相似问重复时): + +```json +{ + "success": false, + "error": { + "code": "BAD_REQUEST", + "message": "标准问与已有FAQ重复" + } +} +``` + +## PUT `/knowledge-bases/:id/faq/entries/:entry_id` - 更新单个FAQ条目 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entries/faq-00000001' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "standard_question": "如何重置账户密码?", + "similar_questions": ["忘记密码怎么办", "密码找回", "重置密码"], + "answers": ["您可以通过以下步骤重置密码:1. 点击登录页面的\"忘记密码\" 2. 输入注册邮箱 3. 查收重置邮件"], + "is_enabled": true +}' +``` + +**响应**: + +```json +{ + "success": true +} +``` + +## PUT `/knowledge-bases/:id/faq/entries/status` - 批量更新FAQ启用状态 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entries/status' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "updates": { + "faq-00000001": true, + "faq-00000002": false, + "faq-00000003": true + } +}' +``` + +**响应**: + +```json +{ + "success": true +} +``` + +## PUT `/knowledge-bases/:id/faq/entries/tags` - 批量更新FAQ标签 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entries/tags' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "updates": { + "faq-00000001": "tag-00000001", + "faq-00000002": "tag-00000002", + "faq-00000003": null + } +}' +``` + +注:设置为 `null` 可清除标签关联。 + +**响应**: + +```json +{ + "success": true +} +``` + +## DELETE `/knowledge-bases/:id/faq/entries` - 批量删除FAQ条目 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/entries' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "ids": ["faq-00000001", "faq-00000002"] +}' +``` + +**响应**: + +```json +{ + "success": true +} +``` + +## POST `/knowledge-bases/:id/faq/search` - 混合搜索FAQ + +**请求参数**: +- `query_text`: 搜索查询文本 +- `vector_threshold`: 向量相似度阈值(0-1) +- `match_count`: 返回结果数量(最大200) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/faq/search' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "query_text": "如何重置密码", + "vector_threshold": 0.5, + "match_count": 10 +}' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "faq-00000001", + "chunk_id": "chunk-00000001", + "knowledge_id": "knowledge-00000001", + "knowledge_base_id": "kb-00000001", + "tag_id": "tag-00000001", + "is_enabled": true, + "standard_question": "如何重置密码?", + "similar_questions": ["忘记密码怎么办", "密码找回"], + "answers": ["您可以通过点击登录页面的'忘记密码'链接来重置密码。"], + "chunk_type": "faq", + "score": 0.95, + "match_type": "vector", + "created_at": "2025-08-12T10:00:00+08:00", + "updated_at": "2025-08-12T10:00:00+08:00" + } + ], + "success": true +} +``` diff --git a/docs/api/knowledge-base.md b/docs/api/knowledge-base.md new file mode 100644 index 000000000..a06c65ccf --- /dev/null +++ b/docs/api/knowledge-base.md @@ -0,0 +1,370 @@ +# 知识库管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | ------------------------------------ | ------------------------ | +| POST | `/knowledge-bases` | 创建知识库 | +| GET | `/knowledge-bases` | 获取知识库列表 | +| GET | `/knowledge-bases/:id` | 获取知识库详情 | +| PUT | `/knowledge-bases/:id` | 更新知识库 | +| DELETE | `/knowledge-bases/:id` | 删除知识库 | +| POST | `/knowledge-bases/copy` | 拷贝知识库 | +| GET | `/knowledge-bases/:id/hybrid-search` | 混合搜索(向量+关键词) | + +## POST `/knowledge-bases` - 创建知识库 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--data '{ + "name": "weknora", + "description": "weknora description", + "chunking_config": { + "chunk_size": 1000, + "chunk_overlap": 200, + "separators": [ + "." + ], + "enable_multimodal": true + }, + "image_processing_config": { + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "vlm_config": { + "enabled": true, + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "cos_config": { + "secret_id": "", + "secret_key": "", + "region": "", + "bucket_name": "", + "app_id": "", + "path_prefix": "" + } +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "b5829e4a-3845-4624-a7fb-ea3b35e843b0", + "name": "weknora", + "description": "weknora description", + "tenant_id": 1, + "chunking_config": { + "chunk_size": 1000, + "chunk_overlap": 200, + "separators": [ + "." + ], + "enable_multimodal": true + }, + "image_processing_config": { + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "vlm_config": { + "enabled": true, + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "cos_config": { + "secret_id": "", + "secret_key": "", + "region": "", + "bucket_name": "", + "app_id": "", + "path_prefix": "" + }, + "created_at": "2025-08-12T11:30:09.206238645+08:00", + "updated_at": "2025-08-12T11:30:09.206238854+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/knowledge-bases` - 获取知识库列表 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "kb-00000001", + "name": "Default Knowledge Base", + "description": "System Default Knowledge Base", + "tenant_id": 1, + "chunking_config": { + "chunk_size": 1000, + "chunk_overlap": 200, + "separators": [ + "\n\n", + "\n", + "。", + "!", + "?", + ";", + ";" + ], + "enable_multimodal": true + }, + "image_processing_config": { + "model_id": "" + }, + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "vlm_config": { + "enabled": true, + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "cos_config": { + "secret_id": "", + "secret_key": "", + "region": "", + "bucket_name": "", + "app_id": "", + "path_prefix": "" + }, + "created_at": "2025-08-11T20:10:41.817794+08:00", + "updated_at": "2025-08-12T11:23:00.593097+08:00", + "deleted_at": null + } + ], + "success": true +} +``` + +## GET `/knowledge-bases/:id` - 获取知识库详情 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' +``` + +**响应**: + +```json +{ + "data": { + "id": "kb-00000001", + "name": "Default Knowledge Base", + "description": "System Default Knowledge Base", + "tenant_id": 1, + "chunking_config": { + "chunk_size": 1000, + "chunk_overlap": 200, + "separators": [ + "\n\n", + "\n", + "。", + "!", + "?", + ";", + ";" + ], + "enable_multimodal": true + }, + "image_processing_config": { + "model_id": "" + }, + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "vlm_config": { + "enabled": true, + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "cos_config": { + "secret_id": "", + "secret_key": "", + "region": "", + "bucket_name": "", + "app_id": "", + "path_prefix": "" + }, + "created_at": "2025-08-11T20:10:41.817794+08:00", + "updated_at": "2025-08-12T11:23:00.593097+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## PUT `/knowledge-bases/:id` - 更新知识库 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/knowledge-bases/b5829e4a-3845-4624-a7fb-ea3b35e843b0' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--data '{ + "name": "weknora new", + "description": "weknora description new", + "config": { + "chunking_config": { + "chunk_size": 1000, + "chunk_overlap": 200, + "separators": [ + "\n\n", + "\n", + "。", + "!", + "?", + ";", + ";" + ], + "enable_multimodal": true + }, + "image_processing_config": { + "model_id": "" + } + } +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "b5829e4a-3845-4624-a7fb-ea3b35e843b0", + "name": "weknora new", + "description": "weknora description new", + "tenant_id": 1, + "chunking_config": { + "chunk_size": 1000, + "chunk_overlap": 200, + "separators": [ + "\n\n", + "\n", + "。", + "!", + "?", + ";", + ";" + ], + "enable_multimodal": true + }, + "image_processing_config": { + "model_id": "" + }, + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "rerank_model_id": "b30171a1-787b-426e-a293-735cd5ac16c0", + "vlm_config": { + "enabled": true, + "model_id": "f2083ad7-63e3-486d-a610-e6c56e58d72e" + }, + "cos_config": { + "secret_id": "", + "secret_key": "", + "region": "", + "bucket_name": "", + "app_id": "", + "path_prefix": "" + }, + "created_at": "2025-08-12T11:30:09.206238+08:00", + "updated_at": "2025-08-12T11:36:09.083577609+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## DELETE `/knowledge-bases/:id` - 删除知识库 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/knowledge-bases/b5829e4a-3845-4624-a7fb-ea3b35e843b0' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' +``` + +**响应**: + +```json +{ + "message": "Knowledge base deleted successfully", + "success": true +} +``` + +## GET `/knowledge-bases/:id/hybrid-search` - 混合搜索 + +执行向量搜索和关键词搜索的混合检索。 + +**注意**:此接口使用 GET 方法但需要 JSON 请求体。 + +**请求参数**: +- `query_text`: 搜索查询文本(必填) +- `vector_threshold`: 向量相似度阈值(0-1,可选) +- `keyword_threshold`: 关键词匹配阈值(可选) +- `match_count`: 返回结果数量(可选) +- `disable_keywords_match`: 是否禁用关键词匹配(可选) +- `disable_vector_match`: 是否禁用向量匹配(可选) + +**请求**: + +```curl +curl --location --request GET 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/hybrid-search' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "query_text": "如何使用知识库", + "vector_threshold": 0.5, + "match_count": 10 +}' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "chunk-00000001", + "content": "知识库是用于存储和检索知识的系统...", + "knowledge_id": "knowledge-00000001", + "chunk_index": 0, + "knowledge_title": "知识库使用指南", + "start_at": 0, + "end_at": 500, + "seq": 1, + "score": 0.95, + "chunk_type": "text", + "image_info": "", + "metadata": {}, + "knowledge_filename": "guide.pdf", + "knowledge_source": "file" + } + ], + "success": true +} +``` diff --git a/docs/api/knowledge.md b/docs/api/knowledge.md new file mode 100644 index 000000000..dafd26fe9 --- /dev/null +++ b/docs/api/knowledge.md @@ -0,0 +1,313 @@ +# 知识管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | ------------------------------------- | ------------------------ | +| POST | `/knowledge-bases/:id/knowledge/file` | 从文件创建知识 | +| POST | `/knowledge-bases/:id/knowledge/url` | 从 URL 创建知识 | +| POST | `/knowledge-bases/:id/knowledge/manual` | 创建手工 Markdown 知识 | +| GET | `/knowledge-bases/:id/knowledge` | 获取知识库下的知识列表 | +| GET | `/knowledge/:id` | 获取知识详情 | +| DELETE | `/knowledge/:id` | 删除知识 | +| GET | `/knowledge/:id/download` | 下载知识文件 | +| PUT | `/knowledge/:id` | 更新知识 | +| PUT | `/knowledge/manual/:id` | 更新手工 Markdown 知识 | +| PUT | `/knowledge/image/:id/:chunk_id` | 更新图像分块信息 | +| PUT | `/knowledge/tags` | 批量更新知识标签 | +| GET | `/knowledge/batch` | 批量获取知识 | + +## POST `/knowledge-bases/:id/knowledge/file` - 从文件创建知识 + +**表单参数**: +- `file`: 上传的文件(必填) +- `metadata`: JSON 格式的元数据(可选) +- `enable_multimodel`: 是否启用多模态处理(可选,true/false) +- `fileName`: 自定义文件名,用于文件夹上传时保留路径(可选) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/knowledge/file' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--form 'file=@"/Users/xxxx/tests/彗星.txt"' \ +--form 'enable_multimodel="true"' +``` + +**响应**: + +```json +{ + "data": { + "id": "4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "type": "file", + "title": "彗星.txt", + "description": "", + "source": "", + "parse_status": "processing", + "enable_status": "disabled", + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "file_name": "彗星.txt", + "file_type": "txt", + "file_size": 7710, + "file_hash": "d69476ddbba45223a5e97e786539952c", + "file_path": "data/files/1/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5/1754970756171067621.txt", + "storage_size": 0, + "metadata": null, + "created_at": "2025-08-12T11:52:36.168632288+08:00", + "updated_at": "2025-08-12T11:52:36.173612121+08:00", + "processed_at": null, + "error_message": "", + "deleted_at": null + }, + "success": true +} +``` + +## POST `/knowledge-bases/:id/knowledge/url` - 从 URL 创建知识 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/knowledge/url' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "url":"https://github.com/Tencent/WeKnora", + "enable_multimodel":true +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "9c8af585-ae15-44ce-8f73-45ad18394651", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "type": "url", + "title": "", + "description": "", + "source": "https://github.com/Tencent/WeKnora", + "parse_status": "processing", + "enable_status": "disabled", + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "file_name": "", + "file_type": "", + "file_size": 0, + "file_hash": "", + "file_path": "", + "storage_size": 0, + "metadata": null, + "created_at": "2025-08-12T11:55:05.709266776+08:00", + "updated_at": "2025-08-12T11:55:05.712918234+08:00", + "processed_at": null, + "error_message": "", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/knowledge-bases/:id/knowledge` - 获取知识库下的知识列表 + +**查询参数**: +- `page`: 页码(默认 1) +- `page_size`: 每页条数(默认 20) +- `tag_id`: 按标签ID筛选(可选) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/knowledge?page_size=1&page=1&tag_id=tag-00000001' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "9c8af585-ae15-44ce-8f73-45ad18394651", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "type": "url", + "title": "", + "description": "", + "source": "https://github.com/Tencent/WeKnora", + "parse_status": "pending", + "enable_status": "disabled", + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "file_name": "", + "file_type": "", + "file_size": 0, + "file_hash": "", + "file_path": "", + "storage_size": 0, + "metadata": null, + "created_at": "2025-08-12T11:55:05.709266+08:00", + "updated_at": "2025-08-12T11:55:05.709266+08:00", + "processed_at": null, + "error_message": "", + "deleted_at": null + } + ], + "page": 1, + "page_size": 1, + "success": true, + "total": 2 +} +``` + +注:parse_status 包含 `pending/processing/failed/completed` 四种状态 + +## GET `/knowledge/:id` - 获取知识详情 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": { + "id": "4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "type": "file", + "title": "彗星.txt", + "description": "彗星是由冰和尘埃构成的太阳系小天体,接近太阳时会形成彗发和彗尾。其轨道周期差异大,来源包括柯伊伯带和奥尔特云。彗星与小行星的区别逐渐模糊,部分彗星已失去挥发物质,类似小行星。截至2019年,已知彗星超6600颗,数量庞大。彗星在古代被视为凶兆,现代研究揭示其复杂结构与起源。", + "source": "", + "parse_status": "completed", + "enable_status": "enabled", + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "file_name": "彗星.txt", + "file_type": "txt", + "file_size": 7710, + "file_hash": "d69476ddbba45223a5e97e786539952c", + "file_path": "data/files/1/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5/1754970756171067621.txt", + "storage_size": 33689, + "metadata": null, + "created_at": "2025-08-12T11:52:36.168632+08:00", + "updated_at": "2025-08-12T11:52:53.376871+08:00", + "processed_at": "2025-08-12T11:52:53.376573+08:00", + "error_message": "", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/knowledge/batch` - 批量获取知识 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge/batch?ids=9c8af585-ae15-44ce-8f73-45ad18394651&ids=4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "9c8af585-ae15-44ce-8f73-45ad18394651", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "type": "url", + "title": "", + "description": "", + "source": "https://github.com/Tencent/WeKnora", + "parse_status": "pending", + "enable_status": "disabled", + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "file_name": "", + "file_type": "", + "file_size": 0, + "file_hash": "", + "file_path": "", + "storage_size": 0, + "metadata": null, + "created_at": "2025-08-12T11:55:05.709266+08:00", + "updated_at": "2025-08-12T11:55:05.709266+08:00", + "processed_at": null, + "error_message": "", + "deleted_at": null + }, + { + "id": "4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "type": "file", + "title": "彗星.txt", + "description": "彗星是由冰和尘埃构成的太阳系小天体,接近太阳时会形成彗发和彗尾。其轨道周期差异大,来源包括柯伊伯带和奥尔特云。彗星与小行星的区别逐渐模糊,部分彗星已失去挥发物质,类似小行星。截至2019年,已知彗星超6600颗,数量庞大。彗星在古代被视为凶兆,现代研究揭示其复杂结构与起源。", + "source": "", + "parse_status": "completed", + "enable_status": "enabled", + "embedding_model_id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "file_name": "彗星.txt", + "file_type": "txt", + "file_size": 7710, + "file_hash": "d69476ddbba45223a5e97e786539952c", + "file_path": "data/files/1/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5/1754970756171067621.txt", + "storage_size": 33689, + "metadata": null, + "created_at": "2025-08-12T11:52:36.168632+08:00", + "updated_at": "2025-08-12T11:52:53.376871+08:00", + "processed_at": "2025-08-12T11:52:53.376573+08:00", + "error_message": "", + "deleted_at": null + } + ], + "success": true +} +``` + +## DELETE `/knowledge/:id` - 删除知识 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/knowledge/9c8af585-ae15-44ce-8f73-45ad18394651' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "message": "Deleted successfully", + "success": true +} +``` + +## GET `/knowledge/:id/download` - 下载知识文件 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge/4c4e7c1a-09cf-485b-a7b5-24b8cdc5acf5/download' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +``` +attachment +``` diff --git a/docs/api/message.md b/docs/api/message.md new file mode 100644 index 000000000..b419d6762 --- /dev/null +++ b/docs/api/message.md @@ -0,0 +1,180 @@ +# 消息管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | ---------------------------- | ------------------------ | +| GET | `/messages/:session_id/load` | 获取最近的会话消息列表 | +| DELETE | `/messages/:session_id/:id` | 删除消息 | + +## GET `/messages/:session_id/load` - 获取最近的会话消息列表 + +**查询参数**: + +- `before_time`: 上一次拉取的最早一条消息的 created_at 字段,为空拉取最近的消息 +- `limit`: 每页条数(默认 20) + +**请求**: + +```curl +curl --location --request GET 'http://localhost:8080/api/v1/messages/ceb9babb-1e30-41d7-817d-fd584954304b/load?limit=3&before_time=2030-08-12T14%3A35%3A42.123456789Z' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "query": "彗尾的形状" +}' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "b8b90eeb-7dd5-4cf9-81c6-5ebcbd759451", + "session_id": "ceb9babb-1e30-41d7-817d-fd584954304b", + "request_id": "hCA8SDjxcAvv", + "content": "\n好的", + "role": "assistant", + "knowledge_references": [ + { + "id": "c8347bef-127f-4a22-b962-edf5a75386ec", + "content": "彗星xxx", + "knowledge_id": "a6790b93-4700-4676-bd48-0d4804e1456b", + "chunk_index": 0, + "knowledge_title": "彗星.txt", + "start_at": 0, + "end_at": 2760, + "seq": 0, + "score": 4.038836479187012, + "match_type": 4, + "sub_chunk_id": [ + "688821f0-40bf-428e-8cb6-541531ebeb76", + "c1e9903e-2b4d-4281-be15-0149288d45c2", + "7d955251-3f79-4fd5-a6aa-02f81e044091" + ], + "metadata": {}, + "chunk_type": "text", + "parent_chunk_id": "", + "image_info": "", + "knowledge_filename": "彗星.txt", + "knowledge_source": "" + }, + { + "id": "fa3aadee-cadb-4a84-9941-c839edc3e626", + "content": "# 文档名称\n彗星.txt\n\n# 摘要\n彗星是由冰和尘埃构成的太阳系小天体,接近太阳时会释放气体形成彗发和彗尾。其轨道周期差异大,来源包括柯伊伯带和奥尔特云。彗星与小行星的区别逐渐模糊,部分彗星已失去挥发物质,类似小行星。目前已知彗星数量众多,且存在系外彗星。彗星在古代被视为凶兆,现代研究揭示其复杂结构与起源。", + "knowledge_id": "a6790b93-4700-4676-bd48-0d4804e1456b", + "chunk_index": 6, + "knowledge_title": "彗星.txt", + "start_at": 0, + "end_at": 0, + "seq": 6, + "score": 0.6131043121858466, + "match_type": 0, + "sub_chunk_id": null, + "metadata": {}, + "chunk_type": "summary", + "parent_chunk_id": "c8347bef-127f-4a22-b962-edf5a75386ec", + "image_info": "", + "knowledge_filename": "彗星.txt", + "knowledge_source": "" + } + ], + "agent_steps": [], + "is_completed": true, + "created_at": "2025-08-12T10:24:38.370548+08:00", + "updated_at": "2025-08-12T10:25:40.416382+08:00", + "deleted_at": null + }, + { + "id": "7fa136ae-a045-424e-baac-52113d92ae94", + "session_id": "ceb9babb-1e30-41d7-817d-fd584954304b", + "request_id": "3475c004-0ada-4306-9d30-d7f5efce50d2", + "content": "彗尾的形状", + "role": "user", + "knowledge_references": [], + "agent_steps": [], + "is_completed": true, + "created_at": "2025-08-12T14:30:39.732246+08:00", + "updated_at": "2025-08-12T14:30:39.733277+08:00", + "deleted_at": null + }, + { + "id": "9bcafbcf-a758-40af-a9a3-c4d8e0f49439", + "session_id": "ceb9babb-1e30-41d7-817d-fd584954304b", + "request_id": "3475c004-0ada-4306-9d30-d7f5efce50d2", + "content": "\n好的", + "role": "assistant", + "knowledge_references": [ + { + "id": "c8347bef-127f-4a22-b962-edf5a75386ec", + "content": "彗星xxx", + "knowledge_id": "a6790b93-4700-4676-bd48-0d4804e1456b", + "chunk_index": 0, + "knowledge_title": "彗星.txt", + "start_at": 0, + "end_at": 2760, + "seq": 0, + "score": 4.038836479187012, + "match_type": 3, + "sub_chunk_id": [ + "688821f0-40bf-428e-8cb6-541531ebeb76", + "c1e9903e-2b4d-4281-be15-0149288d45c2", + "7d955251-3f79-4fd5-a6aa-02f81e044091" + ], + "metadata": {}, + "chunk_type": "text", + "parent_chunk_id": "", + "image_info": "", + "knowledge_filename": "彗星.txt", + "knowledge_source": "" + }, + { + "id": "fa3aadee-cadb-4a84-9941-c839edc3e626", + "content": "# 文档名称\n彗星.txt\n\n# 摘要\n彗星是由冰和尘埃构成的太阳系小天体,接近太阳时会释放气体形成彗发和彗尾。其轨道周期差异大,来源包括柯伊伯带和奥尔特云。彗星与小行星的区别逐渐模糊,部分彗星已失去挥发物质,类似小行星。目前已知彗星数量众多,且存在系外彗星。彗星在古代被视为凶兆,现代研究揭示其复杂结构与起源。", + "knowledge_id": "a6790b93-4700-4676-bd48-0d4804e1456b", + "chunk_index": 6, + "knowledge_title": "彗星.txt", + "start_at": 0, + "end_at": 0, + "seq": 6, + "score": 0.6131043121858466, + "match_type": 3, + "sub_chunk_id": null, + "metadata": {}, + "chunk_type": "summary", + "parent_chunk_id": "c8347bef-127f-4a22-b962-edf5a75386ec", + "image_info": "", + "knowledge_filename": "彗星.txt", + "knowledge_source": "" + } + ], + "agent_steps": [], + "is_completed": true, + "created_at": "2025-08-12T14:30:39.735108+08:00", + "updated_at": "2025-08-12T14:31:17.829926+08:00", + "deleted_at": null + } + ], + "success": true +} +``` + +## DELETE `/messages/:session_id/:id` - 删除消息 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/messages/ceb9babb-1e30-41d7-817d-fd584954304b/9bcafbcf-a758-40af-a9a3-c4d8e0f49439' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "message": "Message deleted successfully", + "success": true +} +``` diff --git a/docs/api/model.md b/docs/api/model.md new file mode 100644 index 000000000..9f9e5aa16 --- /dev/null +++ b/docs/api/model.md @@ -0,0 +1,271 @@ +# 模型管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | --------------------- | --------------------- | +| POST | `/models` | 创建模型 | +| GET | `/models` | 获取模型列表 | +| GET | `/models/:id` | 获取模型详情 | +| PUT | `/models/:id` | 更新模型 | +| DELETE | `/models/:id` | 删除模型 | + +## POST `/models` - 创建模型 + +### 创建对话模型(KnowledgeQA) + +```curl +curl --location 'http://localhost:8080/api/v1/models' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--data '{ + "name": "qwen3:8b", + "type": "KnowledgeQA", + "source": "local", + "description": "LLM Model for Knowledge QA", + "parameters": { + "base_url": "", + "api_key": "" + }, + "is_default": false +}' +``` + +### 创建嵌入模型(Embedding) + +```curl +curl --location 'http://localhost:8080/api/v1/models' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--data '{ + "name": "nomic-embed-text:latest", + "type": "Embedding", + "source": "local", + "description": "Embedding Model", + "parameters": { + "base_url": "", + "api_key": "", + "embedding_parameters": { + "dimension": 768, + "truncate_prompt_tokens": 0 + } + }, + "is_default": false +}' +``` + +### 创建排序模型(Rerank) + +```curl +curl --location 'http://localhost:8080/api/v1/models' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--data '{ + "name": "linux6200/bge-reranker-v2-m3:latest", + "type": "Rerank", + "source": "local", + "description": "Rerank Model for Knowledge QA", + "parameters": { + "base_url": "", + "api_key": "" + }, + "is_default": false +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "09c5a1d6-ee8b-4657-9a17-d3dcbd5c70cb", + "tenant_id": 1, + "name": "nomic-embed-text:latest3", + "type": "Embedding", + "source": "local", + "description": "Embedding Model", + "parameters": { + "base_url": "", + "api_key": "", + "embedding_parameters": { + "dimension": 768, + "truncate_prompt_tokens": 0 + } + }, + "is_default": false, + "status": "downloading", + "created_at": "2025-08-12T10:39:01.454591766+08:00", + "updated_at": "2025-08-12T10:39:01.454591766+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/models` - 获取模型列表 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/models' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "tenant_id": 1, + "name": "nomic-embed-text:latest", + "type": "Embedding", + "source": "local", + "description": "Embedding Model", + "parameters": { + "base_url": "", + "api_key": "", + "embedding_parameters": { + "dimension": 768, + "truncate_prompt_tokens": 0 + } + }, + "is_default": true, + "status": "active", + "created_at": "2025-08-11T20:10:41.813832+08:00", + "updated_at": "2025-08-11T20:10:41.822354+08:00", + "deleted_at": null + }, + { + "id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "tenant_id": 1, + "name": "qwen3:8b", + "type": "KnowledgeQA", + "source": "local", + "description": "LLM Model for Knowledge QA", + "parameters": { + "base_url": "", + "api_key": "", + "embedding_parameters": { + "dimension": 0, + "truncate_prompt_tokens": 0 + } + }, + "is_default": true, + "status": "active", + "created_at": "2025-08-11T20:10:41.811761+08:00", + "updated_at": "2025-08-11T20:10:41.825381+08:00", + "deleted_at": null + } + ], + "success": true +} +``` + +## GET `/models/:id` - 获取模型详情 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/models/dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' +``` + +**响应**: + +```json +{ + "data": { + "id": "dff7bc94-7885-4dd1-bfd5-bd96e4df2fc3", + "tenant_id": 1, + "name": "nomic-embed-text:latest", + "type": "Embedding", + "source": "local", + "description": "Embedding Model", + "parameters": { + "base_url": "", + "api_key": "", + "embedding_parameters": { + "dimension": 768, + "truncate_prompt_tokens": 0 + } + }, + "is_default": true, + "status": "active", + "created_at": "2025-08-11T20:10:41.813832+08:00", + "updated_at": "2025-08-11T20:10:41.822354+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## PUT `/models/:id` - 更新模型 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/models/8fdc464d-8eaa-44d4-a85b-094b28af5330' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--data '{ + "name": "linux6200/bge-reranker-v2-m3:latest", + "description": "Rerank Model for Knowledge QA new", + "parameters": { + "base_url": "", + "api_key": "" + }, + "is_default": false +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "8fdc464d-8eaa-44d4-a85b-094b28af5330", + "tenant_id": 1, + "name": "linux6200/bge-reranker-v2-m3:latest", + "type": "Rerank", + "source": "local", + "description": "Rerank Model for Knowledge QA new", + "parameters": { + "base_url": "", + "api_key": "", + "embedding_parameters": { + "dimension": 0, + "truncate_prompt_tokens": 0 + } + }, + "is_default": false, + "status": "active", + "created_at": "2025-08-12T10:57:39.512681+08:00", + "updated_at": "2025-08-12T11:00:27.271678+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## DELETE `/models/:id` - 删除模型 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/models/8fdc464d-8eaa-44d4-a85b-094b28af5330' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' +``` + +**响应**: + +```json +{ + "message": "Model deleted", + "success": true +} +``` diff --git a/docs/api/session.md b/docs/api/session.md new file mode 100644 index 000000000..489ac7f77 --- /dev/null +++ b/docs/api/session.md @@ -0,0 +1,361 @@ +# 会话管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | --------------------------------------- | --------------------- | +| POST | `/sessions` | 创建会话 | +| GET | `/sessions/:id` | 获取会话详情 | +| GET | `/sessions` | 获取租户的会话列表 | +| PUT | `/sessions/:id` | 更新会话 | +| DELETE | `/sessions/:id` | 删除会话 | +| POST | `/sessions/:session_id/generate_title` | 生成会话标题 | +| GET | `/sessions/continue-stream/:session_id` | 继续未完成的会话 | + +## POST `/sessions` - 创建会话 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/sessions' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "knowledge_base_id": "kb-00000001", + "session_strategy": { + "max_rounds": 5, + "enable_rewrite": true, + "fallback_strategy": "FIXED_RESPONSE", + "fallback_response": "对不起,我无法回答这个问题", + "embedding_top_k": 10, + "keyword_threshold": 0.5, + "vector_threshold": 0.7, + "rerank_model_id": "排序模型ID", + "rerank_top_k": 3, + "rerank_threshold": 0.7, + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_parameters": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。xxx", + "context_template": "你是一个专业的智能信息检索助手xxx", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "no_match_prefix": "\n\nNO_MATCH" + } +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "411d6b70-9a85-4d03-bb74-aab0fd8bd12f", + "title": "", + "description": "", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "max_rounds": 5, + "enable_rewrite": true, + "fallback_strategy": "FIXED_RESPONSE", + "fallback_response": "对不起,我无法回答这个问题", + "embedding_top_k": 10, + "keyword_threshold": 0.5, + "vector_threshold": 0.7, + "rerank_model_id": "排序模型ID", + "rerank_top_k": 3, + "rerank_threshold": 0.7, + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_parameters": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。xxx", + "context_template": "你是一个专业的智能信息检索助手xxx", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "agent_config": null, + "context_config": null, + "created_at": "2025-08-12T12:26:19.611616669+08:00", + "updated_at": "2025-08-12T12:26:19.611616919+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/sessions/:id` - 获取会话详情 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/sessions/ceb9babb-1e30-41d7-817d-fd584954304b' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": { + "id": "ceb9babb-1e30-41d7-817d-fd584954304b", + "title": "模型优化策略", + "description": "", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "max_rounds": 5, + "enable_rewrite": true, + "fallback_strategy": "fixed", + "fallback_response": "抱歉,我无法回答这个问题。", + "embedding_top_k": 10, + "keyword_threshold": 0.3, + "vector_threshold": 0.5, + "rerank_model_id": "", + "rerank_top_k": 5, + "rerank_threshold": 0.7, + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_parameters": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话", + "context_template": "你是一个专业的智能信息检索助手", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "agent_config": null, + "context_config": null, + "created_at": "2025-08-12T10:24:38.308596+08:00", + "updated_at": "2025-08-12T10:25:41.317761+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/sessions?page=&page_size=` - 获取租户的会话列表 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/sessions?page=1&page_size=1' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": [ + { + "id": "411d6b70-9a85-4d03-bb74-aab0fd8bd12f", + "title": "", + "description": "", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "max_rounds": 5, + "enable_rewrite": true, + "fallback_strategy": "FIXED_RESPONSE", + "fallback_response": "对不起,我无法回答这个问题", + "embedding_top_k": 10, + "keyword_threshold": 0.5, + "vector_threshold": 0.7, + "rerank_model_id": "排序模型ID", + "rerank_top_k": 3, + "rerank_threshold": 0.7, + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_parameters": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。xxx", + "context_template": "你是一个专业的智能信息检索助手xxx", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "created_at": "2025-08-12T12:26:19.611616+08:00", + "updated_at": "2025-08-12T12:26:19.611616+08:00", + "deleted_at": null + } + ], + "page": 1, + "page_size": 1, + "success": true, + "total": 2 +} +``` + +## PUT `/sessions/:id` - 更新会话 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/sessions/411d6b70-9a85-4d03-bb74-aab0fd8bd12f' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "title": "weknora", + "description": "weknora description", + "knowledge_base_id": "kb-00000001", + "max_rounds": 5, + "enable_rewrite": true, + "fallback_strategy": "FIXED_RESPONSE", + "fallback_response": "对不起,我无法回答这个问题", + "embedding_top_k": 10, + "keyword_threshold": 0.5, + "vector_threshold": 0.7, + "rerank_model_id": "排序模型ID", + "rerank_top_k": 3, + "rerank_threshold": 0.7, + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_parameters": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。xxx", + "context_template": "你是一个专业的智能信息检索助手xxx", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + } +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "411d6b70-9a85-4d03-bb74-aab0fd8bd12f", + "title": "weknora", + "description": "weknora description", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "max_rounds": 5, + "enable_rewrite": true, + "fallback_strategy": "FIXED_RESPONSE", + "fallback_response": "对不起,我无法回答这个问题", + "embedding_top_k": 10, + "keyword_threshold": 0.5, + "vector_threshold": 0.7, + "rerank_model_id": "排序模型ID", + "rerank_top_k": 3, + "rerank_threshold": 0.7, + "summary_model_id": "8aea788c-bb30-4898-809e-e40c14ffb48c", + "summary_parameters": { + "max_tokens": 0, + "repeat_penalty": 1, + "top_k": 0, + "top_p": 0, + "frequency_penalty": 0, + "presence_penalty": 0, + "prompt": "这是用户和助手之间的对话。xxx", + "context_template": "你是一个专业的智能信息检索助手xxx", + "no_match_prefix": "\n\nNO_MATCH", + "temperature": 0.3, + "seed": 0, + "max_completion_tokens": 2048 + }, + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "2025-08-12T14:20:56.738424351+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## DELETE `/sessions/:id` - 删除会话 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/sessions/411d6b70-9a85-4d03-bb74-aab0fd8bd12f' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "message": "Session deleted successfully", + "success": true +} +``` + +## POST `/sessions/:session_id/generate_title` - 生成会话标题 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/sessions/ceb9babb-1e30-41d7-817d-fd584954304b/generate_title' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "messages": [ + { + "role": "user", + "content": "你好,我想了解关于人工智能的知识" + }, + { + "role": "assistant", + "content": "人工智能是计算机科学的一个分支..." + } + ] +}' +``` + +**响应**: + +```json +{ + "data": "模型优化策略", + "success": true +} +``` + +## GET `/sessions/continue-stream/:session_id` - 继续未完成的会话 + +**查询参数**: +- `message_id`: 从 `/messages/:session_id/load` 接口中获取的 `is_completed` 为 `false` 的消息 ID + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/sessions/continue-stream/ceb9babb-1e30-41d7-817d-fd584954304b?message_id=b8b90eeb-7dd5-4cf9-81c6-5ebcbd759451' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应格式**: +服务器端事件流(Server-Sent Events),与 `/knowledge-chat/:session_id` 返回结果一致 diff --git a/docs/api/tag.md b/docs/api/tag.md new file mode 100644 index 000000000..43c2c0fcc --- /dev/null +++ b/docs/api/tag.md @@ -0,0 +1,150 @@ +# 标签管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | ------------------------------------- | ------------------------ | +| GET | `/knowledge-bases/:id/tags` | 获取知识库标签列表 | +| POST | `/knowledge-bases/:id/tags` | 创建标签 | +| PUT | `/knowledge-bases/:id/tags/:tag_id` | 更新标签 | +| DELETE | `/knowledge-bases/:id/tags/:tag_id` | 删除标签 | + +## GET `/knowledge-bases/:id/tags` - 获取知识库标签列表 + +**查询参数**: +- `page`: 页码(默认 1) +- `page_size`: 每页条数(默认 20) +- `keyword`: 标签名称关键字搜索(可选) + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/tags?page=1&page_size=10' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "data": { + "total": 2, + "page": 1, + "page_size": 10, + "data": [ + { + "id": "tag-00000001", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "name": "技术文档", + "color": "#1890ff", + "sort_order": 1, + "created_at": "2025-08-12T10:00:00+08:00", + "updated_at": "2025-08-12T10:00:00+08:00", + "knowledge_count": 5, + "chunk_count": 120 + }, + { + "id": "tag-00000002", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "name": "常见问题", + "color": "#52c41a", + "sort_order": 2, + "created_at": "2025-08-12T10:00:00+08:00", + "updated_at": "2025-08-12T10:00:00+08:00", + "knowledge_count": 3, + "chunk_count": 45 + } + ] + }, + "success": true +} +``` + +## POST `/knowledge-bases/:id/tags` - 创建标签 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/tags' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "name": "产品手册", + "color": "#faad14", + "sort_order": 3 +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "tag-00000003", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "name": "产品手册", + "color": "#faad14", + "sort_order": 3, + "created_at": "2025-08-12T11:00:00+08:00", + "updated_at": "2025-08-12T11:00:00+08:00" + }, + "success": true +} +``` + +## PUT `/knowledge-bases/:id/tags/:tag_id` - 更新标签 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/tags/tag-00000003' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' \ +--data '{ + "name": "产品手册更新", + "color": "#ff4d4f" +}' +``` + +**响应**: + +```json +{ + "data": { + "id": "tag-00000003", + "tenant_id": 1, + "knowledge_base_id": "kb-00000001", + "name": "产品手册更新", + "color": "#ff4d4f", + "sort_order": 3, + "created_at": "2025-08-12T11:00:00+08:00", + "updated_at": "2025-08-12T11:30:00+08:00" + }, + "success": true +} +``` + +## DELETE `/knowledge-bases/:id/tags/:tag_id` - 删除标签 + +**查询参数**: +- `force`: 设置为 `true` 时强制删除(即使标签被引用) + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/knowledge-bases/kb-00000001/tags/tag-00000003?force=true' \ +--header 'X-API-Key: sk-vQHV2NZI_LK5W7wHQvH3yGYExX8YnhaHwZipUYbiZKCYJbBQ' \ +--header 'Content-Type: application/json' +``` + +**响应**: + +```json +{ + "success": true +} +``` diff --git a/docs/api/tenant.md b/docs/api/tenant.md new file mode 100644 index 000000000..f24527c3b --- /dev/null +++ b/docs/api/tenant.md @@ -0,0 +1,243 @@ +# 租户管理 API + +[返回目录](./README.md) + +| 方法 | 路径 | 描述 | +| ------ | -------------- | --------------------- | +| POST | `/tenants` | 创建新租户 | +| GET | `/tenants/:id` | 获取指定租户信息 | +| PUT | `/tenants/:id` | 更新租户信息 | +| DELETE | `/tenants/:id` | 删除租户 | +| GET | `/tenants` | 获取租户列表 | + +## POST `/tenants` - 创建新租户 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/tenants' \ +--header 'Content-Type: application/json' \ +--data '{ + "name": "weknora", + "description": "weknora tenants", + "business": "wechat", + "retriever_engines": { + "engines": [ + { + "retriever_type": "keywords", + "retriever_engine_type": "postgres" + }, + { + "retriever_type": "vector", + "retriever_engine_type": "postgres" + } + ] + } +}' +``` + +**响应**: + +```json +{ + "data": { + "id": 10000, + "name": "weknora", + "description": "weknora tenants", + "api_key": "sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG", + "status": "active", + "retriever_engines": { + "engines": [ + { + "retriever_engine_type": "postgres", + "retriever_type": "keywords" + }, + { + "retriever_engine_type": "postgres", + "retriever_type": "vector" + } + ] + }, + "business": "wechat", + "storage_quota": 10737418240, + "storage_used": 0, + "created_at": "2025-08-11T20:37:28.396980093+08:00", + "updated_at": "2025-08-11T20:37:28.396980301+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## GET `/tenants/:id` - 获取指定租户信息 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/tenants/10000' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG' +``` + +**响应**: + +```json +{ + "data": { + "id": 10000, + "name": "weknora", + "description": "weknora tenants", + "api_key": "sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG", + "status": "active", + "retriever_engines": { + "engines": [ + { + "retriever_engine_type": "postgres", + "retriever_type": "keywords" + }, + { + "retriever_engine_type": "postgres", + "retriever_type": "vector" + } + ] + }, + "business": "wechat", + "storage_quota": 10737418240, + "storage_used": 0, + "created_at": "2025-08-11T20:37:28.39698+08:00", + "updated_at": "2025-08-11T20:37:28.405693+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## PUT `/tenants/:id` - 更新租户信息 + +注意 API Key 会变更 + +**请求**: + +```curl +curl --location --request PUT 'http://localhost:8080/api/v1/tenants/10000' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-KREi84yPtahKxMtIMOW-Cxx2dxb9xROpUuDSpi3vbiC1QVDe' \ +--data '{ + "name": "weknora new", + "description": "weknora tenants new", + "status": "active", + "retriever_engines": { + "engines": [ + { + "retriever_engine_type": "postgres", + "retriever_type": "keywords" + }, + { + "retriever_engine_type": "postgres", + "retriever_type": "vector" + } + ] + }, + "business": "wechat", + "storage_quota": 10737418240 +}' +``` + +**响应**: + +```json +{ + "data": { + "id": 10000, + "name": "weknora new", + "description": "weknora tenants new", + "api_key": "sk-IKtd9JGV4-aPGQ6RiL8YJu9Vzb3-ae4lgFkjFJZmhvUn2mLu", + "status": "active", + "retriever_engines": { + "engines": [ + { + "retriever_engine_type": "postgres", + "retriever_type": "keywords" + }, + { + "retriever_engine_type": "postgres", + "retriever_type": "vector" + } + ] + }, + "business": "wechat", + "storage_quota": 10737418240, + "storage_used": 0, + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "2025-08-11T20:49:02.13421034+08:00", + "deleted_at": null + }, + "success": true +} +``` + +## DELETE `/tenants/:id` - 删除租户 + +**请求**: + +```curl +curl --location --request DELETE 'http://localhost:8080/api/v1/tenants/10000' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-IKtd9JGV4-aPGQ6RiL8YJu9Vzb3-ae4lgFkjFJZmhvUn2mLu' +``` + +**响应**: + +```json +{ + "message": "Tenant deleted successfully", + "success": true +} +``` + +## GET `/tenants` - 获取租户列表 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/tenants' \ +--header 'Content-Type: application/json' \ +--header 'X-API-Key: sk-An7_t_izCKFIJ4iht9Xjcjnj_MC48ILvwezEDki9ScfIa7KA' +``` + +**响应**: + +```json +{ + "data": { + "items": [ + { + "id": 10002, + "name": "weknora", + "description": "weknora tenants", + "api_key": "sk-An7_t_izCKFIJ4iht9Xjcjnj_MC48ILvwezEDki9ScfIa7KA", + "status": "active", + "retriever_engines": { + "engines": [ + { + "retriever_engine_type": "postgres", + "retriever_type": "keywords" + }, + { + "retriever_engine_type": "postgres", + "retriever_type": "vector" + } + ] + }, + "business": "wechat", + "storage_quota": 10737418240, + "storage_used": 0, + "created_at": "2025-08-11T20:52:58.05679+08:00", + "updated_at": "2025-08-11T20:52:58.060495+08:00", + "deleted_at": null + } + ] + }, + "success": true +} +```