WayFlow에서 에이전트 메모리 사용
이 문서에서는 에이전트가 세션 간에 영구 팩트를 재사용할 수 있도록 에이전트 메모리를 WayFlow 에이전트에 연결하는 방법에 대해 알아봅니다.
참고: 패키지 설정은 에이전트 메모리 시작하기를 참조하십시오. 이 예에 대한 로컬 Oracle AI Database가 필요한 경우 Run Oracle AI Database Locally를 참조하십시오. WayFlow에 대한 자세한 내용은 (https://github.com/oracle/wayflow)을 참조하십시오.
에이전트 메모리 및 WayFlow 구성
사용자에 대한 에이전트 메모리 스레드를 생성하고, WayFlow에 search_memory 툴을 노출하고, OpenAIModel를 사용하여 WayFlow Agent를 구성합니다. search_memory 도구는 사용자 및 에이전트 ID별로 에이전트 메모리 API를 쿼리하므로 현재 스레드로 제한되는 대신 이전 세션에서 영구적인 팩트를 복구할 수 있습니다. 또한 에이전트 메모리 클라이언트는 자체 LLM을 사용하여 최근 스레드 메시지에서 영구 메모리를 주기적으로 추출하고, WayFlow Agent는 회신 및 도구 호출에 자체 OpenAIModel를 계속 사용합니다.
import oracledb
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
from oracleagentmemory.core.oracleagentmemory import OracleAgentMemory
from wayflowcore.agent import Agent
from wayflowcore.models import OpenAIModel
from wayflowcore.tools import tool
embedder = Embedder(
model="YOUR_EMBEDDING_MODEL",
api_base="YOUR_EMBEDDING_API_BASE",
api_key="YOUR_EMBEDDING_API_KEY",
)
llm = Llm(
model="gpt-4.1-mini",
api_key="YOUR_OPENAI_API_KEY",
)
db_pool = oracledb.SessionPool(
user="YOUR DB USER",
password="YOUR DB PASSWORD",
dsn="YOUR DB CONNECT STRING",
)
wayflow_llm = OpenAIModel(
model_id="gpt-4.1-mini",
api_key="YOUR_OPENAI_API_KEY",
)
#Keep these identifiers stable for the same assistant and end user so memory
#is scoped consistently across threads and sessions.
agent_id = "support_agent"
user_id = "user_123"
memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
llm=llm,
)
memory_thread = memory.create_thread(
thread_id="wayflow_memory_demo",
user_id=user_id,
agent_id=agent_id,
)
from typing import Annotated
@tool
def search_memory(
query: Annotated[str, "Question to search in Oracle Agent Memory"],
) -> Annotated[str, "Top matching memory content"]:
"""Search Oracle Agent Memory for durable user facts relevant to the current request."""
results = memory.search(
query=query,
user_id=user_id,
agent_id=agent_id,
max_results=1,
record_types=["memory"],
)
if not results:
return "No relevant memory found."
return results[0].content
assistant = Agent(
llm=wayflow_llm,
agent_id=agent_id,
custom_instruction=(
"You are a support agent. When the user asks about durable facts from "
"prior sessions, call the search_memory tool before answering."
),
tools=[search_memory],
)
세션 후 사용자 컨텍스트 유지
각 WayFlow 세션 후에 교환된 메시지를 에이전트 메모리에 추가하고 나중에 재사용해야 하는 영구적인 사실을 저장합니다.
session_1 = assistant.start_conversation()
user_message = (
"I am John, a Python developer and I need help debugging a payment service."
)
session_1.append_user_message(user_message)
session_1.execute()
assistant_reply = session_1.get_last_message().content
print(assistant_reply)
#I can help with that. What error are you seeing?
#add_messages will add messages to the DB and extract memories automatically
memory_thread.add_messages(
[
{"role": "user", "content": user_message},
{"role": "assistant", "content": assistant_reply},
]
)
#add_memory adds memory to the DB
memory_thread.add_memory("The user is John, a Python developer.")
새 WayFlow 세션에서 메모리 재사용
이후 세션이 시작되면 동일한 에이전트 메모리 스레드를 다시 열고 WayFlow 에이전트가 search_memory를 호출하여 이전 사용자 컨텍스트를 복구하도록 합니다.
memory_thread = memory.get_thread("wayflow_memory_demo")
assistant = Agent(
llm=wayflow_llm,
agent_id=agent_id,
custom_instruction=(
"You are a support agent. When the user asks about durable facts from "
"prior sessions, call the search_memory tool before answering."
),
tools=[search_memory],
)
session_2 = assistant.start_conversation()
session_2.append_user_message("Who am I?")
session_2.execute()
remembered_reply = session_2.get_last_message().content
print(remembered_reply)
출력:
The user is John, a Python developer.
고급 사용
보다 긴밀한 통합을 위해 ConversationMessageAddedEvent 항목을 버퍼링하고 실행 종료 시 에이전트 메모리에 기록하는 WayFlow 이벤트 리스너를 등록할 수 있습니다. 이렇게 하면 에이전트 메모리 업데이트 경로가 주 스레드 코드와 분리되어 유지되지만 마지막으로 교환된 메시지는 계속 유지됩니다.
from wayflowcore.events.event import ConversationMessageAddedEvent
from wayflowcore.events.eventlistener import GenericEventListener, register_event_listeners
pending_messages: list[dict[str, str]] = []
def _buffer_thread_message(event: ConversationMessageAddedEvent) -> None:
if event.streamed:
return
pending_messages.append(
{
"role": event.message.role,
"content": event.message.content,
}
)
message_listener = GenericEventListener(
[ConversationMessageAddedEvent],
_buffer_thread_message,
)
with register_event_listeners([message_listener]):
session_3 = assistant.start_conversation()
session_3.append_user_message("Please remember that I prefer concise code reviews.")
session_3.execute()
if pending_messages:
memory_thread.add_messages(pending_messages)
자동 추출 사용 안함
메시지를 지속하고 영구 메모리를 수동으로 추가하려면 extract_memories=False를 사용하여 에이전트 메모리 클라이언트를 만들고 영구 메모리 행을 직접 삽입합니다.
manual_memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
extract_memories=False,
)
manual_memory_thread = manual_memory.create_thread(
thread_id="wayflow_manual_memory_demo",
user_id=user_id,
agent_id=agent_id,
)
manual_memory_thread.add_messages(
[
{
"role": "user",
"content": "Please remember that I prefer concise code reviews.",
},
{
"role": "assistant",
"content": "Understood. I will keep responses concise.",
},
]
)
manual_memory_thread.add_memory("The user prefers concise code reviews.")
결론
이 문서에서는 에이전트 메모리를 WayFlow 에이전트에 연결하고, 각 세션 후에 교환된 메시지와 영구 메모리를 유지하고, 이후 실행에서 이전 사용자 컨텍스트를 재사용하는 방법을 배웠습니다.
참고: 에이전트 메모리를 WayFlow와 통합하는 방법을 배웠을 때 에이전트 메모리를 LangGraph와 통합에도 관심이 있을 수 있습니다.
전체 코드
#Copyright © 2026 Oracle and/or its affiliates.
#This software is under the Apache License 2.0
#(LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
#(UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.
#Agent Memory Code Example - Integration with WayFlow
#-----------------------------------------------------
##Configure Oracle Memory and WayFlow
import oracledb
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
from oracleagentmemory.core.oracleagentmemory import OracleAgentMemory
from wayflowcore.agent import Agent
from wayflowcore.models import OpenAIModel
from wayflowcore.tools import tool
embedder = Embedder(
model="YOUR_EMBEDDING_MODEL",
api_base="YOUR_EMBEDDING_API_BASE",
api_key="YOUR_EMBEDDING_API_KEY",
)
llm = Llm(
model="gpt-4.1-mini",
api_key="YOUR_OPENAI_API_KEY",
)
db_pool = oracledb.SessionPool(
user="YOUR DB USER",
password="YOUR DB PASSWORD",
dsn="YOUR DB CONNECT STRING",
)
wayflow_llm = OpenAIModel(
model_id="gpt-4.1-mini",
api_key="YOUR_OPENAI_API_KEY",
)
#Keep these identifiers stable for the same assistant and end user so memory
#is scoped consistently across threads and sessions.
agent_id = "support_agent"
user_id = "user_123"
memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
llm=llm,
)
memory_thread = memory.create_thread(
thread_id="wayflow_memory_demo",
user_id=user_id,
agent_id=agent_id,
)
from typing import Annotated
@tool
def search_memory(
query: Annotated[str, "Question to search in Oracle Agent Memory"],
) -> Annotated[str, "Top matching memory content"]:
"""Search Oracle Agent Memory for durable user facts relevant to the current request."""
results = memory.search(
query=query,
user_id=user_id,
agent_id=agent_id,
max_results=1,
record_types=["memory"],
)
if not results:
return "No relevant memory found."
return results[0].content
assistant = Agent(
llm=wayflow_llm,
agent_id=agent_id,
custom_instruction=(
"You are a support agent. When the user asks about durable facts from "
"prior sessions, call the search_memory tool before answering."
),
tools=[search_memory],
)
##Persist user context after a session
session_1 = assistant.start_conversation()
user_message = (
"I am John, a Python developer and I need help debugging a payment service."
)
session_1.append_user_message(user_message)
session_1.execute()
assistant_reply = session_1.get_last_message().content
print(assistant_reply)
#I can help with that. What error are you seeing?
memory_thread.add_messages(
[
{"role": "user", "content": user_message},
{"role": "assistant", "content": assistant_reply},
]
)
memory_thread.add_memory("The user is John, a Python developer.")
##Reuse memory in a new WayFlow session
memory_thread = memory.get_thread("wayflow_memory_demo")
assistant = Agent(
llm=wayflow_llm,
agent_id=agent_id,
custom_instruction=(
"You are a support agent. When the user asks about durable facts from "
"prior sessions, call the search_memory tool before answering."
),
tools=[search_memory],
)
session_2 = assistant.start_conversation()
session_2.append_user_message("Who am I?")
session_2.execute()
remembered_reply = session_2.get_last_message().content
print(remembered_reply)
#The user is John, a Python developer.
##Advanced use event listeners
from wayflowcore.events.event import ConversationMessageAddedEvent
from wayflowcore.events.eventlistener import GenericEventListener, register_event_listeners
pending_messages: list[dict[str, str]] = []
def _buffer_thread_message(event: ConversationMessageAddedEvent) -> None:
if event.streamed:
return
pending_messages.append(
{
"role": event.message.role,
"content": event.message.content,
}
)
message_listener = GenericEventListener(
[ConversationMessageAddedEvent],
_buffer_thread_message,
)
with register_event_listeners([message_listener]):
session_3 = assistant.start_conversation()
session_3.append_user_message("Please remember that I prefer concise code reviews.")
session_3.execute()
if pending_messages:
memory_thread.add_messages(pending_messages)
##Disable automatic memory extraction
manual_memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
extract_memories=False,
)
manual_memory_thread = manual_memory.create_thread(
thread_id="wayflow_manual_memory_demo",
user_id=user_id,
agent_id=agent_id,
)
manual_memory_thread.add_messages(
[
{
"role": "user",
"content": "Please remember that I prefer concise code reviews.",
},
{
"role": "assistant",
"content": "Understood. I will keep responses concise.",
},
]
)
manual_memory_thread.add_memory("The user prefers concise code reviews.")