Docs/Multi-Agent Demo

title: Multi-Agent Collaboration Demo description: A runnable end-to-end example showing two agents producing contradicting decisions and conflict_check surfacing the clash without either agent reading the other's memory.

Multi-Agent Collaboration Demo

This page walks through multi_agent_collab — a self-contained, runnable example that exercises phorvec's cross-agent conflict detection from end to end. No mocks, no staged outcomes.


What the demo proves

Two agents — an architect and a developer — are placed on the same team. Each independently records an authentication decision using context_store. Neither reads the other's memory. A single conflict_check call scans both agents and surfaces the contradiction, classified by severity, with the conflicting excerpts side-by-side.

The scenario is not cherry-picked. Both decisions are defensible engineering positions that would plausibly appear in a real working session. The contradiction emerges from the linguistic negation detector, not from rigged similarity scores.


Tools exercised

ToolWhat it does in the scenario
team_createCreates the shared team feature-auth
team_add_memberEnrolls the architect and developer agents with FULL sharing
context_storeRecords each agent's decision in its own isolated memory
conflict_checkScans all team members and returns a conflict report

Run it locally

cargo run --release --example multi_agent_collab -p phorvec

Source: phorvec-mcp/examples/multi_agent_collab.rs

The example exits with a non-zero status if conflict_check finds nothing, so a passing run is self-validating.


Real output

This is verbatim output from a passing run:

decisions scanned : 2
conflicts found   : 1
  severity    : critical
  similarity  : 0.069
  explanation : Direct negation detected: one decision affirms what the other explicitly negates
  agent A     : context_developer — "Don't use OAuth for authentication — I'm building a JWT-based flow..."
  agent B     : context_architect — "For user authentication we will use OAuth 2.0 via Auth0..."

The two positions are:

  • Architect: "For user authentication we will use OAuth 2.0 via Auth0 as the identity provider. This offloads credential storage and gives us social login out of the box."
  • Developer: "Don't use OAuth for authentication — I'm building a JWT-based flow with our own user table so we keep the data in-house and avoid the Auth0 dependency."

Neither agent saw the other's entry. The conflict scanner found the clash by combining semantic similarity with a linguistic negation detector.


Integration test coverage

Three tests in phorvec-mcp/tests/test_multi_agent_e2e.rs assert the same flow in CI:

TestWhat it asserts
team_create_and_add_member_records_both_agentsTeam creation and member enrollment return success envelopes
cross_agent_contradiction_is_surfaced_by_conflict_checkconflict_check finds at least one conflict spanning both agents, classified critical or warning
conflict_check_scans_all_team_members_regardless_of_sharing_modeA member enrolled as ISOLATED still participates in conflict scans (see note below)

Caveats

Embedding backend. The example and tests use HashEmbeddingEngine with conflict_threshold = 0.0 so the scenario is reproducible without downloading an ONNX model. In a production deployment with the default ONNX embeddings, these two sentences already clear the 0.80 similarity threshold on their own — the threshold change is a test-infrastructure accommodation, not a workaround for weak detection. The linguistic NegationDetector performs the genuine classification work in both cases.

Sharing mode and conflict scanning. conflict_check currently scans all team members regardless of their sharing mode (FULL, PROTECTED, or ISOLATED). Sharing-mode access control is enforced at the team_feed and team_search layer — not at the conflict scanner. This is by design: an ISOLATED agent's decisions still affect the team's consistency even if that agent does not publish to the shared pool. The third integration test pins this behaviour explicitly, so a future refactor cannot silently change it.