C# WPF 自制ChatGPT对话界面
By
jerryxjr1220
at 2023-09-09 • 0人收藏 • 1529人看过
与ChatGPT玩《海龟汤》游戏


后面会放出详细制作过程 以及编译后程序
14 个回复 | 最后更新于 2023-09-21
2023-09-10
#2
在C# WPF中按照MVVM框架结构进行拆分:
| 架构 | 名称 | 用途 |
| Model | Message | 用来存放对话内容 |
| ViewModel | ChatGPTAPI | 实现对话的模型 |
| View | MainWindow | 主界面 |
Model:
namespace WpfAppOpenAI.Models;
public class Message
{
public string? role { get; set; }
public string? content { get; set; }
public string? showname { get; set; }
}ViewModel:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WpfAppOpenAI.Models;
namespace WpfAppOpenAI.ViewModels;
public partial class ChatGPTAPI : ObservableObject
{
[ObservableProperty] private HttpClient client;
[ObservableProperty] private Dictionary<string, object> data;
[ObservableProperty] private ObservableCollection<Message> messages;
[ObservableProperty] private string model;
[ObservableProperty] private string prompt;
[ObservableProperty] private double temperature;
[ObservableProperty] private Uri url;
public ChatGPTAPI(string? key, string? model, string? prop, double temperature = 0.7)
{
Client = new HttpClient();
Url = new Uri("https://api.chatanywhere.com.cn/v1/chat/completions");
Client.DefaultRequestHeaders.Add("Authorization", "Bearer " + key);
Client.DefaultRequestHeaders.Add("ContentType", "application/json");
Model = model ?? "gpt-3.5-turbo";
Prompt = prop ?? "You are a helpful assistant. Try your best to answer the question.";
Temperature = temperature;
Messages = new ObservableCollection<Message>();
Messages.Add(new Message { role = "user", content = Prompt, showname = "You: " });
Data = new Dictionary<string, object>();
Data["model"] = Model;
Data["messages"] = Messages;
Data["temperature"] = Temperature;
}
[RelayCommand]
public async Task<string> ask(string question)
{
Messages.Add(new Message { role = "user", content = question, showname = "You: " });
Data["messages"] = Messages;
var js = JsonConvert.SerializeObject(Data);
HttpContent content = new StringContent(js, Encoding.UTF8, "application/json");
var resp = await Client.PostAsync(Url, content);
var jobj = JObject.Parse(resp.Content.ReadAsStringAsync().Result);
var answer = jobj["choices"].First()["message"]["content"].ToString();
Messages.Add(new Message { role = "assistant", content = answer, showname = "GPT: " });
Data["messages"] = Messages;
return answer;
}
}View:
Xaml
<Window x:Class="WpfAppOpenAI.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfAppOpenAI"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:ChatGPTAPI}"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:vm="clr-namespace:WpfAppOpenAI.ViewModels"
WindowStyle="None" ResizeMode="NoResize"
Title="MainWindow" Height="500" Width="800"
FontFamily="JetBrains Mono" FontSize="14">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WrapPanel Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Center"
Margin="10,5,0,0" MouseDown="MainWindow_OnMouseDown">
<fa:ImageAwesome Icon="Wechat" Width="20" Foreground="{StaticResource SuccessBrush}" />
<TextBlock Text="OpenAI - ChatGPT" FontSize="20" Margin="10,0,0,0"
Foreground="{StaticResource PrimaryBrush}" />
</WrapPanel>
<hc:ButtonGroup Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" FontSize="20">
<Button Content="-" Click="ButtonMinimize_OnClick"
Foreground="{StaticResource PrimaryBrush}" />
<!--<Button Content="^" Click="ButtonMaximize_OnClick"/>-->
<Button Content="X" Background="{StaticResource DangerBrush}"
Foreground="{StaticResource LightInfoBrush}" Click="ButtonClose_OnClick" />
</hc:ButtonGroup>
<StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Top"
Margin="20,10,0,0">
<TextBlock Style="{StaticResource TextBlockTitle}" Text="Settings" FontSize="14"
Foreground="{StaticResource DangerBrush}" Margin="0,0,0,10" />
<Expander Header="sk Key" FontSize="24" Foreground="{StaticResource PrimaryBrush}" Margin="0,0,0,10">
<hc:TextBox x:Name="tbKey" FontSize="10" Text="sk-你申请的key" />
</Expander>
<Expander Header="Model" FontSize="24" Foreground="{StaticResource PrimaryBrush}" Margin="0,0,0,10">
<hc:ButtonGroup>
<RadioButton x:Name="rbGPT3" Content="GPT 3" FontSize="10" />
<RadioButton x:Name="rbGPT35" Content="GPT 3.5" IsChecked="True" FontSize="10" Padding="-2,0,-2,0" />
<RadioButton x:Name="rbGPT4" Content="GPT 4" FontSize="10" />
</hc:ButtonGroup>
</Expander>
<WrapPanel Orientation="Vertical" Margin="0,0,0,10">
<TextBlock Text="{Binding ElementName=sdTemperature, Path=Value, StringFormat=Temperature: {0:0.0}}"
FontSize="10" Foreground="{StaticResource PrimaryBrush}"
HorizontalAlignment="Left" VerticalAlignment="Center" />
<Slider x:Name="sdTemperature" Minimum="0.1" Maximum="0.9" Value="0.7" Width="100"
IsHitTestVisible="True" />
</WrapPanel>
<WrapPanel Orientation="Vertical" Margin="0,0,0,10">
<TextBlock Text="Prompt" FontSize="10" Foreground="{StaticResource PrimaryBrush}"
HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBox x:Name="tbPrompt" Width="150" Height="220" FontSize="10" VerticalContentAlignment="Top"
MaxLines="12"
TextWrapping="Wrap" AcceptsReturn="True" Foreground="{StaticResource SecondaryTextBrush}"
Text="You are a helpful assistant. Try your best to answer the questions." />
</WrapPanel>
<Button Content="Change and Save" Style="{StaticResource ButtonPrimary}" Click="ButtonSave_OnClick" />
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<!--<TextBox x:Name="tbOutput" Width="550" Height="400" ScrollViewer.VerticalScrollBarVisibility="Visible"
IsReadOnly="True" VerticalContentAlignment="Top" TextWrapping="Wrap"
Foreground="{StaticResource PrimaryBrush}" FontSize="14" />-->
<ItemsControl x:Name="icOutput" ItemsSource="{Binding Messages}" Padding="0,0,10,0" Height="400">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<hc:TextBox Text="{Binding content}" IsReadOnly="True"
hc:InfoElement.Title="{Binding showname}"
hc:InfoElement.TitlePlacement="Left"
TextWrapping="Wrap" Style="{StaticResource TextBoxExtend}"
Foreground="{StaticResource PrimaryBrush}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<WrapPanel Orientation="Horizontal" Margin="10,10,0,0">
<TextBox x:Name="tbQuestion" Width="530" Height="45" FontSize="13" VerticalAlignment="Top" MaxLines="5"
TextWrapping="Wrap" AcceptsReturn="True" Foreground="{StaticResource SecondaryTextBrush}" />
<Button Style="{StaticResource ButtonPrimary}" Click="ButtonSend_OnClick">
<fa:FontAwesome Icon="Send" />
</Button>
</WrapPanel>
</StackPanel>
</Grid>
</Window>CS
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Controls;
using WpfAppOpenAI.ViewModels;
using MessageBox = HandyControl.Controls.MessageBox;
using Window = System.Windows.Window;
namespace WpfAppOpenAI.Views;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ChatGPTAPI api;
public MainWindow()
{
InitializeComponent();
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
private void ButtonMinimize_OnClick(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
// private void ButtonMaximize_OnClick(object sender, RoutedEventArgs e)
// {
// if (this.WindowState == WindowState.Maximized)
// this.WindowState = WindowState.Normal;
// else
// this.WindowState = WindowState.Maximized;
// }
private void ButtonClose_OnClick(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void MainWindow_OnMouseDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
private void ScrollToBottom()
{
// Scroll to the bottom of the ScrollViewer
var scrollViewer = FindVisualChild<ScrollViewer>(icOutput);
scrollViewer?.ScrollToEnd();
}
private static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is T result)
return result;
var descendant = FindVisualChild<T>(child);
if (descendant != null)
return descendant;
}
return null;
}
private async void ButtonSend_OnClick(object sender, RoutedEventArgs e)
{
try
{
var question = tbQuestion.Text;
var ans = await api.ask(question);
//tbOutput.Text += "You: " + question + "\r\n";
//tbOutput.Text += "GPT: " + ans + "\r\n\r\n";
ScrollToBottom();
}
catch
{
//tbOutput.Text += "Get Error! Try other models again!\r\n\r\n";
MessageBox.Show("Got Error! Try again!");
}
}
private void ButtonSave_OnClick(object sender, RoutedEventArgs e)
{
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
}PS:由于我使用的是免费api,所有只能用GPT 3.5。 GPT 4需要申请收费key。
2023-09-14
#4
根据B站上一位up主的提示词工具,把ChatGPT升级成AutoGPT,会根据用户的目标分解任务并给出解决方案。
只需要把Prompt修改为:
你作为精通问题解决方案的X教授,你的职责是通过了解用户的目标和偏好,然后选择最合适该任务的专家代理来帮助用户达到他们的目标。
初始化:
我是一位${role}的X教授,我知道${context}。我会逐步推理,确定达到${goal}的最佳行动方案。我可以使用${tools}来协助这个过程。
我将通过以下步骤来帮你实现你的目标:${reasoned steps}。 当${completion}时,我的任务结束。 ${first step, question}
解决问题的步骤:
首先,X教授需要收集相关信息,并通过提问明确用户目标。
一旦用户确认,X教授会挑选专家代理,支持用户直到达到目标。
命令:
/start - X教授自我介绍并开始第一步
/save - X教授需要重申SMART目标,总结目前进展,并建议下一步
/reason - X教授和专家代理一起逐步推理,然后为用户提供继续前进的建议
/settings - X教授更新目标或代理
/new - 忘记以前的输入
规则:
- 每个输出都以一个问题或推荐的下一步结束
- 在第一次输出中列出你的命令,或者当用户询问时提供
- 作为X教授,在挑选新的专家代理前先询问
- 最后,记得用中文和我交流尤其是对于一个庞大的问题,它会自动拆分成若干小任务目标,然后依次给出解决方案。
建议用该Prompt时,把Temperature尽量调小,这样对话基本就会严格按照我们制定的规则进行。
2023-09-17
#6
继续优化,新增了语音播放功能,并且增加了对话保存功能

视频教程:
2023-09-21
#9
继续优化,针对不同使用场景增加不同Prompt提示词模板。
目前设了3个Prompt:
1、通用场景 General 2、专业问题解决场景 Professional 3、翻译场景 Translate

2023-09-21
#10
//MainWindow.xaml.cs
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using Newtonsoft.Json.Linq;
using WpfAppOpenAI.Model;
using WpfAppOpenAI.ViewModel;
using MessageBox = HandyControl.Controls.MessageBox;
using ScrollViewer = HandyControl.Controls.ScrollViewer;
using Window = System.Windows.Window;
namespace WpfAppOpenAI.View;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ChatGPTAPI api;
public MainWindow()
{
InitializeComponent();
tbPrompt.Text = """
You are a helpful assistant.
Try your best to answer the question or provide a possible solution.
""";
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
private void ButtonMinimize_OnClick(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
// private void ButtonMaximize_OnClick(object sender, RoutedEventArgs e)
// {
// if (this.WindowState == WindowState.Maximized)
// this.WindowState = WindowState.Normal;
// else
// this.WindowState = WindowState.Maximized;
// }
private void ButtonClose_OnClick(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void MainWindow_OnMouseDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
private async void ButtonSend_OnClick(object sender, RoutedEventArgs e)
{
try
{
var question = tbQuestion.Text;
var ans = await api.ask(question);
//tbOutput.Text += "You: " + question + "\r\n";
//tbOutput.Text += "GPT: " + ans + "\r\n\r\n";
}
catch
{
//tbOutput.Text += "Get Error! Try other models again!\r\n\r\n";
MessageBox.Show("Got Error! Try again!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void ButtonSave_OnClick(object sender, RoutedEventArgs e)
{
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
private void LbHistory_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedHistory = api.HistoryList[lbHistory.SelectedIndex];
var historyFile = api.historyDictionary[selectedHistory];
var jsonString = File.ReadAllText(historyFile, Encoding.UTF8);
var jobj = JArray.Parse(jsonString);
api.Messages.Clear();
for (var i = 0; i < jobj.Count; i++)
{
if (jobj[i].SelectToken("role")!.ToString() == "user")
api.Messages.Add(new YouMessage { role = "user", content = jobj[i].SelectToken("content")!.ToString() });
else
api.Messages.Add(new GptMessage { role = "assistant", content = jobj[i].SelectToken("content")!.ToString() });
}
}
private void Rabtn0_OnClick(object sender, RoutedEventArgs e)
{
if (rabtn0.IsChecked==true)
{
tbPrompt.Text = """
You are a helpful assistant.
Try your best to answer the question or provide a possible solution.
""";
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
}
private void Rabtn1_OnClick(object sender, RoutedEventArgs e)
{
if (rabtn1.IsChecked == true)
{
tbPrompt.Text = """
你作为问题解决方案的X教授,你的职责是通过了解用户的目标和偏好,然后选择最合适该任务的专家代理来帮助用户达到他们的目标。
初始化:
我是一位${role}的X教授,我知道${context}。我会逐步推理,确定达到${goal}的最佳行动方案。我可以使用${tools}来协助这个过程。
我将通过以下步骤来帮你实现你的目标:${reasoned steps}。 当${completion}时,我的任务结束。 ${first step, question}
解决问题的步骤:
首先,X教授需要收集相关信息,并通过提问明确用户目标。
一旦用户确认,X教授会挑选专家代理,支持用户直到达到目标。
命令:
/start - X教授自我介绍并开始第一步
/save - X教授需要重申SMART目标,总结目前进展,并建议下一步
/reason - X教授和专家代理一起逐步推理,然后为用户提供继续前进的建议
/settings - X教授更新目标或代理
/new - 忘记以前的输入
规则:
- 每个输出都以一个问题或推荐的下一步结束
- 在第一次输出中列出你的命令,或者当用户询问时提供
- 作为X教授,在挑选新的专家代理前先询问
- 最后,记得用中文和我交流
""";
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
}
private void Rabtn2_OnClick(object sender, RoutedEventArgs e)
{
if (rabtn2.IsChecked==true)
{
tbPrompt.Text = """
You are a professional translator.
Try your best to translate from Chinese to target language or from source language to Chinese.
Rules:
- I will put the content need to translate into "[" and "]" symbols;
- You should put the translated content into "[" and "]" symbols also;
""";
var key = tbKey.Text;
var model = string.Empty;
if (rbGPT3.IsChecked == true)
model = "gpt-3.5-turbo-0301";
if (rbGPT35.IsChecked == true)
model = "gpt-3.5-turbo";
if (rbGPT4.IsChecked == true)
model = "gpt-3.5-turbo-0613";
var prompt = tbPrompt.Text;
var temperature = Math.Round(sdTemperature.Value * 10) / 10;
api = new ChatGPTAPI(key, model, prompt, temperature);
DataContext = api;
}
}
}
public class ShortValueConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Math.Round(((double)value) * 10) / 10;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}// MainViewWindow.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WpfAppOpenAI.Model;
using MessageBox = HandyControl.Controls.MessageBox;
namespace WpfAppOpenAI.ViewModel;
public partial class ChatGPTAPI : ObservableObject
{
[ObservableProperty] private HttpClient client;
[ObservableProperty] private Dictionary<string, object> data;
[ObservableProperty] private ObservableCollection<Message> messages;
[ObservableProperty] private string model;
[ObservableProperty] private string prompt;
[ObservableProperty] private double temperature;
[ObservableProperty] private Uri url;
[ObservableProperty] private BindingList<string> historyList;
public Dictionary<string, string> historyDictionary;
public ChatGPTAPI(string? key, string? model, string? prop, double temperature = 0.7)
{
Client = new HttpClient();
Url = new Uri("https://api.chatanywhere.com.cn/v1/chat/completions");
Client.DefaultRequestHeaders.Add("Authorization", "Bearer " + key);
Client.DefaultRequestHeaders.Add("ContentType", "application/json");
Model = model ?? "gpt-3.5-turbo";
Prompt = prop ?? "You are a helpful assistant. Try your best to answer the question.";
Temperature = temperature;
Messages = new ObservableCollection<Message>();
Messages.Add(new YouMessage { role = "user", content = Prompt });
Data = new Dictionary<string, object>();
Data["model"] = Model;
Data["messages"] = Messages;
Data["temperature"] = Temperature;
historyDictionary = new Dictionary<string, string>();
HistoryList = new BindingList<string>();
string curdir = Directory.GetCurrentDirectory();
var files = Directory.GetFiles(curdir + @"\log", "*.log", SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
var filename = Path.GetFileName(file);
historyDictionary[filename] = file;
HistoryList.Add(filename);
}
}
[RelayCommand]
public async Task<string> ask(string question)
{
Messages.Add(new YouMessage { role = "user", content = question });
Data["messages"] = Messages;
var js = JsonConvert.SerializeObject(Data);
HttpContent content = new StringContent(js, Encoding.UTF8, "application/json");
var resp = await Client.PostAsync(Url, content);
var jobj = JObject.Parse(resp.Content.ReadAsStringAsync().Result);
var answer = jobj["choices"].First()["message"]["content"].ToString();
Messages.Add(new GptMessage { role = "assistant", content = answer });
Data["messages"] = Messages;
return answer;
}
[RelayCommand]
public void SaveHistory()
{
string curdir = Directory.GetCurrentDirectory();
string filename = DateTime.Now.ToString("yyMMddHHmmss") + ".log";
string logpath = curdir + @"\log\" + filename;
var jsonString = JsonConvert.SerializeObject(Messages);
File.WriteAllText(logpath, jsonString, Encoding.UTF8);
historyDictionary[filename] = logpath;
HistoryList.Add(filename);
MessageBox.Show("Dialogue Saved!", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
}
}登录后方可回帖


看你们乐的...

前几天在Github上找到了一个免费的ChatGPT的API接口,此API服务器是在国内的,所有访问速度比之前翻墙访问要快不少,最主要是它可以免费使用GPT3.5(GPT4是收费的)。
https://github.com/chatanywhere/gpt_api_free
免费申请到一个sk-key以后就可以访问了
根据API文档,可以知道几个必要参数:
api网址:
http的header
header = { 'Content-Type': 'application/json', 'Authorization': 'Bearer sk-你申请的key' }json序列化的数据
data = { 'model': 'gpt-3.5-turbo', 'messages': [{'role': 'user', 'content': 'Hello!'}], 'temperature': 0.7 }其中model是选择的模型,temperature是话题新鲜度,messages中存放对话
有了这些信息就可以先在python中进行测试了
import requests import json data = { 'model': 'gpt-3.5-turbo', 'messages': [{'role': 'user', 'content': 'Hello!'}], 'temperature': 0.7 } header = { 'Content-Type': 'application/json', 'Authorization': 'Bearer sk-你申请的key' } resp = requests.post(url='https://api.chatanywhere.com.cn/v1/chat/completions', headers=header, data=json.dumps(data)) res = json.loads(resp.text)['choices'][0]['message']['content'] print(res)正确收到返回的响应后就可以在C#中尝试封装了。