Skip to content

Commit bb6a802

Browse files
authored
Merge pull request #150 from hchen2020/master
RoutingSettings.Provider and Model.
2 parents a56d770 + 18eb9d6 commit bb6a802

File tree

13 files changed

+44
-29
lines changed

13 files changed

+44
-29
lines changed

docs/agent/router.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Router
2+
3+
This section will explain in detail the usage of Router. Router has a dedicated configuration node for customization.
4+
5+
```json
6+
"Router": {
7+
"RouterId": "",
8+
"Provider": "azure-openai",
9+
"Model": "gpt-4"
10+
}
11+
```

docs/architecture/routing.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
11
# Routing
22

3-
Routing is an important function that allows multiple Agents to work together to complete enterprise-level tasks. When you apply LLM to your business system, it is inevitable to develop agents with different functions. How to effectively manage so many agents with different responsibilities is a challenging task. From an engineering perspective, each Different teams are responsible for the development of different Agents, and the teams will face the problem of mutual isolation between Agents. The ideal situation is that they can be developed independently but cooperate with each other.
3+
Routing is an important function that allows multiple Agents to work together to complete enterprise-level tasks. When you apply LLM to your business system, it is inevitable to develop agents with different functions. How to effectively manage so many agents with different responsibilities is a challenging task. From an engineering perspective, each Different teams are responsible for the development of different Agents, and the teams will face the problem of mutual isolation between Agents. The ideal situation is that they can be developed independently but cooperate with each other.
4+
5+
## Router
6+
7+
The Routing feature is the core technology used by BotSharp to manage multiple Agents. BotSharp has a built-in intelligent Agent called `Router`. When you enable this function, all user requests will be pre-processed by the Router to determine which Agent to distribute the request to for processing. The advantage of Routing technology is that it can isolate different Agents and allow them to work together to achieve the user's goals. The adoption of `Routing` ensures that Agent can be scalable, flexible and robust enough in enterprise applications.
8+
9+
## Reasoner
10+
11+
For simple questions raised by users, the ordinary routing function can already handle it. However, for the scenario where the user has a long description and needs to disassemble the task, ordinary routing cannot handle it. At this time, the `Reasoning` feature needs to be turned on, and LLM will respond according to the problem. The complexity is broken down into different small tasks. These small tasks can be processed by the corresponding Agent. During the processing process, the Router will constantly adjust the next step plan to deal with the different results returned by the Agent.
12+
13+
14+
### How to register agent to router?
15+
16+
When you add a new Agent, the Router can automatically read the Agent's configuration, but in order for the Router to distribute the Request to the new Agent, you must set the `AllowRouting` attribute to `True`. For more information on how to use Router, please refer to the Agent/Router chapter.

docs/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ The main documentation for the site is organized into the following sections:
5252
agent/intro
5353
agent/conversation
5454
agent/state
55+
agent/router
5556

5657
.. _integration-docs:
5758

src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Text.Json.Serialization;
2-
31
namespace BotSharp.Abstraction.Conversations.Models;
42

53
public class IncomingMessageModel

src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionCallFromLlm.cs

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using BotSharp.Abstraction.Routing.Models;
2-
using System.Text.Json;
3-
using System.Text.Json.Serialization;
42

53
namespace BotSharp.Abstraction.Functions.Models;
64

src/Infrastructure/BotSharp.Abstraction/Routing/Models/RetrievalArgs.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Text.Json;
2-
using System.Text.Json.Serialization;
32

43
namespace BotSharp.Abstraction.Routing.Models;
54

@@ -19,6 +18,6 @@ public class RetrievalArgs : RoutingArgs
1918

2019
public override string ToString()
2120
{
22-
return $" [{AgentName}]: {Question} ({JsonSerializer.Serialize(Arguments)}) => {Answer} ({Reason})";
21+
return $"[{AgentName}, {Reason}]: ({JsonSerializer.Serialize(Arguments)}) {Question}";
2322
}
2423
}

src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs

+4
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ public class RoutingSettings
88
public string RouterId { get; set; } = string.Empty;
99

1010
public bool EnableReasoning { get; set; } = false;
11+
12+
public string Provider { get; set; } = string.Empty;
13+
14+
public string Model { get; set; } = string.Empty;
1115
}

src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public string GetState(string name, string defaultValue = "")
126126
_states[name] = defaultValue ?? "";
127127
}
128128

129-
if (_states[name] == null)
129+
if (string.IsNullOrEmpty(_states[name]))
130130
{
131131
return defaultValue;
132132
}

src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ public static IChatCompletion GetChatCompletion(IServiceProvider services, strin
1010

1111
var state = services.GetRequiredService<IConversationStateService>();
1212

13-
if (provider == null)
13+
if (string.IsNullOrEmpty(provider))
1414
{
1515
provider = state.GetState("provider", "azure-openai");
1616
}
1717

18-
if (model == null)
18+
if (string.IsNullOrEmpty(model))
1919
{
2020
model = state.GetState("model", "gpt-3.5-turbo");
2121
}

src/Infrastructure/BotSharp.Core/Routing/Prompts/router_prompt.liquid

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ You're a Agent Router with reasoning, you can dispatch request to different agen
1111
Route request to appropriate agent.
1212
Parameters:
1313
1. agent_name: the name of the agent;
14+
2. reason: why route to this agent;
1415

1516
# task_end
1617
Call this function when current task is completed.

src/Infrastructure/BotSharp.Core/Routing/ReasoningHook.cs

-14
This file was deleted.

src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ private bool HasMissingRequiredField(RoleDialogModel message, out string agentId
103103
// Add field to args
104104
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "missing_fields", missingFields);
105105
message.ExecutionResult = $"missing some information: {string.Join(',', missingFields)}";
106+
message.Content = message.ExecutionResult;
106107

107108
// Handle redirect
108109
var routingRule = routingRules.FirstOrDefault(x => missingFields.Contains(x.Field));
@@ -113,6 +114,7 @@ private bool HasMissingRequiredField(RoleDialogModel message, out string agentId
113114

114115
// Add redirected agent
115116
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", record.Name);
117+
agentId = routingRule.RedirectTo;
116118
}
117119
else
118120
{

src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs

+7-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public async Task<RoleDialogModel> Enter(Agent agent, List<RoleDialogModel> whil
3232
_dialogs = new List<RoleDialogModel>();
3333
RoleDialogModel result = new RoleDialogModel(AgentRole.Assistant, "not handled");
3434

35-
foreach (var dialog in whileDialogs.TakeLast(10))
35+
foreach (var dialog in whileDialogs.TakeLast(20))
3636
{
3737
agent.Instruction += $"\r\n{dialog.Role}: {dialog.Content}";
3838
}
@@ -120,13 +120,15 @@ public async Task<RoleDialogModel> Enter(Agent agent, List<RoleDialogModel> whil
120120

121121
private async Task<FunctionCallFromLlm> GetNextInstructionFromReasoner(Agent reasoner)
122122
{
123-
var responseFormat = "{\"function\": \"\", \"parameters\": {\"agent_name\": \"\", \"args\":{}}";
123+
var responseFormat = "{\"function\": \"\", \"parameters\": {\"agent_name\": \"\", \"reason\":\"\", \"args\":{}}";
124124
var wholeDialogs = new List<RoleDialogModel>
125125
{
126-
new RoleDialogModel(AgentRole.User, $"What's the next step? Response in JSON format {responseFormat}.")
126+
new RoleDialogModel(AgentRole.System, $"What's the next step? Response in JSON format {responseFormat}.")
127127
};
128128

129-
var chatCompletion = CompletionProvider.GetChatCompletion(_services);
129+
var chatCompletion = CompletionProvider.GetChatCompletion(_services,
130+
provider: _settings.Provider,
131+
model: _settings.Model);
130132

131133
RoleDialogModel response = null;
132134
await chatCompletion.GetChatCompletionsAsync(reasoner, wholeDialogs, async msg
@@ -142,7 +144,7 @@ await chatCompletion.GetChatCompletionsAsync(reasoner, wholeDialogs, async msg
142144

143145
args.Function = args.Function.Split('.').Last();
144146

145-
_logger.LogInformation($"Next Instruction: {args}");
147+
_logger.LogInformation($"*** Next Instruction *** {args}");
146148

147149
return args;
148150
}

0 commit comments

Comments
 (0)