# Conversation Agent with DeepSeek Function Calling

A reusable pattern for building autonomous conversation agents that use DeepSeek's
native function calling to access external data and tools.

Deployed at: `/home/agentuser/project/scripts/conversation_agent.py`

## Architecture

```
User message
    ↓
process(chat_id, message) — session management
    ↓
chat_with_tools(messages) — DeepSeek API loop
    ↓  (tool_calls?)
get_today_articles() / get_article_detail()
    ↓
Return text response → save to session
```

## Key Design Decisions

### 1. DeepSeek Native Function Calling
Use DeepSeek's `tools` parameter (OpenAI-compatible format) instead of prompt-based
tool calling. More reliable, less token waste.

```python
body = {
    "model": "deepseek-chat",
    "messages": full_messages,
    "tools": [...],        # Tool definitions
    "tool_choice": "auto", # Let model decide
}
```

### 2. Tool Call Loop
Model may request multiple tool calls before responding. Loop up to 5 iterations:

```python
for iteration in range(5):
    resp = requests.post(...)
    msg = resp["choices"][0]["message"]
    if msg.get("tool_calls"):
        # Execute tools, append results, continue loop
    else:
        return msg["content"]  # Final text response
```

### 3. Session Management
Per-chat_id JSON files in `state/conversations/`. Auto-expire after 1 hour.
Keep history trimmed to MAX_HISTORY rounds to avoid token bloat.

### 4. System Prompt Design
- Define role and capabilities clearly
- Describe available tools and WHEN to call them
- Provide output format examples
- Set tone (concise, actionable, no fluff)

## Pitfalls

- **max_tokens too high**: 1500 is enough for most replies; 2000+ causes timeouts with large context
- **Content too long**: Truncate article content to 2000 chars before feeding to model
- **Tool call loop exhaustion**: If model keeps calling tools without answering, increase loop limit or add guard
- **Session bloat**: Long conversation histories cause API timeouts; trim aggressively
- **DeepSeek API timeout**: Use 180s timeout for tool-call-heavy requests

## Integration with Messaging

The agent is transport-agnostic. It's been used with:
- 企微 WebSocket 智能机器人 (`aibot_ws_client.py`)
- Command-line testing
- (Planned) 企微 AI 机器人 MCP plugin
