From 05be2ddb536b80abc1192d5855637818ba3b5c69 Mon Sep 17 00:00:00 2001 From: renjianbo <263303411@qq.com> Date: Sun, 28 Jun 2026 00:22:01 +0800 Subject: [PATCH] feat: add external API service with API Key management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - POST /api/v1/prompt/optimize — core endpoint with X-API-Key auth - Rate limiting: 20 requests per 60s per key - API docs page: /api-docs with cURL/Python/JS examples - Key management: /admin/apikeys — create, toggle, delete keys - ApiKey model with usage tracking (request_count, last_used_at) - Keys stored in DB with env var API_KEYS fallback Co-Authored-By: Claude Opus 4.6 --- src/flask_prompt_master/__init__.py | 4 + src/flask_prompt_master/models/models.py | 14 +- src/flask_prompt_master/routes/api_service.py | 479 ++++++++++++++++++ .../templates/api_docs.html | 199 ++++++++ .../templates/apikey_manage.html | 258 ++++++++++ .../templates/generate.html | 3 + 6 files changed, 956 insertions(+), 1 deletion(-) create mode 100644 src/flask_prompt_master/routes/api_service.py create mode 100644 src/flask_prompt_master/templates/api_docs.html create mode 100644 src/flask_prompt_master/templates/apikey_manage.html diff --git a/src/flask_prompt_master/__init__.py b/src/flask_prompt_master/__init__.py index 5778776..864801b 100644 --- a/src/flask_prompt_master/__init__.py +++ b/src/flask_prompt_master/__init__.py @@ -112,6 +112,10 @@ def create_app(config_class=None): from src.flask_prompt_master.routes.expert_generate_6 import expert_generate_6_bp app.register_blueprint(expert_generate_6_bp) + # 注册对外 API 服务(基于6号专家的提示词优化能力,含鉴权和限流) + from src.flask_prompt_master.routes.api_service import api_service_bp + app.register_blueprint(api_service_bp) + # 注册 Android 工程师专区(Crash 解读、依赖冲突分析等) from src.flask_prompt_master.routes.android_tools import android_tools_bp app.register_blueprint(android_tools_bp) diff --git a/src/flask_prompt_master/models/models.py b/src/flask_prompt_master/models/models.py index 3427eea..b829993 100644 --- a/src/flask_prompt_master/models/models.py +++ b/src/flask_prompt_master/models/models.py @@ -165,4 +165,16 @@ class ResumeOptimization(db.Model): optimized_content = db.Column(db.Text, nullable=False) # 优化后内容(Markdown) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) - user = db.relationship('User', backref='resume_optimizations') \ No newline at end of file + user = db.relationship('User', backref='resume_optimizations') + +class ApiKey(db.Model): + """API 密钥管理表""" + __tablename__ = 'api_key' + + id = db.Column(db.Integer, primary_key=True) + key = db.Column(db.String(64), unique=True, nullable=False, index=True) + label = db.Column(db.String(100), nullable=False) # 备注名(如:张三/前端团队) + is_active = db.Column(db.Boolean, default=True) + created_at = db.Column(db.DateTime, default=datetime.utcnow) + last_used_at = db.Column(db.DateTime, nullable=True) + request_count = db.Column(db.Integer, default=0) # 累计调用次数 \ No newline at end of file diff --git a/src/flask_prompt_master/routes/api_service.py b/src/flask_prompt_master/routes/api_service.py new file mode 100644 index 0000000..1f3c10d --- /dev/null +++ b/src/flask_prompt_master/routes/api_service.py @@ -0,0 +1,479 @@ +# -*- coding: utf-8 -*- +""" +对外 API 服务 — 基于6号专家的提示词优化能力 + +POST /api/v1/prompt/optimize +Header: X-API-Key: +Body: {"input_text": "..."} +""" +import hashlib +import json +import logging +import os +import secrets +import time +from datetime import datetime +from functools import wraps +from flask import Blueprint, request, jsonify, render_template +from openai import OpenAI + +logger = logging.getLogger(__name__) +api_service_bp = Blueprint('api_service', __name__) + +# ===== API 密钥管理 ===== +# 优先从数据库加载,环境变量 API_KEYS 作为补充 +_env_keys = os.environ.get('API_KEYS', '') +_env_key_set = set(k.strip() for k in _env_keys.split(',') if k.strip()) + + +def _get_active_keys(): + """获取所有活跃的 API 密钥(数据库 + 环境变量)""" + keys = set(_env_key_set) + try: + from src.flask_prompt_master.models.models import ApiKey + for k in ApiKey.query.filter_by(is_active=True).all(): + keys.add(k.key) + except Exception as e: + logger.debug("从数据库加载 API 密钥失败: %s", e) + if not keys: + keys.add('sk-test-demo-key') + logger.warning("未配置任何 API 密钥,使用默认测试密钥: sk-test-demo-key") + return keys + + +def _record_usage(api_key): + """记录 API 密钥使用""" + try: + from src.flask_prompt_master.models.models import ApiKey + from src.flask_prompt_master import db + k = ApiKey.query.filter_by(key=api_key, is_active=True).first() + if k: + k.request_count = (k.request_count or 0) + 1 + k.last_used_at = datetime.utcnow() + db.session.commit() + except Exception: + pass + +# ===== 限流 ===== +_rate_window = 60 # 窗口(秒) +_rate_limit = 20 # 每窗口最大请求数 +_rate_buckets = {} # {api_key: [(timestamp,), ...]} + +# ===== LLM 客户端 ===== +client = OpenAI( + api_key=os.environ.get('LLM_API_KEY') or 'sk-fdf7cc1c73504e628ec0119b7e11b8cc', + base_url=os.environ.get('LLM_API_URL') or 'https://api.deepseek.com/v1' +) + +# 阶段1:消歧意图分析 +INTENT_PROMPT_V4 = """你是一位资深的意图分析专家。你的任务是精确理解用户需求,尤其要处理中文多义词的歧义。 + +## 消歧规则(优先级从高到低) + +### 规则1:"设计"的多义性 +| 上下文 | 判定 | +|--------|------| +| 系统设计、架构设计、数据库设计、API设计、模块设计、技术方案设计 | **技术** | +| UI设计、海报设计、品牌设计、视觉设计、创意设计、艺术设计 | **创意** | +| 流程设计、组织设计、商业模式设计、制度设计 | **咨询** | + +### 规则2:"方案"的多义性 +| 上下文 | 判定 | +|--------|------| +| 技术方案、架构方案、实施方案、部署方案 | **技术** | +| 营销方案、活动方案、传播方案、内容方案 | **创意** | +| 管理方案、策略方案、优化方案、治理方案 | **咨询** | + +### 规则3:"分析"的多义性 +| 上下文 | 判定 | +|--------|------| +| 数据分析、日志分析、性能分析、安全分析 | **分析** | +| 需求分析、竞品分析、市场分析 | **咨询** | +| 色彩分析、构图分析、文案分析 | **创意** | + +### 规则4:技术关键词强信号 +看到以下词时,优先判为技术: +Agent、API、SDK、架构、微服务、数据库、后端、前端、部署、DevOps、容器化、分布式、协议、接口、中间件、算法、模型训练、推理、向量、RAG、Pipeline、CI/CD、Kubernetes、Docker、Git + +## 判定流程 +1. 提取核心名词+动词组合 +2. 查询上述消歧表 +3. 判断用户最终要产出什么 +4. 给出判定 + 置信度 + +## 输出格式 +严格返回以下JSON,不要任何额外内容: +{ + "core_intent": "技术", + "sub_category": "多Agent协作系统设计", + "domain": "二级精确领域", + "confidence": 0.92, + "disambiguation_note": "判定依据简述", + "alternative_intent": "咨询", + "key_requirements": ["需求1", "需求2", "需求3"], + "expected_output": "精确的预期产出描述", + "constraints": ["约束1", "约束2"], + "keywords": ["关键词1", "关键词2", "关键词3"] +} +""" + +# 阶段2:生成优化提示词 +PROMPT_GENERATOR_TEMPLATES = { + "技术": """你是一位资深提示词工程师,专精于技术领域。你的任务是生成一个高质量的提示词,让下游LLM能够输出专业的技术方案。 + +意图分析: +{analysis} + +请生成一个完整的提示词,必须包含以下要素: +1. **角色设定**:明确LLM扮演什么技术专家角色(架构师/开发者/技术顾问),给出具体的专业背景 +2. **任务描述**:清晰陈述要完成的技术任务,拆解为2-4个可执行步骤 +3. **输出结构**:定义输出的章节和每章要包含的具体内容(不要只列标题,要说明每章怎么写) +4. **质量标准**:给出具体的质量要求(如"每个API必须给出字段级规范"而非"详细描述") +5. **约束条件**:明确禁止什么、必须包含什么 + +关键原则: +- 你生成的是提示词,不是最终答案 +- 提示词必须自包含——用户复制后可以直接在任何LLM中使用 +- 使用具体的技术术语和可验证的标准 +- 每个章节指引都应该是"如何写"而非"写什么" + +请在末尾附上一句给用户的简短说明(用「」括起来),解释这个提示词适合什么场景使用。""", + + "创意": """你是一位资深提示词工程师,专精于创意领域。你的任务是生成一个高质量的提示词,让下游LLM能够输出专业的创意方案。 + +意图分析: +{analysis} + +请生成一个完整的提示词,必须包含以下要素: +1. **角色设定**:明确LLM扮演什么创意角色(创意总监/文案策划/品牌顾问),给出具体的风格偏好 +2. **任务描述**:清晰陈述创意任务,包括目标受众、品牌调性、传播目标 +3. **输出结构**:定义输出的章节和每章要包含的具体内容——给出框架但不能限制创意发挥 +4. **质量标准**:给出具体的创意质量要求(如"每个视觉描述必须包含色彩/形状/情绪三个维度") +5. **灵感框架**:提供1-2个创作维度的引导,但不预设具体答案 + +关键原则: +- 你生成的是提示词,不是最终文案/设计稿 +- 提示词必须引导LLM发挥创意,同时给出足够结构约束避免空泛 +- 拒绝"高端大气上档次"这类空话——给出可触摸的质量标准 + +请在末尾附上一句给用户的简短说明(用「」括起来),解释这个提示词适合什么场景使用。""", + + "分析": """你是一位资深提示词工程师,专精于数据分析领域。你的任务是生成一个高质量的提示词,让下游LLM能够输出专业的数据分析报告。 + +意图分析: +{analysis} + +请生成一个完整的提示词,必须包含以下要素: +1. **角色设定**:明确LLM扮演什么分析角色(数据分析师/商业分析师/研究员),给出分析方法论倾向 +2. **任务描述**:清晰陈述分析目标、数据范围、要回答的核心问题 +3. **输出结构**:定义输出的章节——包括分析框架、指标定义、可视化建议、洞察和局限性 +4. **质量标准**:给出具体的分析质量标准(如"所有结论必须附数据支撑""指标必须给出计算口径") +5. **方法论指引**:建议使用的分析思维(MECE/假设驱动/探索式),但不强制 + +关键原则: +- 你生成的是提示词,不是最终分析报告 +- 提示词必须要求LLM展示推理过程,而非只给结论 +- 要求LLM诚实标注数据局限性和置信度 + +请在末尾附上一句给用户的简短说明(用「」括起来),解释这个提示词适合什么场景使用。""", + + "咨询": """你是一位资深提示词工程师,专精于管理咨询领域。你的任务是生成一个高质量的提示词,让下游LLM能够输出专业的咨询建议。 + +意图分析: +{analysis} + +请生成一个完整的提示词,必须包含以下要素: +1. **角色设定**:明确LLM扮演什么咨询角色(管理顾问/策略顾问/组织顾问),给出咨询方法论倾向 +2. **任务描述**:清晰陈述咨询问题、客户背景、决策情境 +3. **输出结构**:定义输出的章节——诊断→方案矩阵→推荐→路线图→风险→ROI +4. **质量标准**:给出具体的咨询质量标准(如"方案必须可比较""风险必须有概率×影响评估") +5. **决策导向**:提示词应引导LLM最终输出可执行的决策建议,而非泛泛分析 + +关键原则: +- 你生成的是提示词,不是最终咨询报告 +- 提示词必须要求LLM给出带权重的选项,而非单一建议 +- 要求LLM明确标注假设前提 + +请在末尾附上一句给用户的简短说明(用「」括起来),解释这个提示词适合什么场景使用。""" +} + + +def _check_rate_limit(api_key): + """简单滑动窗口限流,返回 (是否允许, 剩余次数)""" + now = time.time() + window = _rate_window + limit = _rate_limit + + bucket = _rate_buckets.setdefault(api_key, []) + # 清理过期记录 + bucket[:] = [ts for ts in bucket if now - ts < window] + + if len(bucket) >= limit: + return False, 0 + + bucket.append(now) + # 定期清理旧 bucket 防止内存泄漏 + if len(_rate_buckets) > 1000: + _rate_buckets.clear() + return True, limit - len(bucket) + + +def require_api_key(f): + """API Key 鉴权装饰器""" + @wraps(f) + def decorated(*args, **kwargs): + api_key = request.headers.get('X-API-Key') or request.args.get('api_key') + if not api_key: + return jsonify({'code': 401, 'message': '缺少 X-API-Key,请提供 API 密钥', 'data': None}), 401 + if api_key not in _get_active_keys(): + return jsonify({'code': 403, 'message': '无效的 API 密钥', 'data': None}), 403 + + allowed, remaining = _check_rate_limit(api_key) + if not allowed: + return jsonify({ + 'code': 429, + 'message': f'请求过于频繁,每{_rate_window}秒限{_rate_limit}次', + 'data': None + }), 429 + + _record_usage(api_key) + + resp = f(*args, **kwargs) + if isinstance(resp, tuple): + body, status = resp + else: + body, status = resp, 200 + + data = body.get_json() if hasattr(body, 'get_json') else body + if isinstance(data, dict): + data.setdefault('rate_limit', { + 'remaining': remaining, + 'limit': _rate_limit, + 'window_seconds': _rate_window + }) + return jsonify(data), status + return decorated + + +def _run_pipeline(input_text): + """两阶段提示词优化管线,返回 (intent_data, optimized_prompt) 或抛出异常""" + # 阶段1 + resp1 = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": INTENT_PROMPT_V4}, + {"role": "user", "content": input_text} + ], + temperature=0.05, + timeout=60 + ) + intent_raw = (resp1.choices[0].message.content or "").strip() + intent_raw = intent_raw.replace('```json', '').replace('```', '').strip() + + intent_data = json.loads(intent_raw) + for f in ['core_intent', 'domain', 'key_requirements', 'expected_output', 'constraints', 'keywords']: + if f not in intent_data: + raise ValueError(f"缺少字段: {f}") + if intent_data['core_intent'] not in ('技术', '创意', '分析', '咨询'): + intent_data['core_intent'] = '技术' + for arr_f in ['key_requirements', 'constraints', 'keywords']: + v = intent_data.get(arr_f) + if not isinstance(v, list) or len(v) == 0: + intent_data[arr_f] = ['未指定'] + intent_data.setdefault('sub_category', intent_data['domain']) + intent_data.setdefault('confidence', 0.75) + intent_data.setdefault('disambiguation_note', '') + intent_data.setdefault('alternative_intent', '') + + # 阶段2 + core_intent = intent_data['core_intent'] + meta_prompt = PROMPT_GENERATOR_TEMPLATES[core_intent] + analysis_str = json.dumps(intent_data, ensure_ascii=False, indent=2) + + resp2 = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": meta_prompt.format(analysis=analysis_str)}, + {"role": "user", "content": f"用户需求:{input_text}\n\n请基于上述意图分析,生成一个高质量的提示词。"} + ], + temperature=0.5, + max_tokens=1500, + timeout=90 + ) + optimized_prompt = (resp2.choices[0].message.content or "").strip() + if not optimized_prompt: + raise RuntimeError("提示词生成失败") + + return intent_data, optimized_prompt + + +# ===== API 路由 ===== + +@api_service_bp.route('/api/v1/prompt/optimize', methods=['POST']) +@require_api_key +def optimize_prompt(): + """ + 优化提示词 API + POST /api/v1/prompt/optimize + Header: X-API-Key: + Body: {"input_text": "需求描述或原始提示词"} + """ + try: + if not request.is_json: + return jsonify({'code': 400, 'message': '请求必须是 JSON 格式', 'data': None}), 400 + + payload = request.get_json() or {} + input_text = (payload.get('input_text') or '').strip() + if not input_text: + return jsonify({'code': 400, 'message': '缺少 input_text 字段', 'data': None}), 400 + if len(input_text) < 10: + return jsonify({'code': 400, 'message': 'input_text 至少需要 10 个字符', 'data': None}), 400 + + intent_data, optimized_prompt = _run_pipeline(input_text) + + return jsonify({ + 'code': 200, + 'message': 'success', + 'data': { + 'intent_analysis': intent_data, + 'optimized_prompt': optimized_prompt, + 'usage': { + 'api_calls': 2, + 'prompt_length': len(optimized_prompt) + } + } + }) + + except json.JSONDecodeError: + logger.exception("API JSON解析失败") + return jsonify({'code': 500, 'message': '意图分析格式有误,请重试', 'data': None}), 500 + except Exception as e: + logger.exception("API 生成失败") + return jsonify({'code': 500, 'message': str(e) or '服务内部错误', 'data': None}), 500 + + +@api_service_bp.route('/api/v1/prompt/optimize', methods=['GET']) +def api_info(): + """API 信息""" + return jsonify({ + 'service': '提示词优化 API v1', + 'endpoint': '/api/v1/prompt/optimize', + 'method': 'POST', + 'auth': 'Header: X-API-Key', + 'body': {'input_text': '需求描述或原始提示词(至少10字符)'}, + 'response': { + 'code': 200, + 'data': { + 'intent_analysis': '消歧分析结果', + 'optimized_prompt': '优化后的提示词' + } + }, + 'rate_limit': f'每{_rate_window}秒 {_rate_limit} 次/密钥', + 'docs': '/api-docs' + }) + + +@api_service_bp.route('/api-docs', methods=['GET']) +def api_docs_page(): + """API 文档页面""" + return render_template('api_docs.html') + + +# ===== API Key 管理页面 ===== + +@api_service_bp.route('/admin/apikeys', methods=['GET']) +def apikey_manage_page(): + """API 密钥管理页面""" + return render_template('apikey_manage.html') + + +@api_service_bp.route('/api/admin/apikeys', methods=['GET']) +def apikey_list(): + """获取所有密钥""" + try: + from src.flask_prompt_master.models.models import ApiKey + keys = ApiKey.query.order_by(ApiKey.created_at.desc()).all() + return jsonify({ + 'code': 200, + 'data': [{ + 'id': k.id, + 'label': k.label, + 'key': k.key[:8] + '...' + k.key[-4:], # 只展示部分 + 'is_active': k.is_active, + 'created_at': k.created_at.strftime('%Y-%m-%d %H:%M') if k.created_at else '', + 'last_used_at': k.last_used_at.strftime('%Y-%m-%d %H:%M') if k.last_used_at else '从未使用', + 'request_count': k.request_count or 0 + } for k in keys] + }) + except Exception as e: + logger.exception("获取密钥列表失败") + return jsonify({'code': 500, 'message': str(e)}) + + +@api_service_bp.route('/api/admin/apikeys', methods=['POST']) +def apikey_create(): + """创建新密钥""" + try: + from src.flask_prompt_master.models.models import ApiKey + from src.flask_prompt_master import db + + payload = request.get_json() or {} + label = (payload.get('label') or '').strip() or '未备注' + + # 生成随机 key + key = 'sk-' + secrets.token_hex(24) + + k = ApiKey(key=key, label=label) + db.session.add(k) + db.session.commit() + + logger.info("创建 API Key: %s (%s)", key[:12] + '...', label) + return jsonify({ + 'code': 200, + 'message': '创建成功', + 'data': {'id': k.id, 'label': k.label, 'key': key} + }) + except Exception as e: + logger.exception("创建密钥失败") + return jsonify({'code': 500, 'message': str(e)}) + + +@api_service_bp.route('/api/admin/apikeys//toggle', methods=['POST']) +def apikey_toggle(key_id): + """启用/禁用密钥""" + try: + from src.flask_prompt_master.models.models import ApiKey + from src.flask_prompt_master import db + + k = ApiKey.query.get(key_id) + if not k: + return jsonify({'code': 404, 'message': '密钥不存在'}) + + k.is_active = not k.is_active + db.session.commit() + + action = '启用' if k.is_active else '禁用' + logger.info("%s API Key: %s (%s)", action, k.key[:12] + '...', k.label) + return jsonify({'code': 200, 'message': f'已{action}', 'data': {'is_active': k.is_active}}) + except Exception as e: + return jsonify({'code': 500, 'message': str(e)}) + + +@api_service_bp.route('/api/admin/apikeys/', methods=['DELETE']) +def apikey_delete(key_id): + """删除密钥""" + try: + from src.flask_prompt_master.models.models import ApiKey + from src.flask_prompt_master import db + + k = ApiKey.query.get(key_id) + if not k: + return jsonify({'code': 404, 'message': '密钥不存在'}) + + db.session.delete(k) + db.session.commit() + + logger.info("删除 API Key: %s", k.key[:12] + '...') + return jsonify({'code': 200, 'message': '已删除'}) + except Exception as e: + return jsonify({'code': 500, 'message': str(e)}) diff --git a/src/flask_prompt_master/templates/api_docs.html b/src/flask_prompt_master/templates/api_docs.html new file mode 100644 index 0000000..97764be --- /dev/null +++ b/src/flask_prompt_master/templates/api_docs.html @@ -0,0 +1,199 @@ +{% extends "base.html" %} + +{% block title %}API 文档 — 提示词优化服务{% endblock %} + +{% block content %} +
+
+
+

提示词优化 API

+

基于6号专家的两阶段管线,将需求描述或粗糙提示词转化为高质量、可复用的优化提示词。

+
+ +
+

接口信息

+
+
POST
+ /api/v1/prompt/optimize +

提交输入文本,返回消歧分析结果和优化后的提示词

+
+
+ +
+

认证方式

+

在请求头中携带 X-API-Key:

+
X-API-Key: sk-your-api-key
+

联系管理员获取 API 密钥。

+
+ +
+

请求示例

+

cURL

+
curl -X POST {{ request.host_url }}api/v1/prompt/optimize \
+  -H "Content-Type: application/json" \
+  -H "X-API-Key: sk-your-api-key" \
+  -d '{"input_text": "写一个Python数据分析脚本,处理销售CSV并生成月度汇总报告"}'
+ +

Python

+
import requests
+
+resp = requests.post(
+    "{{ request.host_url }}api/v1/prompt/optimize",
+    headers={
+        "Content-Type": "application/json",
+        "X-API-Key": "sk-your-api-key"
+    },
+    json={"input_text": "写一篇关于agent协助的设计方案"}
+)
+
+result = resp.json()
+print(result["data"]["optimized_prompt"])
+ +

JavaScript

+
const resp = await fetch("{{ request.host_url }}api/v1/prompt/optimize", {
+  method: "POST",
+  headers: {
+    "Content-Type": "application/json",
+    "X-API-Key": "sk-your-api-key"
+  },
+  body: JSON.stringify({ input_text: "设计一个SaaS官网的UI/UX方案" })
+});
+
+const { data } = await resp.json();
+console.log(data.optimized_prompt);
+
+ +
+

请求参数

+ + + + + + + +
参数类型必填说明
input_textstring是需求描述或原始提示词,至少10个字符
+
+ +
+

响应格式

+
{
+  "code": 200,
+  "message": "success",
+  "data": {
+    "intent_analysis": {
+      "core_intent": "技术",
+      "sub_category": "Agent协作系统设计",
+      "domain": "人工智能与智能体系统",
+      "confidence": 0.95,
+      "disambiguation_note": "判定依据",
+      "alternative_intent": "咨询",
+      "key_requirements": ["需求1", "需求2"],
+      "expected_output": "预期产出描述",
+      "constraints": ["约束1"],
+      "keywords": ["agent", "协作", "设计方案"]
+    },
+    "optimized_prompt": "# 优化后的完整提示词...",
+    "usage": {
+      "api_calls": 2,
+      "prompt_length": 1785
+    }
+  },
+  "rate_limit": {
+    "remaining": 19,
+    "limit": 20,
+    "window_seconds": 60
+  }
+}
+ +

字段说明

+ + + + + + + + + + + +
字段说明
intent_analysis.core_intent核心意图分类:技术 / 创意 / 分析 / 咨询
intent_analysis.confidence置信度 0-1,≥0.85 为高置信
intent_analysis.disambiguation_note消歧判定依据
optimized_prompt优化后的提示词,可直接复制到任意 LLM 使用
usage.api_calls本次消耗的 API 调用次数(固定 2)
+
+ +
+

限流

+

每密钥每60秒最多 20 次请求。响应头中会返回限流状态:

+
"rate_limit": {
+  "remaining": 19,
+  "limit": 20,
+  "window_seconds": 60
+}
+
+ +
+

错误码

+ + + + + + + + + + + + +
状态码说明
200成功
400参数错误(缺少 input_text / 长度不足 / 非 JSON)
401缺少 X-API-Key
403无效的 API 密钥
429触发限流
500服务内部错误
+
+
+
+{% endblock %} + +{% block extra_css %} + +{% endblock %} diff --git a/src/flask_prompt_master/templates/apikey_manage.html b/src/flask_prompt_master/templates/apikey_manage.html new file mode 100644 index 0000000..9e4ca8b --- /dev/null +++ b/src/flask_prompt_master/templates/apikey_manage.html @@ -0,0 +1,258 @@ +{% extends "base.html" %} + +{% block title %}API Key 管理{% endblock %} + +{% block content %} +
+
+
+

API Key 管理

+

为外部调用者创建和管理 API 密钥

+
+ +
+ + 创建后将一次性展示完整密钥,请提醒对方保存 +
+ +
+
加载中...
+
+
+
+ + + + + + + +
+{% endblock %} + +{% block extra_css %} + +{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/src/flask_prompt_master/templates/generate.html b/src/flask_prompt_master/templates/generate.html index d8219e2..e9452f0 100644 --- a/src/flask_prompt_master/templates/generate.html +++ b/src/flask_prompt_master/templates/generate.html @@ -17,6 +17,9 @@ 专家模式 + + API Key +