基于OpenAI-DotNet的Assistant多轮对话续聊实现疑问
如何在OpenAI-DotNet的Assistant线程中添加消息继续对话?
我正在用ChatGPT做相关实验,发现OpenAI-DotNet这个NuGet包使用起来较为简便。我希望实现用户与AI的对话功能,了解到Assistant是合适的实现方式,因此编写了如下代码:
var request = new CreateAssistantRequest(Model.GPT4o); assistant = await client.AssistantsEndpoint.CreateAssistantAsync( new CreateAssistantRequest( name: "English Teacher", instructions: "You are a personal English Teacher.", model: Model.GPT4o)); var messages = new List<Message> { "Good morning! How is the weather?" }; var threadRequest = new CreateThreadRequest(messages); chats = await assistant.CreateThreadAndRunAsync(threadRequest);
但我不清楚创建Thread后,如何添加更多消息以继续对话,难道每次添加消息都需要重新创建chats?
不需要每次重新创建线程或chats,你只需要保留线程ID,后续直接向该线程添加消息并触发新的Run即可,具体步骤如下:
保存线程ID
首次创建线程并运行后,从返回的Run对象中提取线程ID并存储,后续对话都基于这个ID操作:string threadId = chats.ThreadId;向已有线程添加新消息
使用ThreadsEndpoint.CreateMessageAsync方法,将用户的新消息添加到指定线程:var newMessageRequest = new CreateMessageRequest( role: Role.User, content: "Teach me some daily English sentences about weather."); await client.ThreadsEndpoint.CreateMessageAsync(threadId, newMessageRequest);触发Assistant处理新消息
调用CreateRunAsync让Assistant处理线程中的最新消息:var runRequest = new CreateRunRequest(assistant.Id); var newRun = await client.ThreadsEndpoint.CreateRunAsync(threadId, runRequest);等待处理完成并获取对话结果
轮询Run的状态,直到其完成后拉取线程中的所有消息查看完整对话:// 等待Run执行完成 while (newRun.Status is RunStatus.Queued or RunStatus.InProgress) { await Task.Delay(1000); newRun = await client.ThreadsEndpoint.RetrieveRunAsync(threadId, newRun.Id); } // 获取线程中的所有消息并按时间排序 var messagesList = await client.ThreadsEndpoint.ListMessagesAsync(threadId); foreach (var msg in messagesList.OrderBy(m => m.CreatedAt)) { Console.WriteLine($"{msg.Role}: {msg.Content.First().Text.Value}"); }
完整对话示例代码
// 首次创建Assistant和初始线程 var assistant = await client.AssistantsEndpoint.CreateAssistantAsync( new CreateAssistantRequest( name: "English Teacher", instructions: "You are a personal English Teacher.", model: Model.GPT4o)); var initialMessages = new List<Message> { new Message(Role.User, "Good morning! How is the weather?") }; var threadRequest = new CreateThreadRequest(initialMessages); var initialRun = await assistant.CreateThreadAndRunAsync(threadRequest); string threadId = initialRun.ThreadId; // 等待首次回复生成 while (initialRun.Status is RunStatus.Queued or RunStatus.InProgress) { await Task.Delay(1000); initialRun = await client.ThreadsEndpoint.RetrieveRunAsync(threadId, initialRun.Id); } // 添加新消息并触发新一轮对话 var newMessage = new CreateMessageRequest(Role.User, "Teach me some daily English sentences about weather."); await client.ThreadsEndpoint.CreateMessageAsync(threadId, newMessage); var newRun = await client.ThreadsEndpoint.CreateRunAsync(threadId, new CreateRunRequest(assistant.Id)); // 等待新回复生成并输出完整对话 while (newRun.Status is RunStatus.Queued or RunStatus.InProgress) { await Task.Delay(1000); newRun = await client.ThreadsEndpoint.RetrieveRunAsync(threadId, newRun.Id); } var allMessages = await client.ThreadsEndpoint.ListMessagesAsync(threadId); foreach (var msg in allMessages.OrderBy(m => m.CreatedAt)) { Console.WriteLine($"{msg.Role}: {msg.Content.First().Text.Value}"); }
关键要点
- 线程(Thread)是对话的持久化容器,所有历史消息都存储在其中,无需重复创建
- 每次用户发送新消息,只需添加到对应线程,再创建新的Run即可触发Assistant的回复
- 必须等待Run状态变为
Completed后,才能获取到最新的AI回复消息
内容的提问来源于stack exchange,提问作者Enrico
相关产品推荐
相关产品推荐

