signal_agent.tools.mcp_config import (
get_reddit_mcp_toolset,
get_dk_mcp_toolset,
get_nano_banana_mcp_toolset
)
PROJECT_ID, MODEL_LOC, SERVICE_LOC, SECRETS = init_environment()
shared_model = Gemini(
model="gemini-3-flash-preview",
vertexai=True,
project=PROJECT_ID,
location=MODEL_LOC,
retry_options=types.HttpRetryOptions(attempts=3),
)
### Memory Ingestion Logic
The architecture separates short-term working memory from long-term semantic persistence. Long-term memory uses automated callbacks to vectorize and store session history, while short-term memory handles intra-session handoffs.
#### Long-term Memory
Automated via `save_session_to_memory_callback`, which runs after every turn to persist session details. Vertex AI handles embedding, storage, and semantic indexing.
Paste this code in `dev_signal_agent/agent.py`:
async def save_session_to_memory_callback(*args, **kwargs) -> None:
"""
Defensive callback to persist session history to the Vertex AI memory bank.
"""
ctx = kwargs.get("callback_context") or (args[0] if args else None)
# Check connection to Memory Service
if ctx and hasattr(ctx, "_invocation_context") and ctx._invocation_context.memory_service:
# Save the session!
await ctx._invocation_context.memory_service.add_session_to_memory(
ctx._invocation_context.session
)
#### Short-term Memory
The `add_info_to_state` function manages intra-session working memory, ensuring reliable handoffs between specialists. This state is managed by the Vertex AI Session Service for transient resilience but resets on new session IDs.
Paste this code in `dev_signal_agent/agent.py`
def add_info_to_state(tool_context: ToolContext, key: str, data: str) -> dict:
tool_context.state[key] = data
return {"status": "success", "message": f"Saved '{key}' to state."}
### Specialist 1: Reddit Scanner (Discovery)
Identifies high-engagement questions from the last 21 days. Leverages `load_memory` to calibrate searches against historical user interests, and actively captures new preferences for callback persistence.
Paste this code in `dev_signal_agent/agent.py`
Singleton toolsets
reddit_mcp = get_reddit_mcp_toolset(
client_id=SECRETS.get("REDDIT_CLIENT_ID", ""),
client_secret=SECRETS.get("REDDIT_CLIENT_SECRET", ""),
user_agent=SECRETS.get("REDDIT_USER_AGENT", "")
)
reddit_scanner = Agent(
name="reddit_scanner",
model=shared_model,
instruction="""
You are a Reddit research specialist. Your goal is to identify high-engagement questions
from the last 3 weeks on specific topics of interest, such as AI/agents on Cloud Run.
Follow these steps:
- MEMORY CHECK: Use
load_memory to retrieve the user's past areas of interest and preferred topics. Calibrate your search to align with these interests.
- Use the Reddit MCP tools to search for relevant subreddits and posts.
- Filter results for posts created within the last 21 days (3 weeks).
- Analyze "high-engagement" based on upvote counts and the number of comments.
- Recommend the most important and relevant questions for a technical audience.
- CRITICAL: For each recommended question, provide a direct link to the original thread and a concise summary of the discussion.
- CAPTURE PREFERENCES: Actively listen for user preferences, interests, or project details. Explicitly acknowledge them to ensure they are captured in the session history for future personalization.
""",
tools=[reddit_mcp, load_memory_tool.LoadMemoryTool()],
after_agent_callback=save_session_to_memory_callback,
)
### Specialist 2: GCP Expert (Grounding)
Triangulates facts by synthesizing official documentation, community sentiment, and broader web context. Enforces strict citation and state-handoff protocols.
Paste this code in `dev_signal_agent/agent.py`
dk_mcp = get_dk_mcp_toolset(api_key=SECRETS.get("DK_API_KEY", ""))
search_agent = Agent(
name="search_agent",
model=shared_model,
instruction="Execute Google Searches and return raw, structured results (Title, Link, Snippet).",
tools=[google_search],
)
gcp_expert = Agent(
name="gcp_expert",
model=shared_model,
instruction="""
You are a Google Cloud Platform (GCP) documentation expert.
Your goal is to provide accurate, detailed, and cited answers to technical questions by synthesizing official documentation with community insights.
For EVERY technical question, you MUST perform a comprehensive research sweep using ALL available tools:
- Official Docs (Grounding): Use DeveloperKnowledge MCP (
search_documents) to find the definitive technical facts.
- Social Media Research (Reddit): Use the Reddit MCP to research the question on social media. This allows you to find real-world user discussions, common pain points, or alternative solutions that might not be in official documentation.
- Broader Context (Web/Social): Use the
search_agent tool to find recent technical blogs, social media discussions, or tutorials.
Synthesize your answer:
- Start with the official answer based on GCP docs.
- Add "Social Media Insights" or "Common Issues" sections derived from Reddit and Web Search findings.
- CRITICAL: After providing your answer, you MUST use the
add_info_to_state tool to save your full technical response under the key: technical_research_findings.
- Cite your sources specifically at the end of your response, providing direct links (URLs) to the official documentation, blog posts, and Reddit threads used.
- CAPTURE PREFERENCES: Actively listen for user preferences, interests, or project details. Explicitly acknowledge them to ensure they are captured in the session history for future personalization.
""",
tools=[dk_mcp, AgentTool(search_agent), reddit_mcp, add_info_to_state],
after_agent_callback=save_session_to_memory_callback,
)
### Specialist 3: Blog Drafter (Creativity)
Drafts content based on expert findings and retrieves stylistic preferences from long-term memory.
Paste this code in `dev_signal_agent/agent.py`
nano_mcp = get_nano_banana_mcp_toolset()
blog_drafter = Agent
## Pitfall Guide
1. **Blurring Session State vs. Long-Term Memory Boundaries**: Using `tool_context.state` for cross-session preferences causes data loss on restart. Always route stylistic/interest data to Vertex AI Memory Bank via callbacks, and reserve state strictly for intra-session handoffs.
2. **Over-Reliance on PreloadMemoryTool**: Injecting all historical context upfront bloats the context window and increases latency. Use `PreloadMemoryTool` only for high-level preferences, and rely on `LoadMemoryTool` for targeted, on-demand retrieval during complex reasoning steps.
3. **Missing Defensive Callback Guards**: Memory ingestion callbacks can fail if the memory service isn't initialized or the invocation context is malformed. Always implement defensive checks (`hasattr(ctx, "_invocation_context")`) to prevent pipeline crashes during transient infrastructure hiccups.
4. **Unstructured Preference Capture**: Agents that don't explicitly acknowledge user preferences fail to trigger session history updates. Instruct agents to verbally confirm captured preferences ("Noted, I'll use a witty tone...") to ensure the callback successfully persists the data.
5. **Tool Routing Without Grounding**: Specialist agents querying multiple sources (Docs, Reddit, Web) without a synthesis step produce fragmented outputs. Enforce a strict instruction pipeline: Official Docs β Social/Community β Web Context β Structured Synthesis with direct citations.
6. **Ignoring Memory Service Latency**: Vector embedding and indexing introduce asynchronous delays. Design agent workflows to be resilient to eventual consistency, avoiding hard dependencies on immediately available memory vectors for critical path decisions.
## Deliverables
- **π Blueprint**: Multi-Agent Architecture with Vertex AI Memory Bank Integration (PDF/Markdown)
- Covers environment initialization, MCP server configuration, memory callback implementation, specialist agent routing, and preference capture validation.
- **β
Implementation Checklist**:
- [ ] Initialize `dev_signal_agent/agent.py` with shared Gemini model & retry options
- [ ] Configure MCP toolsets (Reddit, DK, Nano Banana)
- [ ] Implement `save_session_to_memory_callback` with defensive guards
- [ ] Deploy `add_info_to_state` for intra-session handoffs
- [ ] Configure `PreloadMemoryTool` + `LoadMemoryTool` retrieval patterns
- [ ] Validate specialist agent instructions for preference capture & citation enforcement
- [ ] Test cross-session personalization persistence & state boundary isolation
- **π§ Configuration Templates**: `mcp_config.py`, `env.py`, and ADK app routing scaffolds ready for Cloud Run deployment.