├── .gitignore
├── LICENSE
├── README.md
├── README_EN.md
├── cf_workers_version.js
├── index.html
├── package.json
├── postcss.config.js
├── src
├── App.vue
├── assets
│ └── icon.svg
├── data
│ ├── descriptions.json
│ ├── examples.json
│ └── prompts.json
├── index.css
├── main.js
└── views
│ └── Home.vue
├── tailwind.config.js
└── vite.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules/
3 | npm-debug.log*
4 | yarn-debug.log*
5 | yarn-error.log*
6 | package-lock.json
7 | yarn.lock
8 |
9 | # Build outputs
10 | dist/
11 | build/
12 | .next/
13 | out/
14 | .specstory
15 |
16 | # Environment variables
17 | .env
18 | .env.local
19 | .env.*.local
20 | .cursorignore
21 | # IDE and editor files
22 | .idea/
23 | .vscode/
24 | *.swp
25 | *.swo
26 | .DS_Store
27 |
28 | # Logs
29 | logs/
30 | *.log
31 |
32 | # Coverage directory
33 | coverage/
34 |
35 | # Cache directories
36 | .cache/
37 | .npm/
38 | .eslintcache
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 reverse-check
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🔍 reverse-check:LLM API 逆向检测工具
2 | **当前版本:v0.02**
3 |
4 | [English Version](./README_EN.md) | 中文版
5 |
6 | **项目地址**:[GitHub](https://github.com/star5o/reverse-check) | [网站1(vercel域名)](https://reverse-check.vercel.app/) | [网站2(我的域名)](https://reverse-check.no-reverse-api.com)
7 |
8 | **Vercel一键部署**:[](https://vercel.com/new/clone?repository-url=https://github.com/star5o/Freverse-check&project-name=reverse-check&repository-name=reverse-check)
9 |
10 | 本工具是一个基于是否支持官方参数的逆向检测工具。不能通过本工具检测的API极大概率是逆向的。
11 |
12 | 目前项目处于初步阶段,暂时需要人工对比响应结果与示例进行判断。
13 |
14 | ## 功能特性
15 |
16 | - 🔍 支持多种模型提供商的API检测
17 | - OpenAI
18 | - Claude
19 | - Gemini
20 |
21 | - 🛠 丰富的参数测试选项
22 | - max_tokens参数检测
23 | - logprobs参数检测
24 | - n参数检测
25 | - stop参数检测
26 | - function_call/tools参数检测
27 | - response_format参数检测
28 | - 图像输入检测
29 |
30 | - 📊 直观的结果展示
31 | - API请求信息实时展示
32 | - 响应结果对比分析
33 | - 官方示例参考
34 | - 简洁/完整响应切换
35 |
36 | ## 技术栈
37 |
38 | - 前端框架:Vue 3
39 | - UI组件:Tailwind CSS
40 | - 构建工具:Vite
41 |
42 | ## 手动部署
43 |
44 | ### 安装依赖
45 |
46 | ```bash
47 | npm install
48 | ```
49 |
50 | ### 运行开发服务器
51 |
52 | ```bash
53 | npm run dev
54 | ```
55 |
56 | ### 构建生产版本
57 |
58 | ```bash
59 | npm run build
60 | ```
61 |
62 | ## 使用说明
63 |
64 | 1. 选择模型提供商(OpenAI/Claude/Gemini)
65 | 2. 选择要测试的参数类型
66 | 3. 填写API配置信息
67 | - API Base URL
68 | - API Key
69 | - 模型名称
70 | 4. 点击「开始检测」按钮
71 | 5. 查看检测结果和对比信息
72 |
73 | ## 参数详情
74 |
75 | ### OpenAI 参数
76 |
77 | | **参数** | **说明** |
78 | |------------------|--------------------------------------------------------------------------|
79 | | **max_tokens** | 官方API严格遵循token限制(如max_tokens=10),逆向API会忽略限制。 |
80 | | **logprobs** | 官方API会返回每个token的logprobs信息,逆向API不支持此功能。 |
81 | | **n** | 官方API可以返回多个答案(如n=2),逆向API只返回一个。 |
82 | | **stop** | 官方API会在遇到停止词时停止生成,逆向API会忽略停止词。 |
83 | | **image_url** | 官方API能正确处理图片URL并生成描述,逆向API无法处理图片。 |
84 | | **function_call**| 官方API返回JSON格式的函数调用,逆向API不调用函数。 |
85 | | **response_format**| 官方API返回指定格式(如JSON),逆向API只返回字符串。 |
86 |
87 | ### Claude 参数
88 |
89 | | **参数** | **说明** |
90 | |------------------|--------------------------------------------------------------------------|
91 | | **max_tokens** | 官方API严格遵循token限制(如max_tokens=10),逆向API会忽略限制。 |
92 | | **stop** | 官方API会在遇到停止词时停止生成,逆向API会忽略停止词。 |
93 | | **function_call**| 官方API返回JSON格式的函数调用,逆向API不调用函数。 |
94 |
95 | ### Gemini 参数
96 |
97 | | **参数** | **说明** |
98 | |------------------|--------------------------------------------------------------------------|
99 | | **max_tokens** | 官方API严格遵循token限制(如max_tokens=10),逆向API会忽略限制。 |
100 | | **codeExecution**| 官方API有内置的代码执行工具,逆向实现无法执行代码。 |
101 | | **googleSearch** | 官方API能正确调用Google搜索并返回结果,逆向实现无法使用Google搜索工具。 |
102 | | **response_format**| 官方API返回指定格式(如JSON),逆向实现只返回字符串。 |
103 |
104 | ## 待办事项
105 |
106 | 1. 实现自动化逆向检测
107 | 2. 实现与Uptime Kuma的集成以进行持续监控
108 |
109 | ## change log
110 | ### v0.0.2
111 | 1. 增加了推理模型专用检测参数
112 | - OpenAI: reasoning_max_tokens参数检测
113 | - Claude: reasoning_stop参数检测
114 | 2. 当API响应返回错误时(如520错误),也能在页面上显示完整的响应体,而不是弹窗提示。
115 |
116 | ## 推理模型说明
117 | OpenAI的 API 不会返回reasoning_content字段
118 |
119 | ## API文档参考
120 |
121 | - [OpenAI API文档](https://platform.openai.com/docs/api-reference/chat)
122 | - [Claude API文档](https://docs.anthropic.com/en/api/messages)
123 | - [Gemini API文档](https://ai.google.dev/gemini-api/docs)
124 |
125 | ## 许可证
126 |
127 | MIT License
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | # 🔍 LLM API Reverse Engineering Detection Tool
2 | **Current Version: v0.02**
3 |
4 | [中文版](./README.md) | English Version
5 |
6 | **Project Links**: [GitHub](https://github.com/star5o/reverse-check) | [Website](https://reverse-check.vercel.app/)
7 |
8 | [](https://vercel.com/new/clone?repository-url=https://github.com/star5o/Freverse-check&project-name=reverse-check&repository-name=reverse-check)
9 |
10 | This LLM API reverse engineering detection tool based on official parameter support. APIs that fail the detection are highly likely to be reverse-engineered.
11 |
12 | The project is currently in its initial phase, requiring manual comparison of response results with examples.
13 |
14 | ## Features
15 |
16 | - 🔍 Multi-Provider API Detection
17 | - OpenAI
18 | - Claude
19 | - Gemini
20 |
21 | - 🛠 Comprehensive Parameter Testing
22 | - max_tokens parameter validation
23 | - logprobs parameter testing
24 | - n parameter verification
25 | - stop sequence testing
26 | - function_call/tools parameter validation
27 | - response_format parameter testing
28 | - image input support testing
29 |
30 | - 📊 Intuitive Results Display
31 | - Real-time API request information
32 | - Response comparison analysis
33 | - Official examples reference
34 | - Toggle between concise/complete responses
35 |
36 | ## Tech Stack
37 |
38 | - Frontend Framework: Vue 3
39 | - UI Components: Tailwind CSS
40 | - Build Tool: Vite
41 |
42 | ## Quick Start
43 |
44 | ### Install Dependencies
45 |
46 | ```bash
47 | npm install
48 | ```
49 |
50 | ### Run Development Server
51 |
52 | ```bash
53 | npm run dev
54 | ```
55 |
56 | ### Build for Production
57 |
58 | ```bash
59 | npm run build
60 | ```
61 |
62 | ## Usage Guide
63 |
64 | 1. Select a model provider (OpenAI/Claude/Gemini)
65 | 2. Choose parameter types to test
66 | 3. Configure API settings
67 | - API Base URL
68 | - API Key
69 | - Model name
70 | 4. Click "Start Detection" button
71 | 5. Review test results and comparison data
72 |
73 | ## Parameter Details
74 |
75 | ### OpenAI Parameters
76 |
77 | | **Parameter** | **Explanation** |
78 | |------------------|--------------------------------------------------------------------------|
79 | | **max_tokens** | Official API strictly follows token limits (e.g., max_tokens=10), reverse-engineered ones ignore limits. |
80 | | **logprobs** | Official API returns logprobs information for each token, reverse-engineered ones don't support it. |
81 | | **n** | Official API returns multiple answers (e.g., n=2), reverse-engineered ones only return one. |
82 | | **stop** | Official API stops generation at stop words, reverse-engineered ones ignore them. |
83 | | **image_url** | Official API properly processes image URLs and generates descriptions, reverse-engineered ones can't handle images. |
84 | | **function_call**| Official API returns JSON-formatted function calls, reverse-engineered ones don't call functions. |
85 | | **response_format**| Official API returns specified formats (like JSON), reverse-engineered ones only return strings. |
86 |
87 | ### Claude Parameters
88 |
89 | | **Parameter** | **Explanation** |
90 | |------------------|--------------------------------------------------------------------------|
91 | | **max_tokens** | Official API strictly follows token limits (e.g., max_tokens=10), reverse-engineered ones ignore limits. |
92 | | **stop** | Official API stops generation at stop words, reverse-engineered ones ignore them. |
93 | | **function_call**| Official API returns JSON-formatted function calls, reverse-engineered ones don't call functions. |
94 |
95 | ### Gemini Parameters
96 |
97 | | **Parameter** | **Explanation** |
98 | |------------------|--------------------------------------------------------------------------|
99 | | **max_tokens** | Official API strictly follows token limits (e.g., max_tokens=10), reverse-engineered ones ignore limits. |
100 | | **codeExecution**| Official API has built-in code execution tools, reverse-engineered implementations can't execute code. |
101 | | **googleSearch** | Official API correctly calls Google Search and returns results, reverse-engineered implementations can't use Google Search tool. |
102 | | **response_format**| Official API returns specified formats (like JSON), reverse-engineered implementations only return strings. |
103 |
104 |
105 | ## TODO
106 |
107 | 1. Implement automated reverse engineering detection
108 | 2. Implement integration with Uptime Kuma for continuous monitoring
109 |
110 | ## Changelog
111 | ### v0.02
112 | 1. Added reasoning model specific detection parameters
113 | - OpenAI: reasoning_max_tokens parameter testing
114 | - Claude: reasoning_stop parameter testing
115 | - Gemini: reasoning_max_tokens parameter testing
116 | 2. Fixed error handling to display complete response body on API errors (e.g., 520 errors) instead of showing popup alerts.
117 |
118 | ## API Documentation References
119 |
120 | - [OpenAI API Documentation](https://platform.openai.com/docs/api-reference/chat)
121 | - [Claude API Documentation](https://docs.anthropic.com/en/api/messages)
122 | - [Gemini API Documentation](https://ai.google.dev/gemini-api/docs)
123 |
124 | ## License
125 |
126 | MIT License
--------------------------------------------------------------------------------
/cf_workers_version.js:
--------------------------------------------------------------------------------
1 | const HTML_CONTENT = `
2 |
3 |
4 |
5 |
6 |
7 | 逆向与否
8 |
9 |
10 |
11 |
12 |
逆向与否
13 |
14 |
15 |
16 |
49 |
50 |
51 |
52 |
响应结果:
53 |
54 |
55 |
58 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
72 |
73 |
74 |
78 |
79 |
80 |
81 |
321 |
322 |
323 | `;
324 |
325 | async function handleApiTest(request) {
326 | const { baseUrl, apiKey, model, testType } = await request.json();
327 |
328 | // 添加 https:// 前缀(如果用户没有输入)
329 | const fullBaseUrl = baseUrl.startsWith('http') ? baseUrl : `https://${baseUrl}`;
330 |
331 | let requestBody = {
332 | model: model,
333 | messages: [{
334 | role: "user",
335 | content: "repeat ' deepseek number 1 ' 20 times"
336 | }]
337 | };
338 |
339 | // 根据测试类型添加相应参数
340 | switch(testType) {
341 | case 'max_tokens':
342 | requestBody.max_tokens = 9;
343 | break;
344 | case 'logprobs':
345 | requestBody.logprobs = true;
346 | break;
347 | case 'n':
348 | requestBody.n = 2;
349 | break;
350 | case 'stop':
351 | requestBody.stop = ["stop"];
352 | break;
353 | }
354 |
355 | try {
356 | const response = await fetch(`${fullBaseUrl}/v1/chat/completions`, {
357 | method: 'POST',
358 | headers: {
359 | 'Content-Type': 'application/json',
360 | 'Authorization': `Bearer ${apiKey}`
361 | },
362 | body: JSON.stringify(requestBody)
363 | });
364 |
365 | const data = await response.json();
366 | return new Response(JSON.stringify(data), {
367 | headers: { 'Content-Type': 'application/json' }
368 | });
369 | } catch (error) {
370 | return new Response(JSON.stringify({ error: error.message }), {
371 | status: 500,
372 | headers: { 'Content-Type': 'application/json' }
373 | });
374 | }
375 | }
376 |
377 | async function handleRequest(request) {
378 | const url = new URL(request.url);
379 |
380 | if (url.pathname === '/api_request' && request.method === 'POST') {
381 | return handleApiTest(request);
382 | }
383 |
384 | // 返回主页
385 | return new Response(HTML_CONTENT, {
386 | headers: { 'Content-Type': 'text/html' }
387 | });
388 | }
389 |
390 | addEventListener('fetch', event => {
391 | event.respondWith(handleRequest(event.request));
392 | });
393 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 逆向与否
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reverse-check",
3 | "private": true,
4 | "version": "0.0.1",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@ant-design/icons-vue": "^7.0.1",
13 | "@vercel/analytics": "^1.5.0",
14 | "@vueuse/core": "^10.6.1",
15 | "ant-design-vue": "^4.0.7",
16 | "vue": "^3.3.8",
17 | "vue-i18n": "^9.8.0",
18 | "vue-router": "^4.2.5"
19 | },
20 | "devDependencies": {
21 | "@vitejs/plugin-vue": "^4.5.0",
22 | "autoprefixer": "^10.4.16",
23 | "postcss": "^8.4.31",
24 | "tailwindcss": "^3.3.0",
25 | "vite": "^5.0.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/data/descriptions.json:
--------------------------------------------------------------------------------
1 | {
2 | "openai": {
3 | "max_tokens": {
4 | "title": "max_tokens 参数检测说明",
5 | "description": "此检测通过设置较小的 max_tokens 值(10)来观察模型的输出限制处理。官方API会严格遵守token限制,而逆向会忽略此限制。",
6 | "focus_points": [
7 | "官方API:输出将严格限制在10个token以内",
8 | "逆向API:会遵循prompt输出完整的重复内容,超过token限制",
9 | "当前prompt:'输出 'deepseek number 1' 5次'",
10 | "检测参数设置:max_tokens=10"
11 | ]
12 | },
13 | "reasoning_max_tokens": {
14 | "title": "推理模型专用 max_tokens 参数检测说明",
15 | "description": "此检测针对推理模型(如o1等),通过设置较小的max_tokens值(10)观察模型输出限制。官方API会严格遵守token限制,而逆向会完整输出响应内容。",
16 | "focus_points": [
17 | "官方API:message.content内容为空或极短",
18 | "逆向API:message.content会生成完整内容",
19 | "当前prompt:输出 'deepseek number 1' 5次",
20 | "检测参数设置:max_tokens=10"
21 | ]
22 | },
23 | "logprobs": {
24 | "title": "logprobs 参数检测说明",
25 | "description": "此参数在官方API中支持,而逆向实现会不支持该参数。",
26 | "focus_points": [
27 | "官方API:会返回每一个token的logprobs信息,也就是每个token的概率",
28 | "逆向API:只会回答prompt的问题,不会返回logprobs信息",
29 | "当前prompt:'hello!",
30 | "检测参数设置:logprobs=true,top_logprobs=2"
31 | ]
32 | },
33 | "n": {
34 | "title": "n 参数检测说明",
35 | "description": "通过设置n=2测试模型是否能正确返回多个不同的回答。官方API会返回两个回答,而逆向实现只会返回一个回答。",
36 | "focus_points": [
37 | "官方API:返回两个回答",
38 | "逆向API:返回一个回答",
39 | "当前prompt:'Hello!'",
40 | "检测参数设置:n=2"
41 | ]
42 | },
43 | "stop": {
44 | "title": "stop 参数检测说明",
45 | "description": "测试模型是否正确实现了停止序列功能。当遇到停止词时,官方API会立即停止生成,而逆向会忽略此参数输出完整内容。",
46 | "focus_points": [
47 | "官方API:遇到'4'时会立即停止生成",
48 | "逆向API:会生成完整的数字序列",
49 | "当前prompt:'Count from 1 to 10'"
50 | ]
51 | },
52 | "image_url": {
53 | "title": "image_url 参数检测说明",
54 | "description": "测试模型对图像URL输入的处理能力。官方API能正确处理图像输入并生成相关描述,而逆向实现可能无法处理或返回错误。",
55 | "focus_points": [
56 | "官方API:能正确解析图像并生成相关描述",
57 | "逆向API:可能无法处理图像URL或返回错误信息",
58 | "当前prompt:'这是一张什么图片'",
59 | "image_url: https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png",
60 | "注意!image_url参数已被大多数中转商单独处理,带image_url参数的请求走官方渠道(或通过逆向脚本上传图片),所以该参数检测结果不可信"
61 | ]
62 | },
63 | "function_call": {
64 | "title": "function_call 参数检测说明",
65 | "description": "测试模型对函数调用的处理能力。官方API能准确解析和执行函数调用,而逆向就不会调用函数。",
66 | "focus_points": [
67 | "官方API:准确返回函数执行的参数",
68 | "逆向API:不会使用函数调用",
69 | "当前prompt:'Whats the weather like in Boston today?'",
70 | "注意!function_call参数已被众多中转商单独处理,带function_call参数的请求走官方渠道,所以该参数检测结果不可信"
71 | ]
72 | },
73 | "response_format": {
74 | "title": "response_format 参数检测说明",
75 | "description": "测试模型对响应格式的支持。官方API能正确返回指定格式的响应,而逆向只会返回字符串。",
76 | "focus_points": [
77 | "官方API:返回为json格式",
78 | "逆向API:普通字符串格式",
79 | "当前prompt:'给我一个名字和年龄吧'",
80 | "注意!response_format参数已被某些中转商单独处理,带response_format参数的请求走官方渠道,所以该参数检测结果不可信"
81 | ]
82 | }
83 | },
84 | "claude": {
85 | "max_tokens": {
86 | "title": "max_tokens 参数检测说明",
87 | "description": "此检测通过设置较小的 max_tokens 值(10)来观察模型的输出限制处理。官方API会严格遵守token限制,而逆向实现可能会忽略此限制。",
88 | "focus_points": [
89 | "官方API:输出将严格限制在10个token以内",
90 | "逆向API:会遵循prompt输出完整的重复内容,超过token限制",
91 | "当前prompt:'输出 'deepseek number 1' 5次'",
92 | "检测参数设置:max_tokens=10"
93 | ]
94 | },
95 | "reasoning_stop": {
96 | "title": "推理模型专用 stop 参数检测说明",
97 | "description": "此检测针对Claude推理模型,通过设置stop参数为['3']观察模型的推理过程如何展示。官方API会在消息内容中正确停止生成,推理内容不受影响。",
98 | "focus_points": [
99 | "官方API:message.content内容不含有字符'3'",
100 | "逆向API:message.content内容包含完整数字序列,包括'3'",
101 | "当前prompt:'Count from 1 to 10 with Arabic numerals'",
102 | "检测参数设置:stop=['3']"
103 | ]
104 | },
105 | "stop": {
106 | "title": "stop 参数检测说明",
107 | "description": "测试模型是否正确实现了停止序列功能。当遇到停止词时,官方API会立即停止生成,而逆向会忽略此参数输出完整内容。",
108 | "focus_points": [
109 | "官方API:遇到'4'时会立即停止生成",
110 | "逆向API:会生成完整的数字序列",
111 | "当前prompt:'Count from 1 to 10'"
112 | ]
113 | },
114 | "function_call": {
115 | "title": "tools 参数检测说明",
116 | "description": "测试模型对函数调用的处理能力。官方API能准确解析和执行函数调用,而逆向就不会调用函数。",
117 | "focus_points": [
118 | "官方API:准确返回函数执行的参数",
119 | "逆向API:不会使用函数调用",
120 | "当前prompt:'Whats the weather like in Boston today?'",
121 | "注意!tools参数已被众多中转商单独处理,带tools参数的请求走官方渠道,所以该参数检测结果不可信"
122 | ]
123 | }
124 | },
125 | "gemini": {
126 | "max_tokens": {
127 | "title": "max_tokens 参数检测说明",
128 | "description": "此检测通过设置较小的 max_tokens 值(10)来观察模型的输出限制处理。官方API会严格遵守token限制,而逆向实现可能会忽略此限制。",
129 | "focus_points": [
130 | "官方API:输出将严格限制在10个token以内",
131 | "逆向API:会遵循prompt输出完整的重复内容,超过token限制",
132 | "当前prompt:'输出 'deepseek number 1' 5次'",
133 | "检测参数设置:max_tokens=10"
134 | ]
135 | },
136 | "codeExecution": {
137 | "title": "codeExecution 参数检测说明",
138 | "description": "Gemini官方的API内置代码执行工具,会自动编写并执行代码,然后基于代码执行结果进行回答。",
139 | "focus_points": [
140 | "官方API:因为执行了代码,所以结果比较准确,为5117",
141 | "逆向API:可能是其他数字",
142 | "当前prompt:要求前50个指数的和,即'What is the sum of the first 50 prime numbers? Generate and run code for the calculation, and make sure you get all 50'"
143 | ]
144 | },
145 | "googleSearch": {
146 | "title": "googleSearch 参数检测说明",
147 | "description": "Gemini官方的API内置谷歌搜索工具。官方API能正确返回调用谷歌搜索后的结果。",
148 | "focus_points": [
149 | "官方API:会返回今天的日期",
150 | "逆向API:不为今天的日期",
151 | "当前prompt:'今天是几月几号'"
152 | ]
153 | },
154 | "response_format": {
155 | "title": "response_format 参数检测说明",
156 | "description": "测试模型对响应格式的支持。官方API能正确返回指定格式的响应,而逆向只会返回字符串。",
157 | "focus_points": [
158 | "官方API:返回为json格式",
159 | "逆向API:普通字符串格式",
160 | "当前prompt:'给我一个名字和年龄吧'",
161 | "注意!response_format参数已被某些中转商单独处理,带response_format参数的请求走官方渠道,所以该参数检测结果不可信"
162 | ]
163 | }
164 | }
165 | }
--------------------------------------------------------------------------------
/src/data/examples.json:
--------------------------------------------------------------------------------
1 | {
2 | "openai": {
3 | "max_tokens": {
4 | "reverse": {
5 | "id": "chatcmpl-5478735d-4e52-492a-935e-5d2f5e2bd664",
6 | "object": "chat.completion",
7 | "created": 1740733120,
8 | "system_fingerprint": "fp_494464e1cbeb",
9 | "choices": [
10 | {
11 | "index": 0,
12 | "message": {
13 | "role": "assistant",
14 | "content": "deepseek number 1 \ndeepseek number 1 \ndeepseek number 1 \ndeepseek number 1 \ndeepseek number 1 "
15 | },
16 | "finish_reason": "stop"
17 | }
18 | ],
19 | "usage": {
20 | "prompt_tokens": 11,
21 | "completion_tokens": 30,
22 | "total_tokens": 41
23 | }
24 | },
25 | "official": {
26 | "id": "chatcmpl-B5ciMnnnBD4JOKqlxqbV6Ju4mw3nn",
27 | "object": "chat.completion",
28 | "created": 1740680158,
29 | "model": "gpt-4o-2024-11-20",
30 | "choices": [
31 | {
32 | "index": 0,
33 | "message": {
34 | "role": "assistant",
35 | "content": "好的,以下是输出 `'deepseek number ",
36 | "refusal": null
37 | },
38 | "logprobs": null,
39 | "finish_reason": "length"
40 | }
41 | ],
42 | "usage": {
43 | "prompt_tokens": 18,
44 | "completion_tokens": 10,
45 | "total_tokens": 28,
46 | "prompt_tokens_details": {
47 | "cached_tokens": 0,
48 | "audio_tokens": 0
49 | },
50 | "completion_tokens_details": {
51 | "reasoning_tokens": 0,
52 | "audio_tokens": 0,
53 | "accepted_prediction_tokens": 0,
54 | "rejected_prediction_tokens": 0
55 | }
56 | },
57 | "service_tier": "default",
58 | "system_fingerprint": "fp_178d5ba2c0"
59 | }
60 | },
61 | "logprobs": {
62 | "reverse": {
63 | "id": "chatcmpl-a8cf55be-a34a-4a8f-8342-2646ac4ceff5",
64 | "object": "chat.completion",
65 | "created": 1740733338,
66 | "model": "gpt-4o",
67 | "provider": "NiansuhAI",
68 | "system_fingerprint": "fp_4151a65e5332",
69 | "choices": [
70 | {
71 | "index": 0,
72 | "message": {
73 | "role": "assistant",
74 | "content": "Hello! How can I assist you today?"
75 | },
76 | "finish_reason": "stop"
77 | }
78 | ],
79 | "usage": {
80 | "prompt_tokens": 2,
81 | "completion_tokens": 9,
82 | "total_tokens": 11
83 | }
84 | },
85 | "official": {
86 | "id": "chatcmpl-B5qYR17RXblmgllUhW1FMGFb40pnY",
87 | "object": "chat.completion",
88 | "created": 1740733359,
89 | "model": "gpt-4o-2024-08-06",
90 | "choices": [
91 | {
92 | "index": 0,
93 | "message": {
94 | "role": "assistant",
95 | "content": "Hello! How can I assist you today?",
96 | "refusal": null
97 | },
98 | "logprobs": {
99 | "content": [
100 | {
101 | "token": "Hello",
102 | "logprob": -0.47408080101013184,
103 | "bytes": [
104 | 72,
105 | 101,
106 | 108,
107 | 108,
108 | 111
109 | ],
110 | "top_logprobs": [
111 | {
112 | "token": "Hello",
113 | "logprob": -0.47408080101013184,
114 | "bytes": [
115 | 72,
116 | 101,
117 | 108,
118 | 108,
119 | 111
120 | ]
121 | },
122 | {
123 | "token": "Hi",
124 | "logprob": -0.9740808010101318,
125 | "bytes": [
126 | 72,
127 | 105
128 | ]
129 | }
130 | ]
131 | },
132 | {
133 | "token": "!",
134 | "logprob": -0.0000062729995988775045,
135 | "bytes": [
136 | 33
137 | ],
138 | "top_logprobs": [
139 | {
140 | "token": "!",
141 | "logprob": -0.0000062729995988775045,
142 | "bytes": [
143 | 33
144 | ]
145 | },
146 | {
147 | "token": " there",
148 | "logprob": -12.000006675720215,
149 | "bytes": [
150 | 32,
151 | 116,
152 | 104,
153 | 101,
154 | 114,
155 | 101
156 | ]
157 | }
158 | ]
159 | },
160 | {
161 | "token": " How",
162 | "logprob": -0.0000018624639324116288,
163 | "bytes": [
164 | 32,
165 | 72,
166 | 111,
167 | 119
168 | ],
169 | "top_logprobs": [
170 | {
171 | "token": " How",
172 | "logprob": -0.0000018624639324116288,
173 | "bytes": [
174 | 32,
175 | 72,
176 | 111,
177 | 119
178 | ]
179 | },
180 | {
181 | "token": " What",
182 | "logprob": -13.250001907348633,
183 | "bytes": [
184 | 32,
185 | 87,
186 | 104,
187 | 97,
188 | 116
189 | ]
190 | }
191 | ]
192 | },
193 | {
194 | "token": " can",
195 | "logprob": -0.000003531315314830863,
196 | "bytes": [
197 | 32,
198 | 99,
199 | 97,
200 | 110
201 | ],
202 | "top_logprobs": [
203 | {
204 | "token": " can",
205 | "logprob": -0.000003531315314830863,
206 | "bytes": [
207 | 32,
208 | 99,
209 | 97,
210 | 110
211 | ]
212 | },
213 | {
214 | "token": " may",
215 | "logprob": -12.625003814697266,
216 | "bytes": [
217 | 32,
218 | 109,
219 | 97,
220 | 121
221 | ]
222 | }
223 | ]
224 | },
225 | {
226 | "token": " I",
227 | "logprob": 0,
228 | "bytes": [
229 | 32,
230 | 73
231 | ],
232 | "top_logprobs": [
233 | {
234 | "token": " I",
235 | "logprob": 0,
236 | "bytes": [
237 | 32,
238 | 73
239 | ]
240 | },
241 | {
242 | "token": " assist",
243 | "logprob": -23.5,
244 | "bytes": [
245 | 32,
246 | 97,
247 | 115,
248 | 115,
249 | 105,
250 | 115,
251 | 116
252 | ]
253 | }
254 | ]
255 | },
256 | {
257 | "token": " assist",
258 | "logprob": -0.0021852378267794847,
259 | "bytes": [
260 | 32,
261 | 97,
262 | 115,
263 | 115,
264 | 105,
265 | 115,
266 | 116
267 | ],
268 | "top_logprobs": [
269 | {
270 | "token": " assist",
271 | "logprob": -0.0021852378267794847,
272 | "bytes": [
273 | 32,
274 | 97,
275 | 115,
276 | 115,
277 | 105,
278 | 115,
279 | 116
280 | ]
281 | },
282 | {
283 | "token": " help",
284 | "logprob": -6.127185344696045,
285 | "bytes": [
286 | 32,
287 | 104,
288 | 101,
289 | 108,
290 | 112
291 | ]
292 | }
293 | ]
294 | },
295 | {
296 | "token": " you",
297 | "logprob": 0,
298 | "bytes": [
299 | 32,
300 | 121,
301 | 111,
302 | 117
303 | ],
304 | "top_logprobs": [
305 | {
306 | "token": " you",
307 | "logprob": 0,
308 | "bytes": [
309 | 32,
310 | 121,
311 | 111,
312 | 117
313 | ]
314 | },
315 | {
316 | "token": " today",
317 | "logprob": -24.125,
318 | "bytes": [
319 | 32,
320 | 116,
321 | 111,
322 | 100,
323 | 97,
324 | 121
325 | ]
326 | }
327 | ]
328 | },
329 | {
330 | "token": " today",
331 | "logprob": 0,
332 | "bytes": [
333 | 32,
334 | 116,
335 | 111,
336 | 100,
337 | 97,
338 | 121
339 | ],
340 | "top_logprobs": [
341 | {
342 | "token": " today",
343 | "logprob": 0,
344 | "bytes": [
345 | 32,
346 | 116,
347 | 111,
348 | 100,
349 | 97,
350 | 121
351 | ]
352 | },
353 | {
354 | "token": "?",
355 | "logprob": -18.5,
356 | "bytes": [
357 | 63
358 | ]
359 | }
360 | ]
361 | },
362 | {
363 | "token": "?",
364 | "logprob": -6.704273118884885e-7,
365 | "bytes": [
366 | 63
367 | ],
368 | "top_logprobs": [
369 | {
370 | "token": "?",
371 | "logprob": -6.704273118884885e-7,
372 | "bytes": [
373 | 63
374 | ]
375 | },
376 | {
377 | "token": "?\n",
378 | "logprob": -14.250000953674316,
379 | "bytes": [
380 | 63,
381 | 10
382 | ]
383 | }
384 | ]
385 | }
386 | ],
387 | "refusal": null
388 | },
389 | "finish_reason": "stop"
390 | }
391 | ],
392 | "usage": {
393 | "prompt_tokens": 9,
394 | "completion_tokens": 10,
395 | "total_tokens": 19,
396 | "prompt_tokens_details": {
397 | "cached_tokens": 0,
398 | "audio_tokens": 0
399 | },
400 | "completion_tokens_details": {
401 | "reasoning_tokens": 0,
402 | "audio_tokens": 0,
403 | "accepted_prediction_tokens": 0,
404 | "rejected_prediction_tokens": 0
405 | }
406 | },
407 | "service_tier": "default",
408 | "system_fingerprint": "fp_eb9dce56a8"
409 | }
410 | },
411 | "function_call": {
412 | "reverse": {
413 | "id": "chatcmpl-123",
414 | "object": "chat.completion",
415 | "created": 1677652288,
416 | "choices": [
417 | {
418 | "index": 0,
419 | "message": {
420 | "role": "assistant",
421 | "content": "I'm unable to provide real-time information, including current weather conditions. However, you can easily check the weather in Boston today by using a weather website like Weather.com or a weather app on your smartphone. Alternatively, you can ask a voice assistant like Siri, Google Assistant, or Alexa for the latest updates. Let me know if you'd like help with anything else!"
422 | }
423 | }
424 | ]
425 | },
426 | "official": {
427 | "id": "chatcmpl-B5oYcSyY7aWHMWXZ5Fv3ZA8984P38",
428 | "object": "chat.completion",
429 | "created": 1740725682,
430 | "model": "gpt-4o-2024-11-20",
431 | "choices": [
432 | {
433 | "index": 0,
434 | "message": {
435 | "role": "assistant",
436 | "content": null,
437 | "tool_calls": [
438 | {
439 | "id": "call_sZxRdvpwKMvwyJtj6NMVDVzz",
440 | "type": "function",
441 | "function": {
442 | "name": "get_current_weather",
443 | "arguments": "{\"location\":\"Boston, MA\"}"
444 | }
445 | }
446 | ],
447 | "refusal": null
448 | },
449 | "logprobs": null,
450 | "finish_reason": "tool_calls"
451 | }
452 | ],
453 | "usage": {
454 | "prompt_tokens": 80,
455 | "completion_tokens": 18,
456 | "total_tokens": 98,
457 | "prompt_tokens_details": {
458 | "cached_tokens": 0,
459 | "audio_tokens": 0
460 | },
461 | "completion_tokens_details": {
462 | "reasoning_tokens": 0,
463 | "audio_tokens": 0,
464 | "accepted_prediction_tokens": 0,
465 | "rejected_prediction_tokens": 0
466 | }
467 | },
468 | "service_tier": "default",
469 | "system_fingerprint": "fp_7c1f2cecc3"
470 | }
471 | },
472 | "response_format": {
473 | "reverse": {
474 | "id": "chatcmpl-ROdemkVP3dCjKqoarimhx09pnpqQ0",
475 | "object": "chat.completion",
476 | "created": 1740729771,
477 | "model": "gpt-4o-2024-11-20",
478 | "choices": [
479 | {
480 | "index": 0,
481 | "message": {
482 | "role": "assistant",
483 | "content": "好的,我给你取一个名字叫 **晨曦**,寓意着清晨的第一缕阳光,充满希望和活力。年龄的话,就设定为 **25 岁**,正值青春年华,充满无限可能!😊",
484 | "refusal": null
485 | },
486 | "logprobs": null,
487 | "finish_reason": "stop"
488 | }
489 | ],
490 | "usage": {
491 | "prompt_tokens": 0,
492 | "completion_tokens": 0,
493 | "total_tokens": 0,
494 | "prompt_tokens_details": {
495 | "cached_tokens": 0,
496 | "audio_tokens": 0
497 | },
498 | "completion_tokens_details": {
499 | "reasoning_tokens": 0,
500 | "audio_tokens": 0,
501 | "accepted_prediction_tokens": 0,
502 | "rejected_prediction_tokens": 0
503 | }
504 | },
505 | "system_fingerprint": "fp_6807a54d31"
506 | },
507 | "official": {
508 | "id": "chatcmpl-B5pcqTv3SEQcQUIFZTG3INF4dl30I",
509 | "object": "chat.completion",
510 | "created": 1740729788,
511 | "model": "gpt-4o-2024-11-20",
512 | "choices": [
513 | {
514 | "index": 0,
515 | "message": {
516 | "role": "assistant",
517 | "content": "{\"name\":\"小明\",\"age\":25}",
518 | "refusal": null
519 | },
520 | "logprobs": null,
521 | "finish_reason": "stop"
522 | }
523 | ],
524 | "usage": {
525 | "prompt_tokens": 51,
526 | "completion_tokens": 11,
527 | "total_tokens": 62,
528 | "prompt_tokens_details": {
529 | "cached_tokens": 0,
530 | "audio_tokens": 0
531 | },
532 | "completion_tokens_details": {
533 | "reasoning_tokens": 0,
534 | "audio_tokens": 0,
535 | "accepted_prediction_tokens": 0,
536 | "rejected_prediction_tokens": 0
537 | }
538 | },
539 | "service_tier": "default",
540 | "system_fingerprint": "fp_7c1f2cecc3"
541 | }
542 | },
543 | "n": {
544 | "reverse": {
545 | "id": "chatcmpl-SRRSjviQNd1eCUHHQWbN4rumeX3ct",
546 | "object": "chat.completion",
547 | "created": 1740679079,
548 | "model": "gpt-4o-2024-11-20",
549 | "choices": [
550 | {
551 | "index": 0,
552 | "message": {
553 | "role": "assistant",
554 | "content": "Got it! How can I assist you today? 😊",
555 | "refusal": null
556 | },
557 | "logprobs": null,
558 | "finish_reason": "stop"
559 | }
560 | ],
561 | "usage": {
562 | "prompt_tokens": 0,
563 | "completion_tokens": 0,
564 | "total_tokens": 0,
565 | "prompt_tokens_details": {
566 | "cached_tokens": 0,
567 | "audio_tokens": 0
568 | },
569 | "completion_tokens_details": {
570 | "reasoning_tokens": 0,
571 | "audio_tokens": 0,
572 | "accepted_prediction_tokens": 0,
573 | "rejected_prediction_tokens": 0
574 | }
575 | },
576 | "system_fingerprint": "fp_45b1fb6a83"
577 | },
578 | "official": {
579 | "id": "chatcmpl-B5cPnUjHj3f0s39DpKbu0xHA7ZCmS",
580 | "object": "chat.completion",
581 | "created": 1740679007,
582 | "model": "gpt-4o-2024-11-20",
583 | "choices": [
584 | {
585 | "index": 0,
586 | "message": {
587 | "role": "assistant",
588 | "content": "Hello! 😊 How can I assist you today?",
589 | "refusal": null
590 | },
591 | "logprobs": null,
592 | "finish_reason": "stop"
593 | },
594 | {
595 | "index": 1,
596 | "message": {
597 | "role": "assistant",
598 | "content": "Hi there! How can I assist you today? 😊",
599 | "refusal": null
600 | },
601 | "logprobs": null,
602 | "finish_reason": "stop"
603 | }
604 | ],
605 | "usage": {
606 | "prompt_tokens": 9,
607 | "completion_tokens": 23,
608 | "total_tokens": 32,
609 | "prompt_tokens_details": {
610 | "cached_tokens": 0,
611 | "audio_tokens": 0
612 | },
613 | "completion_tokens_details": {
614 | "reasoning_tokens": 0,
615 | "audio_tokens": 0,
616 | "accepted_prediction_tokens": 0,
617 | "rejected_prediction_tokens": 0
618 | }
619 | },
620 | "service_tier": "default",
621 | "system_fingerprint": "fp_4dd9e4e381"
622 | }
623 | },
624 | "image_url": {
625 | "reverse": {
626 | "choices": [
627 | {
628 | "finish_reason": "stop",
629 | "index": 0,
630 | "message": {
631 | "content": "很抱歉,我无法查看或分析图片。如果你能描述一下图片的内容或提供一些详细信息,我会尽力帮助你解答相关问题!",
632 | "role": "assistant"
633 | }
634 | }
635 | ],
636 | "created": 1740720538,
637 | "id": "chatcmpl-B5nDvCe77Y07LferKAyvNEa82ETAI",
638 | "model": "gpt-4o-2024-11-20",
639 | "object": "chat.completion",
640 | "usage": {
641 | "completion_tokens": 52,
642 | "prompt_tokens": 8,
643 | "total_tokens": 60
644 | }
645 | },
646 | "official": {
647 | "id": "chatcmpl-B5ny062ZzdKkkR3lDxsTvFtvcjNXr",
648 | "object": "chat.completion",
649 | "created": 1740723412,
650 | "model": "gpt-4o-2024-11-20",
651 | "choices": [
652 | {
653 | "index": 0,
654 | "message": {
655 | "role": "assistant",
656 | "content": "这是一张谷歌(Google)标志的图片。",
657 | "refusal": null
658 | },
659 | "logprobs": null,
660 | "finish_reason": "stop"
661 | }
662 | ],
663 | "usage": {
664 | "prompt_tokens": 452,
665 | "completion_tokens": 14,
666 | "total_tokens": 466,
667 | "prompt_tokens_details": {
668 | "cached_tokens": 0,
669 | "audio_tokens": 0
670 | },
671 | "completion_tokens_details": {
672 | "reasoning_tokens": 0,
673 | "audio_tokens": 0,
674 | "accepted_prediction_tokens": 0,
675 | "rejected_prediction_tokens": 0
676 | }
677 | },
678 | "service_tier": "default",
679 | "system_fingerprint": "fp_4dd9e4e381"
680 | }
681 | },
682 | "stop": {
683 | "reverse": {
684 | "id": "chatcmpl-bb5034c3-2e24-4ed1-b733-12e66505ce1a",
685 | "object": "chat.completion",
686 | "created": 1740734955,
687 | "system_fingerprint": "fp_d5139097a00d",
688 | "choices": [
689 | {
690 | "index": 0,
691 | "message": {
692 | "role": "assistant",
693 | "content": "Sure! Here you go:\n\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10."
694 | },
695 | "finish_reason": "stop"
696 | }
697 | ],
698 | "usage": {
699 | "prompt_tokens": 7,
700 | "completion_tokens": 35,
701 | "total_tokens": 42
702 | }
703 | },
704 | "official": {
705 | "id": "chatcmpl-B5cNThpGsSY90qFeJYEs1SkG6D073",
706 | "object": "chat.completion",
707 | "created": 1740678863,
708 | "model": "gpt-4o-2024-08-06",
709 | "choices": [
710 | {
711 | "index": 0,
712 | "message": {
713 | "role": "assistant",
714 | "content": "Certainly! Here you go:\n\n1, 2, 3, ",
715 | "refusal": null
716 | },
717 | "logprobs": null,
718 | "finish_reason": "stop"
719 | }
720 | ],
721 | "usage": {
722 | "prompt_tokens": 14,
723 | "completion_tokens": 15,
724 | "total_tokens": 29,
725 | "prompt_tokens_details": {
726 | "cached_tokens": 0,
727 | "audio_tokens": 0
728 | },
729 | "completion_tokens_details": {
730 | "reasoning_tokens": 0,
731 | "audio_tokens": 0,
732 | "accepted_prediction_tokens": 0,
733 | "rejected_prediction_tokens": 0
734 | }
735 | },
736 | "service_tier": "default",
737 | "system_fingerprint": "fp_b491d0b9e9"
738 | }
739 | },
740 | "reasoning_max_tokens": {
741 | "reverse": {
742 | "id": "1c24e05b-b008-435a-9a93-6a14218b13c0",
743 | "object": "chat.completion",
744 | "created": 1743440167261,
745 | "model": "o3-mini",
746 | "choices": [
747 | {
748 | "index": 0,
749 | "message": {
750 | "role": "assistant",
751 | "content": "## Thought:\n\n\n\nReasoned about output repetition for a few seconds\n\n\n\n## Answer:\n\ndeepseek number 1 \ndeepseek number 1 \ndeepseek number 1 \ndeepseek number 1 \ndeepseek number 1"
752 | },
753 | "finish_reason": "stop"
754 | }
755 | ]
756 | },
757 | "official": {
758 | "id": "gen-1743440107-lNK2x8KVMirOwk3NYukG",
759 | "provider": "OpenAI",
760 | "model": "openai/o3-mini",
761 | "object": "chat.completion",
762 | "created": 1743440107,
763 | "choices": [
764 | {
765 | "logprobs": null,
766 | "finish_reason": "length",
767 | "native_finish_reason": "length",
768 | "index": 0,
769 | "message": {
770 | "role": "assistant",
771 | "content": "",
772 | "refusal": null
773 | }
774 | }
775 | ],
776 | "system_fingerprint": "fp_617f206dd9",
777 | "usage": {
778 | "prompt_tokens": 17,
779 | "completion_tokens": 10,
780 | "total_tokens": 27,
781 | "prompt_tokens_details": {
782 | "cached_tokens": 0
783 | },
784 | "completion_tokens_details": {
785 | "reasoning_tokens": 10
786 | }
787 | }
788 | }
789 | }
790 | },
791 | "claude": {
792 | "max_tokens": {
793 | "reverse": {
794 | "id": "chatcmpl-ac3e1f9d84a441e189f463d9e373b",
795 | "object": "chat.completion",
796 | "created": 1740740434,
797 | "model": "claude-3-5-sonnet-20241022",
798 | "system_fingerprint": "fp_a24b4d720c",
799 | "choices": [
800 | {
801 | "index": 0,
802 | "message": {
803 | "role": "assistant",
804 | "content": "你可以通过简单的循环来实现这个输出。你可以想象一个循环结构,重复输出字符串 'deepseek number 1' 五次。每次循环都会打印这个字符串,直到达到五次为止。"
805 | },
806 | "finish_reason": "stop"
807 | }
808 | ],
809 | "usage": {
810 | "prompt_tokens": 8,
811 | "completion_tokens": 23,
812 | "total_tokens": 31
813 | }
814 | },
815 | "official": {
816 | "id": "chatcmpl-beiu3LcIeCg5JyJwebH650FToElv6",
817 | "object": "chat.completion",
818 | "created": 1740740337,
819 | "model": "claude-3-5-sonnet-20241022",
820 | "choices": [
821 | {
822 | "index": 0,
823 | "message": {
824 | "role": "assistant",
825 | "content": "Here are 5 repetitions of '",
826 | "refusal": null
827 | },
828 | "logprobs": null,
829 | "finish_reason": "stop"
830 | }
831 | ],
832 | "usage": {
833 | "prompt_tokens": 22,
834 | "completion_tokens": 10,
835 | "total_tokens": 32
836 | }
837 | }
838 | },
839 | "stop": {
840 | "reverse": {
841 | "id": "chatcmpl-62b7e2cfd5a345b9b572182c8670b",
842 | "object": "chat.completion",
843 | "created": 1740740227,
844 | "model": "claude-3-5-sonnet-20241022",
845 | "system_fingerprint": "fp_a24b4d720c",
846 | "choices": [
847 | {
848 | "index": 0,
849 | "message": {
850 | "role": "assistant",
851 | "content": "Here is the count from 1 to 10 using Arabic numerals:\n\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10"
852 | },
853 | "finish_reason": "stop"
854 | }
855 | ],
856 | "usage": {
857 | "prompt_tokens": 10,
858 | "completion_tokens": 23,
859 | "total_tokens": 33
860 | }
861 | },
862 | "official": {
863 | "id": "chatcmpl-EG0noygvQICNxMc7oTJobFt9r09ZP",
864 | "object": "chat.completion",
865 | "created": 1740740283,
866 | "model": "claude-3-5-sonnet-20241022",
867 | "choices": [
868 | {
869 | "index": 0,
870 | "message": {
871 | "role": "assistant",
872 | "content": "1\n2\n3\n",
873 | "refusal": null
874 | },
875 | "logprobs": null,
876 | "finish_reason": "stop"
877 | }
878 | ],
879 | "usage": {
880 | "prompt_tokens": 20,
881 | "completion_tokens": 8,
882 | "total_tokens": 28
883 | }
884 | }
885 | },
886 | "function_call": {
887 | "reverse": {
888 | "id": "chatcmpl-cf84c54e0443436fa0910dd982772",
889 | "object": "chat.completion",
890 | "created": 1740740119,
891 | "model": "claude-3-5-sonnet-20241022",
892 | "system_fingerprint": "fp_a24b4d720c",
893 | "choices": [
894 | {
895 | "index": 0,
896 | "message": {
897 | "role": "assistant",
898 | "content": "I'm unable to provide real-time information such as current weather conditions. I recommend checking a reliable weather website or app for the latest updates on the weather in Boston."
899 | },
900 | "finish_reason": "stop"
901 | }
902 | ],
903 | "usage": {
904 | "prompt_tokens": 10,
905 | "completion_tokens": 48,
906 | "total_tokens": 58
907 | }
908 | },
909 | "official": {
910 | "id": "msg_bdrk_01QTe5d7DHQADTBXHDNAVrEH",
911 | "model": "claude-3-5-sonnet-20241022",
912 | "object": "chat.completion",
913 | "created": 1740739157,
914 | "choices": [
915 | {
916 | "index": 0,
917 | "message": {
918 | "role": "assistant",
919 | "content": "I'll help you check the current weather in Boston. Let me get that information for you.",
920 | "tool_calls": [
921 | {
922 | "id": "toolu_bdrk_01LxMrXghyBxrUVhroBzGpJV",
923 | "type": "function",
924 | "function": {
925 | "name": "get_current_weather",
926 | "arguments": "{\"location\":\"Boston, MA\"}"
927 | }
928 | }
929 | ]
930 | },
931 | "finish_reason": "tool_use"
932 | }
933 | ],
934 | "usage": {
935 | "prompt_tokens": 426,
936 | "completion_tokens": 77,
937 | "total_tokens": 503
938 | }
939 | }
940 | },
941 | "reasoning_stop": {
942 | "reverse": {
943 | "id": "chatcmpl-08c0e27865f14316b8102656455ea53d",
944 | "object": "chat.completion",
945 | "created": 1743445861,
946 | "model": "claude-3-7-sonnet-20250219-thinking",
947 | "choices": [
948 | {
949 | "index": 0,
950 | "message": {
951 | "role": "assistant",
952 | "content": "以下是从1到10的计数:\n\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
953 | }
954 | }
955 | ]
956 | },
957 | "official": {
958 | "id": "gen-1743445740-2bw4LAyVVgNwDbAG6mNU",
959 | "provider": "Google",
960 | "model": "anthropic/claude-3.7-sonnet",
961 | "object": "chat.completion",
962 | "created": 1743445740,
963 | "choices": [
964 | {
965 | "logprobs": null,
966 | "finish_reason": "stop",
967 | "native_finish_reason": "stop",
968 | "index": 0,
969 | "message": {
970 | "role": "assistant",
971 | "content": "Here's counting from 1 to 10:\n\n1\n2\n",
972 | "refusal": null,
973 | "reasoning": "The human is asking me to count from 1 to 10. This is a simple task where I need to list the numbers in ascending order from 1 to 10.\n\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n\nThat's the complete count from 1 to 10."
974 | }
975 | }
976 | ],
977 | "usage": {
978 | "prompt_tokens": 43,
979 | "completion_tokens": 100,
980 | "total_tokens": 143
981 | }
982 | }
983 | }
984 | },
985 | "gemini": {
986 | "max_tokens": {
987 | "reverse": {
988 | "id": "chatcmpl-zsFrobjxCsqpeuCNUfJaFBK4OXMTr",
989 | "object": "chat.completion",
990 | "created": 1740740838,
991 | "model": "gemini-2.0-flash-thinking-exp",
992 | "choices": [
993 | {
994 | "index": 0,
995 | "message": {
996 | "role": "assistant",
997 | "content": "好的,没问题!\n\ndeepseek number 1 deepseek number 1 deepseek number 1 deepseek number 1 deepseek number 1\n\n希望这个输出符合你的要求! 如果你还有其他指令,尽管告诉我。",
998 | "refusal": null
999 | },
1000 | "logprobs": null,
1001 | "finish_reason": "stop"
1002 | }
1003 | ],
1004 | "usage": {
1005 | "prompt_tokens": 0,
1006 | "completion_tokens": 0,
1007 | "total_tokens": 0,
1008 | "prompt_tokens_details": {
1009 | "cached_tokens": 0,
1010 | "audio_tokens": 0
1011 | },
1012 | "completion_tokens_details": {
1013 | "reasoning_tokens": 0,
1014 | "audio_tokens": 0,
1015 | "accepted_prediction_tokens": 0,
1016 | "rejected_prediction_tokens": 0
1017 | }
1018 | },
1019 | "system_fingerprint": "fp_4a61d2ebb8"
1020 | },
1021 | "official": {
1022 | "id": "chatcmpl-0915722c518345f894d9aeb4efc77e28",
1023 | "model": "gemini-2.0-flash",
1024 | "object": "chat.completion",
1025 | "created": 1740741172,
1026 | "choices": [
1027 | {
1028 | "index": 0,
1029 | "message": {
1030 | "role": "assistant",
1031 | "content": "deepseek number 1\ndeepseek number "
1032 | },
1033 | "finish_reason": "length"
1034 | }
1035 | ],
1036 | "error": null,
1037 | "usage": {
1038 | "prompt_tokens": 16,
1039 | "completion_tokens": 10,
1040 | "total_tokens": 26,
1041 | "prompt_tokens_details": {
1042 | "cached_tokens": 0,
1043 | "text_tokens": 0,
1044 | "audio_tokens": 0,
1045 | "image_tokens": 0
1046 | },
1047 | "completion_tokens_details": {
1048 | "text_tokens": 0,
1049 | "audio_tokens": 0
1050 | }
1051 | }
1052 | }
1053 | },
1054 | "codeExecution": {
1055 | "reverse": {
1056 | "id": "chatcmpl-JVxi2NwSIJVkwoNzuozEjhVKiOQbU",
1057 | "object": "chat.completion",
1058 | "created": 1740742479,
1059 | "model": "gemini-2.0-flash-thinking-exp",
1060 | "choices": [
1061 | {
1062 | "index": 0,
1063 | "message": {
1064 | "role": "assistant",
1065 | "content": "The sum of the first 50 prime numbers is a fascinating question! Let's embark on a journey to discover this sum. We'll need to identify those elusive prime numbers first, and then, with a bit of computational magic, we'll add them all up.\n\nHere's a little code snippet in Python to help us on our quest:\n\n```python\ndef is_prime(n):\n if n <= 1:\n return False\n if n <= 3:\n return True\n if n % 2 == 0 or n % 3 == 0:\n return False\n i = 5\n while i * i <= n:\n if n % i == 0 or n % (i + 2) == 0:\n return False\n i += 6\n return True\n\ndef sum_first_n_primes(n):\n primes = []\n num = 2\n while len(primes) < n:\n if is_prime(num):\n primes.append(num)\n num += 1\n return sum(primes)\n\nnumber_of_primes = 50\nsum_of_primes = sum_first_n_primes(number_of_primes)\nprint(f\"The sum of the first {number_of_primes} prime numbers is: {sum_of_primes}\")\n\n```\n\nWhen we run this code, it diligently calculates and reveals that the sum of the first 50 prime numbers is **24133**.\n\nIsn't it amazing how numbers hold such secrets waiting to be uncovered? Prime numbers, in particular, have intrigued mathematicians for centuries, and their distribution and properties continue to be a source of wonder and study.",
1066 | "refusal": null
1067 | },
1068 | "logprobs": null,
1069 | "finish_reason": "stop"
1070 | }
1071 | ],
1072 | "usage": {
1073 | "prompt_tokens": 0,
1074 | "completion_tokens": 0,
1075 | "total_tokens": 0,
1076 | "prompt_tokens_details": {
1077 | "cached_tokens": 0,
1078 | "audio_tokens": 0
1079 | },
1080 | "completion_tokens_details": {
1081 | "reasoning_tokens": 0,
1082 | "audio_tokens": 0,
1083 | "accepted_prediction_tokens": 0,
1084 | "rejected_prediction_tokens": 0
1085 | }
1086 | },
1087 | "system_fingerprint": "fp_a713964b2e"
1088 | },
1089 | "official": {
1090 | "id": "chatcmpl-1b79cf65137f4601a498c5c95b701b64",
1091 | "model": "gemini-2.0-flash",
1092 | "object": "chat.completion",
1093 | "created": 1740742508,
1094 | "choices": [
1095 | {
1096 | "index": 0,
1097 | "message": {
1098 | "role": "assistant",
1099 | "content": "Okay, I need to calculate the sum of the first 50 prime numbers. Here's my plan:\n\n1. **Generate Prime Numbers:** Create a function to generate prime numbers. I will iterate through numbers, checking for primality.\n2. **Store Prime Numbers:** Store the generated prime numbers in a list until I have 50 of them.\n3. **Sum the Primes:** Calculate the sum of the prime numbers in the list.\n4. **Output:** Present the sum.\n\nHere's the Python code:\n\n\n```PYTHON\ndef is_prime(n):\n \"\"\"Check if a number is prime.\"\"\"\n if n <= 1:\n return False\n if n <= 3:\n return True\n if n % 2 == 0 or n % 3 == 0:\n return False\n i = 5\n while i * i <= n:\n if n % i == 0 or n % (i + 2) == 0:\n return False\n i += 6\n return True\n\nprimes = []\nnum = 2\nwhile len(primes) < 50:\n if is_prime(num):\n primes.append(num)\n num += 1\n\nsum_of_primes = sum(primes)\nprint(f'{primes=}')\nprint(f'{sum_of_primes=}')\n\n```\n```output\nprimes=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229]\nsum_of_primes=5117\n\n```\nThe sum of the first 50 prime numbers is 5117.\n"
1100 | },
1101 | "finish_reason": "stop"
1102 | }
1103 | ],
1104 | "error": null,
1105 | "usage": {
1106 | "prompt_tokens": 31,
1107 | "completion_tokens": 560,
1108 | "total_tokens": 1164,
1109 | "prompt_tokens_details": {
1110 | "cached_tokens": 0,
1111 | "text_tokens": 0,
1112 | "audio_tokens": 0,
1113 | "image_tokens": 0
1114 | },
1115 | "completion_tokens_details": {
1116 | "text_tokens": 0,
1117 | "audio_tokens": 0
1118 | }
1119 | }
1120 | }
1121 | },
1122 | "googleSearch": {
1123 | "reverse": {
1124 | "id": "chatcmpl-nOOGow6EqWOsXskZmEMEqxvgfyU7L",
1125 | "object": "chat.completion",
1126 | "created": 1740742300,
1127 | "model": "gemini-2.0-flash-thinking-exp",
1128 | "choices": [
1129 | {
1130 | "index": 0,
1131 | "message": {
1132 | "role": "assistant",
1133 | "content": "今天是一月二十六号。",
1134 | "refusal": null
1135 | },
1136 | "logprobs": null,
1137 | "finish_reason": "stop"
1138 | }
1139 | ],
1140 | "usage": {
1141 | "prompt_tokens": 0,
1142 | "completion_tokens": 0,
1143 | "total_tokens": 0,
1144 | "prompt_tokens_details": {
1145 | "cached_tokens": 0,
1146 | "audio_tokens": 0
1147 | },
1148 | "completion_tokens_details": {
1149 | "reasoning_tokens": 0,
1150 | "audio_tokens": 0,
1151 | "accepted_prediction_tokens": 0,
1152 | "rejected_prediction_tokens": 0
1153 | }
1154 | },
1155 | "system_fingerprint": "fp_082af1d649"
1156 | },
1157 | "official": {
1158 | "id": "chatcmpl-ee821b0f754d432bac99dddaf0bcc88e",
1159 | "model": "gemini-2.0-flash",
1160 | "object": "chat.completion",
1161 | "created": 1740742342,
1162 | "choices": [
1163 | {
1164 | "index": 0,
1165 | "message": {
1166 | "role": "assistant",
1167 | "content": "今天是2025年2月28日。\n"
1168 | },
1169 | "finish_reason": "stop"
1170 | }
1171 | ],
1172 | "error": null,
1173 | "usage": {
1174 | "prompt_tokens": 7,
1175 | "completion_tokens": 14,
1176 | "total_tokens": 21,
1177 | "prompt_tokens_details": {
1178 | "cached_tokens": 0,
1179 | "text_tokens": 0,
1180 | "audio_tokens": 0,
1181 | "image_tokens": 0
1182 | },
1183 | "completion_tokens_details": {
1184 | "text_tokens": 0,
1185 | "audio_tokens": 0
1186 | }
1187 | }
1188 | }
1189 | },
1190 | "response_format": {
1191 | "reverse": {
1192 | "id": "chatcmpl-Jj0K7EANLPteO602hziq673IYnNLC",
1193 | "object": "chat.completion",
1194 | "created": 1740741510,
1195 | "model": "gemini-2.0-flash-thinking-exp",
1196 | "choices": [
1197 | {
1198 | "index": 0,
1199 | "message": {
1200 | "role": "assistant",
1201 | "content": "当然! 让我给你一个名字和年龄:\n\n名字: 李明 (Lǐ Míng)\n年龄: 25 岁",
1202 | "refusal": null
1203 | },
1204 | "logprobs": null,
1205 | "finish_reason": "stop"
1206 | }
1207 | ],
1208 | "usage": {
1209 | "prompt_tokens": 0,
1210 | "completion_tokens": 0,
1211 | "total_tokens": 0,
1212 | "prompt_tokens_details": {
1213 | "cached_tokens": 0,
1214 | "audio_tokens": 0
1215 | },
1216 | "completion_tokens_details": {
1217 | "reasoning_tokens": 0,
1218 | "audio_tokens": 0,
1219 | "accepted_prediction_tokens": 0,
1220 | "rejected_prediction_tokens": 0
1221 | }
1222 | },
1223 | "system_fingerprint": "fp_0cb7f95a34"
1224 | },
1225 | "official": {
1226 | "id": "chatcmpl-9585ed9d59aa42499b5adf73473b7382",
1227 | "model": "gemini-2.0-flash",
1228 | "object": "chat.completion",
1229 | "created": 1740741918,
1230 | "choices": [
1231 | {
1232 | "index": 0,
1233 | "message": {
1234 | "role": "assistant",
1235 | "content": "{\n \"age\": 30,\n \"name\": \"李明\"\n}"
1236 | },
1237 | "finish_reason": "stop"
1238 | }
1239 | ],
1240 | "error": null,
1241 | "usage": {
1242 | "prompt_tokens": 10,
1243 | "completion_tokens": 21,
1244 | "total_tokens": 31,
1245 | "prompt_tokens_details": {
1246 | "cached_tokens": 0,
1247 | "text_tokens": 0,
1248 | "audio_tokens": 0,
1249 | "image_tokens": 0
1250 | },
1251 | "completion_tokens_details": {
1252 | "text_tokens": 0,
1253 | "audio_tokens": 0
1254 | }
1255 | }
1256 | }
1257 | }
1258 | }
1259 | }
--------------------------------------------------------------------------------
/src/data/prompts.json:
--------------------------------------------------------------------------------
1 | {
2 | "openai": {
3 | "image_url": {
4 | "content": [
5 | {
6 | "type": "text",
7 | "text": "这是一张什么图片"
8 | },
9 | {
10 | "type": "image_url",
11 | "image_url": {
12 | "url": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png"
13 | }
14 | }
15 | ],
16 | "params": {
17 | "max_tokens": 100
18 | }
19 | },
20 | "max_tokens": {
21 | "content": "输出 'deepseek number 1' 5次",
22 | "params": {
23 | "max_tokens": 10
24 | }
25 | },
26 | "reasoning_max_tokens": {
27 | "content": "输出 'deepseek number 1' 5次",
28 | "params": {
29 | "max_tokens": 10
30 | }
31 | },
32 | "logprobs": {
33 | "content": "Hello!",
34 | "params": {
35 | "logprobs": true,
36 | "top_logprobs": 2
37 | }
38 | },
39 | "n": {
40 | "content": "Hello!",
41 | "params": {
42 | "n": 2
43 | }
44 | },
45 | "stop": {
46 | "content": "Count from 1 to 10",
47 | "params": {
48 | "stop": [
49 | "4"
50 | ]
51 | }
52 | },
53 | "function_call": {
54 | "content": "Whats the weather like in Boston today?",
55 | "params": {
56 | "tools": [
57 | {
58 | "type": "function",
59 | "function": {
60 | "name": "get_current_weather",
61 | "description": "Get the current weather in a given location",
62 | "parameters": {
63 | "type": "object",
64 | "properties": {
65 | "location": {
66 | "type": "string",
67 | "description": "The city and state, e.g. San Francisco, CA"
68 | },
69 | "unit": {
70 | "type": "string",
71 | "enum": [
72 | "celsius",
73 | "fahrenheit"
74 | ]
75 | }
76 | },
77 | "required": [
78 | "location"
79 | ]
80 | }
81 | }
82 | }
83 | ],
84 | "tool_choice": "auto"
85 | }
86 | },
87 | "response_format": {
88 | "content": "给我一个名字和年龄吧",
89 | "params": {
90 | "response_format": {
91 | "type": "json_schema",
92 | "json_schema": {
93 | "name": "user_info",
94 | "schema": {
95 | "type": "object",
96 | "properties": {
97 | "name": {
98 | "type": "string"
99 | },
100 | "age": {
101 | "type": "number"
102 | }
103 | },
104 | "required": [
105 | "name",
106 | "age"
107 | ],
108 | "additionalProperties": false
109 | },
110 | "strict": true
111 | }
112 | }
113 | }
114 | }
115 | },
116 | "claude": {
117 | "max_tokens": {
118 | "content": "输出 'deepseek number 1' 5次",
119 | "params": {
120 | "max_tokens": 10
121 | }
122 | },
123 | "reasoning_stop": {
124 | "content": "Count from 1 to 10 with Arabic numerals",
125 | "params": {
126 | "stop": ["3"]
127 | }
128 | },
129 | "stop": {
130 | "content": "Count from 1 to 10 with Arabic numerals",
131 | "params": {
132 | "stop": [
133 | "4"
134 | ]
135 | }
136 | },
137 | "function_call": {
138 | "content": "Whats the weather like in Boston today?",
139 | "params": {
140 | "tools": [
141 | {
142 | "type": "function",
143 | "function": {
144 | "name": "get_current_weather",
145 | "description": "Get the current weather in a given location",
146 | "parameters": {
147 | "type": "object",
148 | "properties": {
149 | "location": {
150 | "type": "string",
151 | "description": "The city and state, e.g. San Francisco, CA"
152 | },
153 | "unit": {
154 | "type": "string",
155 | "enum": [
156 | "celsius",
157 | "fahrenheit"
158 | ]
159 | }
160 | },
161 | "required": [
162 | "location"
163 | ]
164 | }
165 | }
166 | }
167 | ],
168 | "tool_choice": "auto"
169 | }
170 | }
171 | },
172 | "gemini": {
173 | "max_tokens": {
174 | "content": "输出 'deepseek number 1' 5次",
175 | "params": {
176 | "max_tokens": 10
177 | }
178 | },
179 | "codeExecution": {
180 | "content": "What is the sum of the first 50 prime numbers? Generate and run code for the calculation, and make sure you get all 50.",
181 | "params": {
182 | "tools": [
183 | {
184 | "type": "function",
185 | "function": {
186 | "name": "codeExecution"
187 | }
188 | }
189 | ]
190 | }
191 | },
192 | "googleSearch": {
193 | "content": "今天是几月几号.",
194 | "params": {
195 | "tools": [
196 | {
197 | "type": "function",
198 | "function": {
199 | "name": "googleSearch"
200 | }
201 | }
202 | ]
203 | }
204 | },
205 | "response_format": {
206 | "content": "给我一个名字和年龄吧",
207 | "params": {
208 | "response_format": {
209 | "type": "json_schema",
210 | "json_schema": {
211 | "name": "user_info",
212 | "schema": {
213 | "type": "object",
214 | "properties": {
215 | "name": {
216 | "type": "string"
217 | },
218 | "age": {
219 | "type": "number"
220 | }
221 | },
222 | "required": [
223 | "name",
224 | "age"
225 | ],
226 | "additionalProperties": false
227 | },
228 | "strict": true
229 | }
230 | }
231 | }
232 | }
233 | }
234 | }
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --primary-color: #4f46e5;
7 | --primary-hover: #4338ca;
8 | --secondary-color: #0ea5e9;
9 | --secondary-hover: #0284c7;
10 | --bg-color: #f8fafc;
11 | --card-bg: #ffffff;
12 | --text-color: #1e293b;
13 | --text-light: #64748b;
14 | --border-color: #e2e8f0;
15 | --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
16 | --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
17 | --shadow-md: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
18 | }
19 |
20 | body {
21 | background-color: var(--bg-color);
22 | color: var(--text-color);
23 | }
24 |
25 | @layer components {
26 | .btn-primary {
27 | @apply bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-all duration-200;
28 | }
29 |
30 | .btn-secondary {
31 | @apply bg-sky-500 text-white px-4 py-2 rounded-md hover:bg-sky-600 focus:outline-none focus:ring-2 focus:ring-sky-400 focus:ring-offset-2 transition-all duration-200;
32 | }
33 |
34 | .card {
35 | @apply bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden transition-shadow duration-300 hover:shadow-lg;
36 | }
37 |
38 | .input-field {
39 | @apply w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-200;
40 | }
41 |
42 | .select-field {
43 | @apply w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-200;
44 | }
45 | }
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import { createRouter, createWebHistory } from 'vue-router'
4 | import { createI18n } from 'vue-i18n'
5 | import './index.css'
6 |
7 | // 路由配置
8 | const router = createRouter({
9 | history: createWebHistory(),
10 | routes: [
11 | {
12 | path: '/',
13 | component: () => import('./views/Home.vue')
14 | }
15 | ]
16 | })
17 |
18 | // i18n配置
19 | const i18n = createI18n({
20 | legacy: false,
21 | locale: 'zh-CN',
22 | messages: {
23 | 'zh-CN': {
24 | message: {
25 | title: '模型逆向与否检测',
26 | startCheck: '开始检测',
27 | modelProvider: '模型提供商',
28 | testParams: '检测参数',
29 | apiBaseUrl: 'API Base URL',
30 | apiKey: 'API Key',
31 | apiKeyPlaceholder: '请输入您的API密钥',
32 | apiBaseUrlPlaceholder: '例如:api.openai.com(无需添加https://或/v1)',
33 | model: '待检测模型',
34 | modelPlaceholder: '例如:gpt-4o-2024-11-20, gpt-3.5-turbo',
35 | reverseExample: '逆向接口返回示例',
36 | officialExample: '官方接口返回示例',
37 | requestResult: '请求结果',
38 | showBriefResponse: '显示简要响应',
39 | showFullResponse: '显示完整响应',
40 | apiDocs: 'API文档链接',
41 | }
42 | }
43 | }
44 | })
45 |
46 | const app = createApp(App)
47 |
48 | app.use(router)
49 | app.use(i18n)
50 |
51 | app.mount('#app')
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ t('message.title') }}
9 |
10 |
v0.02
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
122 |
123 |
124 |
125 |
{{ t('message.requestResult') }}
126 |
127 |
128 |
API请求信息
129 |
130 |
131 | 请求地址:
132 | {{ requestInfo.url }}
133 |
134 |
135 |
请求体:
136 |
{{ JSON.stringify(requestInfo.body, null, 2) }}
137 |
138 |
139 |
140 |
141 |
API响应信息
142 |
{{ displayResult }}
143 |
144 |
149 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
{{ t('message.reverseExample') }}
163 |
{{ displayReverseExample }}
164 |
165 |
170 |
175 |
176 |
177 |
178 |
{{ t('message.officialExample') }}
179 |
{{ displayOfficialExample }}
180 |
181 |
186 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
{{ t('message.apiDocs') }}
198 |
248 |
249 |
250 |
251 |
252 |
253 |
460 |
461 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{vue,js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import vue from '@vitejs/plugin-vue'
3 |
4 | export default defineConfig({
5 | plugins: [vue()],
6 | server: {
7 | port: 3000,
8 | proxy: {
9 | '/api': {
10 | target: 'http://localhost:3000',
11 | changeOrigin: true,
12 | rewrite: (path) => path.replace(/^\/api/, '')
13 | }
14 | }
15 | }
16 | })
--------------------------------------------------------------------------------