当前位置: 首页 > article >正文

走进科学json版:在 JSON 格式中,字符串值必须使用双引号 “ 来界定,而不能使用单引号 ‘

走进科学疑难问题出现

在调试fastapi程序的时候,报错碰到422错误

INFO:     192.168.0.99:46536 - "POST /v1/chat/completions/ HTTP/1.1" 422 Unprocessable Entity

干净利索,只有这一句报错,不管代码里加入多少print语句查看中间变量,都只有这一句话,就像根本没有走下去(事实上确实没有走下去)。

使用的测试语句是:

curl -X 'POST' \
  'http://192.168.0.99:8000/v1/chat/completions/' \
  -H 'accept: application/json' \
  -d "{'msg':[ {'role': 'user', 'content': 'hello'} ]}"

不知道问题在哪,后来专门找了另一条测试语句,并写了/items/的代码,测试通过,没报错:

curl -X POST http://192.168.0.99:8000/items/ -H "Content-Type: application/json" \
-d '{"name": "Bruce_Lee", "description":"this is a book of Bruce_Lee", "price": 12}'

解决问题

然后就比对代码,比对/items/ 和/v1/chat/completions/ 里面代码的书写,甚至比对着写了个最简单的json数据,把这句"{'msg':[ {'role': 'user', 'content': 'hello'} ]}"学着对的那句简化成-d '{"msg": "hello"}

你还别说,输出了很多打印信息,证明程序跑下去了。当然因为简化json,中间还改了程序,再用回长段json的时候再改回去,总之是改的头昏眼花。

后来到文心一言里,让它帮我把单引号改成双引号,

提问:

请把单括号换成双括号{'msg':[ {'role': 'user', 'content': 'hello'} ]} (这里因为头昏,错把引号说成了括号,索性一言给我了份正确格式的答案)

回答

当您提到将“单括号”换成“双括号”时,我猜测您是指将某种不规范的或错误的括号使用方式更正为标准的 JSON 格式。在 JSON 中,对象(即键值对的集合)应该使用大括号 {} 来表示,而数组(即有序值的集合)应该使用方括号 [] 来表示。

根据您提供的示例 {'msg':[ {'role': 'user', 'content': 'hello'} ]},这实际上已经是一个有效的 JSON 字符串(尽管它可能被错误地称为“单括号”或“双括号”,这取决于上下文和解释者的视角)。在这个字符串中:

  • 最外层的 {} 表示一个 JSON 对象。
  • msg 是这个对象的一个键,其对应的值是一个 JSON 数组。
  • 这个数组由方括号 [] 表示,并且包含一个 JSON 对象。
  • 这个内部的对象又由大括号 {} 表示,并且有两个键值对:role 和 content

如果您的意图是确保这个 JSON 字符串被正确地用于 curl 命令中,那么您应该这样做:

curl -X 'POST' \
  'http://192.168.0.99:8000/v1/chat/completions/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"messages":[{"role": "user", "content": "hello"}]}'

使用这份curl格式的代码,终于消除了422报错!

后来才知道(也许我以前就知道,只是忘记了) ,json一定要用双引号!

在 JSON 格式中,字符串值必须使用双引号 " 来界定,而不能使用单引号 '。这是 JSON 标准的一部分,它确保了数据的一致性和可解析性。

json编程,砥砺前行!

总结下

这回对json格式算是印象深刻了,主要是受了python的影响,单引号和双引号混用,这才阴沟里翻了船。

最终问题解决,且原来计划的使用树莓派启动fastapi 中转openai指令,使ESP32开发板能够连上大模型,方案也被验证可行。

目前将fastapi 中转openai放置于树莓派2服务器上,

fastapi 中转openai配置

fastapi的代码为:

cat app.py 
from typing import Annotated
import json
from fastapi import FastAPI, Path, Query
from pydantic import BaseModel
from openai import OpenAI

import os
import time
from typing import Union, Optional

app = FastAPI()
API_KEY = "xxxx"
model="ernie-speed-8k"


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

class ChatItem(BaseModel):
    messages: list
    model: str | None = None

def ChatCompletions(
        messages: list,
        model: str,
        # provider: Optional[ProviderType] = None,
        stream: Optional[bool] = False,
        # proxy: Optional[str] = None,
        response_format: Optional[dict] = None,
        max_tokens: Optional[int] = None,
        stop: Optional[Union[list[str], str]] = None,
        api_key: Optional[str] = None,
        # ignored: Optional[list[str]] = None,
        # ignore_working: Optional[bool] = False,
        ignore_stream: Optional[bool] = False,
        **kwargs):
    client = OpenAI(
         api_key=api_key,  # 含有 AI Studio 访问令牌的环境变量,https://aistudio.baidu.com/account/accessToken,
         base_url="https://aistudio.baidu.com/llm/lmapi/v3",  # aistudio 大模型 api 服务域名
)
    chat_completion = client.chat.completions.create(
        messages=messages,
        model=model,
)
    print(f"==log for app chat_completion:{chat_completion} ")
    # response = chat_completion.result
    # print(f"==log for app  response:{response}")
    return chat_completion
    

@app.get("/items/{item_id}")
async def read_items(
    item_id: Annotated[int, Path(title="The ID of the item to get")],
    q: Annotated[str | None, Query(alias="item-query")] = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    return results

@app.post("/v1/chat/completions/")
async def chat_completions(chatitem: ChatItem):
    print(chatitem)
    chatitemdict = chatitem.dict()
    print(f"==== items:{chatitemdict}")
    #print ("=" * 20 , messages, type(messages))
    #yjson = json.loads(messages)
    #print("="*10, yjson, type(yjson))
    #zmessages = yjson["messages"]
    #print("="*10, zmessages, typr(zmessages))
    model="ernie-speed-8k"
    messages = chatitem.messages
    print(f"==== messages=chatitem.msg:{messages}")
    y = ChatCompletions(messages=messages, model=model, api_key=API_KEY)
    print("="*10, y)
    z = y.choices[0].message.content
    return z
    
@app.post("/items/")
async def create_item(item: Item):
    print(f"==== get the Item type:{type(item)}, item:{item}")
    item_dict = item.dict()
    print(f"==== item_dict{item_dict}")
    if item.tax:
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

需要到AiStudio官网获取apk_key并填入上面的代码中,在树莓派启动fastapi服务器:

uvicorn app:app --host 0.0.0.0 --reload

最终测试命令为:

curl -X 'POST' \
  'http://192.168.0.99:8000/v1/chat/completions/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"messages":[{"role": "user", "content": "hello"}]}'

省略一条head,这个命令也可以: 

curl -X 'POST' \
  'http://192.168.0.99:8000/v1/chat/completions/' \
  -H 'Content-Type: application/json' \
  -d '{"messages":[{"role": "user", "content": "hello"}]}'

 ESP32S3开发板通过中转连星河大模型

在ESP32S3开发板的MicroPython环境下,使用requests来fastapi的中转服务器,连接成功:

import requests

response = requests.post(
    'http://192.168.0.99:8000/v1/chat/completions/',
    headers = {
        'Content-Type': 'application/json',},
    json = {
        'model': "ernie-speed-8k",
        "messages": [{"role": "user", "content": "hello"}]}
)


print(response.status_code, response.reason)
print(response.text)

 输出显示:

>>> print(response.status_code, response.reason)
200 b'OK'
>>> print(response.text)
"你好!请问有什么需要我帮助你的吗?"

太棒了,使用这种解决方案,在家里使用一台树莓派做中转,就可以让家里的物联网设备都使用百度星河大模型啦!


http://www.kler.cn/a/417986.html

相关文章:

  • CSP-J初赛不会备考咋办?
  • Permute for Mac 媒体文件格式转换软件 安装教程【音视频图像文件转换,简单操作,轻松转换,提高效率】
  • 【Linux】进程控制,手搓简洁版shell
  • 分布式项目使用Redis实现数据库对象自增主键ID
  • 向日葵连接xrdp虚拟桌面
  • 大模型翻译能力评测
  • 【Python网络爬虫笔记】5-(Request 带参数的get请求) 爬取豆瓣电影排行信息
  • 洛谷 P2415 集合求和 C语言
  • 学习日志017--python的几种排序算法
  • 根据导数的定义计算导函数
  • 数据库学习记录02
  • 学习嵩山版《Java 开发手册》:编程规约 - 命名风格(P13 ~ P14)
  • 【操作系统不挂科】<内存管理-分页与分段(15)>选择题&简答题(带答案与解析)
  • C#运动控制技术详解:基础、实现与应用实例
  • 【S500无人机】--地面端下载
  • 大数据HCIA笔记1
  • Android11修改摄像头前后置方法,触觉智能RK3568开发板演示
  • redis 底层数据结构
  • YOLO系列论文综述(从YOLOv1到YOLOv11)【第12篇:YOLOv9——可编程梯度信息(PGI)+广义高效层聚合网络(GELAN)】
  • Rust学习笔记_02——数组
  • 可视化大屏系统如何实现3D数据导入与Web交互?
  • SpringAi整合大模型(进阶版)
  • MyBatis-Plus - 查询解析数据异常处理
  • Linux内核机制自学笔记
  • spring-boot自定义ApplicationListener及源码分析
  • SVN迁移至Git,保留commit提交记录