Unity 工具 之 Azure 微软 【GPT4o】HttpClient 异步流式请求的简单封装
创始人
2024-11-10 18:34:56

Unity 工具 之 Azure 微软 【GPT4o】HttpClient 异步流式请求的简单封装

目录

Unity 工具 之 Azure 微软 【GPT4o】HttpClient 异步流式请求的简单封装

一、简单介绍

二、实现原理

三、注意实现

四、简单效果预览

五、案例简单实现步骤

六、关键代码


一、简单介绍

Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。

本节介绍,这里在使用微软的Azure 进行语音合成的两个方法的做简单整理,这里简单说明,如果你有更好的方法,欢迎留言交流。

官网注册:

面向学生的 Azure - 免费帐户额度 | Microsoft Azure

官网技术文档网址:

技术文档 | Microsoft Learn

Azure OpenAI 一些模型介绍:

Azure OpenAI 服务模型 - Azure OpenAI | Microsoft Learn

GPT-4o 和 GPT-4 Turbo

GPT-4o 是 OpenAI 的最新模型。 GPT-4o 在单个模型中集成文本和图像,从而能够同时处理多个数据类型。 这种多模式方法提高了人机交互的准确性和响应能力。 GPT-4o 在英语文本和编码任务方面与 GPT-4 Turbo 相当,但在非英语语言和视觉任务方面具有更优越的性能,为 AI 功能设定了新的基准。

如何访问 GPT-4o 模型?

GPT-4o 可用于标准和全球标准模型部署。

需要在该模型可用的受支持标准或全球标准区域中创建或使用现有资源。

创建资源后,可以部署 GPT-4o 模型。 

发起请求的json 格式:

{             "messages": [                  {                     "role": "system",                      "content": "You are a helpful assistant."                  },                 {                     "role": "user",                      "content": [ 	                    { 	                        "type": "text", 	                        "text": "Describe this picture:" 	                    }, 	                    { 	                        "type": "image_url", 	                        "image_url": {                                 "url": ""                             }                         }                     ]                  }             ],             "max_tokens": 100,              "stream": false          }

返回的格式根据是否是流式返回,略有所不同:

非流式的:

 { 	"id": "chatcmpl-8X0uY6Xbv4XpU4zo0KXhVk4iTldJf", 	"object": "chat.completion", 	"created": 1702879018, 	"model": "gpt-4v", 	"prompt_filter_results": [{ 		"prompt_index": 0, 		"content_filter_results": { 			"hate": { 				"filtered": false, 				"severity": "safe" 			}, 			"self_harm": { 				"filtered": false, 				"severity": "safe" 			}, 			"sexual": { 				"filtered": false, 				"severity": "safe" 			}, 			"violence": { 				"filtered": false, 				"severity": "safe" 			} 		} 	}], 	"choices": [{ 		"finish_details": { 			"type": "stop", 			"stop": "<|fim_suffix|>" 		}, 		"index": 0, 		"message": { 			"role": "assistant", 			"content": "这张图片展示了一辆银灰色的跑车,停靠在一个内饰精致的展厅里。车身呈流线型,前脸上有显著的品牌标志和数字“10”。车身上的漆面光洁明亮,反射着展厅内柔和的灯光。背景中可以看到其他几辆停放整齐的高端车辆,以及墙上挂着的一些装饰性画作。整个场景显得高端大气,彰显了跑车的豪华品质。" 		}, 		"content_filter_results": { 			"hate": { 				"filtered": false, 				"severity": "safe" 			}, 			"self_harm": { 				"filtered": false, 				"severity": "safe" 			}, 			"sexual": { 				"filtered": false, 				"severity": "safe" 			}, 			"violence": { 				"filtered": false, 				"severity": "safe" 			} 		} 	}], 	"usage": { 		"prompt_tokens": 826, 		"completion_tokens": 175, 		"total_tokens": 1001 	} }

流式的根据数据内容不同,data 数据不同:

data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_result":{"jailbreak":{"filtered":false,"detected":false},"custom_blocklists":{"filtered":false,"details":[]}}},{"prompt_index":1,"content_filter_result":{"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"},"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"custom_blocklists":{"filtered":false,"details":[]}}}]}  data: {"choices":[{"content_filter_results":{},"delta":{"content":"","role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"镜"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"腿"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"眼"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"镜"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"框"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"控制"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"电"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"路"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"连接"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"电"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"路"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"前"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"顶"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"盖"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"摄"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"像"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"头"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"投"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"影"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"模块"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"鼻"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"梁"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"显示"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"光"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"学"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"元"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"件"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"麦"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"克"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"风"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}  data: [DONE]

二、实现原理

1、官网申请得到对应使用 GPT4o 模型的相关key 等信息(和之前申请GPT3.5、GPT4 类似)

2、使用 HttpClinet 进行网络 Post 请求,且使用异步请求 ,使用 cancellationToken 用于取消请求

// 发送请求并获取响应 HttpResponseMessage response = await client.SendAsync(request, cancellationToken);

3、根据请求流式和非流式的标志 “stream”,false 为非流式,true 为流式返回数据

4、其中 HttpClient 的异步请求也是可以打断的

 cancellationTokenSource.Cancel();

三、注意实现

1、GPT4o 支持文本和图片数据发起 Post 请求访问,其中 图片数据,可以是 url ,也可以是 Base64 ,其中 Base64 数据注意添加上前缀,例如 png 图片,前缀:data:image/png;base64,

 string IMAGE_png_EXTRA_PREFIXES_BASE64 = "data:image/png;base64,";  string base64 = await ImageLoader.Instance.LoadImageAndConvertToBase64();  base64 = IMAGE_png_EXTRA_PREFIXES_BASE64 + base64;

2、这里没有添加历史数据,需要的话可以自动添加历史数据,添加到请求的 public List messages; 列表中即可,不过,提问要放到最后

 public class JsonRequestStruct     {         public int max_tokens;         public bool stream;         public float temperature;         public List messages;      }      public class Message     {         public string role;         public object content; //这个是不规则的json 列表     }

四、简单效果预览

五、案例简单实现步骤

1、新建 Unity 工程

2、创建接口脚本,定义一些基本功能和回调

3、创建基类,HttpClient 实现数据的请求,取消请求的基本功能

4、创建实现了,填写自己的 GPT4o key 相关信息

5、测试接口,先测试非流式的文字请求

6、测试流式,图片请求的接口

六、关键代码

1、IAzureGpt4o

 using System; using System.Threading.Tasks;  public interface IAzureGpt4o {     ///      /// 请求失败的回调     ///      Action OnSendRequestFailed { get; set; }      ///      /// 响应的流式数据     ///      Action OnResponsingData { get; set; }     ///      /// 响应接收完的数据     ///      Action OnResponseFinished { get; set; }      ///      /// 发送请求     ///      ///      /// 图片数据,支持 url/base64     ///      Task SendRequestAsync(string askContent, string imgData);      ///      /// 发送请求(流式返回数据)     ///      ///      /// 图片数据,支持 url/base64     ///      Task SendRequestStreamResponseAsync(string askContent, string imgData);      ///      /// Helper function to cancel the ongoing request     ///      public void CancelRequest(); } 

2、BaseAzureGpt4o

using Newtonsoft.Json; using System.Collections.Generic; using System.IO; using System.Net; using System.Text.RegularExpressions; using System.Text; using UnityEngine; using System; using System.Threading.Tasks; using System.Threading; using System.Net.Http;  ///  /// GPT 4o 基类 ///  ///  public class BaseAzureGpt4o : IAzureGpt4o {     #region Data     ///      /// TAG     ///      protected virtual string TAG { get; } = "[BaseAzureGpt4o]";     ///      /// API_BASE     ///      protected virtual string API_BASE { get; } = "https://gpt4o-version.openai.azure.com/";     ///      /// DEPLOYMENT_NAME     ///      protected virtual string DEPLOYMENT_NAME { get; } = "Your_Deplyment_Name";     ///      /// API_KEY     ///      protected virtual string API_KEY { get; } = "YOur_API_Key";      ///      /// 对应模型接口的发行版本     ///      protected virtual string MODEL_VERSION { get; } = "2024-05-01-preview";      ///      /// 组织基础的 Url     ///      protected virtual string m_BaseUrl { get{ return $"{API_BASE}/openai/deployments/{DEPLOYMENT_NAME}"; } }       ///      /// 组成最后访问的 Url      ///      protected virtual string m_EndPointend { get {return $"{m_BaseUrl}/chat/completions?api-version={MODEL_VERSION}"; } }       ///      /// 最大的 Tokens     ///      protected virtual int MAX_TOKENS { get; } = 100;      ///      /// 请求失败的回调     ///      public Action OnSendRequestFailed { get; set; }     ///      /// 响应的流式数据     ///      public Action OnResponsingData { get; set; }     ///      /// 响应接收完的数据     ///      public Action OnResponseFinished { get; set; }      ///      /// CancellationTokenSource     ///      private CancellationTokenSource cancellationTokenSource;      ///      /// HttpClient     ///      private static readonly HttpClient client = new HttpClient();      #endregion      #region Inteface function      ///      /// 发送请求(正常返回数据)     ///      ///      /// 图片数据,支持 url/base64     ///      public virtual async Task SendRequestAsync(string askContent, string imgData)     {         Debug.Log(TAG + "Start HttpWebRequest m_EndPointend : " + m_EndPointend);          cancellationTokenSource = new CancellationTokenSource();         CancellationToken cancellationToken = cancellationTokenSource.Token;          // json 数据         string jsonData = GetJsonStr(askContent, imgData);          /// 设置请求头         client.DefaultRequestHeaders.Clear();         client.DefaultRequestHeaders.Add("api-key", API_KEY);          // 创建 HTTP 内容         var content = new StringContent(jsonData, Encoding.UTF8, "application/json");          try         {             // 创建请求             var request = new HttpRequestMessage(HttpMethod.Post, m_EndPointend)             {                 Content = content             };              // 发送请求并获取响应             HttpResponseMessage response = await client.SendAsync(request, cancellationToken);              // 检查响应状态码             if (response.IsSuccessStatusCode)             {                 // 读取整个响应内容                 string responseText = await response.Content.ReadAsStringAsync();                  if (cancellationToken.IsCancellationRequested)                 {                     Debug.Log(TAG + "Operation was canceled.");                     OnSendRequestFailed?.Invoke("Operation was canceled.");                     return null; // 或抛出异常,根据需要处理                 }                  Debug.Log(TAG + " PostRequestStreamToStringAsync whole stream data : " + responseText);                 string jsonString = DecodeUnicode(responseText);                  string parseWholeRlt;                  // 使用 Newtonsoft.Json 将 JSON 字符串映射到对应的对象                 JsonResponseStruct data = JsonConvert.DeserializeObject(jsonString);                 if (data != null)                 {                     parseWholeRlt = data.choices[0].message.content.ToString();                     Debug.Log(TAG + " PostRequestStreamToStringAsync whole stream data : " + parseWholeRlt);                 }                 else                 {                     Debug.Log(TAG + " PostRequestStreamToStringAsync whole stream data : " + jsonString);                     parseWholeRlt = jsonString;                 }                  if (OnResponseFinished != null)                 {                     Debug.Log(TAG + " PostRequestStreamToStringAsync OnResponseFinished is  not null ");                     OnResponseFinished?.Invoke(parseWholeRlt);                 }                 else                 {                     Debug.Log(TAG + " PostRequestStreamToStringAsync OnResponseFinished is null ");                 }                  return parseWholeRlt;             }             else             {                 // 打印错误状态码                 Debug.LogError(TAG + "Error: " + response.StatusCode);                 OnSendRequestFailed?.Invoke(response.Content.ToString());                 return null;             }         }         catch (OperationCanceledException e)         {             Debug.Log(TAG + "Operation was canceled. " + e.Message);             OnSendRequestFailed?.Invoke(e.Message);             return null; // 或抛出异常,根据需要处理         }         catch (WebException e)         {             Debug.Log(TAG + " e.Message: " + e.Message);             OnSendRequestFailed?.Invoke(e.Message);             return null;         }     }      ///      /// 发送请求(流式返回数据)     ///      ///      /// 图片数据,支持 url/base64     ///      public virtual async Task SendRequestStreamResponseAsync(string askContent, string imgData) {          Debug.Log(TAG + "Start HttpWebRequest m_EndPointend : " + m_EndPointend);          cancellationTokenSource = new CancellationTokenSource();         CancellationToken cancellationToken = cancellationTokenSource.Token;          // json 数据         string jsonData = GetJsonStr(askContent, imgData, true);          /// 设置请求头         client.DefaultRequestHeaders.Clear();         client.DefaultRequestHeaders.Add("api-key", API_KEY);          // 创建 HTTP 内容         var content = new StringContent(jsonData, Encoding.UTF8, "application/json");          try         {             // 创建请求             var request = new HttpRequestMessage(HttpMethod.Post, m_EndPointend)             {                 Content = content             };              // 发送请求并获取响应头             HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);              // 检查响应状态码             if (response.IsSuccessStatusCode)             {                 // 以流的方式读取响应内容                 using (var stream = await response.Content.ReadAsStreamAsync())                 {                     using (var reader = new StreamReader(stream))                     {                         StringBuilder sb = new StringBuilder();                         string line;                         while ((line = await reader.ReadLineAsync()) != null)                         {                              string parseRlt = HandleStreamData(line);                             if (string.IsNullOrEmpty(parseRlt) == false)                             {                                 OnResponsingData?.Invoke(parseRlt);                             }                              sb.AppendLine(line); // 逐行读取并累积响应数据                             Debug.Log(TAG + " PostRequestStreamToStringAsync getting steam data : " + sb.ToString());                              // Check for cancellation                             if (cancellationToken.IsCancellationRequested)                             {                                 Debug.Log(TAG + "Operation was canceled.");                                 return null; // or throw an exception, handle as needed                             }                         }                          Debug.Log(TAG + " PostRequestStreamToStringAsync whole stream data : " + sb.ToString());                         string jsonString = DecodeUnicode(sb.ToString());                          string parseWholeRlt = HandleStreamData(jsonString);                         Debug.Log(TAG + " PostRequestStreamToStringAsync whole stream data : " + parseWholeRlt);                          if (OnResponseFinished != null)                         {                             Debug.Log(TAG + " PostRequestStreamToStringAsync OnResponseFinished is  not null ");                             OnResponseFinished?.Invoke(parseWholeRlt);                         }                         else                         {                             Debug.Log(TAG + " PostRequestStreamToStringAsync OnResponseFinished is null ");                         }                          return parseWholeRlt;                     }                 }             }             else             {                 // 打印错误状态码                 Debug.LogError(TAG + "Error: " + response.StatusCode);                 OnSendRequestFailed?.Invoke(response.Content.ToString());                 return null;             }         }         catch (OperationCanceledException e)         {             Debug.Log(TAG + "Operation was canceled. " + e.Message);             OnSendRequestFailed?.Invoke(e.Message);             return null; // or throw an exception, handle as needed         }         catch (WebException e)         {             Debug.Log(TAG + " e.Message: " + e.Message);             OnSendRequestFailed?.Invoke(e.Message);             return null;         }     }      ///      /// Helper function to cancel the ongoing request     ///      public virtual void CancelRequest()     {         if (cancellationTokenSource != null && !cancellationTokenSource.IsCancellationRequested)         {             cancellationTokenSource.Cancel();         }     }      #endregion      #region Protected function      ///      /// 将 Unicode 转义字符解码为 UTF-8 字符串的方法     ///      ///      ///      protected string DecodeUnicode(string input)     {         return Regex.Replace(input, @"\\u([0-9a-fA-F]{4})", match =>         {             string hex = match.Groups[1].Value;             int codePoint = Convert.ToInt32(hex, 16);             return char.ConvertFromUtf32(codePoint);         });     }      ///      /// 组织提问和图片数据     ///      ///      ///      /// 是否流式响应返回数据     ///      protected string GetJsonStr(string askContent, string imgBase64OrUrlg, bool isStreamResponse = false)     {         List contentList = new List();         contentList.Add(new         {             type = "text",             text = askContent,          });          if (imgBase64OrUrlg != null)         {             // 创建一个包含指定数据结构的对象列表             contentList.Add(new             {                 type = "image_url",                 image_url = new                 {                     url = imgBase64OrUrlg                 },             });         }          // 将对象列表转换为 JSON 字符串         string jsonString = JsonConvert.SerializeObject(contentList, Formatting.Indented);          Message messageS = new Message() { role = "system", content = "You are a helpful assistant." };         Message message = new Message() { role = "user", content = contentList };         List messages = new List();         messages.Add(messageS);         messages.Add(message);          JsonRequestStruct jsonRequest = new JsonRequestStruct() { messages = messages, max_tokens = MAX_TOKENS, stream = isStreamResponse };         jsonString = JsonConvert.SerializeObject(jsonRequest, Formatting.Indented);         Debug.Log(jsonString);          return jsonString;     }      #region Stream Response 数据解析      /*      data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"克"},"finish_reason":null,"index":0,"logprobs":null}],"created":1718690676,"id":"chatcmpl-9bMFIE4gPNKU6Z1QyKvFsjwqNTOtw","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_abc28019ad"}      */      ///      ///  流式处理数据     ///      ///      ///      string HandleStreamData(string data)     {         try         {             string[] dataLines = data.Split(new string[] { "data: " }, StringSplitOptions.RemoveEmptyEntries);             StringBuilder sb = new StringBuilder();             foreach (var line in dataLines)             {                 sb.Append(ProcessDataLine(line));             }              return sb.ToString();         }         catch (Exception e)         {             return null;         }              }      ///      /// 处理单行数据,解析获取 content,finish_reason 数据     /// content : 回复内容     /// finish_reason : 判断流式回答是否结束     ///      ///      /// ///      string ProcessDataLine(string dataLine)     {         string content = ExtractField(dataLine, "\"content\":\"", "\"},");         string finishReason = ExtractField(dataLine, "\"finish_reason\":", ",");          Debug.Log(TAG + "ProcessDataLine():Content: " + content);         content = content == null ? "" : content;         // 排除这个情况 "delta":{"content":"","role":"assistant"},"finish_reason":null,"         if(content.Contains("\"role\":\"assistant")) content="";          if (finishReason!=null && finishReason == "\"stop\"")         {             Debug.Log(TAG+ "ProcessDataLine(): Finish reason is stop. Stopping further processing.");             return "";  // 如果 finish_reason 是 stop,停止进一步处理         }         else         {             return content;         }     }      ///      /// 抽取块数据     ///      /// 行数据     /// 块名称     /// 分割符     ///      string ExtractField(string dataLine, string fieldName, string delimiter)     {         int fieldIndex = dataLine.IndexOf(fieldName);         if (fieldIndex == -1)         {             return null;         }          int startIndex = fieldIndex + fieldName.Length;         int endIndex = dataLine.IndexOf(delimiter, startIndex);         if (endIndex == -1)         {             return dataLine.Substring(startIndex).Trim(' ', '}', ']');         }          return dataLine.Substring(startIndex, endIndex - startIndex);     }      #endregion      #endregion      #region JsonRequestStruct     /* json 字符串      {         "messages": [             { "role": "system", "content": "You are a helpful assistant." }, # Content can be a string, OR             { "role": "user", "content": [       # It can be an array containing strings and images.                 "描述一下这张图,请用中文回答",                 { "image": "img_base64" }      # Images are represented like this.             ] }         ],         "max_tokens": 100     }          */      /* 更新 json 字符串               {             "messages": [                  {                     "role": "system",                      "content": "You are a helpful assistant."                  },                 {                     "role": "user",                      "content": [ 	                    { 	                        "type": "text", 	                        "text": "Describe this picture:" 	                    }, 	                    { 	                        "type": "image_url", 	                        "image_url": {                                 "url": ""                             }                         }                     ]                  }             ],             "max_tokens": 100,              "stream": false          }            */      public class JsonRequestStruct     {         public int max_tokens;         public bool stream;         public float temperature;         public List messages;      }      public class Message     {         public string role;         public object content; //这个是不规则的json 列表     }      #endregion      #region JsonResponseStruct     /* json 字符串      { 	"id": "chatcmpl-8X0uY6Xbv4XpU4zo0KXhVk4iTldJf", 	"object": "chat.completion", 	"created": 1702879018, 	"model": "gpt-4v", 	"prompt_filter_results": [{ 		"prompt_index": 0, 		"content_filter_results": { 			"hate": { 				"filtered": false, 				"severity": "safe" 			}, 			"self_harm": { 				"filtered": false, 				"severity": "safe" 			}, 			"sexual": { 				"filtered": false, 				"severity": "safe" 			}, 			"violence": { 				"filtered": false, 				"severity": "safe" 			} 		} 	}], 	"choices": [{ 		"finish_details": { 			"type": "stop", 			"stop": "<|fim_suffix|>" 		}, 		"index": 0, 		"message": { 			"role": "assistant", 			"content": "这张图片展示了一辆银灰色的跑车,停靠在一个内饰精致的展厅里。车身呈流线型,前脸上有显著的品牌标志和数字“10”。车身上的漆面光洁明亮,反射着展厅内柔和的灯光。背景中可以看到其他几辆停放整齐的高端车辆,以及墙上挂着的一些装饰性画作。整个场景显得高端大气,彰显了跑车的豪华品质。" 		}, 		"content_filter_results": { 			"hate": { 				"filtered": false, 				"severity": "safe" 			}, 			"self_harm": { 				"filtered": false, 				"severity": "safe" 			}, 			"sexual": { 				"filtered": false, 				"severity": "safe" 			}, 			"violence": { 				"filtered": false, 				"severity": "safe" 			} 		} 	}], 	"usage": { 		"prompt_tokens": 826, 		"completion_tokens": 175, 		"total_tokens": 1001 	} }      */     public class JsonResponseStruct     {         public string id { get; set; }         public string @object { get; set; }         public long created { get; set; }         public string model { get; set; }         public Usage usage { get; set; }         public List choices { get; set; }         public List prompt_filter_results { get; set; }     }      public class Usage     {         public int prompt_tokens { get; set; }         public int completion_tokens { get; set; }         public int total_tokens { get; set; }     }      public class Choice     {         public RMessage message { get; set; }         public FinishDetails finish_details { get; set; }         public int index { get; set; }         public ContentFilterResult content_filter_results { get; set; }     }      public class RMessage     {         public string role;         public string content; //这个是不规则的json 列表     }      public class FinishDetails     {         public string type { get; set; }         public string stop { get; set; }     }      public class PromptFilterResult     {         public int index { get; set; }         public ContentFilterResult content_filter_results { get; set; }      }      public class ContentFilterResult     {         public FilterReuslt hate { get; set; }         public FilterReuslt self_harm { get; set; }         public FilterReuslt sexual { get; set; }         public FilterReuslt violence { get; set; }     }      public class FilterReuslt     {         public bool filtered { get; set; }         public string severity { get; set; }     }      #endregion }  

3、AzureGPT4o

  public class AzureGPT4o : BaseAzureGpt4o {     ///      /// TAG     ///      protected override string TAG { get; } = "[AzureGPT4o]";     ///      /// API_BASE     ///      protected override string API_BASE { get; } = "https://gpt4o-version.openai.azure.com/";     ///      /// DEPLOYMENT_NAME     ///      protected override string DEPLOYMENT_NAME { get; } = "Your_Deployment_Name";     ///      /// API_KEY     ///      protected override string API_KEY { get; } = "Your_API_Key";      ///      /// 对应模型接口的发行版本     ///      protected override string MODEL_VERSION { get; } = "2024-05-01-preview";      ///      /// 最大的 Tokens     ///      protected override int MAX_TOKENS { get; } = 300; } 

4、TestAzureGPT4o

using System.Collections; using System.Collections.Generic; using UnityEngine;  public class TestAzureGPT4o : MonoBehaviour {     string TAG = "[TestAzureGPT4o] ";      IAzureGpt4o m_AzureGpt4o;      // Start is called before the first frame update     void Start()     {         //TestGPT4o_Text();         TestGPT4o_Image();     }      // Update is called once per frame     void Update()     {         if (Input.GetKeyDown(KeyCode.Space)) {             m_AzureGpt4o?.CancelRequest();         }     }      async void TestGPT4o_Text()     {         m_AzureGpt4o = new AzureGPT4o();         m_AzureGpt4o.OnSendRequestFailed = (err) => { Debug.Log(TAG + "TestGPT4o_Text(): OnSendRequestFailed err " + err); };         m_AzureGpt4o.OnResponseFinished = (str) => { Debug.Log(TAG + "TestGPT4o_Text(): OnResponseFinished str " + str); };         m_AzureGpt4o.OnResponsingData = (str) => { Debug.Log(TAG + "TestGPT4o_Text(): OnResponsingData str " + str); };         string rlt = await m_AzureGpt4o.SendRequestAsync(             "你好呀,你是谁?",              null);         Debug.Log(TAG + "TestGPT4o_Text(): rlt " + rlt);     }      async void TestGPT4o_Image()     {         m_AzureGpt4o = new AzureGPT4o();         m_AzureGpt4o.OnSendRequestFailed = (err) => { Debug.Log(TAG + "TestGPT4o_Image(): OnSendRequestFailed err " + err); };         m_AzureGpt4o.OnResponseFinished = (str) => { Debug.Log(TAG + "TestGPT4o_Image(): OnResponseFinished str " + str); };         m_AzureGpt4o.OnResponsingData = (str) => { Debug.Log(TAG + "TestGPT4o_Image(): OnResponsingData str " + str); };         string rlt = await m_AzureGpt4o.SendRequestStreamResponseAsync(             "描述一下",             "https://d1.faiusr.com/4/AAEIABAEGAAggOra9AUooNDeiAEwoAY45gM.png");         Debug.Log(TAG + "TestGPT4o_Image(): rlt " + rlt);     } } 

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...