当前位置:   article > 正文

利用OpenRouter API,搭建google/gemma-7b-it:free本地客户端

openrouter

这篇文章起源于小毕超的《无需 GPU 服务器,借助 OpenRouter 零成本搭建自己的大模型助手-CSDN博客》。关于OpenRouter的介绍,此文章已经比较全面。该文章中使用 Python + tornado 实现 Web 服务,前端使用基础的 Html + Jquery编写的server.py、app.py和html文件为我提供了重要帮助。之所以写这篇文章,是因为在使用server.py中出现了“405 服务接口调用异常”。在利用chrome devtool跟踪网络请求后,发现tornado.web.Application的“/assistant”路由,在向app.py发起post请求之后,还将发起第二次options请求,而文章中的Assistant并没有加入响应options请求的处理代码。

        经询问kimi AIKimi.ai - 帮你看更大的世界,了解问题出在“在使用Tornado搭建的服务端时,如果遇到发起OPTIONS请求出错的问题,这通常是由于预请求(pre-flight request)导致的。在HTTP协议中,OPTIONS请求是一种预请求,用于客户端在发送实际请求之前,询问服务器是否允许某个HTTP方法(如POST、GET、PUT、DELETE等)”。解决方案为:

  • 配置CORS:可以使用Tornado的tornado.web.CorsFilter来设置CORS策略,或者手动设置响应头Access-Control-Allow-Methods

  • 添加OPTIONS请求处理器:在Tornado中,可以为路由添加一个OPTIONS方法的处理器,返回允许的HTTP方法。

       server.py中对cors的设置已经由set_default_headers正确设置,但Assistant类中缺少options处理方法。修改后的server.py代码如下:

  1. from tornado.concurrent import run_on_executor
  2. from tornado.web import RequestHandler
  3. import tornado.gen
  4. from openai import OpenAI
  5. import json
  6. class Assistant(RequestHandler):
  7. model = "google/gemma-7b-it:free"
  8. client = OpenAI(
  9. base_url="https://openrouter.ai/api/v1",
  10. api_key="sk-##########################",
  11. )
  12. default_prompt = "You are an AI assistant that helps people find information."
  13. def prepare(self):
  14. self.executor = self.application.pool
  15. def set_default_headers(self):
  16. self.set_header('Access-Control-Allow-Origin', "*")
  17. self.set_header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept")
  18. self.set_header('Access-Control-Allow-Methods', "GET, POST, PUT, DELETE, OPTIONS")
  19. def options(self):
  20. # 直接调用set_default_headers来设置CORS头部
  21. self.set_default_headers()
  22. # OPTIONS请求不需要响应体,因此直接finish
  23. self.finish()
  24. @tornado.gen.coroutine
  25. def post(self):
  26. json_data = json.loads(self.request.body)
  27. if 'questions' not in json_data or 'history' not in json_data:
  28. self.write({
  29. "code": 400,
  30. "message": "缺少必填参数"
  31. })
  32. return
  33. questions = json_data['questions']
  34. history = json_data['history']
  35. result = yield self.do_handler(questions, history)
  36. self.write(result)
  37. @run_on_executor
  38. def do_handler(self, questions, history):
  39. try:
  40. answer, history = self.llm(questions, history)
  41. return {
  42. "code": 200,
  43. "message": "success",
  44. "answer": answer,
  45. "history": history
  46. }
  47. except Exception as e:
  48. return {
  49. "code": 400,
  50. "message": str(e)
  51. }
  52. def llm(self, user_prompt, messages, system_prompt=default_prompt):
  53. if not messages:
  54. messages = []
  55. messages.append({"role": "user", "content": user_prompt})
  56. completion = self.client.chat.completions.create(
  57. extra_headers={
  58. "HTTP-Referer": "http://localhost:8088",
  59. "X-Title": "test",
  60. },
  61. model=self.model,
  62. messages=messages,
  63. max_tokens=2048
  64. )
  65. answer = completion.choices[0].message.content
  66. messages.append({"role": "assistant", "content": answer})
  67. return answer, messages

app.py和本地html文件无需更改。

最后,openrouter中还有其他免费的LLM,但是免费的LLM都有一定的限制,google/gemma-7b-it:free在处理中文方面还存在不足,会出现中英文混排输出和乱码的问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/869485
推荐阅读
相关标签
  

闽ICP备14008679号