diff --git a/mcp_server.py b/mcp_server.py index 5948a3c9..8508f6ca 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -65,31 +65,37 @@ MODEL_CONFIGS = { "api_key": "sk-7363bdb28d7d4bf0aa68eb9449f8f063", "base_url": "https://api.deepseek.com", "model": "deepseek-chat", # 默认模型 + "max_tokens": 8192, # DeepSeek 限制为 8192 }, "kimi-k2": { "api_key": "sk-TzB4VYJfCoXGcGrGMiewukVRzjuDsbVCkaZXi2LvkS8s60E5", "base_url": "https://api.moonshot.cn/v1", "model": "moonshot-v1-8k", # 快速模型 + "max_tokens": 8192, # moonshot-v1-8k 限制为 8k }, "kimi-k2-thinking": { "api_key": "sk-TzB4VYJfCoXGcGrGMiewukVRzjuDsbVCkaZXi2LvkS8s60E5", "base_url": "https://api.moonshot.cn/v1", "model": "kimi-k2-thinking", # 深度思考模型 + "max_tokens": 32768, # Kimi 思考模型支持更大 }, "glm-4.6": { "api_key": "", # 需要配置智谱AI密钥 "base_url": "https://open.bigmodel.cn/api/paas/v4", "model": "glm-4", + "max_tokens": 8192, }, "deepmoney": { "api_key": "", # 空值 "base_url": "http://111.62.35.50:8000/v1", "model": "deepmoney", + "max_tokens": 32768, }, "gemini-3": { "api_key": "", # 需要配置Google API密钥 "base_url": "https://generativelanguage.googleapis.com/v1", "model": "gemini-pro", + "max_tokens": 8192, }, } @@ -2451,11 +2457,13 @@ class MCPAgentIntegrated: try: # 尝试使用选中的模型流式 API + # 从模型配置获取 max_tokens,默认 8192 + model_max_tokens = model_config.get("max_tokens", 8192) if model_config else 32768 stream = planning_client.chat.completions.create( model=planning_model, messages=messages, temperature=1.0, - max_tokens=32768, + max_tokens=model_max_tokens, stream=True, # 启用流式输出 ) @@ -3673,6 +3681,8 @@ async def stream_role_response( # 第一次调用:可能触发工具调用 tool_calls_made = [] + # 从模型配置获取 max_tokens,默认 8192 + max_tokens = model_config.get("max_tokens", 8192) if openai_tools: response = client.chat.completions.create( model=model_config["model"], @@ -3681,7 +3691,7 @@ async def stream_role_response( tool_choice="auto", stream=False, # 工具调用不使用流式 temperature=0.7, - max_tokens=32768, # 增大 token 限制以避免输出被截断 + max_tokens=max_tokens, ) assistant_message = response.choices[0].message @@ -3741,7 +3751,7 @@ async def stream_role_response( messages=messages, stream=True, temperature=0.7, - max_tokens=8192, # 大幅增加 token 限制以避免输出被截断 + max_tokens=max_tokens, ) full_content = "" diff --git a/swagger_stress_test.yaml b/swagger_stress_test.yaml new file mode 100644 index 00000000..e27cb86f --- /dev/null +++ b/swagger_stress_test.yaml @@ -0,0 +1,865 @@ +openapi: 3.0.3 +info: + title: VF React 压测接口文档 + description: | + 登录认证 + 社区/事件中心 高频接口文档 + + **压测建议优先级:** + 1. `GET /api/events` - 事件列表(最高频,首页核心) + 2. `GET /api/auth/session` - 会话检查(每次页面加载) + 3. `GET /api/events/{id}` - 事件详情 + 4. `GET /api/events/{id}/stocks` - 相关股票(需Pro订阅) + 5. `GET /api/events/hot` - 热点事件(首页展示) + version: 1.0.0 + contact: + name: VF Team + +servers: + - url: https://api.valuefrontier.cn + description: 生产环境 + - url: http://localhost:5001 + description: 本地开发 + +tags: + - name: 认证 + description: 登录认证相关接口 + - name: 事件 + description: 事件/社区相关接口 + +paths: + # ==================== 认证接口 ==================== + /api/auth/session: + get: + tags: + - 认证 + summary: 获取当前会话信息 + description: | + **高频指数: ⭐⭐⭐⭐⭐** + + 每次页面加载都会调用,用于检查用户登录状态。 + 无需认证即可调用,未登录时返回 isAuthenticated: false + operationId: getSessionInfo + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + isAuthenticated: + type: boolean + example: true + user: + type: object + nullable: true + properties: + id: + type: integer + example: 1 + username: + type: string + example: "testuser" + nickname: + type: string + example: "测试用户" + email: + type: string + example: "test@example.com" + phone: + type: string + example: "13800138000" + phone_confirmed: + type: boolean + example: true + avatar_url: + type: string + nullable: true + has_wechat: + type: boolean + example: false + subscription_type: + type: string + enum: [free, pro, max] + example: "pro" + subscription_status: + type: string + enum: [active, expired, none] + example: "active" + is_subscription_active: + type: boolean + example: true + subscription_days_left: + type: integer + nullable: true + example: 30 + + /api/auth/login: + post: + tags: + - 认证 + summary: 密码登录 + description: | + **高频指数: ⭐⭐⭐** + + 支持用户名/手机号/邮箱 + 密码登录。 + 登录成功后设置 Session Cookie。 + operationId: login + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - password + properties: + username: + type: string + description: 用户名或手机号 + example: "testuser" + email: + type: string + description: 邮箱(与username二选一) + example: "test@example.com" + phone: + type: string + description: 手机号(与username二选一) + example: "13800138000" + password: + type: string + description: 密码 + example: "password123" + responses: + '200': + description: 登录成功 + headers: + Set-Cookie: + description: Session Cookie + schema: + type: string + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + user: + $ref: '#/components/schemas/UserBasic' + '400': + description: 参数错误 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: 密码错误 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: 用户不存在 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /api/auth/send-verification-code: + post: + tags: + - 认证 + summary: 发送验证码 + description: | + **高频指数: ⭐⭐** + + 发送手机/邮箱验证码,用于验证码登录。 + 验证码5分钟内有效。 + operationId: sendVerificationCode + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - target + - type + properties: + target: + type: string + description: 手机号或邮箱 + example: "13800138000" + type: + type: string + enum: [phone, email] + description: 验证码类型 + example: "phone" + responses: + '200': + description: 发送成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "验证码已发送" + '400': + description: 参数错误 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '429': + description: 发送过于频繁 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /api/auth/login-with-code: + post: + tags: + - 认证 + summary: 验证码登录/注册 + description: | + **高频指数: ⭐⭐⭐** + + 使用验证码登录,如用户不存在则自动注册。 + operationId: loginWithCode + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - target + - code + - type + properties: + target: + type: string + description: 手机号或邮箱 + example: "13800138000" + code: + type: string + description: 6位验证码 + example: "123456" + type: + type: string + enum: [phone, email] + example: "phone" + responses: + '200': + description: 登录成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + is_new_user: + type: boolean + example: false + user: + $ref: '#/components/schemas/UserBasic' + '400': + description: 验证码错误或已过期 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + # ==================== 事件接口 ==================== + /api/events: + get: + tags: + - 事件 + summary: 获取事件列表 + description: | + **高频指数: ⭐⭐⭐⭐⭐(最高频)** + + 社区/事件中心核心接口,支持丰富的筛选、排序、分页功能。 + 只返回有关联股票的事件。 + + **压测重点接口** + operationId: getEvents + parameters: + # 分页 + - name: page + in: query + schema: + type: integer + default: 1 + minimum: 1 + description: 页码 + - name: per_page + in: query + schema: + type: integer + default: 10 + minimum: 1 + maximum: 100 + description: 每页数量 + # 基础筛选 + - name: type + in: query + schema: + type: string + default: "all" + description: 事件类型 + - name: status + in: query + schema: + type: string + default: "active" + enum: [active, ended, all] + description: 事件状态 + - name: importance + in: query + schema: + type: string + default: "all" + description: 重要性等级,支持多个用逗号分隔(如 S,A) + # 日期筛选 + - name: recent_days + in: query + schema: + type: integer + description: 最近N天的事件 + - name: start_date + in: query + schema: + type: string + format: date + description: 开始日期 + - name: end_date + in: query + schema: + type: string + format: date + description: 结束日期 + # 搜索 + - name: q + in: query + schema: + type: string + description: 搜索关键词(搜索标题、描述、关键词、关联股票) + # 行业筛选 + - name: industry_code + in: query + schema: + type: string + description: 申万行业代码(如 S22),支持前缀匹配 + # 排序 + - name: sort + in: query + schema: + type: string + default: "new" + enum: [new, hot, return] + description: 排序方式 + - name: order + in: query + schema: + type: string + default: "desc" + enum: [asc, desc] + description: 排序顺序 + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + $ref: '#/components/schemas/EventListItem' + pagination: + $ref: '#/components/schemas/Pagination' + + /api/events/hot: + get: + tags: + - 事件 + summary: 获取热点事件 + description: | + **高频指数: ⭐⭐⭐⭐** + + 首页热点展示,按平均涨幅排序。 + operationId: getHotEvents + parameters: + - name: days + in: query + schema: + type: integer + default: 3 + description: 最近N天 + - name: limit + in: query + schema: + type: integer + default: 4 + description: 返回数量 + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + $ref: '#/components/schemas/HotEvent' + + /api/events/{event_id}: + get: + tags: + - 事件 + summary: 获取事件详情 + description: | + **高频指数: ⭐⭐⭐⭐** + + 获取单个事件的详细信息,每次调用会增加浏览计数。 + operationId: getEventDetail + parameters: + - name: event_id + in: path + required: true + schema: + type: integer + description: 事件ID + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + $ref: '#/components/schemas/EventDetail' + '404': + description: 事件不存在 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /api/events/{event_id}/stocks: + get: + tags: + - 事件 + summary: 获取事件相关股票 + description: | + **高频指数: ⭐⭐⭐⭐** + + 获取事件关联的股票列表,按相关性排序。 + **需要 Pro 订阅** + operationId: getEventStocks + security: + - sessionAuth: [] + parameters: + - name: event_id + in: path + required: true + schema: + type: integer + description: 事件ID + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + $ref: '#/components/schemas/RelatedStock' + '403': + description: 需要Pro订阅 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: false + error: + type: string + example: "需要Pro订阅" + required_level: + type: string + example: "pro" + '404': + description: 事件不存在 + + /api/events/{event_id}/follow: + post: + tags: + - 事件 + summary: 关注/取消关注事件 + description: | + **高频指数: ⭐⭐⭐** + + 切换事件的关注状态(需要登录) + operationId: toggleEventFollow + security: + - sessionAuth: [] + parameters: + - name: event_id + in: path + required: true + schema: + type: integer + description: 事件ID + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + is_following: + type: boolean + example: true + follower_count: + type: integer + example: 42 + '401': + description: 未登录 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: 事件不存在 + + /api/events/keywords/popular: + get: + tags: + - 事件 + summary: 获取热门关键词 + description: | + **高频指数: ⭐⭐⭐** + + 获取热门事件关键词,用于筛选和推荐。 + operationId: getPopularKeywords + parameters: + - name: limit + in: query + schema: + type: integer + default: 20 + description: 返回数量 + responses: + '200': + description: 成功 + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + type: object + properties: + keyword: + type: string + example: "人工智能" + count: + type: integer + example: 15 + +components: + securitySchemes: + sessionAuth: + type: apiKey + in: cookie + name: session + description: Flask Session Cookie + + schemas: + Error: + type: object + properties: + success: + type: boolean + example: false + error: + type: string + example: "错误信息" + + UserBasic: + type: object + properties: + id: + type: integer + example: 1 + username: + type: string + example: "testuser" + nickname: + type: string + example: "测试用户" + email: + type: string + nullable: true + phone: + type: string + nullable: true + avatar_url: + type: string + nullable: true + + Pagination: + type: object + properties: + page: + type: integer + example: 1 + per_page: + type: integer + example: 10 + total: + type: integer + example: 100 + pages: + type: integer + example: 10 + + EventListItem: + type: object + properties: + id: + type: integer + example: 1 + title: + type: string + example: "OpenAI发布GPT-5" + description: + type: string + example: "OpenAI正式发布GPT-5模型..." + event_type: + type: string + example: "technology" + status: + type: string + enum: [active, ended] + example: "active" + importance: + type: string + enum: [S, A, B, C] + example: "S" + created_at: + type: string + format: date-time + hot_score: + type: number + example: 85.5 + view_count: + type: integer + example: 1234 + follower_count: + type: integer + example: 56 + related_avg_chg: + type: number + description: 关联股票平均涨幅(%) + example: 5.23 + related_max_chg: + type: number + description: 关联股票最大涨幅(%) + example: 10.05 + expectation_surprise_score: + type: number + description: 超预期得分 + example: 75 + keywords: + type: array + items: + type: string + example: ["AI", "GPT", "人工智能"] + creator: + type: object + properties: + id: + type: integer + username: + type: string + + HotEvent: + type: object + properties: + id: + type: integer + example: 1 + title: + type: string + example: "OpenAI发布GPT-5" + description: + type: string + importance: + type: string + example: "S" + created_at: + type: string + format: date-time + related_avg_chg: + type: number + example: 5.23 + related_max_chg: + type: number + example: 10.05 + expectation_surprise_score: + type: number + example: 75 + creator: + type: object + properties: + username: + type: string + + EventDetail: + type: object + properties: + id: + type: integer + title: + type: string + description: + type: string + event_type: + type: string + status: + type: string + start_time: + type: string + format: date-time + nullable: true + end_time: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + hot_score: + type: number + view_count: + type: integer + trending_score: + type: number + post_count: + type: integer + follower_count: + type: integer + related_industries: + type: string + nullable: true + description: 申万行业代码 + keywords: + type: array + items: + type: string + importance: + type: string + related_avg_chg: + type: number + nullable: true + related_max_chg: + type: number + nullable: true + related_week_chg: + type: number + nullable: true + invest_score: + type: number + nullable: true + expectation_surprise_score: + type: number + nullable: true + creator_id: + type: integer + nullable: true + has_chain_analysis: + type: boolean + description: 是否有传导链分析 + is_following: + type: boolean + + RelatedStock: + type: object + properties: + id: + type: integer + stock_code: + type: string + example: "600000.SH" + stock_name: + type: string + example: "浦发银行" + sector: + type: string + nullable: true + example: "银行" + relation_desc: + type: string + description: 关联原因描述 + correlation: + type: number + description: 相关性分数 + example: 0.85 + momentum: + type: number + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time