Oracle AI Databaseのローカル実行
この記事では、DockerまたはPodmanを使用してOracle AI Databaseをローカルで実行し、oracleagentmemoryをそのデータベースに接続する方法について説明します。
この記事では、次の方法について学習します。
-
DockerまたはPodmanでOracle AI Databaseをプルして起動します。
-
オプションで、
oracleagentmemoryのローカルOracleユーザーおよび表領域を作成します。 -
LiteLLM埋込みおよびLLMアダプタを使用して、Oracleバックアップの
oracleagentmemoryAPIを構成します。 -
2番目のAPIインスタンスを介して同じスレッドを再オープンすることで、レコードが永続していることを確認します。
前提条件
DockerまたはPodmanをインストールし、対応するCLIがシェルで使用可能であることを確認します。次に、Oracle ContainerレジストリからOracle AI Database Free Liteイメージをプルします。
コンテナを起動する前に、Oracle SYSTEMユーザーの強力なパスワードを選択し、エクスポートします。
export ORACLE_PWD='<your-secure-password>'
Docker:
docker pull container-registry.oracle.com/database/free:latest-lite
Podman:
podman pull container-registry.oracle.com/database/free:latest-lite
Oracle AI Database Containerの起動
名前付きボリュームを作成して、データベース・ファイルが再起動後も保持されるようにします。
Docker:
docker volume create OracleDBData
Podman:
podman volume create OracleDBData
次に、コンテナを起動します。
Docker:
docker run -d \
--name oracle-free-lite \
-p 1521:1521 \
-e ORACLE_PWD="$ORACLE_PWD" \
-v OracleDBData:/opt/oracle/oradata \
container-registry.oracle.com/database/free:latest-lite
Podman:
podman run -d \
--name oracle-free-lite \
-p 1521:1521 \
-e ORACLE_PWD="$ORACLE_PWD" \
-v OracleDBData:/opt/oracle/oradata \
container-registry.oracle.com/database/free:latest-lite
ノート: PodmanでRHELでSELinuxのラベル付けの問題が発生した場合は、security-opt構成パラメータを調べることができます。
次に、コンテナ・ログに従って、データベースの準備が整ったことが報告されます。
Docker:
docker logs -f oracle-free-lite
Podman:
podman logs -f oracle-free-lite
ログにDATABASE IS READY TO USE!が含まれている場合、リスナーおよびデフォルトのプラガブル・データベースは稼働しています。
データベースの準備ができたら、データベースに接続します。
Docker:
docker exec -it oracle-free-lite sqlplus system/"$ORACLE_PWD"@FREEPDB1
Podman:
podman exec -it oracle-free-lite sqlplus system/"$ORACLE_PWD"@FREEPDB1
コンテナ内から単純な問合せを実行して、PDBがオープンしていることを確認します。
SELECT sys_context('USERENV', 'CON_NAME') AS container_name FROM dual;
FREEPDB1が表示されます。
次に、exitと入力し、Enterを押してSQL*Plusを終了します。
[オプション]ローカルOracleユーザーの作成
すでにOracle AI Databaseおよびアプリケーション・ユーザーがある場合は、この項をスキップして、次の項「ローカル・データベースに対してoracleagentmemoryを試行」に進みます。API自体のより短いクイックスタート・スタイルのウォークスルーについては、「1人のユーザーのメモリーの格納および検索」を参照してください。
この記事のスクリプト例では、専用のローカル・データベース・ユーザーを使用しています。
DB_USER = os.environ.get("ORACLE_MEMORY_DB_USER", "dmuser")
DB_PASSWORD = os.environ["ORACLE_MEMORY_DB_PASSWORD"]
DB_CONNECT_STRING = os.environ.get(
"ORACLE_MEMORY_DB_CONNECT_STRING",
"localhost:1521/FREEPDB1",
)
スクリプトを実行する前に、そのアプリケーション・ユーザーの強力なパスワードを選択し、エクスポートします。
export ORACLE_MEMORY_DB_PASSWORD='<your-app-user-password>'
次に、PDB内にユーザーを作成します。
Docker:
docker exec -it oracle-free-lite sqlplus system/"$ORACLE_PWD"@FREEPDB1
Podman:
podman exec -it oracle-free-lite sqlplus system/"$ORACLE_PWD"@FREEPDB1
CREATE TABLESPACE dmuser_ts
DATAFILE '/opt/oracle/oradata/FREE/FREEPDB1/dmuser_ts01.dbf'
SIZE 200M
AUTOEXTEND ON NEXT 100M
SEGMENT SPACE MANAGEMENT AUTO;
CREATE USER dmuser IDENTIFIED BY "CHOOSE_A_STRONG_PASSWORD";
GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE VIEW, CREATE PROCEDURE TO dmuser;
ALTER USER dmuser DEFAULT TABLESPACE dmuser_ts;
ALTER USER dmuser QUOTA UNLIMITED ON dmuser_ts;
CHOOSE_A_STRONG_PASSWORDを、ORACLE_MEMORY_DB_PASSWORDに格納したものと同じパスワード値に置き換えます。
次に、ユーザーの準備ができていることを確認します。
SELECT tablespace_name, contents
FROM dba_tablespaces
WHERE tablespace_name = 'DMUSER_TS';
SELECT username, account_status, default_tablespace, temporary_tablespace
FROM dba_users
WHERE username = 'DMUSER';
SELECT privilege
FROM dba_sys_privs
WHERE grantee = 'DMUSER'
ORDER BY privilege;
最初の問合せでは、DMUSER_TSが永続表領域として表示されます。2番目の問合せでは、DMUSERがOPENステータスで、DMUSER_TSがデフォルト表領域として表示されます。権限問合せには、CREATE SESSION、CREATE TABLE、CREATE SEQUENCE、CREATE VIEWおよびCREATE PROCEDURE以上を含める必要があります。
ローカル・データベースに対してoracleagentmemoryを試行
これで、Oracle接続設定の準備ができたので、FREEPDB1でoracleagentmemoryを指し示し、少量のエンドツーエンド永続性チェックを実行できます。
次の例では、次の2つのことを行います。
- メッセージおよびメモリーを書き込む最初のエージェント・メモリーAPIインスタンスが作成されます。
- これは、同じスレッドを再オープンしてOracleから問合せを行う2番目のエージェント・メモリーAPIインスタンスを作成します。
例を実行する前に、アプリケーション接続変数を設定します。次に示すユーザーおよび接続文字列は、以前のオプション設定と一致しますが、独自の既存のOracleユーザーおよびDSNで置換できます。
export ORACLE_MEMORY_DB_USER='dmuser'
export ORACLE_MEMORY_DB_PASSWORD='<your-app-user-password>'
export ORACLE_MEMORY_DB_CONNECT_STRING='localhost:1521/FREEPDB1'
Oracle-Backed APIの構成
import os
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
import oracledb
from oracleagentmemory.core import OracleAgentMemory, SchemaPolicy
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
embedder = Embedder(
model="YOUR_EMBEDDING_MODEL",
api_base="YOUR_EMBEDDING_API_BASE",
api_key="YOUR_EMBEDDING_API_KEY",
)
llm = Llm(
model="YOUR_LLM_MODEL",
api_base="YOUR_LLM_API_BASE",
api_key="YOUR_LLM_API_KEY",
)
DB_USER = os.environ.get("ORACLE_MEMORY_DB_USER", "dmuser")
DB_PASSWORD = os.environ["ORACLE_MEMORY_DB_PASSWORD"]
DB_CONNECT_STRING = os.environ.get("ORACLE_MEMORY_DB_CONNECT_STRING", "localhost:1521/FREEPDB1")
TABLE_NAME_PREFIX = "T_ORACLEMEM_DEMO_"
db_pool = oracledb.SessionPool(
user=DB_USER,
password=DB_PASSWORD,
dsn=DB_CONNECT_STRING,
min=1,
max=4,
increment=1,
homogeneous=True,
)
agent_memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
llm=llm,
schema_policy=SchemaPolicy.RECREATE,
table_name_prefix=TABLE_NAME_PREFIX,
)
この構成では、ローカルのOracle AI DatabaseをプレースホルダのLiteLLM埋込みおよび完了設定とともに使用し、独自のプロバイダ値で置換できます。
レコードの書込みおよび永続性の検証
#Keep the same user identifier for the same end user across sessions
#so durable memory can be retrieved consistently.
user_id = "user_123"
thread = agent_memory.create_thread(user_id=user_id)
thread.add_messages(
[
{
"role": "user",
"content": "Orange juice is my usual breakfast drink.",
},
{
"role": "assistant",
"content": "Pair it with eggs, toast, or Greek yogurt.",
},
]
)
thread.add_memory("The user currently prefers orange juice with breakfast.")
db_pool2 = oracledb.SessionPool(
user=DB_USER,
password=DB_PASSWORD,
dsn=DB_CONNECT_STRING,
min=1,
max=4,
increment=1,
homogeneous=True,
)
agent_memory2 = OracleAgentMemory(
connection=db_pool2,
embedder=embedder,
llm=llm,
schema_policy=SchemaPolicy.REQUIRE_EXISTING,
table_name_prefix=TABLE_NAME_PREFIX,
)
persisted_thread = agent_memory2.get_thread(thread.thread_id)
print("Messages stored in Oracle:")
print_messages(persisted_thread.get_messages())
print("\nSearch results for 'orange juice':")
print_search_results(
agent_memory2.search(
query="orange juice",
user_id=user_id,
max_results=5,
record_types=["memory", "message"],
)
)
この例が正常に実行されると、2番目のエージェント・メモリーAPIインスタンスは、格納されているスレッド・メッセージを出力し、データベースから検索結果を返します。これにより、レコードがプロセス・メモリーにのみ保持されるのではなく、Oracleに保持されたことが確認されます。
クリーンアップ
ローカル・データベースの使用が終了したら、次の手順を実行します。
Docker:
docker stop oracle-free-lite
docker rm oracle-free-lite
Podman:
podman stop oracle-free-lite
podman rm oracle-free-lite
永続データベース・ファイルも削除する場合:
Docker:
docker volume rm OracleDBData
Podman:
podman volume rm OracleDBData
まとめ
この記事では、DockerまたはPodmanを使用してOracle AI Database Free Liteをローカルで起動し、専用のOracleユーザーおよび表領域をoracleagentmemory用に準備し、oracleagentmemory APIをそのデータベースに接続し、別のAPIインスタンスを介して同じスレッドを再オープンおよび検索して永続性を検証する方法を学習しました。
ヒント:ローカルのOracle AI Databaseに対してoracleagentmemoryを実行する方法を学習した後、「1人のユーザーのメモリーの格納および検索」に進むことができます。
完全コード
#Copyright © 2026 Oracle and/or its affiliates.
#isort:skip_file
#fmt: off
#%%[markdown]
#Agent Memory Code Example - Run Oracle DB locally
#--------------------------------------------------------
#How to use:
#Create a new Python virtual environment and install the latest oracleagentmemory version.
#You can now run the script
#1. As a Python file:
#```bash
#python howto_run_oracledb.py
#```
#2. As a Notebook (in VSCode):
#When viewing the file,
#- press the keys Ctrl + Enter to run the selected cell
#- or Shift + Enter to run the selected cell and move to the cell below
##Configure the local Oracle connection
#%%
import os
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
import oracledb
from oracleagentmemory.core import OracleAgentMemory, SchemaPolicy
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
embedder = Embedder(
model="YOUR_EMBEDDING_MODEL",
api_base="YOUR_EMBEDDING_API_BASE",
api_key="YOUR_EMBEDDING_API_KEY",
)
llm = Llm(
model="YOUR_LLM_MODEL",
api_base="YOUR_LLM_API_BASE",
api_key="YOUR_LLM_API_KEY",
)
DB_USER = os.environ.get("ORACLE_MEMORY_DB_USER", "dmuser")
DB_PASSWORD = os.environ["ORACLE_MEMORY_DB_PASSWORD"]
DB_CONNECT_STRING = os.environ.get("ORACLE_MEMORY_DB_CONNECT_STRING", "localhost:1521/FREEPDB1")
TABLE_NAME_PREFIX = "T_ORACLEMEM_DEMO_"
db_pool = oracledb.SessionPool(
user=DB_USER,
password=DB_PASSWORD,
dsn=DB_CONNECT_STRING,
min=1,
max=4,
increment=1,
homogeneous=True,
)
agent_memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
llm=llm,
schema_policy=SchemaPolicy.RECREATE,
table_name_prefix=TABLE_NAME_PREFIX,
)
def print_messages(messages: list) -> None:
for message in messages:
print(f"[{message.role}] {message.content}")
def print_search_results(results: list) -> None:
for result in results:
print(
f"- [{result.record.record_type}] "
f"id={result.id} "
f"user_id={result.record.user_id} "
f"thread_id={result.record.thread_id} "
f"content={result.content}"
)
##Create data and query it
#%%
#Keep the same user identifier for the same end user across sessions so
#durable memory can be retrieved consistently.
user_id = "user_123"
thread = agent_memory.create_thread(user_id=user_id)
#add_messages will add messages to the DB and extract memories automatically
thread.add_messages(
[
{
"role": "user",
"content": "Orange juice is my usual breakfast drink.",
},
{
"role": "assistant",
"content": "Pair it with eggs, toast, or Greek yogurt.",
},
]
)
#add_memory adds memory to the DB
thread.add_memory("The user currently prefers orange juice with breakfast.")
db_pool2 = oracledb.SessionPool(
user=DB_USER,
password=DB_PASSWORD,
dsn=DB_CONNECT_STRING,
min=1,
max=4,
increment=1,
homogeneous=True,
)
agent_memory2 = OracleAgentMemory(
connection=db_pool2,
embedder=embedder,
llm=llm,
schema_policy=SchemaPolicy.REQUIRE_EXISTING,
table_name_prefix=TABLE_NAME_PREFIX,
)
persisted_thread = agent_memory2.get_thread(thread.thread_id)
print("Messages stored in Oracle:")
print_messages(persisted_thread.get_messages())
print("\nSearch results for 'orange juice':")
print_search_results(
agent_memory2.search(
query="orange juice",
user_id=user_id,
max_results=5,
record_types=["memory", "message"],
)
)