You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> OpenAI Responses introduced a new conversation model that simplifies how conversations are handled. This simplifies hosted thread management compared to the now deprecated OpenAI Assistants model. For more information see the [OpenAI Assistants migration guide](https://platform.openai.com/docs/assistants/migration).
@@ -150,7 +150,7 @@ In semantic kernel to expose a function as a tool you must:
@@ -297,13 +297,338 @@ Semantic kernel provides specific agent classes for various services, e.g.
297
297
298
298
#### Agent Framework
299
299
300
-
The agent framework supports all the abovementioned services via a single agent type, `ChatClientAgent`.
300
+
The agent framework supports all the above mentioned services via a single agent type, `ChatClientAgent`.
301
301
302
302
`ChatClientAgent` can be used to build agents using any underlying service that provides an SDK implementing the `Microsoft.Extensions.AI.IChatClient` interface.
303
303
304
304
::: zone-end
305
305
::: zone pivot="programming-language-python"
306
306
307
+
## Key differences
308
+
309
+
Here is a summary of the key differences between the Semantic Kernel Agent Framework and the Microsoft Agent Framework to help you migrate your code.
310
+
311
+
### 1. Package and Import Updates
312
+
313
+
#### Semantic Kernel
314
+
315
+
Semantic Kernel packages are installed as `semantic-kernel` and imported as `semantic_kernel`. The package also has a number of `extras` that you can install to install the different dependencies for different AI providers and other features.
316
+
317
+
```python
318
+
from semantic_kernel import Kernel
319
+
from semantic_kernel.agents import ChatCompletionAgent
320
+
```
321
+
322
+
#### Agent Framework
323
+
324
+
Agent Framework package is installed as `agent-framework` and imported as `agent_framework`.
325
+
Agent Framework is built up differently, it has a core package `agent-framework-core` that contains the core functionality, and then there are multiple packages that rely on that core package, such as `agent-framework-azure-ai`, `agent-framework-mem0`, `agent-framework-copilotstudio`, etc. When you run `pip install agent-framework` it will install the core package and *all* packages, so that you can get started with all the features quickly. When you are ready to reduce the number of packages because you know what you need, you can install only the packages you need, so for instance if you only plan to use Azure AI Foundry and Mem0 you can install only those two packages: `pip install agent-framework-azure-ai agent-framework-mem0`, `agent-framework-core` is a dependency to those two, so will automatically be installed.
326
+
327
+
Even though the packages are split up, the imports are all from `agent_framework`, or it's modules. So for instance to import the client for Azure AI Foundry you would do:
328
+
329
+
```python
330
+
from agent_framework.azure import AzureAIAgentClient
331
+
```
332
+
333
+
Many of the most commonly used types are imported directly from `agent_framework`:
334
+
335
+
```python
336
+
from agent_framework import ChatMessage, ChatAgent
337
+
```
338
+
339
+
### 2. Agent Type Consolidation
340
+
341
+
#### Semantic Kernel
342
+
Semantic Kernel provides specific agent classes for various services, e.g. ChatCompletionAgent, AzureAIAgent, OpenAIAssistantAgent, etc. See [Agent types in Semantic Kernel](/semantic-kernel/agents/agent-types).
343
+
344
+
#### Agent Framework
345
+
In Agent Framework the majority of agents are built using the `ChatAgent` which can be used with all the `ChatClient` based services, such as Azure AI Foundry, OpenAI ChatCompletion and OpenAI Responses. We currently have two other agents, `CopilotStudioAgent` for use with Copilot Studio and `A2AAgent` for use with A2A.
346
+
347
+
All the built-in agents are based on the BaseAgent (`from agent_framework import BaseAgent`). And all agents are consistent with the `AgentProtocol` (`from agent_framework import AgentProtocol`) interface.
348
+
349
+
### 2. Agent Creation Simplification
350
+
351
+
#### Semantic Kernel
352
+
353
+
Every agent in Semantic Kernel depends on a `Kernel` instance and will have
354
+
an empty `Kernel` if not provided.
355
+
356
+
```python
357
+
from semantic_kernel.agents import ChatCompletionAgent
358
+
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
359
+
360
+
agent = ChatCompletionAgent(
361
+
service=OpenAIChatCompletion(),
362
+
name="Support",
363
+
instructions="Answer in one sentence.",
364
+
)
365
+
```
366
+
367
+
368
+
#### Agent Framework
369
+
370
+
Agent creation in Agent Framework can be done in two ways, directly:
371
+
372
+
```python
373
+
from agent_framework.azure import AzureAIAgentClient
374
+
from agent_framework import ChatMessage, ChatAgent
375
+
376
+
agent = ChatAgent(chat_client=AzureAIAgentClient(credential=AzureCliCredential()), instructions="You are a helpful assistant")
377
+
```
378
+
or, with the convenience methods provided by chat clients:
379
+
380
+
```python
381
+
from agent_framework.azure import AzureOpenAIChatClient
382
+
from azure.identity import AzureCliCredential
383
+
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(instructions="You are a helpful assistant")
384
+
```
385
+
386
+
The direct method, exposes all possible parameters you can set for your agent, while the convenience method has a subset, you can still pass in the same set of parameters, because internally we call the direct method.
387
+
388
+
### 3. Agent Thread Creation
389
+
390
+
#### Semantic Kernel
391
+
392
+
The caller has to know the thread type and create it manually.
393
+
394
+
```python
395
+
from semantic_kernel.agents import ChatHistoryAgentThread
396
+
397
+
thread = ChatHistoryAgentThread()
398
+
```
399
+
400
+
#### Agent Framework
401
+
402
+
The agent can be asked to create a new thread for you.
403
+
404
+
```python
405
+
agent =...
406
+
thread = agent.get_new_thread()
407
+
```
408
+
409
+
a thread is then created in one of three ways:
410
+
1. if the agent has a thread_id (or conversation_id or something similar) set, it will create a thread in the underlying service with that id.
411
+
Once a thread has a `service_thread_id`, you can no longer use it to store messages in memory.
412
+
And this only applies to agents that have a service-side thread concept. such as Azure AI Foundry Agents and OpenAI Assistants.
413
+
2. if the agent has a `chat_message_store_factory` set, it will use that factory to create a message store and use that to create an in-memory thread.
414
+
It can then no longer be used with a agent with the `store` parameter set to `True`.
415
+
3. if neither of the above is set, we consider it `uninitialized` and depending on how it is used, it will either become a in-memory thread or a service thread.
416
+
417
+
#### Agent Framework
418
+
419
+
> [!NOTE]
420
+
> OpenAI Responses introduced a new conversation model that simplifies how conversations are handled. This simplifies hosted thread management compared to the now deprecated OpenAI Assistants model. For more information see the [OpenAI Assistants migration guide](https://platform.openai.com/docs/assistants/migration).
421
+
422
+
Agent Framework doesn't have a thread deletion API in the `AgentThread` type as not all providers support hosted threads or thread deletion and this will become more common as more providers shift to responses based architectures.
423
+
424
+
If you require thread deletion and the provider allows this, the caller **should** keep track of the created threads and delete them later when necessary via the provider's sdk.
425
+
426
+
i.e: OpenAI Assistants Provider
427
+
```python
428
+
# OpenAI Assistants threads have self-deletion method in SK
429
+
await thread.delete_async()
430
+
```
431
+
432
+
### 5. Tool Registration
433
+
434
+
#### Semantic Kernel
435
+
436
+
In semantic kernel to expose a function as a tool you must:
437
+
438
+
1. Decorate the function with a `@kernel_function` decorator.
439
+
2. Have a `Plugin` class or use the kernel plugin factory to wrap the function.
440
+
3. Have a `Kernel` to add your plugin to.
441
+
4. Pass the `Kernel` to the agent.
442
+
443
+
```python
444
+
from semantic_kernel.functions import kernel_function
In agent framework in a single call you can register tools directly in the agent creation process. But we no longer have the concept of a plugin, to wrap multiple functions, but you can still do that if you want to.
462
+
463
+
The simplest way to create a tool is just to create a python function:
> Note: the `tools` parameter is present on both the agent creation, the `run` and `run_stream` methods, as well as the `get_response` and `get_streaming_response` methods, it allows you to supply tools both as a list or a single function.
473
+
474
+
The name of the function will then become the name of the tool, and the docstring will become the description of the tool, you can also add a description to the parameters:
475
+
476
+
```python
477
+
from typing import Annotated
478
+
479
+
defget_weather(location: Annotated[str, "The location to get the weather for."]) -> str:
480
+
"""Get the weather for a given location."""
481
+
returnf"The weather in {location} is sunny."
482
+
```
483
+
484
+
Finally, you can use the decorator to further customize the name and description of the tool:
485
+
486
+
```python
487
+
from typing import Annotated
488
+
from agent_framework import ai_function
489
+
490
+
@ai_function(name="weather_tool", description="Retrieves weather information for any location")
491
+
defget_weather(location: Annotated[str, "The location to get the weather for."])
492
+
"""Get the weather for a given location."""
493
+
returnf"The weather in {location} is sunny."
494
+
```
495
+
496
+
This also works when you create a class with multiple tools as methods.
497
+
498
+
When creating the agent, we can now provide the function tool to the agent, by passing it to the `tools` parameter.
499
+
500
+
```python
501
+
classPlugin:
502
+
503
+
def__init__(self, initial_state: str):
504
+
self.state: list[str] = [initial_state]
505
+
506
+
defget_weather(self, location: Annotated[str, "The location to get the weather for."]) -> str:
507
+
"""Get the weather for a given location."""
508
+
self.state.append(f"Requested weather for {location}. ")
509
+
returnf"The weather in {location} is sunny."
510
+
511
+
defget_weather_details(self, location: Annotated[str, "The location to get the weather details for."]) -> str:
512
+
"""Get detailed weather for a given location."""
513
+
self.state.append(f"Requested detailed weather for {location}. ")
514
+
returnf"The weather in {location} is sunny with a high of 25°C and a low of 15°C."
> Note: the functions within the class can also be decorated with `@ai_function` to customize the name and description of the tools.
524
+
525
+
This mechanism is also useful for tools that need additional input that cannot be supplied by the LLM, such as connections, secrets, etc.
526
+
527
+
### 6. Agent Non-Streaming Invocation
528
+
529
+
Key differences can be seen in the method names from `invoke` to `run`, return types (e.g. `AgentRunResponse`) and parameters.
530
+
531
+
#### Semantic Kernel
532
+
533
+
The Non-Streaming invoke uses an async iterator pattern for returning multiple agent messages.
534
+
535
+
```python
536
+
asyncfor response in agent.invoke(
537
+
messages=user_input,
538
+
thread=thread,
539
+
):
540
+
print(f"# {response.role}: {response}")
541
+
thread = response.thread
542
+
```
543
+
And we had a convenience method to get the final response:
544
+
```python
545
+
response =await agent.get_response(messages="How do I reset my bike tire?", thread=thread)
546
+
print(f"# {response.role}: {response}")
547
+
```
548
+
549
+
#### Agent Framework
550
+
551
+
The Non-Streaming run returns a single `AgentRunResponse` with the agent response that can contain multiple messages.
552
+
The text result of the run is available in `response.text` or `str(response)`.
553
+
All messages created as part of the response are returned in the `response.messages` list.
554
+
This may include tool call messages, function results, reasoning updates and final results.
555
+
556
+
```python
557
+
agent =...
558
+
559
+
response =await agent.run(user_input, thread)
560
+
print("Agent response:", response.text)
561
+
562
+
```
563
+
564
+
### 7. Agent Streaming Invocation
565
+
566
+
Key differences in the method names from `invoke` to `run_stream`, return types (`AgentRunResponseUpdate`) and parameters.
567
+
568
+
#### Semantic Kernel
569
+
570
+
```python
571
+
asyncfor update in agent.invoke_stream(
572
+
messages="Draft a 2 sentence blurb.",
573
+
thread=thread,
574
+
):
575
+
if update.message:
576
+
print(update.message.content, end="", flush=True)
577
+
```
578
+
579
+
#### Agent Framework
580
+
581
+
Similar streaming API pattern with the key difference being that it returns `AgentRunResponseUpdate` objects including more agent related information per update.
582
+
583
+
All contents produced by any service underlying the Agent are returned. The final result of the agent is available by combining the `update` values into a single response.
584
+
585
+
```python
586
+
from agent_framework import AgentRunResponse
587
+
agent =...
588
+
updates = []
589
+
asyncfor update in agent.run_stream(user_input, thread):
In agent framework, we allow the passing of all parameters directly to the relevant methods, so that you do not have to import anything extra, or create any options objects, unless you want to. Internally we use a `ChatOptions` object for `ChatClients` and `ChatAgents`, that you can also create and pass in if you want to. This is also created in a `ChatAgent` to hold the options and can be overridden per call.
> Note: The above is specific to a `ChatAgent`, because other agents may have different options, they should all accepts `messages` as a parameter, since that is defined in the `AgentProtocol`.
Copy file name to clipboardExpand all lines: agent-framework/migration-guide/from-semantic-kernel/samples.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,6 +18,6 @@ See the [Agent Framework repository](https://github.com/microsoft/agent-framewor
18
18
::: zone-end
19
19
::: zone pivot="programming-language-python"
20
20
21
-
Samples coming soon.
21
+
See the [Agent Framework repository](https://github.com/microsoft/agent-framework/tree/main/python/samples/semantic-kernel-migration) for detailed per agent type code samples showing the the Agent Framework equivalent code for Semantic Kernel features.
0 commit comments