qwen+ollama实现function call
qwen qwq+ollama实现function call
·
qwen2.5
下载qwen2.5
https://modelscope.cn/models/Qwen/Qwen2.5-7B-Instruct-GGUF
安装ollama
导入模型
新建Modelfile
FROM ./qwen2.5-7b-instruct-q5_k_m.gguf
# set the temperature to 0.7 [higher is more creative, lower is more coherent]
PARAMETER temperature 0.7
PARAMETER top_p 0.8
PARAMETER repeat_penalty 1.05
TEMPLATE """{{ if .Messages }}
{{- if or .System .Tools }}<|im_start|>system
{{ .System }}
{{- if .Tools }}
# Tools
You are provided with function signatures within <tools></tools> XML tags. You may call one or more functions to assist with the user query. Don't make assumptions about what values to plug into functions. Here are the available tools:
<tools>{{- range .Tools }}{{ .Function }}{{- end }}</tools>
For each function call, return a JSON object with function name and arguments within <tool_call></tool_call> XML tags as follows:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>{{- end }}<|im_end|>{{- end }}
{{- range .Messages }}
{{- if eq .Role "user" }}
<|im_start|>{{ .Role }}
{{ .Content }}<|im_end|>
{{- else if eq .Role "assistant" }}
<|im_start|>{{ .Role }}
{{- if .Content }}
{{ .Content }}
{{- end }}
{{- if .ToolCalls }}
<tool_call>
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{ end }}</tool_call>
{{- end }}<|im_end|>
{{- else if eq .Role "tool" }}
<|im_start|>user
<tool_response>
{{ .Content }}
</tool_response><|im_end|>
{{- end }}
{{- end }}
<|im_start|>assistant
{{ else }}{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ end }}
"""
导入
ollama create qwen2.5 --file ./ModelFile
qwq
如果使用ollama直接拉取则直接支持function call
测试
EmailTools.cs
using Microsoft.SemanticKernel;
using System.ComponentModel;
namespace stu
{
public class EmailTools
{
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="email"></param>
/// <param name="title"></param>
/// <param name="content"></param>
/// <returns></returns>
[KernelFunction, Description("发送邮件")]
public string SendEmail([Description("接收人")] string email, [Description("邮件主题")] string title,
[Description("邮件内容")] string? content)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"发送邮件给 {email} 主题:{title} 内容:{content}");
Console.ForegroundColor = ConsoleColor.White;
// 这里模拟发送邮件
return "邮件发送成功";
}
}
}
OpenAIHttpClientHandler.cs
namespace stu
{
/// <summary>
/// OpenAI客户端
/// </summary>
public class OpenAIHttpClientHandler : HttpClientHandler
{
private readonly string _uri;
public OpenAIHttpClientHandler(string uri) => _uri = uri.TrimEnd('/');
/// <summary>
/// 发送消息
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
UriBuilder uriBuilder;
if (request.RequestUri?.LocalPath == "/v1/chat/completions")
{
uriBuilder = new UriBuilder(_uri + "/v1/chat/completions");
request.RequestUri = uriBuilder.Uri;
}
else if (request.RequestUri?.LocalPath == "/v1/embeddings")
{
uriBuilder = new UriBuilder(_uri + "/v1/embeddings");
request.RequestUri = uriBuilder.Uri;
}
return await base.SendAsync(request, cancellationToken);
}
}
}
调用
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System.Text;
namespace stu
{
internal class Program
{
static async Task Main(string[] args)
{
var modelName = "qwen2.5";
//modelName = "qwq";
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: modelName,
apiKey: "sddssd",
httpClient: new HttpClient(new OpenAIHttpClientHandler("http://127.0.0.1:11434")))
.Build();
kernel.Plugins.AddFromType<EmailTools>();
var emailPrompt =
@"
## 需求:
- 我需要解决用户发送邮件问题,邮件参数包含以下参数
- 收件人邮箱
- required
- email
- 邮件主题
- required
- 长度限制 100
- title
- 邮件内容
- content
- required
- 在上面的参数如果是required则是必须的,如果用户没有提供那么你需要提示用户缺少哪些参数。
- 如果用户提供了参数,您需要提示不合法的参数,你不要提供测试用例,你需要提示用户哪些参数不合法。
- 上面要求都满足以后,需要提问用户是否确认发送,如果用户确认发送,那么你需要调用发送邮件。
";
var chatHistory = new ChatHistory();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
StringBuilder resultContent = new StringBuilder();
while (true)
{
Console.Write("用户 > ");
var input = Console.ReadLine();
if (input == "/bye")
{
Console.WriteLine("再见~~");
break;
}
chatHistory.AddUserMessage(input);
// 流式输出
var settings = new OpenAIPromptExecutionSettings()
{
ChatSystemPrompt = emailPrompt,
MaxTokens = 50000,
Temperature = 0.5,
TopP = 1,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
Console.Write($"\n助手 >");
resultContent.Clear();
await foreach (var message in chatCompletionService
.GetStreamingChatMessageContentsAsync(chatHistory,settings,kernel))
{
Console.Write(message.Content);
resultContent.Append(message.Content);
}
Console.Write("\n");
chatHistory.AddAssistantMessage(resultContent.ToString());
}
Console.ReadKey();
}
}
}
更多推荐
所有评论(0)