Files
microdao-daarion/docs/cursor/11_llm_integration.md
Apple c552199eed chore: organize documentation structure for monorepo
- Create /docs structure (microdao, daarion, agents)
- Organize 61 cursor technical docs
- Add README files for each category
- Copy key documents to public categories
- Add GitHub setup instructions and scripts
2025-11-15 04:08:35 -08:00

647 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 11 — LLM Integration Guide (MicroDAO)
Інтеграція ChatGPT / OpenAI / інших моделей у агентську систему MicroDAO
Цей документ описує:
- де і як підключити LLM,
- як організувати backend-виклики,
- як звʼязати агента з моделлю,
- як працює agent-first онбординг,
- як працює агентський чат,
- як працює еволюційна модель на основі LLM.
Документ орієнтований на Cursor + Node/TS backend.
---
# 1. Принцип інтеграції
Усі виклики до LLM здійснюються **на бекенді**, не з фронтенду.
Причини:
- безпека (ключ не світиться),
- стабільність,
- контроль ціни,
- можливість додавати кэшинг, rate-limits,
- можливість підміняти провайдерів (OpenAI → Anthropic → локальні моделі).
---
# 2. Високорівнева архітектура
```
Frontend (React SPA)
|
| POST /agents/{id}/chat
Backend
├── agentsController.ts
├── llm/
│ ├── openaiClient.ts
│ ├── modelRouter.ts
│ └── prompts/
│ ├── system_agent.txt
│ └── system_onboarding.txt
|
OpenAI API (або інша модель)
```
---
# 3. Структура директорій для LLM
Додайте на бекенд:
```
src/
llm/
openaiClient.ts
modelRouter.ts
prompts/
system_agent.txt
system_onboarding.txt
system_evolution.txt
```
- `openaiClient.ts` — клієнт OpenAI / GPT.
- `modelRouter.ts` — місце, де ти можеш вирішити, яку модель використовувати (gpt-4.1-mini, o3, claude тощо).
- `prompts/*.txt` — системні промпти для:
- Agent Chat
- Onboarding Guide Agent
- Evolution Meta-Agent
---
# 4. Реалізація базового клієнта OpenAI
**Файл: `src/llm/openaiClient.ts`**
```ts
import OpenAI from "openai";
export const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY!,
});
export async function callLLM(messages: any[], model = "gpt-4.1-mini") {
const res = await openai.chat.completions.create({
model,
messages,
temperature: 0.2,
});
return res.choices[0]?.message?.content ?? "";
}
```
---
# 5. Model Router
**Файл: `src/llm/modelRouter.ts`**
```ts
export function pickModel(agentProfile: string) {
switch (agentProfile) {
case "technical":
return "gpt-4.1";
case "business":
return "gpt-4.1-mini";
case "creative":
return "gpt-4o-mini";
default:
return "gpt-4.1-mini";
}
}
```
У майбутньому це місце для:
* локальних моделей (Ollama, vLLM),
* кластеру DAGI,
* автоматичного підбору моделі.
---
# 6. Запит до LLM для агентського чату
**Файл: `src/controllers/agentsController.ts`**
```ts
import { callLLM } from "../llm/openaiClient";
import { pickModel } from "../llm/modelRouter";
import systemAgent from "../llm/prompts/system_agent.txt";
export async function chatWithAgent(req, res) {
const { agentId } = req.params;
const { messages } = req.body;
const agent = await db.agent.find(agentId);
const model = pickModel(agent.role);
const llmMessages = [
{ role: "system", content: systemAgent },
...messages
];
const reply = await callLLM(llmMessages, model);
// зберегти останнє повідомлення як agent message
await db.agentMessages.insert({
agent_id: agentId,
role: "assistant",
body: reply
});
res.json({ reply });
}
```
---
# 7. Інтеграція з Agent Chat у фронтенді
**Файл: `api/agents.ts`**
```ts
export async function agentChat(agentId: string, messages: ChatMessage[]) {
return api.post(`/agents/${agentId}/chat`, { messages });
}
```
**У `AgentChatWindow.tsx`:**
```ts
const onSend = async (text: string) => {
addMessage({ role: "user", content: text });
const response = await agentChat(agentId, [
...history,
{ role: "user", content: text }
]);
addMessage({ role: "assistant", content: response.reply });
};
```
---
# 8. Agent-First Onboarding Integration
Використовує той самий LLM-клієнт, але з іншим системним промптом:
**`prompts/system_onboarding.txt`:**
```
You are MicroDAO Guide Agent.
Your job is to ask the user questions one-by-one to configure their microDAO.
NEVER skip steps. NEVER jump too far.
Be friendly, minimalistic and precise.
```
У онбордингу:
```ts
const reply = await callLLM([
{ role: "system", content: onboardingSystemPrompt },
...conversation
]);
```
Але state-machine керує реальними діями (API), LLM — тільки текстом.
---
# 9. Integration with Evolutionary Agent (09_evolutionary_agent.md)
Meta-Agent (self-review) використовує **ще один промпт**:
`prompts/system_evolution.txt`:
```
You are Meta-Agent responsible for analyzing logs of conversations.
Find mistakes, weak answers, missing rules, and propose improvements.
Always output JSON with `["type", "value", "explanation"]`.
```
Self-review:
```ts
const improvements = await callLLM([
{ role: "system", content: evolutionPrompt },
{ role: "user", content: JSON.stringify(conversationLog) }
]);
```
---
# 10. Як передавати пам'ять агента в LLM
У LLM-запит можна додати:
* `short-term memory` (останні X повідомлень)
* `long-term memory` (витяг з Co-Memory)
* `agent profile`
* інструкції агента (структура з DB)
Приклад у messages:
```ts
const llmMessages = [
{ role: "system", content: systemPrompt },
{ role: "assistant", content: "AGENT_PROFILE:" + JSON.stringify(agentProfile) },
{ role: "assistant", content: "MEMORY:" + JSON.stringify(memories) },
...history,
{ role: "user", content: question }
];
```
---
# 11. Безпека
* API key зберігати у `.env` на сервері.
* Ніколи не відправляти ключ у фронтенд.
* Додавати rate limit.
* Додавати аудит використання агента.
---
# 12. Кешування та оптимізація
## 12.1. Кешування відповідей
Для однакових запитів можна кешувати відповіді:
```ts
const cacheKey = hash(messages);
const cached = await cache.get(cacheKey);
if (cached) return cached;
const reply = await callLLM(messages);
await cache.set(cacheKey, reply, { ttl: 3600 });
return reply;
```
## 12.2. Streaming відповідей
Для кращого UX можна використовувати streaming:
```ts
const stream = await openai.chat.completions.create({
model,
messages,
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) {
res.write(content);
}
}
```
## 12.3. Rate Limiting
Обмеження кількості запитів:
```ts
import rateLimit from "express-rate-limit";
const agentLimiter = rateLimit({
windowMs: 60 * 1000, // 1 хвилина
max: 10, // 10 запитів на хвилину
keyGenerator: (req) => req.user.id,
});
```
---
# 13. Альтернативні провайдери
## 13.1. Anthropic Claude
```ts
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY!,
});
export async function callClaude(messages: any[]) {
const response = await anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
messages,
});
return response.content[0].text;
}
```
## 13.2. Локальні моделі (Ollama)
```ts
export async function callOllama(messages: any[], model = "llama2") {
const response = await fetch("http://localhost:11434/api/chat", {
method: "POST",
body: JSON.stringify({
model,
messages,
}),
});
const data = await response.json();
return data.message.content;
}
```
## 13.3. Уніфікований інтерфейс
```ts
interface LLMProvider {
call(messages: any[], options?: any): Promise<string>;
}
class OpenAIProvider implements LLMProvider {
async call(messages: any[], options?: any) {
return callLLM(messages, options?.model);
}
}
class AnthropicProvider implements LLMProvider {
async call(messages: any[], options?: any) {
return callClaude(messages);
}
}
export function getLLMProvider(provider: string): LLMProvider {
switch (provider) {
case "openai":
return new OpenAIProvider();
case "anthropic":
return new AnthropicProvider();
case "ollama":
return new OllamaProvider();
default:
return new OpenAIProvider();
}
}
```
---
# 14. Обробка помилок
## 14.1. Retry Logic
```ts
async function callLLMWithRetry(
messages: any[],
model: string,
maxRetries = 3
): Promise<string> {
for (let i = 0; i < maxRetries; i++) {
try {
return await callLLM(messages, model);
} catch (error) {
if (i === maxRetries - 1) throw error;
await sleep(1000 * (i + 1)); // exponential backoff
}
}
throw new Error("LLM call failed after retries");
}
```
## 14.2. Fallback моделі
```ts
async function callLLMWithFallback(messages: any[], primaryModel: string) {
try {
return await callLLM(messages, primaryModel);
} catch (error) {
console.warn(`Primary model failed, using fallback`);
return await callLLM(messages, "gpt-3.5-turbo");
}
}
```
---
# 15. Моніторинг та логування
## 15.1. Логування викликів
```ts
async function callLLM(messages: any[], model: string) {
const startTime = Date.now();
try {
const reply = await openai.chat.completions.create({
model,
messages,
temperature: 0.2,
});
const duration = Date.now() - startTime;
const tokens = reply.usage?.total_tokens || 0;
logger.info("LLM call", {
model,
duration,
tokens,
cost: calculateCost(model, tokens),
});
return reply.choices[0]?.message?.content ?? "";
} catch (error) {
logger.error("LLM call failed", { model, error });
throw error;
}
}
```
## 15.2. Метрики
Відстежувати:
- кількість викликів на агента
- середній час відповіді
- витрати на токени
- частота помилок
- популярні моделі
---
# 16. Завдання для Cursor
```
You are a senior backend + frontend engineer.
Integrate OpenAI LLM into the MicroDAO Agents system using:
- 11_llm_integration.md
- 03_api_core_snapshot.md
- 05_coding_standards.md
Tasks:
1. Create openaiClient.ts
2. Create modelRouter.ts
3. Add AgentChat endpoint
4. Connect AgentChatWindow to backend
5. Add LLM to AgentOnboardingChat
6. Add LLM to EvolutionMetaAgent (stub)
Output:
- list of modified files
- diff
- summary
```
---
# 17. Типи та інтерфейси
## 17.1. ChatMessage
```ts
interface ChatMessage {
role: "system" | "user" | "assistant";
content: string;
timestamp?: string;
}
```
## 17.2. LLMResponse
```ts
interface LLMResponse {
content: string;
model: string;
tokens?: {
prompt: number;
completion: number;
total: number;
};
finishReason?: string;
}
```
## 17.3. AgentChatRequest
```ts
interface AgentChatRequest {
messages: ChatMessage[];
context?: {
channelId?: string;
threadId?: string;
userId?: string;
};
options?: {
temperature?: number;
maxTokens?: number;
stream?: boolean;
};
}
```
---
# 18. Тестування
## 18.1. Unit Tests
```ts
describe("openaiClient", () => {
it("should call LLM with correct messages", async () => {
const messages = [
{ role: "system", content: "You are a helpful assistant" },
{ role: "user", content: "Hello" },
];
const response = await callLLM(messages);
expect(response).toBeDefined();
expect(typeof response).toBe("string");
});
});
```
## 18.2. Integration Tests
```ts
describe("Agent Chat Integration", () => {
it("should handle full chat flow", async () => {
const agentId = "test-agent";
const messages = [
{ role: "user", content: "Hello" },
];
const response = await agentChat(agentId, messages);
expect(response.reply).toBeDefined();
});
});
```
---
# 19. Результат
Після інтеграції:
* будь-який агент microDAO працює на GPT/LLM,
* онбординг веде агент-гіда,
* Team Assistant відповідає у чаті,
* Meta-Agent генерує покращення,
* вся система стає справжньою OS на базі ШІ.
---
# 20. Наступні кроки
Після базової інтеграції можна додати:
- Streaming відповідей для кращого UX
- Кешування для оптимізації витрат
- Підтримку альтернативних провайдерів
- Fine-tuning моделей для конкретних спільнот
- Інтеграцію з DAGI для колективного навчання
---
**Готово.**
Це **повна специфікація інтеграції LLM**, готова до використання в Cursor.