-
Notifications
You must be signed in to change notification settings - Fork 1k
Python: ADR for Client Composition #3177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,140 @@ | ||||||
| --- | ||||||
| status: proposed | ||||||
| contact: eavanvalkenburg | ||||||
| date: 2026-01-12 | ||||||
| deciders: eavanvalkenburg, markwallace-microsoft, sphenry, alliscode, johanst, brettcannon | ||||||
| consulted: taochenosu, moonbox3, dmytrostruk, giles17 | ||||||
| --- | ||||||
|
|
||||||
| # Python Client and Agent Composition | ||||||
|
|
||||||
| ## Context and Problem Statement | ||||||
|
|
||||||
| In Python we currently use a set of decorators that can be applied to ChatClients and Agents, those are for function calling, telemetry and middleware. However we currently do not allow a user to compose these themselves, for example to create a ChatClient that does not do function calling, but does have tools being passed to a API. Or to only have telemetry enabled on a chat client, but not on the agent. Up unto this point, that has been a sensible decision because it makes getting started very easy. However as we add more features, and more ways to customize the behavior of clients and agents, this becomes a limitation. | ||||||
|
||||||
| In Python we currently use a set of decorators that can be applied to ChatClients and Agents, those are for function calling, telemetry and middleware. However we currently do not allow a user to compose these themselves, for example to create a ChatClient that does not do function calling, but does have tools being passed to a API. Or to only have telemetry enabled on a chat client, but not on the agent. Up unto this point, that has been a sensible decision because it makes getting started very easy. However as we add more features, and more ways to customize the behavior of clients and agents, this becomes a limitation. | |
| In Python we currently use a set of decorators that can be applied to ChatClients and Agents, those are for function calling, telemetry and middleware. However we currently do not allow a user to compose these themselves, for example to create a ChatClient that does not do function calling, but does have tools being passed to an API. Or to only have telemetry enabled on a chat client, but not on the agent. Up until this point, that has been a sensible decision because it makes getting started very easy. However as we add more features, and more ways to customize the behavior of clients and agents, this becomes a limitation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that in all these options except current one (Option 1), we will also need to decide which decorators makes sense to enable out of the box and which decorators delegate to the user for registration. For example, when using OpenAIChatClient, I think that function calling should be enabled by default. For a couple of reasons:
- We have dedicated parameter
toolsthrough the codebase and on abstraction level, so it would be strange if it won't work because the decorator is not applied, even though the parameter is there. - I think OpenAI Chat Client will be used more with
toolsrather than without tools.
So, maybe it makes sense to use some combined approach where we decide which decorators we enable by default and which we allow users to decide (in which case we expose it based on the approach we select here).
If it makes sense, it's probably worth to update the document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I've been thinking about doing a CodeMode function calling feature, in which case even that one would be a choice. I'll also check his dotnet handles this, because we don't want a verbose or unexpected getting started experience
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer Option 3 and Option 4, and if choosing between them, I think Option 3 looks more Pythonic but wondering what other people think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use method accept ChatClient implementation instead of wrapper, so we can have FunctionInvokingChatClient, TelemetryChatClient and so on? With this approach, users will operate with chat clients only without a need to learn about new wrapper abstraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can name the wrappers with names like that? Or is that not what you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an extra space in the deciders list after 'markwallace-microsoft,'. The spacing should be consistent (single space after commas throughout).