Objective-C 对接 chatGPT 接口,怎么做到逐字输出

2023-04-11 15:23:28 +08:00
 brader
chatgpt 的
https://api.openai.com/v1/chat/completions 接口,是支持流式响应的,stream=true ,我是服务端,接入的时候也是流式接收,并实时流式输出给了前端,我自己用浏览器测试了,确实是有一边接收一边输出的逐字输出效果的。

然后我们 ios 前端,好像实现不了,他是一直等待接收完,一次输出所有文字的。

我也不熟 Objective-C ,想请问下,Objective-C 能做到这个效果吗?可以给个大概的小 demo 吗
2824 次点击
所在节点    程序员
18 条回复
dayudayupao
2023-04-11 15:33:20 +08:00
学习一下 sse ,gpt 官网就是用这个做的打字机效果的
jethroX
2023-04-11 15:41:11 +08:00
可以问:Objective-C 如何实现 SSE 流式接收数据?
我试了下,能给出代码,但是我不知道实际运行起来是否可行。
我在接入的时候,实际上都会让 GPT 帮我写一部分代码。
ByteCat
2023-04-11 15:41:17 +08:00
了解一下 SSE ,如果你做服务端也可以转成 WebSocket 之类的来传,这样调用更方便一点,因为 SSE 规范只能用 GET 不能用 POST ,很多库没实现,要自己动手
chuhades
2023-04-11 15:41:30 +08:00
Objective-C 能够实现流式接收和逐字输出的效果。你可以使用 NSURLSession 来实现这一功能。以下是一个简单的示例,展示了如何使用 Objective-C 流式接收数据并逐字输出:

```
#import <Foundation/Foundation.h>

@interface StreamDemo : NSObject <NSURLSessionDataDelegate>
@property (nonatomic, strong) NSMutableData *receivedData;
@end

@implementation StreamDemo

- (instancetype)init {
self = [super init];
if (self) {
_receivedData = [[NSMutableData alloc] init];
}
return self;
}

- (void)startStreamingRequest {
NSString *urlString = @"https://api.openai.com/v1/chat/completions?stream=true";
NSURL *url = [NSURL URLWithString:urlString];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];

// 设置请求头信息
[request setValue:@"your-api-key" forHTTPHeaderField:@"Authorization"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

// 设置请求体信息
NSDictionary *body = @{@"model": @"text-davinci-002",
@"prompt": @"Your prompt here",
@"max_tokens": @30};
NSError *error;
NSData *bodyData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
if (error) {
NSLog(@"Error creating request body: %@", error);
return;
}
[request setHTTPBody:bodyData];

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
}

#pragma mark - NSURLSessionDataDelegate

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.receivedData appendData:data];

// 在这里实现逐字输出的逻辑
NSString *receivedString = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSLog(@"Received Data: %@", receivedString);
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"Request completed successfully");
}
}

@end

int main(int argc, const char * argv[]) {
@autoreleasepool {
StreamDemo *streamDemo = [[StreamDemo alloc] init];
[streamDemo startStreamingRequest];

// 等待请求完成
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
```

请注意,这个示例仅用于演示目的,你需要根据你的需求对其进行调整。在实际应用中,你可能需要将这个代码与你的 iOS 项目结合起来,实现逐字输出到前端界面。
churchill
2023-04-11 15:46:51 +08:00
说到底不就是一个长连接吗
这些人被 AI 替代属实不冤
mmnnyycc
2023-04-11 15:47:21 +08:00
@chuhades #4 这回答很标准的 chatgpt 的回答方式
miromelo
2023-04-11 16:02:24 +08:00
@mmnnyycc 这个就是 ChatGPT 回答的啊,他只是复制了一下而已
brader
2023-04-11 16:06:38 +08:00
@ByteCat 我当然了解 SSE 啊。。。不然我服务端怎么实现了接入 chatgpt 的 sse 格式的流响应,还把结果解析出来了,问题是前端不了解啊。。。他实现不出来,就说做不了
Alias4ck
2023-04-11 16:09:00 +08:00
brader
2023-04-11 16:20:50 +08:00
@Alias4ck 你给的第一个链接的代码应该可以,我一个外行人看着都靠谱
jethroX
2023-04-11 17:28:25 +08:00
@ByteCat 这你就错了,我看了 ChatGPT 的请求,他就是用的 post 还有负载数据。我这边用的微软开源的一个 js sse 请求器。叫:@microsoft/fetch-event-source
ByteCat
2023-04-11 19:49:13 +08:00
@jethroX 是啊,我指的就是 OpenAI stream 不是规范的 SSE ,不能用原生的 EventSource 获取数据,因为只支持 GET ,微软或者第三方实现的「可能」会支持比如 POST 的用法,但这个也可以自己实现,SSE 本身数据格式就比较简单。
linhey
2023-04-11 21:39:16 +08:00
我这个库支持流式输出和 Tokenizer 估算
https://github.com/AxApp/OpenAI
brader
2023-04-12 10:05:01 +08:00
@ByteCat
@jethroX 我在服务端已经自实现了解析 SSE 消息,返回给前端的仅仅是纯文本结果,无须客户端做任何处理了。说到 gpt 的 sse ,就我所知,js 自带的 EventSource 是可用的,obj 语言不熟所以不清楚。而且我的情况而言,客户端并没有这方面的担忧,因为客户端对接面向的是经过我服务端中转的接口,我服务端这边是同时支持 GET 、POST 形式的
jethroX
2023-04-12 10:22:45 +08:00
@brader 那你的客户端没有和你的服务端流式传输?还是说用的 websocket 。如果是等着服务端获取完了消息再返回,那也太慢了吧。
brader
2023-04-12 10:37:03 +08:00
@jethroX
@chuhades
@churchill
@Alias4ck
@linhey 我在服务端已经成功把 SSE 数据解析出来了,然后直接把结果内容 content 纯文本输出给前端了,已经不需要客户端解析了,客户端收到什么数据就输出什么数据就行了,我自己直接把 url 贴到浏览器访问测试,已经是流输出的效果了,然后客户端自己搞不定,就说他接收到就是一次返回的,我很无语。。。领导拉我去小黑屋,也是说他比较菜,让他搞不知道要多久,搞不定的话,想让我转成 websocket 接口提供给他算了。。。

下面我录制的浏览器测试视频,你们看看
https://imgur.com/WSC80VO
Ansen678
2023-04-12 13:00:38 +08:00
ios 跟服务器进行 websoket 连接,服务器去请求 chatgpt
ByteCat
2023-04-12 14:47:39 +08:00
@brader 你这个算 SSE 吗?如果是的话,需要客户端以流方式接受才行,不然就是直接返回最后结果的,或者省得麻烦你就包成 WebSocket 来传,WS 比 SSE 调包容易一点😂可能你们的 iOSer 不懂这个

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/931610

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX