40%+ of Kenyans don't know their constitutional rights. Not because the rights don't exist — Kenya's 2010 constitution is among the most progressive in Africa — but because the information is locked in dense legal language, available only in English, and not easily accessible through any institutional channel.
hakiyangu (haki = rights, yangu = mine — "my rights") is a multi-agent constitutional debate system that presents both the government's position and the citizen's rights on any constitutional question, in Swahili or English.
The Research Basis
arXiv:2305.19118 — Liang et al. (2023): "Encouraging Divergent Thinking in Large Language Models through Debate"
This paper demonstrated that when multiple AI agents argue opposing positions on a question, the final synthesized answer is measurably less biased and more accurate than a single-agent response. The adversarial format forces the AI to consider the strongest version of each position before synthesizing.
For constitutional rights questions, this is particularly important: the government has legitimate interests, and citizens have constitutional protections. Neither perspective alone gives a complete picture.
The Three-Agent Architecture
# Agent 1: Government Legal Officer
gov_response = call_gemini(
system="You are a Senior Government Legal Officer defending the Kenya government
position on constitutional rights. Be factual. Cite actual articles.",
user=f"Citizen question: '{question}'"
)
# Agent 2: Human Rights Advocate
cit_response = call_gemini(
system="You are a Human Rights Advocate defending citizen constitutional rights.
Cite actual articles. Acknowledge government has valid interests.",
user=f"Citizen question: '{question}'"
)
# Agent 3: Constitutional Law Lecturer (synthesis)
synthesis = call_gemini(
system="You are an independent Constitutional Law Lecturer at University of Nairobi.
Synthesize both sides. Focus on: what can the citizen do, what are their
strongest legal protections, when to seek formal legal help.",
user=f"Government argued: {gov_response[:300]}
Rights advocate argued: {cit_response[:300]}"
)
Each agent has a defined role and is explicitly instructed to cite the actual Kenya Constitution articles, not summarize them.
Rights Covered
Six rights from the Kenya Constitution 2010:
- Freedom of Expression (Article 33)
- Right to Property (Article 40)
- Right to a Fair Trial (Article 50)
- Freedom from Discrimination (Article 27)
- Right to Education (Article 43)
- Freedom of Movement (Article 26)
Each right has pre-loaded context, the government's constitutional basis for limitations, and the citizen's strongest protections.
The Error Handling Lesson
The original haki-debate-ai (now hakiyangu) had no try/except around the three Gemini calls. When the API returned HTTP 404 (due to a v1beta vs v1 endpoint change), the error surfaced as a full Streamlit traceback — including file paths and code snippets.
# Before: one unprotected call, full crash on error
gov_response = call_gemini(gov_system, question)
# After: wrapped calls with Swahili error messages
try:
gov_response = call_gemini(gov_system, question)
except Exception as e:
gov_response = f"⚠️ Hitilafu: {str(e)[:60]}"
Users see "Hitilafu ya API (404). Jaribu tena baadaye. / API error. Please try again later." — not a Python traceback. Production apps owe users graceful degradation.
Deploy It
# Streamlit Cloud: github.com/gabrielmahia/hakiyangu
# Secret: GOOGLE_API_KEY = "your-gemini-key"
Try it at hakiyangu.streamlit.app (setup in progress)
github.com/gabrielmahia/hakiyangu · CC BY-NC-ND 4.0
Top comments (1)
Multi-agent debate is a good fit here for a reason that gets overlooked: in low-resource languages the failure is rarely a wrong fact, it is a confidently fluent paraphrase that drops a legal qualifier. A single pass has no way to surface that, but an adversarial pass does, because the critic is looking for what changed rather than whether it reads well. The harder question is evaluation - who judges the debate, and in which language? If the judge is stronger in English than in Swahili you have just moved the bias one layer up.