Session

AgentSession 是跨代理執行的對話狀態容器。

包含什麼內容AgentSession

Field Purpose
StateBag 此會話的任意狀態容器

C# AgentSession 是一個抽象基底類別。 具體實作 (透過 CreateSessionAsync() 建立) 可能會新增其他狀態,例如當使用由服務管理的歷程記錄時,用於遠端聊天記錄儲存的識別碼。

Field Purpose
session_id 此會話的本地唯一識別碼
service_session_id 遠端服務工作階段識別碼 (例如交談或回應識別碼),當使用由服務管理的歷程記錄時
state 與上下文/歷史提供者共享的可變字典
Field Purpose
agent.Session 綁定於對話的鍵值狀態容器

工作階段會提供具類型的索引鍵/值儲存:

type UserPrefs struct {
    Theme    string `json:"theme"`
    Language string `json:"language"`
}

session.Set("user_prefs", UserPrefs{Theme: "dark", Language: "en"})

var prefs UserPrefs
session.Get("user_prefs", &prefs)

session.Delete("user_prefs")

服務會話識別碼範圍

當使用服務管理歷史時,會話可以包含服務發出的會話識別碼。 例如,OpenAI 回應可能會使用 resp_* 回應 ID 為 previous_response_id,而 OpenAI 對話 API 則可能使用 conv_* 對話 ID 作為對話內容。

OpenAI 預設會將這些 ID 範圍設定為支援的 API 金鑰或專案。 當該金鑰或專案已經與應用程式邊界相符時,這通常就足夠了,例如單一使用者應用程式或每個租戶的獨立金鑰/專案。 風險較高的託管模式是為多個終端使用者使用同一組後備金鑰或專案,將原始服務端 ID 傳達給客戶端,然後在不檢查擁有權的情況下接受這些 ID。 在重用單一後備金鑰或專案的託管或多使用者應用程式中,不會將 service_session_idprevious_response_idconversation/conversation_id 視為終端使用者授權邊界。 將服務端 ID 儲存在受信任的應用程式儲存中,將客戶端可見的會話 ID 對應到這些服務端 ID,並在恢復對話前驗證已認證的使用者或租戶。

內建使用模式

AgentSession session = await agent.CreateSessionAsync();

var first = await agent.RunAsync("My name is Alice.", session);
var second = await agent.RunAsync("What is my name?", session);
session = agent.create_session()

first = await agent.run("My name is Alice.", session=session)
second = await agent.run("What is my name?", session=session)
session, err := a.CreateSession(ctx)
if err != nil {
    panic(err)
}

resp, _ := a.RunText(ctx, "Hello!", agent.WithSession(session)).Collect()
resp, _ = a.RunText(ctx, "Follow-up question.", agent.WithSession(session)).Collect()

將工作階段與 Harness Agent 搭配使用

Harness Agent 採用上述 AgentSession 相同的生命週期。 在多個回合中重複使用同一個工作階段,讓聊天記錄與工作階段型執行框架 (Harness) 功能 (例如待辦事項、運作模式、檔案記憶體、工具核准和背景工作狀態) 維持連貫。 當該狀態必須在程序重新啟動後存活時,序列化該會話。

HarnessAgent 預設為 InMemoryChatHistoryProvider。 當歷程記錄必須使用另一個儲存區時,請透過 HarnessAgentOptions.ChatHistoryProvider 取代它。 AsHarnessAgent(options) 是構造 new HarnessAgent(chatClient, options)的簡寫。

HarnessAgent agent = chatClient.AsHarnessAgent();
AgentSession session = await agent.CreateSessionAsync();

await agent.RunAsync("Plan the migration.", session);
await agent.RunAsync("Continue with the next step.", session);

var serialized = await agent.SerializeSessionAsync(session);
AgentSession resumed = await agent.DeserializeSessionAsync(serialized);

此執行框架會在工具呼叫迴圈內的每次模型呼叫後持續儲存本機聊天記錄,而不僅僅是在外部代理程式執行結束後。 繼續傳遞同一個工作階段,以保留該迴圈內歷程記錄及預設內容提供者的狀態。

create_harness_agenthistory_provider 預設為 InMemoryHistoryProvider()。 當歷程記錄必須使用另一個存放區時,請透過 history_provider= 傳遞自訂的 HistoryProvider

agent = create_harness_agent(client)
session = agent.create_session()

await agent.run("Plan the migration.", session=session)
await agent.run("Continue with the next step.", session=session)

serialized = session.to_dict()
resumed = AgentSession.from_dict(serialized)

該執行框架需要針對每次服務呼叫進行歷程記錄持久化,因此設定好的歷程記錄提供者會儲存工具迴圈內的每次模型呼叫。 預設的工具核准中介軟體也需要工作階段;重複使用並還原它,以保留核准與內容提供者的狀態。

Harness Agent 目前還沒有在 Go SDK 裡提供。 請使用上述常見的會談模式。

從現有的服務對話 ID 建立會話

從現有的對話識別碼建立新的會話,會因代理類型而有所不同。 以下是一些範例。

使用 ChatClientAgent

AgentSession session = await chatClientAgent.CreateSessionAsync(conversationId);

當使用 A2AAgent

AgentSession session = await a2aAgent.CreateSessionAsync(contextId, taskId);

當備份服務已經有對話狀態時,使用這個方法。

session = agent.get_session(service_session_id="<service-conversation-id>")
response = await agent.run("Continue this conversation.", session=session)

在託管應用程式中,請在檢查目前使用者或租用戶後,從應用程式自備儲存體解析 <service-conversation-id>。 避免直接接受來自用戶端的原始服務端識別碼,除非您先確認呼叫者擁有該交談。

序列化與還原

var serialized = agent.SerializeSession(session);
AgentSession resumed = await agent.DeserializeSessionAsync(serialized);

在自我託管應用程式中,AgentSessionStore 可在要求處理過程中,透過接續識別碼載入並儲存工作階段。 這與手動持久化會話及設定歷史提供者不同。 請參閱 自我裝載代理程式架構應用程式

serialized = session.to_dict()
resumed = AgentSession.from_dict(serialized)
data, err := json.Marshal(session)
if err != nil {
    panic(err)
}

// Save to disk, database, etc.
if err := os.WriteFile("session.json", data, 0o644); err != nil {
    panic(err)
}

// Later, restore the session.
loaded, err := os.ReadFile("session.json")
if err != nil {
    panic(err)
}

var resumedSession agent.Session
if err := json.Unmarshal(loaded, &resumedSession); err != nil {
    panic(err)
}

resp, _ := a.RunText(ctx, "Continue from where we left off.", agent.WithSession(&resumedSession)).Collect()

Tip

完整範例請參考 持續對話範例

這很重要

會話是針對特定代理或服務的。 重複使用不同代理程式組態或提供者的工作階段可能會導致內容無效。 如果序列化會話包含服務端會話 ID,則僅還原擁有該 ID 的應用程式使用者或租戶的 ID。

下一步