Skip to content

Commit 0ae02b6

Browse files
Merge pull request #809 from MicrosoftDocs/main
Merge main to live
2 parents 3a269a0 + 3b98458 commit 0ae02b6

36 files changed

Lines changed: 1155 additions & 317 deletions

agent-framework/docfx.json

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@
2121
]
2222
}
2323
],
24+
"ms.update-cycle": {
25+
"agent-framework/api-docs/*.md": "180-days",
26+
"agent-framework/api-docs/*.yml": "180-days",
27+
"agent-framework/tutorials/**/*.md": "180-days",
28+
"agent-framework/tutorials/**/*.yml": "180-days",
29+
"agent-framework/migration-guide/**/*.md": "180-days",
30+
"agent-framework/migration-guide/**/*.yml": "180-days",
31+
"agent-framework/overview/*.md": "180-days",
32+
"agent-framework/overview/*.yml": "180-days",
33+
"agent-framework/user-guide/**/*.md": "180-days",
34+
"agent-framework/user-guide/**/*.yml": "180-days",
35+
"agent-framework/integrations/*.md": "180-days",
36+
"agent-framework/integrations/*.yml": "180-days",
37+
"agent-framework/support/**/*.md": "180-days",
38+
"agent-framework/support/**/*.yml": "180-days"
39+
},
40+
2441
"resource": [
2542
{
2643
"files": [
@@ -49,7 +66,42 @@
4966
"feedback_system": "Standard",
5067
"permissioned-type": "public"
5168
},
52-
"fileMetadata": {},
69+
"fileMetadata": {
70+
"ms.collection": {
71+
"api-docs/**/*.md": "ce-skilling-ai-copilot",
72+
"api-docs/**/*.yml": "ce-skilling-ai-copilot",
73+
"integrations/**/*.md": "ce-skilling-ai-copilot",
74+
"integrations/**/*.yml": "ce-skilling-ai-copilot",
75+
"migration-guide/**/*.md": "ce-skilling-ai-copilot",
76+
"migration-guide/**/*.yml": "ce-skilling-ai-copilot",
77+
"overview/**/*.md": "ce-skilling-ai-copilot",
78+
"overview/**/*.yml": "ce-skilling-ai-copilot",
79+
"support/**/*.md": "ce-skilling-ai-copilot",
80+
"support/**/*.yml": "ce-skilling-ai-copilot",
81+
"tutorials/**/*.md": "ce-skilling-ai-copilot",
82+
"tutorials/**/*.yml": "ce-skilling-ai-copilot",
83+
"user-guide/**/*.md": "ce-skilling-ai-copilot",
84+
"user-guide/**/*.yml": "ce-skilling-ai-copilot",
85+
"index.yml": "ce-skilling-ai-copilot"
86+
},
87+
"ms.update-cycle": {
88+
"api-docs/**/*.md": "180-days",
89+
"api-docs/**/*.yml": "180-days",
90+
"integrations/**/*.md": "180-days",
91+
"integrations/**/*.yml": "180-days",
92+
"migration-guide/**/*.md": "180-days",
93+
"migration-guide/**/*.yml": "180-days",
94+
"overview/**/*.md": "180-days",
95+
"overview/**/*.yml": "180-days",
96+
"support/**/*.md": "180-days",
97+
"support/**/*.yml": "180-days",
98+
"tutorials/**/*.md": "180-days",
99+
"tutorials/**/*.yml": "180-days",
100+
"user-guide/**/*.md": "180-days",
101+
"user-guide/**/*.yml": "180-days",
102+
"index.yml": "180-days"
103+
}
104+
},
53105
"template": [],
54106
"dest": "agent-framework"
55107
}

agent-framework/overview/agent-framework-overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ and the same is expected for Agent Framework. Microsoft Agent Framework welcomes
5454
5555
## Installation
5656

57-
Python:
57+
:::no-loc text="Python:":::
5858

5959
```bash
6060
pip install agent-framework --pre
6161
```
6262

63-
.NET:
63+
:::no-loc text=".NET:":::
6464

6565
```dotnetcli
6666
dotnet add package Microsoft.Agents.AI

agent-framework/tutorials/agents/memory.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ This tutorial shows how to add memory to an agent by implementing an `AIContextP
1717
> [!IMPORTANT]
1818
> Not all agent types support `AIContextProvider`. This step uses a `ChatClientAgent`, which does support `AIContextProvider`.
1919
20-
2120
## Prerequisites
2221

2322
For prerequisites and installing NuGet packages, see the [Create and run a simple agent](./run-agent.md) step in this tutorial.
@@ -161,7 +160,7 @@ ChatClient chatClient = new AzureOpenAIClient(
161160

162161
AIAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions()
163162
{
164-
Instructions = "You are a friendly assistant. Always address the user by their name.",
163+
ChatOptions = new() { Instructions = "You are a friendly assistant. Always address the user by their name." },
165164
AIContextProviderFactory = ctx => new UserInfoMemory(
166165
chatClient.AsIChatClient(),
167166
ctx.SerializedState,

agent-framework/tutorials/agents/orchestrate-durable-agents.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,31 +235,31 @@ def agent_orchestration_workflow(context: df.DurableOrchestrationContext):
235235
Returns a dictionary with the original response and translations.
236236
"""
237237
input_text = context.get_input()
238-
238+
239239
# Step 1: Get the main agent's response
240240
main_agent = app.get_agent(context, "MyDurableAgent")
241241
main_response = yield main_agent.run(input_text)
242-
agent_response = main_response.get("response", "")
243-
242+
agent_response = main_response.text
243+
244244
# Step 2: Fan out - get the translation agents and run them concurrently
245245
french_agent = app.get_agent(context, "FrenchTranslator")
246246
spanish_agent = app.get_agent(context, "SpanishTranslator")
247-
247+
248248
parallel_tasks = [
249249
french_agent.run(agent_response),
250250
spanish_agent.run(agent_response)
251251
]
252-
252+
253253
# Step 3: Wait for both translation tasks to complete (fan-in)
254-
translations = yield context.task_all(parallel_tasks)
255-
254+
translations = yield context.task_all(parallel_tasks) # type: ignore
255+
256256
# Step 4: Combine results into a dictionary
257257
result = {
258258
"original": agent_response,
259-
"french": translations[0].get("response", ""),
260-
"spanish": translations[1].get("response", "")
259+
"french": translations[0].text,
260+
"spanish": translations[1].text
261261
}
262-
262+
263263
return result
264264
```
265265

agent-framework/tutorials/agents/third-party-chat-history-storage.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,20 +177,20 @@ using OpenAI;
177177
AIAgent agent = new AzureOpenAIClient(
178178
new Uri("https://<myresource>.openai.azure.com"),
179179
new AzureCliCredential())
180-
.GetChatClient("gpt-4o-mini")
181-
.CreateAIAgent(new ChatClientAgentOptions
182-
{
183-
Name = "Joker",
184-
Instructions = "You are good at telling jokes.",
185-
ChatMessageStoreFactory = ctx =>
186-
{
187-
// Create a new chat message store for this agent that stores the messages in a vector store.
188-
return new VectorChatMessageStore(
180+
.GetChatClient("gpt-4o-mini")
181+
.CreateAIAgent(new ChatClientAgentOptions
182+
{
183+
Name = "Joker",
184+
ChatOptions = new() { Instructions = "You are good at telling jokes." },
185+
ChatMessageStoreFactory = ctx =>
186+
{
187+
// Create a new chat message store for this agent that stores the messages in a vector store.
188+
return new VectorChatMessageStore(
189189
new InMemoryVectorStore(),
190190
ctx.SerializedState,
191191
ctx.JsonSerializerOptions);
192-
}
193-
});
192+
}
193+
});
194194
```
195195

196196
::: zone-end

agent-framework/user-guide/agents/agent-memory.md

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ Agent chat history and memory are crucial capabilities that allow agents to main
1717

1818
## Chat History
1919

20-
Various chat history storage options are supported by the Agent Framework. The available options vary by agent type and the underlying service(s) used to build the agent.
20+
Various chat history storage options are supported by Agent Framework. The available options vary by agent type and the underlying service(s) used to build the agent.
2121

22-
Here are the two main scenarios supported:
22+
The two main supported scenarios are:
2323

24-
1. **In-memory storage**: Agent is built on a service that does not support in-service storage of chat history (e.g. OpenAI Chat Completion). The Agent Framework will by default store the full chat history in-memory in the `AgentThread` object, but developers can provide a custom `ChatMessageStore` implementation to store chat history in a 3rd party store if required.
25-
1. **In-service storage**: Agent is built on a service that requires in-service storage of chat history (e.g. Azure AI Foundry Persistent Agents). The Agent Framework will store the id of the remote chat history in the `AgentThread` object and no other chat history storage options are supported.
24+
- **In-memory storage**: Agent is built on a service that doesn't support in-service storage of chat history (for example, OpenAI Chat Completion). By default, Agent Framework stores the full chat history in-memory in the `AgentThread` object, but developers can provide a custom `ChatMessageStore` implementation to store chat history in a third-party store if required.
25+
- **In-service storage**: Agent is built on a service that requires in-service storage of chat history (for example, Azure AI Foundry Persistent Agents). Agent Framework stores the ID of the remote chat history in the `AgentThread` object, and no other chat history storage options are supported.
2626

2727
### In-memory chat history storage
2828

29-
When using a service that does not support in-service storage of chat history, the Agent Framework will default to storing chat history in-memory in the `AgentThread` object. In this case, the full chat history that is stored in the thread object, plus any new messages, will be provided to the underlying service on each agent run. This allows for a natural conversational experience with the agent, where the caller only provides the new user message, and the agent only returns new answers, but the agent has access to the full conversation history and will use it when generating its response.
29+
When using a service that doesn't support in-service storage of chat history, Agent Framework defaults to storing chat history in-memory in the `AgentThread` object. In this case, the full chat history that's stored in the thread object, plus any new messages, will be provided to the underlying service on each agent run. This design allows for a natural conversational experience with the agent. The caller only provides the new user message, and the agent only returns new answers. But the agent has access to the full conversation history and will use it when generating its response.
3030

31-
When using OpenAI Chat Completion as the underlying service for agents, the following code will result in the thread object containing the chat history from the agent run.
31+
When using OpenAI Chat Completion as the underlying service for agents, the following code results in the thread object containing the chat history from the agent run.
3232

3333
```csharp
3434
AIAgent agent = new OpenAIClient("<your_api_key>")
@@ -38,18 +38,18 @@ AgentThread thread = agent.GetNewThread();
3838
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
3939
```
4040

41-
Where messages are stored in memory, it is possible to retrieve the list of messages from the thread and manipulate the mesages directly if required.
41+
Where messages are stored in memory, it's possible to retrieve the list of messages from the thread and manipulate the messages directly if required.
4242

4343
```csharp
4444
IList<ChatMessage>? messages = thread.GetService<IList<ChatMessage>>();
4545
```
4646

4747
> [!NOTE]
48-
> Retrieving messages from the `AgentThread` object in this way will only work if in-memory storage is being used.
48+
> Retrieving messages from the `AgentThread` object in this way only works if in-memory storage is being used.
4949
50-
#### Chat History reduction with In-Memory storage
50+
#### Chat history reduction with in-memory storage
5151

52-
The built-in `InMemoryChatMessageStore` that is used by default when the underlying service does not support in-service storage,
52+
The built-in `InMemoryChatMessageStore` that's used by default when the underlying service does not support in-service storage,
5353
can be configured with a reducer to manage the size of the chat history.
5454
This is useful to avoid exceeding the context size limits of the underlying service.
5555

@@ -67,7 +67,7 @@ AIAgent agent = new OpenAIClient("<your_api_key>")
6767
.CreateAIAgent(new ChatClientAgentOptions
6868
{
6969
Name = JokerName,
70-
Instructions = JokerInstructions,
70+
ChatOptions = new() { Instructions = JokerInstructions },
7171
ChatMessageStoreFactory = ctx => new InMemoryChatMessageStore(
7272
new MessageCountingChatReducer(2),
7373
ctx.SerializedState,
@@ -81,9 +81,9 @@ AIAgent agent = new OpenAIClient("<your_api_key>")
8181
8282
### Inference service chat history storage
8383

84-
When using a service that requires in-service storage of chat history, the Agent Framework will store the id of the remote chat history in the `AgentThread` object.
84+
When using a service that requires in-service storage of chat history, Agent Framework stores the ID of the remote chat history in the `AgentThread` object.
8585

86-
E.g, when using OpenAI Responses with store=true as the underlying service for agents, the following code will result in the thread object containing the last response id returned by the service.
86+
For example, when using OpenAI Responses with store=true as the underlying service for agents, the following code will result in the thread object containing the last response ID returned by the service.
8787

8888
```csharp
8989
AIAgent agent = new OpenAIClient("<your_api_key>")
@@ -94,19 +94,18 @@ Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread)
9494
```
9595

9696
> [!NOTE]
97-
> Some services, e.g. OpenAI Responses support either in-service storage of chat history (store=true), or providing the full chat history on each invocation (store=false).
98-
> Therefore, depending on the mode that the service is used in, the Agent Framework will either default to storing the full chat history in memory, or storing an id reference
99-
> to the service stored chat history.
97+
> Some services, for example, OpenAI Responses support either in-service storage of chat history (store=true), or providing the full chat history on each invocation (store=false).
98+
> Therefore, depending on the mode that the service is used in, Agent Framework will either default to storing the full chat history in memory, or storing an ID reference to the service stored chat history.
10099
101-
### 3rd party chat history storage
100+
### Third-party chat history storage
102101

103-
When using a service that does not support in-service storage of chat history, the Agent Framework allows developers to replace the default in-memory storage of chat history with 3rd party chat history storage. The developer is required to provide a subclass of the base abstract `ChatMessageStore` class.
102+
When using a service that does not support in-service storage of chat history, Agent Framework allows developers to replace the default in-memory storage of chat history with third-party chat history storage. The developer is required to provide a subclass of the base abstract `ChatMessageStore` class.
104103

105104
The `ChatMessageStore` class defines the interface for storing and retrieving chat messages. Developers must implement the `AddMessagesAsync` and `GetMessagesAsync` methods to add messages to the remote store as they are generated, and retrieve messages from the remote store before invoking the underlying service.
106105

107106
The agent will use all messages returned by `GetMessagesAsync` when processing a user query. It is up to the implementer of `ChatMessageStore` to ensure that the size of the chat history does not exceed the context window of the underlying service.
108107

109-
When implementing a custom `ChatMessageStore` which stores chat history in a remote store, the chat history for that thread should be stored under a key that is unique to that thread. The `ChatMessageStore` implementation should generate this key and keep it in its state. `ChatMessageStore` has a `Serialize` method that can be overridden to serialize its state when the thread is serialized. The `ChatMessageStore` should also provide a constructor that takes a `JsonElement` as input to support deserialization of its state.
108+
When implementing a custom `ChatMessageStore` which stores chat history in a remote store, the chat history for that thread should be stored under a key that is unique to that thread. The `ChatMessageStore` implementation should generate this key and keep it in its state. `ChatMessageStore` has a `Serialize` method that can be overridden to serialize its state when the thread is serialized. The `ChatMessageStore` should also provide a constructor that takes a <xref:System.Text.Json.JsonElement> as input to support deserialization of its state.
110109

111110
To supply a custom `ChatMessageStore` to a `ChatClientAgent`, you can use the `ChatMessageStoreFactory` option when creating the agent.
112111
Here is an example showing how to pass the custom implementation of `ChatMessageStore` to a `ChatClientAgent` that is based on Azure OpenAI Chat Completion.
@@ -115,19 +114,19 @@ Here is an example showing how to pass the custom implementation of `ChatMessage
115114
AIAgent agent = new AzureOpenAIClient(
116115
new Uri(endpoint),
117116
new AzureCliCredential())
118-
.GetChatClient(deploymentName)
119-
.CreateAIAgent(new ChatClientAgentOptions
120-
{
121-
Name = JokerName,
122-
Instructions = JokerInstructions,
123-
ChatMessageStoreFactory = ctx =>
124-
{
125-
// Create a new chat message store for this agent that stores the messages in a custom store.
126-
// Each thread must get its own copy of the CustomMessageStore, since the store
127-
// also contains the id that the thread is stored under.
128-
return new CustomMessageStore(vectorStore, ctx.SerializedState, ctx.JsonSerializerOptions);
129-
}
130-
});
117+
.GetChatClient(deploymentName)
118+
.CreateAIAgent(new ChatClientAgentOptions
119+
{
120+
Name = JokerName,
121+
ChatOptions = new() { Instructions = JokerInstructions },
122+
ChatMessageStoreFactory = ctx =>
123+
{
124+
// Create a new chat message store for this agent that stores the messages in a custom store.
125+
// Each thread must get its own copy of the CustomMessageStore, since the store
126+
// also contains the ID that the thread is stored under.
127+
return new CustomMessageStore(vectorStore, ctx.SerializedState, ctx.JsonSerializerOptions);
128+
}
129+
});
131130
```
132131

133132
> [!TIP]
@@ -144,9 +143,9 @@ To implement such a memory component, the developer needs to subclass the `AICon
144143
145144
## AgentThread Serialization
146145

147-
It is important to be able to persist an `AgentThread` object between agent invocations. This allows for situations where a user may ask a question of the agent, and take a long time to ask follow up questions. This allows the `AgentThread` state to survive service or app restarts.
146+
It is important to be able to persist an `AgentThread` object between agent invocations. This allows for situations where a user might ask a question of the agent, and take a long time to ask follow up questions. This allows the `AgentThread` state to survive service or app restarts.
148147

149-
Even if the chat history is stored in a remote store, the `AgentThread` object still contains an id referencing the remote chat history. Losing the `AgentThread` state will therefore result in also losing the id of the remote chat history.
148+
Even if the chat history is stored in a remote store, the `AgentThread` object still contains an ID referencing the remote chat history. Losing the `AgentThread` state will therefore result in also losing the ID of the remote chat history.
150149

151150
The `AgentThread` as well as any objects attached to it, all therefore provide the `SerializeAsync` method to serialize their state. The `AIAgent` also provides a `DeserializeThread` method that re-creates a thread from the serialized state. The `DeserializeThread` method re-creates the thread with the `ChatMessageStore` and `AIContextProvider` configured on the agent.
152151

@@ -163,7 +162,7 @@ AgentThread resumedThread = AIAgent.DeserializeThread(serializedThreadState);
163162
> [!IMPORTANT]
164163
> Always treat `AgentThread` objects as opaque objects, unless you are very sure of the internals. The contents may vary not just by agent type, but also by service type and configuration.
165164
> [!WARNING]
166-
> Deserializing a thread with a different agent than that which originally created it, or with an agent that has a different configuration than the original agent, may result in errors or unexpected behavior.
165+
> Deserializing a thread with a different agent than that which originally created it, or with an agent that has a different configuration than the original agent, might result in errors or unexpected behavior.
167166
168167
::: zone-end
169168
::: zone pivot="programming-language-python"

0 commit comments

Comments
 (0)