mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-09-13 04:04:09 +00:00
Implements the full Semantica × Agno integration stack as described in issue #249, wiring Semantica's semantic intelligence layer into Agno's agent/team primitives via five focused components. ## New components ### integrations/agno/ - `AgnoContextStore` — graph-backed MemoryDb (AgentMemory/storage) - `AgnoKnowledgeGraph` — relational AgentKnowledge with multi-hop GraphRAG - `AgnoDecisionKit` — Agno Toolkit: 6 decision-intelligence tools - `AgnoKGToolkit` — Agno Toolkit: 7 knowledge-graph tools - `AgnoSharedContext` — team-level shared ContextGraph with role scoping ### tests/integrations/agno/ - 110 tests, 0 failures - conftest.py installs comprehensive agno stubs for offline testing - Covers MemoryDb protocol, tool registration, shared memory pool, thread-safety, GraphRAG search, NER/relation extraction, and inference ### cookbook/integrations/ - agno_decision_intelligence.ipynb (finance/loan underwriting) - agno_graphrag_context.ipynb (regulatory compliance GraphRAG) - agno_multi_agent_shared_context.ipynb (multi-agent product strategy team) ### docs/integrations/agno.md - Full reference documentation with examples for all 5 components ## pyproject.toml - Added `agno = ["agno>=1.0.0"]` optional dependency - Added agno to the `all` extra ## Design notes - Zero breaking changes — fully additive - Graceful degradation when agno is not installed - Auto-creates VectorStore(backend="faiss") when none provided - _tools always populated for inspection regardless of agno install state - Works with both real agno package and offline stubs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
677 lines
27 KiB
Plaintext
677 lines
27 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "title",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Agno × Semantica: Multi-Agent Shared Context\n",
|
||
"\n",
|
||
"This notebook shows how an Agno **Team** of specialist agents can share a single `ContextGraph` so they:\n",
|
||
"\n",
|
||
"- Never make contradictory decisions\n",
|
||
"- Reuse each other's extracted knowledge without coupling implementations\n",
|
||
"- Maintain a full causal audit trail across all agents\n",
|
||
"\n",
|
||
"**Scenario:** A product strategy team with three specialist agents:\n",
|
||
"\n",
|
||
"| Agent | Role | Tools |\n",
|
||
"|---|---|---|\n",
|
||
"| `Researcher` | Extracts competitive intelligence from text | `AgnoKGToolkit` |\n",
|
||
"| `Analyst` | Evaluates opportunities and records decisions | `AgnoDecisionKit` |\n",
|
||
"| `Strategist` | Synthesises both into a recommendation | both |\n",
|
||
"\n",
|
||
"---\n",
|
||
"\n",
|
||
"## Architecture\n",
|
||
"\n",
|
||
"```\n",
|
||
"AgnoSharedContext (single ContextGraph + VectorStore)\n",
|
||
" │\n",
|
||
" ├── bind_agent(\"researcher\") → AgnoContextStore (role-scoped)\n",
|
||
" ├── bind_agent(\"analyst\") → AgnoContextStore (role-scoped)\n",
|
||
" └── bind_agent(\"strategist\") → AgnoContextStore (role-scoped)\n",
|
||
"\n",
|
||
"Agno Team\n",
|
||
" ├── Researcher memory=researcher_store tools=[AgnoKGToolkit(context=shared)]\n",
|
||
" ├── Analyst memory=analyst_store tools=[AgnoDecisionKit(context=shared)]\n",
|
||
" └── Strategist memory=strategist_store tools=[AgnoKGToolkit, AgnoDecisionKit]\n",
|
||
"```\n",
|
||
"\n",
|
||
"## Install\n",
|
||
"\n",
|
||
"```bash\n",
|
||
"pip install semantica[agno]\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "imports-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 1. Imports"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "imports",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import sys, os, json\n",
|
||
"sys.path.insert(0, os.path.abspath(\"../../\"))\n",
|
||
"\n",
|
||
"# ── Semantica core ───────────────────────────────────────────────────────────\n",
|
||
"from semantica.context import ContextGraph, AgentContext, CausalChainAnalyzer\n",
|
||
"from semantica.vector_store import VectorStore\n",
|
||
"from semantica.semantic_extract import NERExtractor, RelationExtractor\n",
|
||
"from semantica.reasoning import Reasoner\n",
|
||
"from semantica.kg import GraphBuilder, GraphAnalyzer, CentralityCalculator\n",
|
||
"\n",
|
||
"# ── Agno integration ─────────────────────────────────────────────────────────\n",
|
||
"from integrations.agno import (\n",
|
||
" AgnoSharedContext,\n",
|
||
" AgnoDecisionKit,\n",
|
||
" AgnoKGToolkit,\n",
|
||
" AGNO_AVAILABLE,\n",
|
||
")\n",
|
||
"\n",
|
||
"print(\"Semantica imports OK\")\n",
|
||
"print(f\"Agno installed: {AGNO_AVAILABLE}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "shared-context-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 2. Build the Shared Semantica Backend\n",
|
||
"\n",
|
||
"A single `VectorStore` and `ContextGraph` underpin the entire team. All agents read and write to the same store — role scoping is applied automatically by `AgnoSharedContext`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "build-shared",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# ── Single shared backends ───────────────────────────────────────────────────\n",
|
||
"shared_vector_store = VectorStore(backend=\"faiss\", dimension=768)\n",
|
||
"shared_graph = ContextGraph(advanced_analytics=True)\n",
|
||
"\n",
|
||
"print(\"Shared VectorStore (FAISS) ready\")\n",
|
||
"print(\"Shared ContextGraph ready\")\n",
|
||
"\n",
|
||
"# ── AgnoSharedContext: the team coordinator ───────────────────────────────────\n",
|
||
"shared = AgnoSharedContext(\n",
|
||
" vector_store=shared_vector_store,\n",
|
||
" knowledge_graph=shared_graph,\n",
|
||
" decision_tracking=True,\n",
|
||
" session_id=\"product_strategy_team_q1_2026\",\n",
|
||
")\n",
|
||
"print(f\"\\nAgnoSharedContext ready — session: {shared.session_id}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "bind-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 3. Bind Agent Roles\n",
|
||
"\n",
|
||
"Each agent gets a **role-scoped** `AgnoContextStore` via `bind_agent()`. All agents share the same underlying graph, but their writes are tagged with their role for filtering."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "bind-agents",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Bind each agent role — idempotent, can be called multiple times safely\n",
|
||
"researcher_store = shared.bind_agent(\"researcher\")\n",
|
||
"analyst_store = shared.bind_agent(\"analyst\")\n",
|
||
"strategist_store = shared.bind_agent(\"strategist\")\n",
|
||
"\n",
|
||
"print(\"Agent roles bound:\")\n",
|
||
"for role in shared.bound_roles:\n",
|
||
" store = shared.bind_agent(role)\n",
|
||
" print(f\" {role:15s} → session={store.session_id}\")\n",
|
||
"\n",
|
||
"# Verify all roles see the same underlying knowledge_graph\n",
|
||
"assert researcher_store._ctx is analyst_store._ctx\n",
|
||
"print(\"\\nAll agents share the same AgentContext ✓\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "seed-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 4. Pre-Load Competitive Intelligence\n",
|
||
"\n",
|
||
"Using **native Semantica APIs**, we load a competitive landscape into the shared graph. This represents knowledge the team has accumulated from prior research sessions."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "seed-intel",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Competitive intelligence documents\n",
|
||
"COMPETITIVE_INTEL = [\n",
|
||
" {\n",
|
||
" \"source\": \"market_research_q4_2025\",\n",
|
||
" \"text\": (\n",
|
||
" \"Competitor Alpha launched a new SaaS analytics platform in Q4 2025. \"\n",
|
||
" \"The product targets mid-market enterprises with annual revenue between \"\n",
|
||
" \"$50M–$500M and has attracted 200 paying customers within 3 months. \"\n",
|
||
" \"Pricing is $2,000/seat/year with volume discounts at 50+ seats. \"\n",
|
||
" \"Alpha raised a $80M Series C led by Sequoia Capital in November 2025.\"\n",
|
||
" ),\n",
|
||
" },\n",
|
||
" {\n",
|
||
" \"source\": \"customer_interviews_q4_2025\",\n",
|
||
" \"text\": (\n",
|
||
" \"Customer interviews reveal strong demand for AI-powered anomaly detection \"\n",
|
||
" \"in financial reporting workflows. 78% of CFOs surveyed cite 'time to insight' \"\n",
|
||
" \"as the top pain point — currently averaging 14 days per reporting cycle. \"\n",
|
||
" \"Competitor Alpha scores poorly on integration depth (NPS: 24) while \"\n",
|
||
" \"our legacy product scores 41. Customers value our data governance features \"\n",
|
||
" \"but want a modern UI and sub-second query times.\"\n",
|
||
" ),\n",
|
||
" },\n",
|
||
" {\n",
|
||
" \"source\": \"technology_scan_q4_2025\",\n",
|
||
" \"text\": (\n",
|
||
" \"Emerging technologies for consideration: LLM-native analytics interfaces \"\n",
|
||
" \"reduce time-to-insight by 60% in pilot studies (Stanford HAI, 2025). \"\n",
|
||
" \"Graph-based anomaly detection outperforms time-series approaches for \"\n",
|
||
" \"multi-entity financial fraud by 34% (ACM SIGMOD 2025). \"\n",
|
||
" \"Vector database adoption in enterprise analytics grew 120% YoY. \"\n",
|
||
" \"Apache Arrow and DuckDB emerging as standards for in-process OLAP.\"\n",
|
||
" ),\n",
|
||
" },\n",
|
||
"]\n",
|
||
"\n",
|
||
"# Use Semantica NER + RelationExtractor directly for rich extraction\n",
|
||
"ner = NERExtractor()\n",
|
||
"rel_extractor = RelationExtractor(confidence_threshold=0.55)\n",
|
||
"graph_builder = GraphBuilder(merge_entities=True)\n",
|
||
"\n",
|
||
"for doc in COMPETITIVE_INTEL:\n",
|
||
" text = doc['text']\n",
|
||
" entities = ner.extract_entities(text) or []\n",
|
||
" relations = rel_extractor.extract_relations(text) or []\n",
|
||
" print(f\"[{doc['source']}]\")\n",
|
||
" print(f\" Entities: {len(entities)}, Relations: {len(relations)}\")\n",
|
||
" # Store into shared context for all agents to access\n",
|
||
" shared._context.store(text, conversation_id=doc['source'])\n",
|
||
"\n",
|
||
"print(\"\\nCompetitive intelligence loaded into shared context\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "tools-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 5. Build Agent-Specific Tools\n",
|
||
"\n",
|
||
"Each toolkit is pointed at the **shared context** so tool calls across agents modify and read the same graph."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "build-tools",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Researcher's KG toolkit — builds knowledge from raw text\n",
|
||
"researcher_kg_kit = AgnoKGToolkit(\n",
|
||
" ner_extractor=ner,\n",
|
||
" relation_extractor=rel_extractor,\n",
|
||
" reasoner=Reasoner(),\n",
|
||
" context=shared.knowledge_graph, # shared graph\n",
|
||
")\n",
|
||
"\n",
|
||
"# Analyst's decision kit — records evaluations and finds precedents\n",
|
||
"analyst_decision_kit = AgnoDecisionKit(\n",
|
||
" context=shared._context, # shared AgentContext\n",
|
||
" max_precedents=5,\n",
|
||
" causal_depth=3,\n",
|
||
" enable_policy_check=True,\n",
|
||
")\n",
|
||
"\n",
|
||
"# Strategist gets both\n",
|
||
"strategist_kg_kit = AgnoKGToolkit(\n",
|
||
" ner_extractor=ner,\n",
|
||
" relation_extractor=rel_extractor,\n",
|
||
" reasoner=Reasoner(),\n",
|
||
" context=shared.knowledge_graph,\n",
|
||
")\n",
|
||
"strategist_decision_kit = AgnoDecisionKit(\n",
|
||
" context=shared._context,\n",
|
||
" max_precedents=5,\n",
|
||
")\n",
|
||
"\n",
|
||
"print(f\"Researcher toolkit: {len(researcher_kg_kit._tools)} tools\")\n",
|
||
"print(f\"Analyst toolkit: {len(analyst_decision_kit._tools)} tools\")\n",
|
||
"print(f\"Strategist toolkits: {len(strategist_kg_kit._tools)} + {len(strategist_decision_kit._tools)} tools\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "simulate-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 6. Simulate Agent Collaboration\n",
|
||
"\n",
|
||
"We simulate the agents' reasoning steps directly, showing how shared context propagates knowledge between roles."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "researcher-turn",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"=\" * 65)\n",
|
||
"print(\"RESEARCHER AGENT TURN\")\n",
|
||
"print(\"=\" * 65)\n",
|
||
"\n",
|
||
"# Researcher extracts entities from new competitive intel\n",
|
||
"new_intel = (\n",
|
||
" \"Competitor Beta just closed a strategic partnership with Microsoft Azure, \"\n",
|
||
" \"integrating their anomaly detection engine natively into Azure Synapse Analytics. \"\n",
|
||
" \"This gives Beta access to Microsoft's 300,000+ enterprise customer base. \"\n",
|
||
" \"Beta's CEO Sarah Chen announced the deal at Gartner Data & Analytics Summit.\"\n",
|
||
")\n",
|
||
"\n",
|
||
"# Step 1: Extract entities\n",
|
||
"entities_result = json.loads(researcher_kg_kit.extract_entities(new_intel))\n",
|
||
"print(f\"\\n[researcher] extracted {entities_result['count']} entities:\")\n",
|
||
"for e in entities_result['entities']:\n",
|
||
" print(f\" {e['name']:30s} type={e['type']}\")\n",
|
||
"\n",
|
||
"# Step 2: Extract relations\n",
|
||
"relations_result = json.loads(researcher_kg_kit.extract_relations(new_intel))\n",
|
||
"print(f\"\\n[researcher] extracted {relations_result['count']} relations\")\n",
|
||
"\n",
|
||
"# Step 3: Add to shared graph — now visible to ALL agents\n",
|
||
"add_result = json.loads(researcher_kg_kit.add_to_graph(\n",
|
||
" entities=json.dumps([\n",
|
||
" {\"name\": \"Competitor Beta\", \"type\": \"COMPANY\"},\n",
|
||
" {\"name\": \"Microsoft Azure\", \"type\": \"COMPANY\"},\n",
|
||
" {\"name\": \"Azure Synapse Analytics\", \"type\": \"PRODUCT\"},\n",
|
||
" {\"name\": \"Sarah Chen\", \"type\": \"PERSON\"},\n",
|
||
" {\"name\": \"Gartner Data & Analytics Summit\", \"type\": \"EVENT\"},\n",
|
||
" ]),\n",
|
||
" relations=json.dumps([\n",
|
||
" {\"source\": \"Competitor Beta\", \"relation\": \"PARTNERSHIP_WITH\", \"target\": \"Microsoft Azure\"},\n",
|
||
" {\"source\": \"Competitor Beta\", \"relation\": \"INTEGRATES_WITH\", \"target\": \"Azure Synapse Analytics\"},\n",
|
||
" {\"source\": \"Sarah Chen\", \"relation\": \"CEO_OF\", \"target\": \"Competitor Beta\"},\n",
|
||
" ]),\n",
|
||
"))\n",
|
||
"print(f\"\\n[researcher] added {add_result['nodes_added']} nodes, {add_result['edges_added']} edges to SHARED graph\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "analyst-turn",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"=\" * 65)\n",
|
||
"print(\"ANALYST AGENT TURN (sees researcher's graph additions)\")\n",
|
||
"print(\"=\" * 65)\n",
|
||
"\n",
|
||
"# Analyst queries the graph the researcher just populated\n",
|
||
"competitor_query = json.loads(analyst_decision_kit.find_precedents(\n",
|
||
" scenario=\"competitor partnership with cloud hyperscaler threatens market position\",\n",
|
||
" limit=3,\n",
|
||
"))\n",
|
||
"print(f\"\\n[analyst] find_precedents → {competitor_query['count']} similar past strategic responses found\")\n",
|
||
"\n",
|
||
"# Analyst records a strategic evaluation decision\n",
|
||
"eval_json = analyst_decision_kit.record_decision(\n",
|
||
" category=\"strategic_response\",\n",
|
||
" scenario=(\n",
|
||
" \"Competitor Beta + Microsoft Azure partnership gives Beta access to \"\n",
|
||
" \"300k enterprise customers via Azure Synapse native integration\"\n",
|
||
" ),\n",
|
||
" reasoning=(\n",
|
||
" \"Threat level: HIGH. Beta's Azure native integration removes our \"\n",
|
||
" \"integration advantage. Existing NPS lead (41 vs 24) remains but \"\n",
|
||
" \"distribution disadvantage is critical. Recommend accelerated cloud-native \"\n",
|
||
" \"partnership evaluation, specifically AWS Marketplace + Snowflake Native App.\"\n",
|
||
" ),\n",
|
||
" outcome=\"escalate_to_strategy\",\n",
|
||
" confidence=0.85,\n",
|
||
" entities=\"Competitor Beta, Microsoft Azure, AWS Marketplace, Snowflake\",\n",
|
||
")\n",
|
||
"eval_result = json.loads(eval_json)\n",
|
||
"analyst_decision_id = eval_result['decision_id']\n",
|
||
"print(f\"\\n[analyst] recorded evaluation → decision_id: {analyst_decision_id}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "strategist-turn",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"=\" * 65)\n",
|
||
"print(\"STRATEGIST AGENT TURN (sees both researcher + analyst work)\")\n",
|
||
"print(\"=\" * 65)\n",
|
||
"\n",
|
||
"# Strategist queries the graph for the full competitive picture\n",
|
||
"related = json.loads(strategist_kg_kit.find_related(\"Competitor Beta\", hops=2))\n",
|
||
"print(f\"\\n[strategist] 'Competitor Beta' 2-hop neighbourhood: {related['count']} entity/entities\")\n",
|
||
"for entity in related['related']:\n",
|
||
" print(f\" → {entity}\")\n",
|
||
"\n",
|
||
"# Strategist traces what the analyst decided\n",
|
||
"causal = json.loads(strategist_decision_kit.trace_causal_chain(analyst_decision_id, depth=3))\n",
|
||
"print(f\"\\n[strategist] causal chain for analyst decision: {causal}\")\n",
|
||
"\n",
|
||
"# Strategist records the final strategic recommendation\n",
|
||
"strategy_json = strategist_decision_kit.record_decision(\n",
|
||
" category=\"product_strategy\",\n",
|
||
" scenario=\"Q1 2026 product strategy: respond to Beta+Azure threat\",\n",
|
||
" reasoning=(\n",
|
||
" \"Based on researcher's KG (Beta+Azure integration, 300k customer reach) \"\n",
|
||
" \"and analyst's evaluation (threat level HIGH, escalated decision). \"\n",
|
||
" \"Strategy: (1) Accelerate AWS Marketplace listing by Q2 2026. \"\n",
|
||
" \"(2) Launch Snowflake Native App by Q3 2026. \"\n",
|
||
" \"(3) Invest $2M in UI modernisation to widen NPS lead. \"\n",
|
||
" \"(4) Fast-track LLM-native analytics interface (60% time-to-insight improvement per HAI study). \"\n",
|
||
" \"Existing NPS advantage (41 vs 24) provides 18-month window before Beta catches up.\"\n",
|
||
" ),\n",
|
||
" outcome=\"approved\",\n",
|
||
" confidence=0.88,\n",
|
||
" entities=\"AWS Marketplace, Snowflake, LLM Analytics, Q2 2026, Q3 2026\",\n",
|
||
")\n",
|
||
"strategy_result = json.loads(strategy_json)\n",
|
||
"print(f\"\\n[strategist] final recommendation recorded → {strategy_result['decision_id']}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "shared-pool-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 7. Verify Shared Memory Pool\n",
|
||
"\n",
|
||
"Memories written by one agent are readable by all others."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "verify-shared",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from integrations.agno.context_store import _MemoryRow as MemoryRow\n",
|
||
"\n",
|
||
"# Researcher writes a memory\n",
|
||
"researcher_row = MemoryRow(\n",
|
||
" memory=\"Beta + Azure partnership announced at Gartner Summit — threat level HIGH\",\n",
|
||
" user_id=\"researcher\",\n",
|
||
")\n",
|
||
"researcher_store.upsert_memory(researcher_row)\n",
|
||
"\n",
|
||
"# Analyst writes a memory\n",
|
||
"analyst_row = MemoryRow(\n",
|
||
" memory=\"NPS advantage (41 vs 24) gives 18-month window — accelerate cloud partnerships\",\n",
|
||
" user_id=\"analyst\",\n",
|
||
")\n",
|
||
"analyst_store.upsert_memory(analyst_row)\n",
|
||
"\n",
|
||
"# Strategist reads ALL memories from both agents\n",
|
||
"strategist_memories = strategist_store.read_memories()\n",
|
||
"\n",
|
||
"print(f\"Strategist sees {len(strategist_memories)} shared memory item(s):\")\n",
|
||
"for m in strategist_memories:\n",
|
||
" uid = getattr(m, 'user_id', '?')\n",
|
||
" text = getattr(m, 'memory', str(m))\n",
|
||
" print(f\" [{uid:12s}] {text[:80]}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "agno-team-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 8. Wire into Agno Team (requires API key)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "agno-team",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"if AGNO_AVAILABLE:\n",
|
||
" from agno.agent import Agent\n",
|
||
" from agno.team import Team\n",
|
||
" from agno.memory import AgentMemory\n",
|
||
" from agno.models.openai import OpenAIChat\n",
|
||
"\n",
|
||
" researcher_agent = Agent(\n",
|
||
" name=\"Researcher\",\n",
|
||
" model=OpenAIChat(id=\"gpt-4o\"),\n",
|
||
" memory=AgentMemory(db=researcher_store),\n",
|
||
" tools=[researcher_kg_kit],\n",
|
||
" show_tool_calls=True,\n",
|
||
" description=(\n",
|
||
" \"You are a competitive intelligence researcher. \"\n",
|
||
" \"Use extract_entities, extract_relations, and add_to_graph \"\n",
|
||
" \"to build a structured knowledge graph from market intelligence. \"\n",
|
||
" \"Always add discoveries to the shared graph.\"\n",
|
||
" ),\n",
|
||
" )\n",
|
||
"\n",
|
||
" analyst_agent = Agent(\n",
|
||
" name=\"Analyst\",\n",
|
||
" model=OpenAIChat(id=\"gpt-4o\"),\n",
|
||
" memory=AgentMemory(db=analyst_store),\n",
|
||
" tools=[analyst_decision_kit],\n",
|
||
" show_tool_calls=True,\n",
|
||
" description=(\n",
|
||
" \"You are a strategic analyst. Use find_precedents to check historical \"\n",
|
||
" \"responses to similar threats, then record_decision with your evaluation. \"\n",
|
||
" \"Always check if a similar situation was handled before acting.\"\n",
|
||
" ),\n",
|
||
" )\n",
|
||
"\n",
|
||
" strategist_agent = Agent(\n",
|
||
" name=\"Strategist\",\n",
|
||
" model=OpenAIChat(id=\"gpt-4o\"),\n",
|
||
" memory=AgentMemory(db=strategist_store),\n",
|
||
" tools=[strategist_kg_kit, strategist_decision_kit],\n",
|
||
" show_tool_calls=True,\n",
|
||
" description=(\n",
|
||
" \"You are the Chief Strategy Officer. Synthesise the researcher's knowledge \"\n",
|
||
" \"graph and the analyst's decision record into a concrete product strategy. \"\n",
|
||
" \"Use find_related to explore the competitive graph, then record_decision \"\n",
|
||
" \"with the final approved strategy.\"\n",
|
||
" ),\n",
|
||
" )\n",
|
||
"\n",
|
||
" strategy_team = Team(\n",
|
||
" name=\"Product Strategy Team\",\n",
|
||
" agents=[researcher_agent, analyst_agent, strategist_agent],\n",
|
||
" mode=\"coordinate\",\n",
|
||
" )\n",
|
||
"\n",
|
||
" strategy_team.print_response(\n",
|
||
" \"Competitor Beta just announced a native Azure integration. \"\n",
|
||
" \"Analyse the competitive landscape and recommend our Q1 2026 product strategy.\"\n",
|
||
" )\n",
|
||
"else:\n",
|
||
" print(\"[Agno not installed — skipping live team run]\")\n",
|
||
" print()\n",
|
||
" print(\"Expected team coordination flow:\")\n",
|
||
" print(\" 1. Researcher: extract_entities + add_to_graph (Beta+Azure)\")\n",
|
||
" print(\" 2. Analyst: find_precedents + record_decision (threat=HIGH, escalate)\")\n",
|
||
" print(\" 3. Strategist: find_related + trace_causal_chain + record_decision (final strategy)\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "post-session-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 9. Post-Session Analysis with Semantica\n",
|
||
"\n",
|
||
"After the team session, use **native Semantica APIs** for cross-agent audit, analytics, and causal chain review."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "cross-agent-insights",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Team-level insights from AgnoSharedContext\n",
|
||
"insights = shared.get_shared_insights()\n",
|
||
"print(\"Team session insights:\")\n",
|
||
"if isinstance(insights, dict):\n",
|
||
" for k, v in insights.items():\n",
|
||
" print(f\" {k}: {v}\")\n",
|
||
"else:\n",
|
||
" print(f\" {insights}\")\n",
|
||
"\n",
|
||
"print(f\"\\nBound agent roles: {shared.bound_roles}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "precedent-search",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Find all cross-agent strategic decisions\n",
|
||
"all_strategic = shared.find_precedents(\n",
|
||
" scenario=\"cloud partnership competitive response\",\n",
|
||
" category=\"strategic_response\",\n",
|
||
")\n",
|
||
"print(f\"Cross-agent strategic precedents: {len(all_strategic or [])}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "graph-analytics",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Graph analytics on the shared knowledge graph (Semantica native)\n",
|
||
"try:\n",
|
||
" analyzer = GraphAnalyzer()\n",
|
||
" analysis = analyzer.analyze_graph(shared.knowledge_graph)\n",
|
||
" print(\"Shared knowledge graph analysis:\")\n",
|
||
" if isinstance(analysis, dict):\n",
|
||
" for k, v in list(analysis.items())[:6]:\n",
|
||
" print(f\" {k}: {v}\")\n",
|
||
" else:\n",
|
||
" print(f\" {analysis}\")\n",
|
||
"except Exception as e:\n",
|
||
" print(f\"GraphAnalyzer: {e}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "centrality-analysis",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Which entities are most central in the competitive intelligence graph?\n",
|
||
"try:\n",
|
||
" centrality = CentralityCalculator()\n",
|
||
" scores = centrality.calculate_degree_centrality(shared.knowledge_graph)\n",
|
||
" print(\"Most central entities in shared graph:\")\n",
|
||
" if isinstance(scores, dict):\n",
|
||
" top = sorted(scores.items(), key=lambda x: x[1], reverse=True)[:5]\n",
|
||
" for entity, score in top:\n",
|
||
" print(f\" {entity:35s} centrality={score:.4f}\")\n",
|
||
" else:\n",
|
||
" print(f\" {scores}\")\n",
|
||
"except Exception as e:\n",
|
||
" print(f\"CentralityCalculator: {e}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "causal-analysis",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Direct Semantica causal chain analysis (no Agno needed)\n",
|
||
"try:\n",
|
||
" causal_analyzer = CausalChainAnalyzer(graph_store=shared.knowledge_graph)\n",
|
||
" # Query all decisions made during this session\n",
|
||
" decisions = shared.knowledge_graph.find_precedents(category=\"product_strategy\", limit=10)\n",
|
||
" print(f\"Product strategy decisions in shared graph: {len(decisions or [])}\")\n",
|
||
" for d in (decisions or [])[:3]:\n",
|
||
" scenario = d.get('scenario', '') if isinstance(d, dict) else str(d)\n",
|
||
" outcome = d.get('outcome', '') if isinstance(d, dict) else ''\n",
|
||
" print(f\" [{outcome:20s}] {scenario[:70]}\")\n",
|
||
"except Exception as e:\n",
|
||
" print(f\"CausalChainAnalyzer: {e}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "summary-section",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Summary\n",
|
||
"\n",
|
||
"| Pattern | Implementation |\n",
|
||
"|---|---|\n",
|
||
"| Single shared knowledge graph | `AgnoSharedContext(vector_store, knowledge_graph)` |\n",
|
||
"| Role-scoped memory | `shared.bind_agent(\"researcher\")` → `_AgentScopedStore` |\n",
|
||
"| Cross-agent memory visibility | All stores read from `shared._shared_memories` |\n",
|
||
"| KG tool sharing | `AgnoKGToolkit(context=shared.knowledge_graph)` |\n",
|
||
"| Decision tool sharing | `AgnoDecisionKit(context=shared._context)` |\n",
|
||
"| Thread-safe binding | `AgnoSharedContext._lock` (RLock) |\n",
|
||
"| Post-session analytics | `GraphAnalyzer`, `CentralityCalculator`, `CausalChainAnalyzer` — all Semantica native |\n",
|
||
"\n",
|
||
"**Key design rule:** Every agent writes to the **same underlying graph** via different role-scoped stores. The Agno integration is a thin routing layer — Semantica's full power is available at any point directly."
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"name": "python",
|
||
"version": "3.11.0"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|