Skip to content

add Interview action #115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
78a5ec0
add interview action
zhangzaibin May 22, 2025
b96dca0
interview actiontype
zhangzaibin May 22, 2025
3d29467
fix warning
zhangzaibin May 22, 2025
66acd8e
fix
zhangzaibin May 22, 2025
d73bade
add todo
zhangzaibin May 22, 2025
705fcb0
refactor interview action
zhangzaibin May 22, 2025
1c9a381
add TODO
zhangzaibin May 22, 2025
0be53d0
fix
zhangzaibin May 22, 2025
c6bacb9
add explaination
zhangzaibin May 22, 2025
3f810c1
add explaination
zhangzaibin May 22, 2025
86f99dd
add interview doc
zhangzaibin May 22, 2025
c4f724d
finish doc
zhangzaibin May 22, 2025
6ecc6ae
clean control action
zhangzaibin May 23, 2025
23be6f4
rafactor env
zhangzaibin May 23, 2025
8263d98
finish the doc of interview action
zhangzaibin May 23, 2025
b7c614e
remove interview from avaliable action list
zhangzaibin May 23, 2025
b67ab18
clean unuseful files
zhangzaibin May 23, 2025
997c8fc
add explaination
zhangzaibin May 23, 2025
aeae315
add test function
zhangzaibin May 23, 2025
44d25c7
fix precommit
zhangzaibin May 23, 2025
b0fc96c
fix precommit
zhangzaibin May 23, 2025
6a8d184
fix format
zhangzaibin May 23, 2025
14b0eb9
issue #101 change twitter_channel to channel
May 25, 2025
c350b3a
refactor interview
zhangzaibin May 30, 2025
87cbf8a
update qr code
yiyiyi0817 May 30, 2025
1298e05
Merge branch 'camel-ai:main' into main
Jack-mi May 31, 2025
e59c365
update twitter_channel name
May 31, 2025
d6ede43
update pytest
yiyiyi0817 Jun 2, 2025
bd9fcf9
add default model=None in gen_control_agents_with_data
yiyiyi0817 Jun 2, 2025
902ccdd
issue #101 change twitter_channel to channel (#122)
yiyiyi0817 Jun 2, 2025
3b28fce
Merge branch 'interview' of https://github.com/camel-ai/oasis into in…
yiyiyi0817 Jun 2, 2025
060924b
add aget_model_response and fix pre-commit
yiyiyi0817 Jun 2, 2025
6943ffd
fix pre-commit
yiyiyi0817 Jun 2, 2025
5f62f88
add interview_record bool args and add more description of interview …
yiyiyi0817 Jun 2, 2025
d854359
fix pytest
yiyiyi0817 Jun 2, 2025
1fc8fe4
update news in readme
yiyiyi0817 Jun 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
326 changes: 326 additions & 0 deletions docs/cookbooks/twitter_interview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
---
title: 'Interview'
description: 'Learn how to conduct interviews with AI agents in Twitter simulations using the INTERVIEW action type'
---

# Interview

This cookbook demonstrates how to use the INTERVIEW action type to conduct interviews with AI agents in a Twitter simulation. The interview functionality allows you to ask specific questions to agents and collect their responses, which is useful for research, opinion polling, and understanding agent behaviors.

## Overview

The INTERVIEW action type enables you to:
- Ask specific questions to individual agents
- Collect structured responses from agents
- Store interview data in the database for analysis
- Conduct interviews alongside regular social media interactions

## Key Features

- **Manual Interview Actions**: Use `ManualAction` with `ActionType.INTERVIEW` to conduct interviews
- **Automatic Response Collection**: The system automatically collects and stores agent responses
- **Database Storage**: All interview data is stored in the trace table for later analysis
- **Concurrent Execution**: Interviews can be conducted alongside other social media actions

## Important Note

**Do NOT include `ActionType.INTERVIEW` in the `available_actions` list** when creating your agent graph. The interview action is designed to be used only manually by researchers/developers, not automatically selected by LLM agents. Including it in `available_actions` would allow agents to interview each other automatically, which is typically not desired behavior.

## Complete Example

```python
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
import asyncio
import os
import sqlite3
import json

from camel.models import ModelFactory
from camel.types import ModelPlatformType, ModelType

import oasis
from oasis import (ActionType, LLMAction, ManualAction,
generate_twitter_agent_graph)


async def main():
openai_model = ModelFactory.create(
model_platform=ModelPlatformType.OPENAI,
model_type=ModelType.GPT_4O_MINI,
)

# Define the available actions for the agents
# Note: INTERVIEW is NOT included here to prevent LLM from automatically selecting it
# INTERVIEW can still be used manually via ManualAction
available_actions = [
ActionType.CREATE_POST,
ActionType.LIKE_POST,
ActionType.REPOST,
ActionType.FOLLOW,
ActionType.DO_NOTHING,
ActionType.QUOTE_POST,
# ActionType.INTERVIEW, # DO NOT include this - interviews should be manual only
]

agent_graph = await generate_twitter_agent_graph(
profile_path=("data/twitter_dataset/anonymous_topic_200_1h/"
"False_Business_0.csv"),
model=openai_model,
available_actions=available_actions,
)

# Define the path to the database
db_path = "./data/twitter_simulation.db"

# Delete the old database
if os.path.exists(db_path):
os.remove(db_path)

# Make the environment
env = oasis.make(
agent_graph=agent_graph,
platform=oasis.DefaultPlatformType.TWITTER,
database_path=db_path,
)

# Run the environment
await env.reset()

# First timestep: Agent 0 creates a post
actions_1 = {}
actions_1[env.agent_graph.get_agent(0)] = ManualAction(
action_type=ActionType.CREATE_POST,
action_args={"content": "Earth is flat."})
await env.step(actions_1)

# Second timestep: Let some agents respond with LLM actions
actions_2 = {
agent: LLMAction()
# Activate 5 agents with id 1, 3, 5, 7, 9
for _, agent in env.agent_graph.get_agents([1, 3, 5, 7, 9])
}
await env.step(actions_2)

# Third timestep: Agent 1 creates a post, and we interview Agent 0
actions_3 = {}
actions_3[env.agent_graph.get_agent(1)] = ManualAction(
action_type=ActionType.CREATE_POST,
action_args={"content": "Earth is not flat."})

# Create an interview action to ask Agent 0 about their views
actions_3[env.agent_graph.get_agent(0)] = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "What do you think about the shape of the Earth? Please explain your reasoning."})

await env.step(actions_3)

# Fourth timestep: Let some other agents respond
actions_4 = {
agent: LLMAction()
for _, agent in env.agent_graph.get_agents([2, 4, 6, 8, 10])
}
await env.step(actions_4)

# Fifth timestep: Interview multiple agents
actions_5 = {}
actions_5[env.agent_graph.get_agent(1)] = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "Why do you believe the Earth is not flat?"})

actions_5[env.agent_graph.get_agent(2)] = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "What are your thoughts on the debate about Earth's shape?"})

await env.step(actions_5)

# Sixth timestep: Final LLM actions for remaining agents
actions_6 = {
agent: LLMAction()
for _, agent in env.agent_graph.get_agents([3, 5, 7, 9])
}
await env.step(actions_6)

# Close the environment
await env.close()

# visualize the interview results
print("\n=== Interview Results ===")
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Here we query all interview records from the database
# We use ActionType.INTERVIEW.value as the query condition to get all interview records
# Each record contains user ID, interview information (in JSON format), and creation timestamp
cursor.execute("""
SELECT user_id, info, created_at
FROM trace
WHERE action = ?
""", (ActionType.INTERVIEW.value,))

# This query retrieves all interview records from the trace table
# - user_id: the ID of the agent who was interviewed
# - info: JSON string containing interview details (prompt, response, etc.)
# - created_at: timestamp when the interview was conducted
# We'll parse this data below to display the interview results
for user_id, info_json, timestamp in cursor.fetchall():
info = json.loads(info_json)
print(f"\nAgent {user_id} (Timestep {timestamp}):")
print(f"Prompt: {info.get('prompt', 'N/A')}")
print(f"Interview ID: {info.get('interview_id', 'N/A')}")
print(f"Response: {info.get('response', 'N/A')}")

conn.close()


if __name__ == "__main__":
asyncio.run(main())
```

## How It Works

### 1. Setup and Configuration

**Important**: Do NOT include `ActionType.INTERVIEW` in your available actions list. Interviews should only be conducted manually:

```python
# Correct configuration - INTERVIEW is NOT included
available_actions = [
ActionType.CREATE_POST,
ActionType.LIKE_POST,
ActionType.REPOST,
ActionType.FOLLOW,
ActionType.DO_NOTHING,
ActionType.QUOTE_POST,
# ActionType.INTERVIEW, # DO NOT include - interviews are manual only
]
```

This prevents LLM agents from automatically selecting the interview action during their decision-making process. Interviews can still be conducted using `ManualAction`.

### 2. Conducting Interviews

Use `ManualAction` with `ActionType.INTERVIEW` to conduct interviews:

```python
# Single interview
interview_action = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "What are your thoughts on climate change?"})

actions = {env.agent_graph.get_agent(0): interview_action}
await env.step(actions)
```

### 3. Multiple Interviews in One Step

You can interview multiple agents simultaneously:

```python
actions = {}
actions[env.agent_graph.get_agent(1)] = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "Why do you believe the Earth is not flat?"})

actions[env.agent_graph.get_agent(2)] = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "What are your thoughts on the debate about Earth's shape?"})

await env.step(actions)
```

### 4. Mixing Interviews with Other Actions

Interviews can be conducted alongside regular social media actions:

```python
actions = {}
# Regular post creation
actions[env.agent_graph.get_agent(1)] = ManualAction(
action_type=ActionType.CREATE_POST,
action_args={"content": "Earth is not flat."})

# Interview action
actions[env.agent_graph.get_agent(0)] = ManualAction(
action_type=ActionType.INTERVIEW,
action_args={"prompt": "What do you think about the shape of the Earth?"})

await env.step(actions)
```

## Data Storage and Retrieval

### Database Schema

Interview data is stored in the `trace` table with the following structure:
- `user_id`: The ID of the interviewed agent
- `action`: Set to `ActionType.INTERVIEW.value`
- `info`: JSON string containing interview details
- `created_at`: Timestamp of the interview

### Retrieving Interview Results

```python
import sqlite3
import json

conn = sqlite3.connect(db_path)
cursor = conn.cursor()

# Query all interview records
cursor.execute("""
SELECT user_id, info, created_at
FROM trace
WHERE action = ?
""", (ActionType.INTERVIEW.value,))

for user_id, info_json, timestamp in cursor.fetchall():
info = json.loads(info_json)
print(f"Agent {user_id}: {info.get('response', 'N/A')}")

conn.close()
```

### Interview Data Structure

Each interview record contains:
- `prompt`: The question asked to the agent
- `interview_id`: Unique identifier for the interview
- `response`: The agent's response to the question

## Best Practices

### 1. Strategic Interview Timing

Conduct interviews at strategic points in your simulation:
- After controversial posts to gauge reactions
- Before and after significant events
- At regular intervals to track opinion changes

### 2. Question Design

Design effective interview questions:
- Be specific and clear
- Avoid leading questions
- Ask open-ended questions for richer responses

```python
# Good examples
"What are your thoughts on renewable energy?"
"How do you feel about the recent policy changes?"
"Can you explain your reasoning behind your last post?"

# Avoid
"Don't you think renewable energy is great?" # Leading
"Yes or no: Do you like cats?" # Too restrictive
```
3 changes: 2 additions & 1 deletion docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"cookbooks/reddit_simulation",
"cookbooks/sympy_tools_simulation",
"cookbooks/search_tools_simulation",
"cookbooks/custom_prompt_simulation"
"cookbooks/custom_prompt_simulation",
"cookbooks/twitter_interview"
]
},
{
Expand Down
Loading