Code Monkey home page Code Monkey logo

openai-scf-goproxy's Introduction

腾讯云函数1分钟搭建 OpenAI 国内代理

项目地址: https://github.com/riba2534/openai-scf-goproxy

ps: 建议大家自己部署好之后在函数配置里面调一调参数,包括但不限于把并发度调高,超时时间调长,可以解决很多问题

最近有一个好消息,OpenAI 开放了自己的 API,开发者可以很方便的调用各种语言模型来完成自己的创意,但是由于众所周知的原因国内访问 OpenAI 时接口可能大概率超时或者调不通,那解决无非是通过 proxy 的方式:

  • 直接在境外服务器运行自己的服务,缺点是国内访问可能比较慢
  • 国内服务器运行服务,把 OpenAPI 的相关请求用境外服务器做一层转发

本文介绍一种对于国内相对而言比较方便的办法,使用腾讯云函数来完成一个指向 OpenAI 的反向代理服务搭建,完成后开发者开发时直接把请求 OpenAPI 的接口直接指向腾讯云函数的地址即可。

直接开始正题

第一步:新建云函数

  1. 打开腾讯云函数控制台: https://console.cloud.tencent.com/scf/list?rid=5&ns=default
  2. 页面左边「函数服务」中,点击「新建」,然后照着下面图填:
  • 点「从头开始」
  • 函数类型选 web函数
  • 名称自己随便填
  • 地域选择一个境外的,推荐新加坡(香港好像不在openai支持地区内)
  • 运行环境选 Go1
  • 时区选上海
  • 提交方法:本地上传zip包
  • 日志投递也推荐选上,方便看日志
  • 触发器配置照着图看

云函数.png

  1. 注意,上传的 zip 包可以在本项目 releases 中下载到,最新的包地址是: main.zip

第二步:查看部署信息

新建好之后,在腾讯云函数列表中找到你刚创建的,从左边 「函数管理」-> 「函数代码」,找到你的访问路径

1678337783998.png

这个访问路径就是你之后请求 OpenAPI 的访问路径,访问路径的格式是 https://service-xxxxxx.hk.apigw.tencentcs.com/release/

注意: 这里的访问路径后面有个 /release/ 你在用的时候把这个去掉,即: https://service-xxxxxx.hk.apigw.tencentcs.com

重要提示:云函数默认访问的超时时间较短,而调用 openai 的时间可能很长,所以我们需要改一下云函数配置,把超时时间调大,在左边「函数管理」-> 「函数配置」 里面,把访问的超时时间和并发度调大,如下图:

超时时间.png

并发配置.png

大功告成

至此,一个指向 openAPI 的反向代理就搭好了,你在开发的时候使用国内服务器,只需要把 api.openapi.com 换成这个新的地址就可以了.

我们可以通过类似 postman 这种工具来测试一下是否可用,查询一个完成模型试试,可以看到,成功的返回了信息!

1678338111283.png

玩耍

接下来就需要去看看 OpenAI 的接口文档了: https://platform.openai.com/docs/introduction

openai-scf-goproxy's People

Contributors

riba2534 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

openai-scf-goproxy's Issues

被封杀了。。。。完犊子。

使用的华为的云函数流程,走的是香港节点。用的代码环境是nodejs,刚调通,就收到禁用的email

Hi there, After a thorough investigation, we have determined that you or a member of your organization are using the OpenAI API in ways that violate our policies. Due to this breach we are halting access to the API immediately for the organization Personal. Common reasons for breach include violations of our content policy, repeated attempts at disallowed use-cases, or accessing the API from an unsupported location. You may also wish to review our Terms of Use. If you believe this is in error and would like to appeal, please contact us through our help center. We will review appeals within one business day and will contact you if we reinstate access to the API. Best, The OpenAI team

ChatGPTError: ChatGPT error 404:

使用的是V3.0的zip包。

完全按照你的配置,但是出现了404的情况。

这是测试的结果:
image

这是实际使用的结果:
image

image

http error 410

根据你的教程操作后 生成的url 访问一直会有问题 。直接访问

如何支持流式返回响应数据?(打字机效果)

我使用作者的反向代理,可以顺利访问openai的接口,但却不能流式返回(打字机效果)。
我做了个测试,本地起来这个服务,在浏览器调用了test接口,是可以实现流式返回的。
但如果把服务部署到腾讯云函数后,使用提供的公网ip调用test接口,则就是一次性返回response。
不确定是服务器设置问题?(但翻遍了服务器设置,也没有看见相关设置,正在提工单。。)还是代码问题?

下图是本地服务,可以看到response header里显示了Transfer-Encoding: chunked
图片

下图是部署到腾讯云函数后,response header里没有显示Transfer-Encoding: chunked
图片

求解决怎么搞?代码如下:

package main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"time"
)

func main() {
	version := "1.0.2"
	targetUrl := "https://api.openai.com/" // 目标域名和端口
	target, err := url.Parse(targetUrl)
	if err != nil {
		log.Fatal(err)
	}

	// 创建反向代理
	proxy := httputil.NewSingleHostReverseProxy(target)
	// 设置输出缓冲区的刷新时间间隔
	proxy.FlushInterval = 1 * time.Second

	// 修改请求头,将Host设置为目标域名
	proxy.Director = func(req *http.Request) {
		req.Host = target.Host
		req.URL.Scheme = target.Scheme
		req.URL.Host = target.Host
	}

	// 设置超时时间
	timeout := time.Duration(1 * time.Minute)
	proxy.Transport = &http.Transport{
		Proxy:                 http.ProxyFromEnvironment,
		DialContext:           (&net.Dialer{Timeout: timeout}).DialContext,
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
	}

	// 打印HTTP请求和响应的日志
	proxy.ModifyResponse = func(resp *http.Response) error {
		// 打印HTTP响应的日志
		responseDump, err := httputil.DumpResponse(resp, true)
		if err != nil {
			log.Printf("Failed to dump response: %v\n", err)
		} else {
			log.Printf("%s Response: \n%s\n", time.Now().Format("2006-01-02 15:04:05"), string(responseDump))
		}

		return nil
	}

	// 设置日志前缀和输出位置
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

	// 启动HTTP服务器
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// 设置 Content-Type 和 Transfer-Encoding
		w.Header().Set("Content-Type", "text/plain")
		w.Header().Set("Transfer-Encoding", "chunked")

		// 将http.ResponseWriter转换为http.Flusher接口
		flusher, ok := w.(http.Flusher)
		if !ok {
			http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
			log.Printf("Streaming unsupported!")
			return
		} else {
			log.Printf("Streaming supported!")
		}

		// 打印HTTP请求日志
		requestDump, err := httputil.DumpRequest(r, true)
		if err != nil {
			log.Printf("Failed to dump request: \n%v\n", err)
		} else {
			log.Printf("proxy version: %s\n%s Request: %s\n", version, time.Now().Format("2006-01-02 15:04:05"), string(requestDump))
		}
		// 反向代理转发
		proxy.ServeHTTP(w, r)

		// 在每个数据块发送完毕后刷新响应缓冲区
		flusher.Flush()
	})

	http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		// 设置响应头
		w.Header().Set("Content-Type", "text/event-stream")
		w.Header().Set("Cache-Control", "no-cache")
		// 设置Transfer-Encoding字段为"chunked"
		w.Header().Set("Transfer-Encoding", "chunked")
		w.WriteHeader(http.StatusOK) // 写入响应头

		// 发送初始化事件
		fmt.Fprint(w, "event: connect\n")
		fmt.Fprint(w, ": server connected\n\n")
		w.(http.Flusher).Flush()

		// 发送数据
		for i := 0; i < 10; i++ {
			fmt.Fprintf(w, "data: {\"count\": %d}\n\n", i)
			w.(http.Flusher).Flush()
			time.Sleep(time.Second)
		}

		// 结束 SSE 连接
		fmt.Fprint(w, "event: close\n")
		w.(http.Flusher).Flush()
		time.Sleep(time.Second)
		return
	})

	log.Printf("Starting server on port 9000...\n")
	if err := http.ListenAndServe(":9000", nil); err != nil {
		log.Fatal(err)
	}
}

可以做鉴权吗

在腾讯云函数里没找到权限管理,应该要在代码里判断吧,对go不是太熟悉

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.