コンテキストの過負荷を超えて:Parlant × MilvusはLLMエージェントの行動をどのように制御し、明確化するか?
200のビジネスルール、50のツール、30のデモを含むタスクをこなすように言われ、それをこなすのに1時間しかないと想像してみてほしい。そんなことは不可能だ。しかし、私たちはしばしば、大規模な言語モデルを「エージェント」化し、指示を過負荷にすることで、まさにそのようなことを期待します。
実際には、このアプローチはすぐに破綻する。LangChainやLlamaIndexのような従来のエージェントフレームワークは、すべてのルールやツールをモデルのコンテキストに一度に注入するため、ルールの衝突、コンテキストの過負荷、本番での予測不可能な動作につながります。
この問題に対処するために、 Parlantというオープンソースのエージェントフレームワークが最近GitHubで人気を集めている。Parlantは、アライメント・モデリングと呼ばれる新しいアプローチを導入し、スーパーバイジング・メカニズムと条件遷移によって、エージェントの振る舞いをより制御しやすく、説明しやすくしています。
オープンソースのベクトルデータベースであるMilvusと組み合わせることで、Parlantはさらに高性能になる。Milvusはセマンティックインテリジェンスを追加し、エージェントがリアルタイムで最も関連性の高いルールとコンテキストを動的に取得することを可能にします。
この投稿では、Parlantがどのように機能するのか、そしてMilvusと統合することでどのようにプロダクショングレードを実現するのかを探ります。
従来のエージェントフレームワークが崩壊する理由
伝統的なエージェントフレームワークは、何百ものルール、何十ものツール、そして一握りのデモ、これらすべてを1つの、詰め込み過ぎのプロンプトに詰め込むというような、大きなことをするのが好きです。デモや小さなサンドボックステストでは素晴らしく見えるかもしれませんが、本番環境に投入すると、すぐに亀裂が入り始めます。
相反するルールが混沌をもたらす:2つ以上のルールが同時に適用される場合、これらのフレームワークには、どちらが勝つかを決める方法が組み込まれていない。どちらかを選ぶこともある。両方をブレンドすることもある。時には、まったく予測不可能なことをすることもある。
エッジケースはギャップを露呈する:ユーザーの発言すべてを予測することはできない。そして、モデルが学習データ外のことに遭遇すると、一般的な、非妥協的な答えがデフォルトになります。
デバッグは苦痛と費用がかかります:エージェントが誤動作したとき、どのルールが問題を引き起こしたかを特定することはほとんど不可能です。すべてが1つの巨大なシステムプロンプトの中にあるため、それを修正する唯一の方法は、プロンプトを書き換えて、ゼロからすべてを再テストすることです。
Parlantとその仕組み
Parlant はオープンソースの LLM エージェント用アライメントエンジンです。エージェントの意思決定プロセスを構造化されたルールベースでモデル化することで、エージェントが様々なシナリオでどのように振る舞うかを正確に制御することができます。
従来のエージェントフレームワークに見られる問題に対処するために、Parlantは新しい強力なアプローチを導入しています:アライメントモデリングです。その中核となる考え方は、ルールの定義とルールの実行を分離することであり、LLM のコンテキストには常に最も関連性の高いルールだけが注入されるようにします。
粒度の細かいガイドラインアライメント・モデリングの中核
Parlantのアライメント・モデルの中核にあるのは、「粒度の細かいガイドライン」というコンセプトです。ルールでいっぱいの巨大なシステムプロンプトを書く代わりに、小さなモジュール式のガイドラインを定義します。
各ガイドラインは3つの部分で構成されます:
条件- どのような場合にそのルールが適用されるかを自然言語で記述します。Parlantはこの条件を意味ベクトルに変換し、ユーザーの入力と照合して関連性があるかどうかを判断します。
アクション- 条件が満たされたときにエージェントがどのように応答すべきかを定義する明確な指示。このアクションは、トリガーされたときだけLLMのコンテキストに注入されます。
ツール- 特定のルールに結びついた外部関数やAPI。これらは、ガイドラインがアクティブなときだけエージェントに公開され、ツールの使用を制御し、コンテキストを認識します。
await agent.create_guideline(
condition="The user asks about a refund and the order amount exceeds 500 RMB",
action="First call the order status check tool to confirm whether the refund conditions are met, then provide a detailed explanation of the refund process",
tools=[check_order_status, calculate_refund_amount]
)
ユーザがエージェントと対話するたびに、Parlantは最も関連性の高い3~5個のガイドラインを見つけるために、軽量なマッチングステップを実行します。これらのルールのみがモデルのコンテキストに注入され、プロンプトを簡潔かつ集中的に保つと同時に、エージェントが一貫して正しいルールに従うことを保証します。
正確性と一貫性のための監督メカニズム
正確性と一貫性をさらに維持するために、Parlantは品質管理の第二層として機能する監督メカニズムを導入しています。このプロセスは3つのステップで展開されます:
1.応答候補の生成- エージェントは、マッチしたガイドラインと現在の会話コンテキストに基づいて、最初の応答を作成します。
2.コンプライアンスチェック- レスポンスがアクティブなガイドラインと比較され、すべての指示が正しく守られていることが確認されます。
3.3.修正または確認- 問題が見つかった場合、システムは出力を修正します。
この監督メカニズムにより、エージェントはルールを理解するだけでなく、返信前に実際にルールを守ることが保証され、信頼性と制御性の両方が向上する。
制御と安全のための条件付き遷移
従来のエージェントフレームワークでは、利用可能なすべてのツールが常にLLMに公開されている。この "テーブル上のすべて "というアプローチは、しばしば過負荷のプロンプトや意図しないツールの呼び出しにつながります。Parlant は、条件付き遷移によってこれを解決します。ステートマシンの仕組みと同様に、特定の条件が満たされたときにのみ、アクションやツールがトリガーされます。各ツールは対応するガイドラインと緊密に結びついており、そのガイドラインの条件が有効化されたときにのみ利用可能になります。
# The balance inquiry tool is exposed only when the condition "the user wants to make a transfer" is met
await agent.create_guideline(
condition="The user wants to make a transfer",
action="First check the account balance. If the balance is below 500 RMB, remind the user that an overdraft fee may apply.",
tools=[get_user_account_balance]
)
このメカニズムにより、ツールの起動は条件遷移となり、トリガー条件が満たされたときにのみ、ツールは「非アクティブ」から「アクティブ」に移行する。このように実行を構造化することで、Parlantはすべてのアクションが意図的かつ文脈的に行われるようにし、効率とシステムの安全性の両方を向上させながら誤用を防止します。
MilvusがParlantを動かす仕組み
Parlantのガイドラインマッチングプロセスのボンネットを覗いてみると、1つの核となる技術的課題が明らかになる。それは、数百、あるいは数千の選択肢の中から、最も関連性の高い3~5個のルールを数ミリ秒で見つけるにはどうすればよいか、ということだ。そこで登場するのがベクター・データベースである。セマンティック検索がこれを可能にするのです。
MilvusはどのようにParlantのガイドラインマッチングプロセスをサポートしているのか?
ガイドラインのマッチングは、意味的類似性によって機能します。各ガイドラインの「条件」フィールドはベクトル埋め込みに変換され、単なるテキストではなく、その意味を捉えます。ユーザーがメッセージを送信すると、Parlantはそのメッセージのセマンティクスを、保存されているすべてのガイドライン埋め込みと比較し、最も関連性の高いものを見つけます。
以下は、そのプロセスの流れです:
1.クエリをエンコードする- ユーザーのメッセージと最近の会話履歴をクエリベクトルに変換します。
2.類似性の検索- システムがガイドラインベクターストア内で類似性検索を行い、最も近い一致を見つける。
3.トップKの結果を取得- 意味的に最も関連性の高い上位3~5つのガイドラインが返されます。
4.コンテキストへの挿入- 一致したガイドラインは、LLMのコンテキストに動的に挿入されます。
このワークフローを可能にするために、ベクトルデータベースは、高性能な近似最近傍(ANN)検索、柔軟なメタデータフィルタリング、リアルタイムのベクトル更新という3つの重要な機能を提供する必要があります。オープンソースのクラウドネイティブなベクトルデータベースであるMilvusは、この3つの領域すべてにおいてプロダクショングレードのパフォーマンスを提供します。
Milvusが実際のシナリオでどのように機能するかを理解するために、金融サービスエージェントを例に見てみよう。
システムが、口座照会、資金移動、資産管理商品の相談などの業務をカバーする800の業務ガイドラインを定義しているとする。この場合、Milvusはすべてのガイドラインデータの保存・検索レイヤーとして機能する。
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
import parlant.sdk as p
# Connect to Milvus
connections.connect(host=“localhost”, port=“19530”)
# Define the schema for the guideline collection
fields = [
FieldSchema(name=“guideline_id”, dtype=DataType.VARCHAR, max_length=100, is_primary=True),
FieldSchema(name=“condition_vector”, dtype=DataType.FLOAT_VECTOR, dim=768),
FieldSchema(name=“condition_text”, dtype=DataType.VARCHAR, max_length=1000),
FieldSchema(name=“action_text”, dtype=DataType.VARCHAR, max_length=2000),
FieldSchema(name=“priority”, dtype=DataType.INT64),
FieldSchema(name=“business_domain”, dtype=DataType.VARCHAR, max_length=50)
]
schema = CollectionSchema(fields=fields, description=“Agent Guidelines”)
guideline_collection = Collection(name=“agent_guidelines”, schema=schema)
# Create an HNSW index for high-performance retrieval
index_params = {
“index_type”: “HNSW”,
“metric_type”: “COSINE”,
“params”: {“M”: 16, “efConstruction”: 200}
}
guideline_collection.create_index(field_name=“condition_vector”, index_params=index_params)
さて、ユーザーが「母の口座に10万人民元を送金したい」と言った場合、実行時のフローは次のようになる:
1.クエリーをレクタライズする- ユーザー入力を768次元のベクトルに変換する。
2.2.ハイブリッド検索- Milvusのベクトル類似性検索とメタデータのフィルタリング(例:business_domain="transfer" )を実行する。
3.結果ランキング- 類似性スコアと優先度値を組み合わせて、ガイドライン候補をランク付けする。
4.コンテキストインジェクション- トップ3にマッチしたガイドラインのaction_text を Parlant エージェントのコンテキストにインジェクションします。
この構成では、Milvusは、ガイドラインライブラリが10万エントリにスケールした場合でも、P99レイテンシを15ミリ秒未満に抑えています。これに比べ、従来のリレーショナルデータベースを使用したキーワードマッチングでは、通常200ミリ秒以上のレイテンシが発生し、マッチング精度も大幅に低下します。
Milvusが長期記憶とパーソナライゼーションを可能にする理由
Milvusはガイドラインマッチング以上のことを行います。エージェントが長期的な記憶とパーソナライズされた応答を必要とするシナリオでは、Milvusはユーザーの過去のやり取りをベクトル埋め込みとして保存し検索するメモリレイヤーとして機能し、エージェントが以前に議論された内容を記憶するのに役立ちます。
# store user’s past interactions
user_memory_fields = [
FieldSchema(name="interaction_id", dtype=DataType.VARCHAR, max_length=100, is_primary=True),
FieldSchema(name="user_id", dtype=DataType.VARCHAR, max_length=50),
FieldSchema(name="interaction_vector", dtype=DataType.FLOAT_VECTOR, dim=768),
FieldSchema(name="interaction_summary", dtype=DataType.VARCHAR, max_length=500),
FieldSchema(name="timestamp", dtype=DataType.INT64)
]
memory_collection = Collection(name="user_memory", schema=CollectionSchema(user_memory_fields))
同じユーザーが戻ってきたとき、エージェントはMilvusから最も関連性の高い過去のやりとりを取得し、よりつながりのある、人間のような体験を生成するためにそれらを使用することができます。例えば、ユーザーが先週投資ファンドについて質問した場合、エージェントはその文脈を思い出し、積極的に応答することができる:「おかえりなさい!"おかえりなさい!前回お話したファンドについてまだご質問はありますか?"
milvus搭載エージェントシステムのパフォーマンスを最適化する方法
Milvusを利用したエージェントシステムを本番環境に導入する場合、パフォーマンスチューニングが重要になります。低レイテンシと高スループットを実現するためには、いくつかの重要なパラメータに注意を払う必要があります:
1.適切なインデックスタイプの選択
適切なインデックス構造を選択することが重要です。例えば、HNSW (Hierarchical Navigable Small World)は、精度が重要な金融やヘルスケアのような高リコールシナリオに最適です。IVF_FLATは、電子商取引の推奨のような大規模なアプリケーションに適しており、高速なパフォーマンスとメモリ使用量の削減と引き換えに、多少リコールが低くても許容されます。
2.シャーディング戦略
保存されたガイドラインの数が100万エントリを超える場合、ビジネスドメインやユースケースごとにデータを分割するためにパーティションを使用することをお勧めします。パーティショニングは、クエリごとの検索スペースを減らし、検索速度を向上させ、データセットが大きくなっても待ち時間を安定させます。
3.キャッシュ構成
標準的な顧客クエリやトラフィックの多いワークフローなど、頻繁にアクセスされるガイドラインについては、Milvusのクエリ結果キャッシュを使用することができます。これにより、システムは以前の結果を再利用することができ、繰り返し検索する際の待ち時間を5ミリ秒以下に短縮することができます。
ハンズオンデモParlantとMilvus LiteでスマートなQ&Aシステムを構築する方法
Milvus LiteはMilvusの軽量版で、アプリケーションに簡単に組み込むことができるPythonライブラリです。Jupyter Notebooksのような環境で素早くプロトタイプを作成したり、計算リソースが限られたエッジデバイスやスマートデバイスで実行するのに理想的です。その小さなフットプリントにもかかわらず、Milvus Liteは他のMilvusデプロイメントと同じAPIをサポートしています。つまり、Milvus Lite用に書いたクライアントサイドのコードは、後からMilvusやZilliz Cloudのフルインスタンスにシームレスに接続することができます。
このデモでは、Milvus LiteとParlantを連携させ、最小限のセットアップでコンテキストに応じた回答を高速に提供するインテリジェントなQ&Aシステムの構築方法をご紹介します。
前提条件
1.Parlant GitHub: https://github.com/emcie-co/parlant
2.Parlant ドキュメント: https://parlant.io/docs
3.python3.10以上
4.OpenAI_key
5.MlivusLite
ステップ1:依存関係のインストール
# Install required Python packages
pip install pymilvus parlant openai
# Or, if you’re using a Conda environment:
conda activate your_env_name
pip install pymilvus parlant openai
ステップ2:環境変数の設定
# Set your OpenAI API key
export OPENAI_API_KEY="your_openai_api_key_here"
# Verify that the variable is set correctly
echo $OPENAI_API_KEY
ステップ 3: コアコードの実装
- カスタムOpenAIエンベッダーの作成
class OpenAIEmbedder(p.Embedder):
# Converts text into vector embeddings with built-in timeout and retry
# Dimension: 1536 (text-embedding-3-small)
# Timeout: 60 seconds; Retries: up to 2 times
- ナレッジベースの初期化
1.kb_articlesというMilvusコレクションを作成する。
2.サンプルデータ(返金ポリシー、交換ポリシー、配送時間など)を挿入する。
3.検索を高速化するためにHNSWインデックスを構築する。
- ベクトル検索ツールの構築
@p.tool
async def vector_search(query: str, top_k: int = 5, min_score: float = 0.35):
# 1. Convert user query into a vector
# 2. Perform similarity search in Milvus
# 3. Return results with relevance above threshold
- パーラントエージェントの設定
ガイドライン1:事実またはポリシーに関連する質問については、エージェントは最初にベクトル検索を実行する必要があります。
ガイドライン 2:証拠が見つかった場合、エージェントは構造化されたテンプレート(要約+要点+ソース)を使って返答しなければならない。
# Guideline 1: Run vector search for factual or policy-related questions
await agent.create_guideline(
condition="User asks a factual question about policy, refund, exchange, or shipping",
action=(
"Call vector_search with the user's query. "
"If evidence is found, synthesize an answer by quoting key sentences and cite doc_id/title. "
"If evidence is insufficient, ask a clarifying question before answering."
),
tools=[vector_search],
# Guideline 2: Use a standardized, structured response when evidence is available
await agent.create_guideline(
condition=“Evidence is available”,
action=(
“Answer with the following template:\n”
“Summary: provide a concise conclusion.\n”
“Key points: 2-3 bullets distilled from evidence.\n”
“Sources: list doc_id and title.\n”
“Note: if confidence is low, state limitations and ask for clarification.”
),
tools=[],
)
tools=[],
)
- 完全なコードを書く
import os
import asyncio
import json
from typing import List, Dict, Any
import parlant.sdk as p
from pymilvus import MilvusClient, DataType
# 1) Environment variables: using OpenAI (as both the default generation model and embedding service)
# Make sure the OPENAI_API_KEY is set
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
if not OPENAI_API_KEY:
raise RuntimeError("Please set OPENAI_API_KEY environment variable")
# 2) Initialize Milvus Lite (runs locally, no standalone service required)
# MilvusClient runs in Lite mode using a local file path (requires pymilvus >= 2.x)
client = MilvusClient("./milvus_demo.db") # Lite mode uses a local file path
COLLECTION = "kb_articles"
# 3) Example data: three policy or FAQ entries (in practice, you can load and chunk data from files)
DOCS = [
{"doc_id": "POLICY-001", "title": "Refund Policy", "chunk": "Refunds are available within 30 days of purchase if the product is unused."},
{"doc_id": "POLICY-002", "title": "Exchange Policy", "chunk": "Exchanges are permitted within 15 days; original packaging required."},
{"doc_id": "FAQ-101", "title": "Shipping Time", "chunk": "Standard shipping usually takes 3–5 business days within the country."},
]
# 4) Generate embeddings using OpenAI (you can replace this with another embedding service)
# Here we use Parlant’s built-in OpenAI embedder for simplicity, but you could also call the OpenAI SDK directly.
class OpenAIEmbedder(p.Embedder):
async def embed(self, texts: List[str], hints: Dict[str, Any] = {}) -> p.EmbeddingResult:
# Generate text embeddings using the OpenAI API, with timeout and retry handling
import openai
try:
client = openai.AsyncOpenAI(
api_key=OPENAI_API_KEY,
timeout=60.0, # 60-second timeout
max_retries=2 # Retry up to 2 times
)
print(f"Generating embeddings for {len(texts)} texts...")
response = await client.embeddings.create(
model="text-embedding-3-small",
input=texts
)
vectors = [data.embedding for data in response.data]
print(f"Successfully generated {len(vectors)} embeddings.")
return p.EmbeddingResult(vectors=vectors)
except Exception as e:
print(f"OpenAI API call failed: {e}")
# Return mock vectors for testing Milvus connectivity
print("Using mock vectors for testing...")
import random
vectors = [[random.random() for _ in range(1536)] for _ in texts]
return p.EmbeddingResult(vectors=vectors)
@property
def id(self) -> str:
return "text-embedding-3-small"
@property
def max_tokens(self) -> int:
return 8192
@property
def tokenizer(self) -> p.EstimatingTokenizer:
from parlant.core.nlp.tokenization import ZeroEstimatingTokenizer
return ZeroEstimatingTokenizer()
@property
def dimensions(self) -> int:
return 1536
embedder = OpenAIEmbedder()
async def ensure_collection_and_load():
# Create the collection (schema: primary key, vector field, additional fields)
if not client.has_collection(COLLECTION):
client.create_collection(
collection_name=COLLECTION,
dimension=len((await embedder.embed(["dimension_probe"])).vectors[0]),
# Default metric: COSINE (can be changed with metric_type="COSINE")
auto_id=True,
)
# Create an index to speed up retrieval (HNSW used here as an example)
client.create_index(
collection_name=COLLECTION,
field_name="vector",
index_type="HNSW",
metric_type="COSINE",
params={"M": 32, "efConstruction": 200}
)
# Insert data (skip if already exists; simple idempotent logic for the demo)
# Generate embeddings
chunks = [d["chunk"] for d in DOCS]
embedding_result = await embedder.embed(chunks)
vectors = embedding_result.vectors
# Check if the same doc_id already exists; this is for demo purposes only — real applications should use stricter deduplication
# Here we insert directly. In production, use an upsert operation or an explicit primary key
client.insert(
COLLECTION,
data=[
{"vector": vectors[i], "doc_id": DOCS[i]["doc_id"], "title": DOCS[i]["title"], "chunk": DOCS[i]["chunk"]}
for i in range(len(DOCS))
],
)
# Load into memory
client.load_collection(COLLECTION)
# 5) Define the vector search tool (Parlant Tool)
@p.tool
async def vector_search(context: p.ToolContext, query: str, top_k: int = 5, min_score: float = 0.35) -> p.ToolResult:
# 5.1 Generate the query vector
embed_res = await embedder.embed([query])
qvec = embed_res.vectors[0]
# 5.2 Search Milvus
results = client.search(
collection_name=COLLECTION,
data=[qvec],
limit=top_k,
output_fields=["doc_id", "title", "chunk"],
search_params={"metric_type": "COSINE", "params": {"ef": 128}},
)
# 5.3 Assemble structured evidence and filter by score threshold
hits = []
for hit in results[0]:
score = hit["distance"] if "distance" in hit else hit.get("score", 0.0)
if score >= min_score:
hits.append({
"doc_id": hit["entity"]["doc_id"],
"title": hit["entity"]["title"],
"chunk": hit["entity"]["chunk"],
"score": float(score),
})
return p.ToolResult({"evidence": hits})
# 6) Run Parlant Server and create the Agent + Guidelines
async def main():
await ensure_collection_and_load()
async with p.Server() as server:
agent = await server.create_agent(
name="Policy Assistant",
description="Rule-controlled RAG assistant with Milvus Lite",
)
# Example variable: current time (can be used in templates or logs)
@p.tool
async def get_datetime(context: p.ToolContext) -> p.ToolResult:
from datetime import datetime
return p.ToolResult({"now": datetime.now().isoformat()})
await agent.create_variable(name="current-datetime", tool=get_datetime)
# Core Guideline 1: Run vector search for factual or policy-related questions
await agent.create_guideline(
condition="User asks a factual question about policy, refund, exchange, or shipping",
action=(
"Call vector_search with the user's query. "
"If evidence is found, synthesize an answer by quoting key sentences and cite doc_id/title. "
"If evidence is insufficient, ask a clarifying question before answering."
),
tools=[vector_search],
)
# Core Guideline 2: Use a standardized, structured response when evidence is available
await agent.create_guideline(
condition="Evidence is available",
action=(
"Answer with the following template:\\n"
"Summary: provide a concise conclusion.\\n"
"Key points: 2-3 bullets distilled from evidence.\\n"
"Sources: list doc_id and title.\\n"
"Note: if confidence is low, state limitations and ask for clarification."
),
tools=[],
)
# Hint: Local Playground URL
print("Playground: <http://localhost:8800>")
if __name__ == "__main__":
asyncio.run(main())
ステップ4:コードを実行する
# Run the main program
python main.py
- プレイグラウンドにアクセスしてください:
<http://localhost:8800>
これで、Parlantとmilvusを使ってインテリジェントなQ&Aシステムを構築することに成功しました。
ParlantとLangChain/LlamaIndexの比較:両者の違いと連携
LangChainや LlamaIndexのような既存のエージェントフレームワークと比較して、Parlantはどのように違うのでしょうか?
LangChainやLlamaIndexは汎用的なフレームワークです。幅広いコンポーネントや統合機能を提供しており、迅速なプロトタイピングや研究実験に最適です。しかし、本番環境でのデプロイとなると、エージェントの一貫性と信頼性を保つために、ルール管理、コンプライアンスチェック、信頼性メカニズムなど、開発者自身が余分なレイヤーを構築する必要があります。
Parlant は、組み込みのガイドライン管理、自己批判メカニズム、説明可能性ツールを提供し、開発者がエージェントの動作、応答、理由を管理するのを支援します。このため、Parlant は、金融、ヘルスケア、法律サービスなど、正確性と説明責任が重要な、顧客と接する重要なユースケースに特に適しています。
実際、これらのフレームワークは連携することができます:
複雑なデータ処理パイプラインや検索ワークフローを構築するにはLangChainを使用します。
最終的なインタラクションレイヤの管理にはParlantを使用し、出力がビジネスルールに従い、解釈可能であることを保証します。
Milvusをベクターデータベースの基盤として使用し、システム全体でリアルタイムの意味検索、記憶、知識検索を実現する。
結論
LLM エージェントが実験から本番へと移行するにつれ、もはや重要な問題は、何ができるかということではなく、いかに確実かつ安全にそれを実行できるかということである。Parlantはその信頼性のための構造と制御を提供し、Milvusはすべてを高速に保ち、コンテキストを認識するスケーラブルなベクトルインフラストラクチャを提供する。
この2つを組み合わせることで、開発者は、単に能力があるだけでなく、信頼でき、説明可能で、生産可能なAIエージェントを構築することができます。
🚀 GitHubでParlantをチェックし、 Milvusと統合して、独自のインテリジェントなルール駆動エージェントシステムを構築してください。
質問がある、またはどの機能についても深く知りたいですか?私たちの Discordチャンネルに参加するか、 GitHubに課題を提出してください。また、 Milvusオフィスアワーを通して、20分間の1対1のセッションを予約し、洞察、ガイダンス、質問への回答を得ることもできます。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



