chatgpt接口开发笔记1:completions接口

Posted raok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了chatgpt接口开发笔记1:completions接口相关的知识,希望对你有一定的参考价值。

chatgpt接口开发笔记1:completions接口

个人博客地址: https://note.raokun.top
拥抱ChatGPT,国内访问网站:https://www.playchat.top

序:写这一系列文章的动机来源于在部署Chanzhaoyu/chatgpt-web项目时发现,体验并不好,会存在多人同时提问时回答会夹断,上下文接不上的现象。同时希望搭建的项目能实现前后端分离。于是用webapi写了一套后端接口。我会把我在对接openai的接口开发的经验分享给大家。

completions接口

目前我们用到最多的接口就是completions接口

POST  https://api.openai.com/v1/chat/completions

官方给出的入参示例为:

curl https://api.openai.com/v1/chat/completions \\
  -H "Content-Type: application/json" \\
  -H "Authorization: Bearer $OPENAI_API_KEY" \\
  -d \'
    "model": "gpt-3.5-turbo",
    "messages": ["role": "user", "content": "Hello!"]
  \'

header部分:

  • Authorization 身份验证 $OPENAI_API_KEY 替换成你用到的key

请求体:

  • model 使用的模型,这里使用的是gpt 3.5的模型
  • messages 会话

**注意点:这里的messages 是接口的核心,分为三类:user、assistant、system **

同时,我们可以

  • 添加max_tokens 用于控制回复内容的最大长度,一般可以设置为2000
  • 添加stream 用于控制接口是返回json字符串还是返回stream的流(stream可以实现打字机效果)
  • 添加presence_penalty或frequency_penalty 用于控制回复的开放程度,官方称为惩罚机制

返回参数官方示例:


  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1677652288,
  "choices": [
    "index": 0,
    "message": 
      "role": "assistant",
      "content": "\\n\\nHello there, how may I assist you today?",
    ,
    "finish_reason": "stop"
  ],
  "usage": 
    "prompt_tokens": 9,
    "completion_tokens": 12,
    "total_tokens": 21
  


重点参数解析:

  • created 回复时间的时间戳
  • message 回复内容,回复内容的role固定为assistant
  • finish_reason 结果完成原因 可能是"stop"(代表没有更多的建议),"cutoff"(代表建议被截断),或者"completion"(代表建议完成)
  • prompt_tokens:消息中包含的单词数量
  • completion_tokens:结果中包含的单词数量
  • total_tokens:消息中总共包含的单词数量

如何控制上下文

相信很多部署过chatgpt-web的同学都有遇到过上下文不连续,接不上的情况。其原因在于会话的数据是存在前端缓存里的,返回消息时出现了夹断,前端获取不到被夹断报错的上一次的聊天回复的内容。

看过chatgpt-web的源码的同学应该发现了,在发起聊天请求时,会传会话id给接口。我开始也是以为id是上下文的判断依据。后来在开发接口时才注意到OpenAI的接口并没有Id这样的参数。这说明会话的id并不是上下文的检索条件。

通过测试实现,我总结了下:

上下文的依据与会话id,还有你使用的key都是没有关系的,它只与你的message参数有关。

实现精确的上下文

为了实现精确的上下文,你可以在发起请求时,将接口回复的内容一并带上。因为message 是一个集合,如下:

"messages": [
      "role": "assistant",
      "content": "\\n\\nHello there, how may I assist you today?",
    "role": "user", "content": "Hello!"]

如果条件允许可以多加点(大于等于2),同时这肯定是消耗更多的余额的。

到此,你应该对completions接口已经有了充足的认识了。

Cursor——ChatGPT的替代品笔记

Cursor——ChatGPT的替代品【笔记】

前言

2023-3-31 22:00:44

以下内容源自《笔记》
仅供学习交流使用

推荐

什么? 你还没用过 Cursor? 智能 AI 代码生成工具 Cursor 安装和使用介绍

Cursor AI IDE 开发者工具

【黑科技】任何人都可以白嫖最强AI!!!

Cursor——ChatGPT的替代品

下载

官网下载Cursor

登录

点击设置
点击sign in

可以使用github账号登录

使用

先别打开任何文件,就可以回答问题了

如果回答的是英文,就它让用中文回答


它能回答,编程问题


如何回答,变成以外的问题,请看后面

可以发现,它默认的是python代码

新建一个文件 main,java

输入文件名,敲回车

编写区,Ctrl+L

就写出的是java代码了

怎么让它问答一个编程以外的问题

新建一个hello.txt文件
然后写一个编程之外的问题

测试有可能不成功

提问:写一封情书

提问:西安邮电大学简介

高级

参考 Cursor AI IDE 开发者工具

以下是扫雷程序

import java.util.Scanner;

public class Minesweeper 
    private int[][] grid;
    private boolean[][] revealed;
    private boolean[][] mines;
    private int rows;
    private int cols;
    private int numMines;

    public Minesweeper(int rows, int cols, int numMines) 
        this.rows = rows;
        this.cols = cols;
        this.numMines = numMines;
        grid = new int[rows][cols];
        revealed = new boolean[rows][cols];
        mines = new boolean[rows][cols];
        placeMines();
        calculateNumbers();
    

    private void placeMines() 
        int count = 0;
        while (count < numMines) 
            int row = (int) (Math.random() * rows);
            int col = (int) (Math.random() * cols);
            if (!mines[row][col]) 
                mines[row][col] = true;
                count++;
            
        
    

    private void calculateNumbers() 
        for (int r = 0; r < rows; r++) 
            for (int c = 0; c < cols; c++) 
                grid[r][c] = countAdjacentMines(r, c);
            
        
    
    
    public void reveal(int row, int col) 
        if (mines[row][col]) 
            gameOver();
            return;
        
        revealed[row][col] = true;
        if (grid[row][col] == 0) 
            for (int r = Math.max(0, row - 1); r <= Math.min(rows - 1, row + 1); r++) 
                for (int c = Math.max(0, col - 1); c <= Math.min(cols - 1, col + 1); c++) 
                    if (!revealed[r][c]) 
                        reveal(r, c);
                    
                
            
        
    

    private void gameOver() 
        System.out.println("Game over!");
        System.exit(0);
    

    public boolean isGameOver() 
        for (int r = 0; r < rows; r++) 
            for (int c = 0; c < cols; c++) 
                if (mines[r][c] && !revealed[r][c]) 
                    return false;
                
                if (!mines[r][c] && !revealed[r][c]) 
                    return false;
                
            
        
        return true;
    

             
    // This method returns the number of adjacent mines for a given cell
    private int countAdjacentMines(int row, int col) 
        int count = 0;
        for (int r = Math.max(0, row - 1); r <= Math.min(rows - 1, row + 1); r++) 
            for (int c = Math.max(0, col - 1); c <= Math.min(cols - 1, col + 1); c++) 
                if (mines[r][c]) 
                    count++;
                
            
        
        return count;
    
	// This method returns the current state of the game as a string
    // Each cell is represented by a single character
    // If the cell is not revealed, it is represented by '-'
    // If the cell is revealed and contains a mine, it is represented by '*'
    // If the cell is revealed and does not contain a mine, it is represented by the number of adjacent mines
    public String toString() 
        StringBuilder sb = new StringBuilder();
        for (int r = 0; r < rows; r++) 
            for (int c = 0; c < cols; c++) 
                if (!revealed[r][c]) 
                    sb.append("-");
                 else if (mines[r][c]) 
                    sb.append("*");
                 else 
                    sb.append(grid[r][c]);
                
            
            sb.append("\\n");
        
        return sb.toString();
    
    // We need to add a main method to the Minesweeper class to continue the Minesweeper program
    // In the main method, we can create a new instance of the Minesweeper class and start the game
    // We can use a Scanner object to get input from the user and call the reveal method with the user's input
    // We can also use the isGameOver method to check if the game is over and end the game if necessary
    
    
    public static void main(String[] args) 
        Minesweeper game = new Minesweeper(10, 10, 10);
        Scanner scanner = new Scanner(System.in);
        while (!game.isGameOver()) 
            System.out.println(game.toString());
            System.out.print("Enter row and column to reveal: ");
            int row = scanner.nextInt();
            int col = scanner.nextInt();
            game.reveal(row, col);
        
        System.out.println(game.toString());
        System.out.println("Game over!");
    




运行结果

以下是GUI编写的扫雷程序

// Import necessary packages// The code provided does not contain any syntax errors that would prevent it from compiling. 
// If the user is experiencing compilation errors, they should check their Java environment and ensure that all necessary packages and dependencies are properly installed.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

// Create a Minesweeper class that extends JFrame and implements ActionListener
public class Minesweeper extends JFrame implements ActionListener 
  
      // Declare necessary variables
      private Container contentPane;
      private JPanel gamePanel, buttonPanel;
      private JButton[][] buttons;
      private int[][] counts;
      private int size = 10;
      private int numMines = 10;
  
      // Create a constructor for the Minesweeper class
      public Minesweeper() 
        // Set the title of the JFrame
        setTitle("Minesweeper");
        
        // Get the content pane of the JFrame
        contentPane = getContentPane();
        
        // Set the layout of the content pane to BorderLayout
        contentPane.setLayout(new BorderLayout());
        
        // Call the createGamePanel method to create the game panel
        createGamePanel();
        
        // Call the createButtonPanel method to create the button panel
        createButtonPanel();
        
        // Pack the JFrame
        pack();
        
        // Set the JFrame to be visible
        setVisible(true);
      
  
    // Create a method to create the game panel
    private void createGamePanel() 
        // Create a new JPanel for the game panel
        gamePanel = new JPanel();
        
        // Set the layout of the game panel to GridLayout
        gamePanel.setLayout(new GridLayout(size, size));
        
        // Create a new 2D array of JButtons for the buttons
        buttons = new JButton[size][size];
        
        // Create a new 2D array of integers for the counts
        counts = new int[size][size];
        
        // Initialize the buttons and counts arrays
        for (int i = 0; i < size; i++) 
          for (int j = 0; j < size; j++) 
            buttons[i][j] = new JButton();
            buttons[i][j].addActionListener(this);
            gamePanel.add(buttons[i][j]);
            counts[i][j] = 0;
          
        
        
        // Add the game panel to the content pane
        contentPane.add(gamePanel, BorderLayout.CENTER);
    
  
    // Create a method to create the button panel
    private void createButtonPanel() 
        // Create a new JPanel for the button panel
        buttonPanel = new JPanel();
        
        // Set the layout// Set the layout of the button panel to FlowLayout
        buttonPanel.setLayout(new FlowLayout());
    
        // Create a new JButton for the "New Game" button
        JButton newGameButton = new JButton("New Game");
    
        // Add an ActionListener to the "New Game" button
        newGameButton.addActionListener(new ActionListener() 
            public void actionPerformed(ActionEvent e) 
                newGame();
            
        );

        // Add the "New Game" button to the button panel
        buttonPanel.add(newGameButton);
        
        // Add the button panel to the content pane
        contentPane.add(buttonPanel, BorderLayout.SOUTH);// Create a new JButton for the "Reset" button
        JButton resetButton = new JButton("Reset");
    
        // Add an ActionListener to the "Reset" button
        resetButton.addActionListener(new ActionListener() 
          public void actionPerformed(ActionEvent e) 
            reset();
          
        );

        // Add the "Reset" button to the button panel
        buttonPanel.add(resetButton);
        
        // Add the button panel to the content pane
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
            
        // Create a new JButton for the "Settings" button
        JButton settingsButton = new JButton("Settings");
        
        // Add an ActionListener to the "Settings" button
        settingsButton.addActionListener(new ActionListener() 
            public void actionPerformed(ActionEvent e) 
                // Call the showSettingsDialog method to show the settings dialog
                showSettingsDialog();
            
        );
    
        // Add the "Settings" button to the button panel
        buttonPanel.add(settingsButton);
    
        // Add the button panel to the content pane
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
    
    // Create a method to generate the mines and update the counts
    private void generateMines(int row, int col) 
      // Declare necessary variables
      int mines = 0;
      int i, j;
      
      // Generate the mines
      while (mines < numMines) 
        i = (int)(Math.random() * size);
        j = (int)(Math.random() * size);
        if (counts[i][j] != -1 && !(i == row && j == col)) 
          counts[i][j] = -1;
          mines++;
        
      
      
      // Update the counts
      for (i = 0; i < size; i++) 
        for (j = 0; j < size; j++) 
          if (counts[i][j] == -1) 
            updateCounts(i, j);
          
        
      
    

    // Create a method to update the counts
    private void updateCounts(int row, int col) 
      // Declare necessary variables
      int i, j;
  
      // Update the counts
      for (i = row - 1; i <= row + 1; i++) 
        for (j = col - 1; j <= col + 1; j++) 
          if (i >= 0 && i < size && j >= 0 && j < size && counts[i][j] != -1) 
            counts[i][j]++;
          
        
      
    

    // Create a method to reveal the button at the specified row and column
    private void reveal(int row, int col) 
      // Check if the button is already revealed or flagged
      if (buttons[row][col].getText().length() > 0) 
        return;
      
      
      // Check if the button contains a mine
      if <

以上是关于chatgpt接口开发笔记1:completions接口的主要内容,如果未能解决你的问题,请参考以下文章

2023很火的ChatGPT中文版PHP网站源码+已配置API接口

3小时!开发ChatGPT微信小程序

.net中最简单的http请求调用(比如调用chatgpt的openAI接口)

新知chatGPT 使用笔记——chatGPT API的使用

ChatGPT官方API可以抢先体验了

ChatGPT的使用学习笔记