File size: 6,971 Bytes
8c1f582
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# Usage Guide

This guide explains how to run UN motion simulations with AI agents.

## Prerequisites

1. **Python 3.12+** installed
2. **Virtual environment** set up
3. **API key** (for cloud provider) OR **Ollama** (for local provider)

## Setup

### 1. Install Dependencies

```bash
# Using uv (recommended)
uv pip install -r requirements.txt

# Or using pip
pip install -r requirements.txt
```

### 2. Configure Environment

```bash
# Copy the example configuration
cp .env.example .env

# Edit .env with your preferred editor
nano .env  # or vim, code, etc.
```

**For Cloud API (OpenAI/GPT):**
```bash
OPENAI_API_KEY=sk-your-key-here
MODEL_NAME=gpt-4
```

**For Cloud API (Anthropic/Claude):**
```bash
ANTHROPIC_API_KEY=sk-ant-your-key-here
MODEL_NAME=claude-3-opus-20240229
```

**For Local Models (Ollama):**
```bash
# No API key needed!
# Install Ollama from https://ollama.ai
# Pull a model: ollama pull llama3
LOCAL_MODEL_NAME=llama3
```

## Running Simulations

### Basic Usage

```bash
# Run a motion with cloud API (default)
python scripts/run_motion.py 01_gaza_ceasefire_resolution

# Run with local model
python scripts/run_motion.py 01_gaza_ceasefire_resolution --provider local

# Run with specific model
python scripts/run_motion.py 01_gaza_ceasefire_resolution --model gpt-4-turbo

# Test with sample (only 5 countries)
python scripts/run_motion.py 01_gaza_ceasefire_resolution --sample 5
```

### Command-Line Options

```
python scripts/run_motion.py <motion_id> [options]

Required:
  motion_id              ID of the motion (e.g., 01_gaza_ceasefire_resolution)

Options:
  --provider {cloud,local}   AI provider (default: cloud)
  --model MODEL_NAME         Specific model to use (optional)
  --sample N                 Only query N countries for testing (optional)
  -h, --help                 Show help message
```

## Example Output

```
============================================================
Running Motion: 01_gaza_ceasefire_resolution
Provider: cloud | Model: gpt-4
============================================================

βœ“ Loaded motion from /home/user/AI-Agent-UN/tasks/motions/01_gaza_ceasefire_resolution.md

πŸ“Š Querying 193 countries

[1/193] Querying Afghanistan... βœ… YES
[2/193] Querying Albania... βœ… YES
[3/193] Querying Algeria... βœ… YES
[4/193] Querying Andorra... βœ… YES
[5/193] Querying Angola... βœ… YES
...

============================================================
Vote Summary:
  YES:     156 (80.8%)
  NO:       25 (13.0%)
  ABSTAIN:  12 ( 6.2%)
============================================================

βœ“ Results saved to: tasks/reactions/01_gaza_ceasefire_resolution_20251009_143022.json
βœ“ Latest results: tasks/reactions/01_gaza_ceasefire_resolution_latest.json

βœ“ Motion simulation complete!
```

## Understanding Results

Results are saved as JSON files in `tasks/reactions/`:

### File Structure

```json
{
  "motion_id": "01_gaza_ceasefire_resolution",
  "motion_path": "tasks/motions/01_gaza_ceasefire_resolution.md",
  "timestamp": "2025-10-09T14:30:22.123456Z",
  "provider": "cloud",
  "model": "gpt-4",
  "total_votes": 193,
  "vote_summary": {
    "yes": 156,
    "no": 25,
    "abstain": 12
  },
  "votes": [
    {
      "country": "United States",
      "country_slug": "united-states",
      "vote": "yes",
      "statement": "The United States supports this ceasefire agreement as it represents a critical step toward de-escalation and humanitarian relief. We emphasize the importance of protecting civilians and ensuring accountability for violations of international law.",
      "error": null
    },
    {
      "country": "Russia",
      "country_slug": "russia",
      "vote": "yes",
      "statement": "Russia welcomes this ceasefire and calls for immediate humanitarian access. We emphasize the need for a comprehensive political settlement based on international law and UN resolutions.",
      "error": null
    }
  ]
}
```

### Analyzing Results

You can analyze results programmatically:

```python
import json

# Load results
with open('tasks/reactions/01_gaza_ceasefire_resolution_latest.json') as f:
    results = json.load(f)

# Print vote breakdown
print(f"Total votes: {results['total_votes']}")
print(f"YES: {results['vote_summary']['yes']}")
print(f"NO: {results['vote_summary']['no']}")
print(f"ABSTAIN: {results['vote_summary']['abstain']}")

# Find all NO votes
no_votes = [v for v in results['votes'] if v['vote'] == 'no']
for vote in no_votes:
    print(f"{vote['country']}: {vote['statement']}")
```

## Tips and Best Practices

### 1. Testing with Samples

When developing or testing, use `--sample` to query only a few countries:

```bash
# Test with 5 countries first
python scripts/run_motion.py 01_gaza_ceasefire_resolution --sample 5
```

### 2. Cost Management (Cloud API)

- Start with small samples to estimate costs
- A full run (193 countries) typically uses ~200-300 API calls
- Use cheaper models (gpt-3.5-turbo) for testing
- Consider local models (Ollama) for cost-free experimentation

### 3. Local Models

Pros:
- No API costs
- Complete privacy
- Unlimited usage

Cons:
- Requires local compute resources
- May have lower quality responses
- Slower than cloud APIs

### 4. Troubleshooting

**Error: "api_key client option must be set"**
- Make sure `.env` file exists
- Check that `OPENAI_API_KEY` is set correctly
- Verify the key is valid

**Error: "Motion not found"**
- Check that the motion ID matches the filename (without .md)
- Motion files must be in `tasks/motions/`

**Error: "openai package not installed"**
- Install dependencies: `uv pip install -r requirements.txt`

**Error: Connection refused (local model)**
- Make sure Ollama is running: `ollama serve`
- Check that the model is pulled: `ollama pull llama3`

## Advanced Usage

### Using Alternative APIs

You can use any OpenAI-compatible API by setting `API_BASE_URL`:

```bash
# OpenRouter
API_BASE_URL=https://openrouter.ai/api/v1
OPENAI_API_KEY=your-openrouter-key

# Local OpenAI-compatible server
API_BASE_URL=http://localhost:11434/v1
```

### Creating New Motions

1. Create a new markdown file in `tasks/motions/`
2. Use the format from existing motions
3. Run: `python scripts/run_motion.py your_new_motion_id`

### Analyzing Patterns

Compare different runs:

```bash
# Run with different models
python scripts/run_motion.py 01_gaza_ceasefire_resolution --model gpt-4
python scripts/run_motion.py 01_gaza_ceasefire_resolution --model gpt-3.5-turbo
python scripts/run_motion.py 01_gaza_ceasefire_resolution --provider local --model llama3

# Compare results
diff tasks/reactions/01_gaza_ceasefire_resolution_20251009_143022.json \
     tasks/reactions/01_gaza_ceasefire_resolution_20251009_144533.json
```

## Next Steps

- Create additional motions in `tasks/motions/`
- Analyze voting patterns across different issues
- Compare how different AI models vote
- Export results to visualization tools
- Build analysis scripts to identify voting blocs