Skip to content

Commit

Permalink
Merge pull request #47 from cnblogs/support-tool-choice
Browse files Browse the repository at this point in the history
feat: support tool choice
  • Loading branch information
ikesnowy authored Nov 25, 2024
2 parents fc07638 + 4984ab8 commit f83e1e0
Show file tree
Hide file tree
Showing 19 changed files with 354 additions and 75 deletions.
15 changes: 15 additions & 0 deletions src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Marks parameter supports setting maximum number of output tokens.
/// </summary>
public interface IMaxTokenParameter
{
/// <summary>
/// The maximum number of tokens the model can generate.
/// </summary>
/// <remarks>
/// Default and maximum number of tokens is 1500(qwen-turbo) or 2000(qwen-max, qwen-max-1201, qwen-max-longcontext, qwen-plus).
/// </remarks>
public int? MaxTokens { get; }
}
10 changes: 9 additions & 1 deletion src/Cnblogs.DashScope.Core/IMultimodalParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@
/// <summary>
/// Optional parameters for multi-model generation request.
/// </summary>
public interface IMultimodalParameters : IProbabilityParameter, ISeedParameter, IIncrementalOutputParameter;
public interface IMultimodalParameters
: IProbabilityParameter, ISeedParameter, IIncrementalOutputParameter, IPenaltyParameter, IMaxTokenParameter,
IStopTokenParameter
{
/// <summary>
/// Allow higher resolution for inputs. When setting to <c>true</c>, increases the maximum input token from 1280 to 16384. Defaults to <c>false</c>.
/// </summary>
public bool? VlHighResolutionImages { get; }
}
18 changes: 18 additions & 0 deletions src/Cnblogs.DashScope.Core/IPenaltyParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Marks parameter accepts presence_penalty and repetition_penalty options.
/// </summary>
public interface IPenaltyParameter
{
/// <summary>
/// Increasing the repetition penalty can reduce the amount of repetition in the model’s output. A value of 1.0 indicates no penalty, with the default set at 1.1.
/// </summary>
public float? RepetitionPenalty { get; }

/// <summary>
/// Control the content repetition in text generated by the model.
/// </summary>
/// <remarks>Must be in [-2.0, 2.0]. Use higher penalty for batter creativity.</remarks>
public float? PresencePenalty { get; }
}
8 changes: 7 additions & 1 deletion src/Cnblogs.DashScope.Core/IProbabilityParameter.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Marks parameter accepts top_p and top_k options.
/// Marks parameter accepts top_p, top_k and temperature options.
/// </summary>
public interface IProbabilityParameter
{
Expand All @@ -16,4 +16,10 @@ public interface IProbabilityParameter
/// </summary>
/// <remarks>top_k would been disabled if applied null or any value larger than 100.</remarks>
public int? TopK { get; }

/// <summary>
/// Controls the diversity of generations. Lower temperature leads to more consistent result.
/// </summary>
/// <remarks>Must be in [0,2), qwen-max defaults to 0.7.</remarks>
public float? Temperature { get; }
}
12 changes: 12 additions & 0 deletions src/Cnblogs.DashScope.Core/IStopTokenParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Marks parameter supports setting stop tokens.
/// </summary>
public interface IStopTokenParameter
{
/// <summary>
/// Stop generation when next token or string is in given range.
/// </summary>
public TextGenerationStop? Stop { get; }
}
34 changes: 8 additions & 26 deletions src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
/// <summary>
/// The text generation options.
/// </summary>
public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter
public interface ITextGenerationParameters
: IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter, IPenaltyParameter, IMaxTokenParameter, IStopTokenParameter
{
/// <summary>
/// The format of the result message, must be <c>text</c> or <c>message</c>.
Expand All @@ -14,30 +15,6 @@ public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedP
/// </remarks>
public string? ResultFormat { get; }

/// <summary>
/// The maximum number of tokens the model can generate.
/// </summary>
/// <remarks>
/// Default and maximum number of tokens is 1500(qwen-turbo) or 2000(qwen-max, qwen-max-1201, qwen-max-longcontext, qwen-plus).
/// </remarks>
public int? MaxTokens { get; }

/// <summary>
/// Increasing the repetition penalty can reduce the amount of repetition in the model’s output. A value of 1.0 indicates no penalty, with the default set at 1.1.
/// </summary>
public float? RepetitionPenalty { get; }

/// <summary>
/// Controls the diversity of generations. Lower temperature leads to more consistent result.
/// </summary>
/// <remarks>Must be in [0,2), defaults to 0.85.</remarks>
public float? Temperature { get; }

/// <summary>
/// Stop generation when next token or string is in given range.
/// </summary>
public TextGenerationStop? Stop { get; }

/// <summary>
/// Enable internet search when generation. Defaults to false.
/// </summary>
Expand All @@ -46,5 +23,10 @@ public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedP
/// <summary>
/// Available tools for model to call.
/// </summary>
public List<ToolDefinition>? Tools { get; }
public IEnumerable<ToolDefinition>? Tools { get; }

/// <summary>
/// Behavior when choosing tools.
/// </summary>
public ToolChoice? ToolChoice { get; }
}
18 changes: 18 additions & 0 deletions src/Cnblogs.DashScope.Core/MultimodalParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,27 @@ public class MultimodalParameters : IMultimodalParameters
/// <inheritdoc />
public int? TopK { get; set; }

/// <inheritdoc />
public float? Temperature { get; set; }

/// <inheritdoc />
public ulong? Seed { get; set; }

/// <inheritdoc />
public bool? IncrementalOutput { get; set; }

/// <inheritdoc />
public bool? VlHighResolutionImages { get; set; }

/// <inheritdoc />
public float? RepetitionPenalty { get; set; }

/// <inheritdoc />
public float? PresencePenalty { get; set; }

/// <inheritdoc />
public int? MaxTokens { get; set; }

/// <inheritdoc />
public TextGenerationStop? Stop { get; set; }
}
8 changes: 7 additions & 1 deletion src/Cnblogs.DashScope.Core/TextGenerationParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public class TextGenerationParameters : ITextGenerationParameters
/// <inheritdoc />
public float? RepetitionPenalty { get; set; }

/// <inheritdoc />
public float? PresencePenalty { get; set; }

/// <inheritdoc />
public float? Temperature { get; set; }

Expand All @@ -33,7 +36,10 @@ public class TextGenerationParameters : ITextGenerationParameters
public bool? EnableSearch { get; set; }

/// <inheritdoc />
public List<ToolDefinition>? Tools { get; set; }
public IEnumerable<ToolDefinition>? Tools { get; set; }

/// <inheritdoc />
public ToolChoice? ToolChoice { get; set; }

/// <inheritdoc />
public bool? IncrementalOutput { get; set; }
Expand Down
47 changes: 47 additions & 0 deletions src/Cnblogs.DashScope.Core/ToolChoice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Text.Json.Serialization;

namespace Cnblogs.DashScope.Core;

/// <summary>
/// Specify the behavior for model when tools are applied.
/// </summary>
[JsonConverter(typeof(ToolChoiceJsonConverter))]
public record ToolChoice
{
/// <summary>
/// Make sure tool choices can not be initiated directly.
/// </summary>
private ToolChoice(string type, ToolChoiceFunction? function = null)
{
Type = type;
Function = function;
}

/// <summary>
/// The type of tool choice.
/// </summary>
public string Type { get; }

/// <summary>
/// The function that model must call.
/// </summary>
public ToolChoiceFunction? Function { get; }

/// <summary>
/// Model can not call any tools.
/// </summary>
public static readonly ToolChoice NoneChoice = new("none");

/// <summary>
/// Model can freely pick between generating a message or calling one or more tools.
/// </summary>
public static readonly ToolChoice AutoChoice = new("auto");

/// <summary>
/// Model must call function with specified name.
/// </summary>
/// <param name="functionName">Name of function.</param>
/// <returns></returns>
public static ToolChoice FunctionChoice(string functionName)
=> new("function", new ToolChoiceFunction(functionName));
}
7 changes: 7 additions & 0 deletions src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Cnblogs.DashScope.Core;

/// <summary>
/// Represents functions that model must call.
/// </summary>
/// <param name="Name">The name of the function.</param>
public record ToolChoiceFunction(string Name);
69 changes: 69 additions & 0 deletions src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Cnblogs.DashScope.Core;

/// <summary>
/// The converter for <see cref="ToolChoice"/>
/// </summary>
public class ToolChoiceJsonConverter : JsonConverter<ToolChoice>
{
/// <inheritdoc />
public override ToolChoice? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var str = reader.GetString();
return str switch
{
"auto" => ToolChoice.AutoChoice,
"none" => ToolChoice.NoneChoice,
_ => throw new JsonException("Unknown tool choice type")
};
}

if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Unknown tool choice.");
}

var element = JsonSerializer.Deserialize<JsonElement>(ref reader, options);
var functionValid = element.TryGetProperty("function", out var function);
var typeValid = element.TryGetProperty("type", out var type);
if (functionValid == false || typeValid == false || type.ValueKind != JsonValueKind.String)
{
throw new JsonException("Unknown tool choice type");
}

var toolFunction = function.Deserialize<ToolChoiceFunction>(options);
var toolChoiceType = type.GetString();
if (toolFunction == null || toolChoiceType != "function")
{
throw new JsonException("Unknown tool choice type");
}

return ToolChoice.FunctionChoice(toolFunction.Name);
}

/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, ToolChoice value, JsonSerializerOptions options)
{
if (value.Type != "function")
{
writer.WriteStringValue(value.Type);
}
else
{
writer.WriteStartObject();
writer.WriteString("type", value.Type);
writer.WritePropertyName("function");
JsonSerializer.Serialize(writer, value.Function, options);
writer.WriteEndObject();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
"parameters": {
"seed": 1234,
"top_k": 100,
"top_p": 0.81
"top_p": 0.81,
"vl_high_resolution_images": true,
"temperature": 1.1,
"repetition_penalty": 1.3,
"presence_penalty": 1.2,
"max_tokens": 120,
"stop": "你好"
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":[{"text":"这张照片显示的是海滩景色,但是无法确定具体的位置信息。图中有一名女子和一只狗在沙滩上互动。背景中有海洋和日出或日落的光线。由于缺乏特定地标或者细节特征,仅凭此图像很难精确识别具体的地点。"}]}}]},"usage":{"output_tokens":58,"input_tokens":1284,"image_tokens":1247},"request_id":"a2a5f2e6-c6d7-9e04-9f92-1d3eee274198"}
{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":[{"text":"这是在海滩上。"}]}}]},"usage":{"output_tokens":6,"input_tokens":3613,"image_tokens":3577},"request_id":"e74b364a-034f-9d0d-8e55-8e5b3580045f"}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
HTTP/1.1 200 OK
eagleeye-traceid: cf6954f685a19435530858304250b3bc
content-type: application/json
HTTP/1.1 200 OK
eagleeye-traceid: c72728928fd0d00883f6edd204cc6721
Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Encoding
X-Request-ID: e74b364a-034f-9d0d-8e55-8e5b3580045f
x-dashscope-timeout: 180
x-dashscope-call-gateway: true
req-cost-time: 4359
req-arrive-time: 1709019927268
resp-start-time: 1709019931627
x-envoy-upstream-service-time: 4353
content-encoding: gzip
vary: Accept-Encoding
date: Tue, 27 Feb 2024 07:45:31 GMT
server: istio-envoy
transfer-encoding: chunked
x-dashscope-finished: true
req-cost-time: 3064
req-arrive-time: 1732531979928
resp-start-time: 1732531982993
x-envoy-upstream-service-time: 3054
Set-Cookie: acw_tc=e74b364a-034f-9d0d-8e55-8e5b3580045f47b5c24e3af603d8590358e45e4696a6;path=/;HttpOnly;Max-Age=1800
Date: Mon, 25 Nov 2024 10:53:02 GMT
Server: istio-envoy
Transfer-Encoding: chunked
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
"top_p": 0.8,
"top_k": 100,
"repetition_penalty": 1.1,
"presence_penalty": 1.2,
"temperature": 0.85,
"stop": [[37763, 367]],
"stop": "你好",
"enable_search": false,
"incremental_output": false,
"tools": [
Expand Down Expand Up @@ -46,6 +47,12 @@
}
}
}
]
],
"tool_choice": {
"type": "function",
"function": {
"name": "get_current_weather"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"output":{"choices":[{"finish_reason":"tool_calls","message":{"role":"assistant","tool_calls":[{"function":{"name":"get_current_weather","arguments":"{\"location\": \"浙江省杭州市\", \"unit\": \"Celsius\"}"},"id":"","type":"function"}],"content":""}}]},"usage":{"total_tokens":36,"output_tokens":31,"input_tokens":5},"request_id":"40b4361e-e936-91b5-879d-355a45d670f8"}
{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","tool_calls":[{"function":{"name":"get_current_weather","arguments":"{\"location\": \"浙江省杭州市\"}"},"index":0,"id":"call_cec4c19d27624537b583af","type":"function"}],"content":""}}]},"usage":{"total_tokens":219,"output_tokens":8,"input_tokens":211},"request_id":"67300049-c108-9987-b1c1-8e0ee2de6b5d"}
Loading

0 comments on commit f83e1e0

Please sign in to comment.