@botpress/adk-cli 1.19.0-beta.3 → 1.19.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/ui-dist/assets/{index-CSTz-oTK.js → index-B3b7PPgV.js} +4 -4
- package/{dist/index-DNqXHLNi-27nvpkee.js → assets/ui-dist/assets/index-BESZeTO5.js} +2 -2
- package/{dist/index-DAztRXeA-vr85xnxs.css → assets/ui-dist/assets/index-DIFGtVmI.css} +1 -1
- package/{dist/index-DfjXY3Oo-szsanhnt.js → assets/ui-dist/assets/index-a3ZL0_Jr.js} +2 -2
- package/assets/ui-dist/index.html +2 -2
- package/dist/{README-wjb7z7f0.md → README-824wa4jj.md} +1 -1
- package/dist/SKILL-75ym6tcj.md +257 -0
- package/dist/SKILL-chnwzmt1.md +548 -0
- package/dist/SKILL-d4bs53y3.md +244 -0
- package/dist/SKILL-h4b2f1n9.md +114 -0
- package/dist/SKILL-hbw5nt95.md +111 -0
- package/dist/actions-h7hxxvxr.md +823 -0
- package/dist/adk-build-emhwd0tg.md +39 -0
- package/dist/adk-debug-yrrdtpmb.md +23 -0
- package/dist/adk-dev-console-7z9rtjpy.md +17 -0
- package/dist/adk-document-ras6zzzh.md +68 -0
- package/dist/adk-eval-vx76dwq0.md +17 -0
- package/dist/adk-explain-fcsaw852.md +22 -0
- package/dist/adk-init-9kmxmbbe.md +30 -0
- package/dist/adk-ship-dybzn884.md +29 -0
- package/dist/adk-test-xq67savs.md +27 -0
- package/dist/adk-validate-1p4skv4m.md +31 -0
- package/dist/advanced-patterns-z86m9h1a.md +669 -0
- package/dist/agent-config-1aqvkrgf.md +450 -0
- package/dist/agent-steps-zj4c1n9t.md +115 -0
- package/dist/agent0-assets/skills/adk/SKILL.md +5 -5
- package/dist/agent0-assets/skills/adk/references/cli.md +265 -24
- package/dist/agent0-assets/skills/adk-debugger/SKILL.md +5 -5
- package/dist/agent0-assets/skills/adk-debugger/references/common-failures.md +1 -1
- package/dist/agent0-assets/skills/adk-debugger/references/debug-workflow.md +3 -3
- package/dist/agent0-assets/skills/adk-debugger/references/traces-and-logs.md +15 -7
- package/dist/assets-q7jt8r2q.md +237 -0
- package/dist/autonomous-execution-fymc12e5.md +747 -0
- package/dist/cli-c31e06yr.md +1334 -0
- package/dist/cli.js +963 -548
- package/dist/commands.json +24 -3
- package/dist/common-failures-ht29w2db.md +231 -0
- package/dist/component-registry-bbpw0see.md +43 -0
- package/dist/context-api-760cvh0h.md +461 -0
- package/dist/conversation-analysis-8ka4nrm4.md +420 -0
- package/dist/conversation-lifecycle-4seqqjc1.md +311 -0
- package/dist/conversations-gwfvxaee.md +1111 -0
- package/dist/custom-components-y5wdgpey.md +167 -0
- package/dist/debug-workflow-vz84q80v.md +239 -0
- package/dist/desk-k54ktvsd.md +852 -0
- package/dist/doc-standards-ck6ax2jd.md +124 -0
- package/dist/eval-format-7n9brja4.md +354 -0
- package/dist/evals-y1zcr1mc.md +11 -0
- package/dist/explain-config-1yaq3zzd.md +424 -0
- package/dist/files-dzt0wxn3.md +918 -0
- package/dist/{index-gqxgqnyz.html → index-3t354nbw.html} +2 -2
- package/dist/{index-CSTz-oTK-mdfh47r8.js → index-B3b7PPgV-zetkb01w.js} +4 -4
- package/{assets/ui-dist/assets/index-DNqXHLNi.js → dist/index-BESZeTO5-2rpmcefa.js} +2 -2
- package/{assets/ui-dist/assets/index-DAztRXeA.css → dist/index-DIFGtVmI-d4dhjg97.css} +1 -1
- package/{assets/ui-dist/assets/index-DfjXY3Oo.js → dist/index-a3ZL0_Jr-q145h35p.js} +2 -2
- package/dist/integration-actions-xang7tma.md +659 -0
- package/dist/integrations-k5ss07f4.md +266 -0
- package/dist/interfaces-6t0bpxs4.md +97 -0
- package/dist/knowledge-bases-20rg8p5c.md +456 -0
- package/dist/llm-debugging-76ng8rzm.md +209 -0
- package/dist/mcp-server-n1asyzhv.md +112 -0
- package/dist/messages-gkkg0b54.md +769 -0
- package/dist/model-configuration-f273kgd0.md +201 -0
- package/dist/multi-agent-dashboard-1mdfjdts.md +70 -0
- package/dist/pages-xn18xn73.md +273 -0
- package/dist/patterns-mistakes-5vb99dhf.md +469 -0
- package/dist/plugins-ttnx8f49.md +280 -0
- package/dist/tables-x45t36dd.md +1136 -0
- package/dist/tags-46td3qrg.md +516 -0
- package/dist/test-patterns-hj47w4nc.md +355 -0
- package/dist/testing-workflow-2vkp932f.md +225 -0
- package/dist/tools-wk7bq24z.md +581 -0
- package/dist/trace-summarization-hdyx1c2e.md +313 -0
- package/dist/traces-and-logs-f2kjfh19.md +203 -0
- package/dist/triggers-4j2cc86x.md +719 -0
- package/dist/ui-server-entry.js +977 -162
- package/dist/workflow-steps-mrdrf1c5.md +851 -0
- package/dist/workflows-gadx3s69.md +1408 -0
- package/dist/zai-agent-reference-e6644aad.md +454 -0
- package/dist/zai-complete-guide-mnna5d6f.md +1408 -0
- package/package.json +4 -4
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# Knowledge Bases
|
|
2
|
+
|
|
3
|
+
Knowledge Bases enable RAG (Retrieval Augmented Generation) by indexing documents, websites, and structured data for semantic search and AI-powered responses.
|
|
4
|
+
|
|
5
|
+
## Basic Concepts
|
|
6
|
+
|
|
7
|
+
### What are Knowledge Bases?
|
|
8
|
+
|
|
9
|
+
- **RAG implementation**: Enhance AI responses with relevant context
|
|
10
|
+
- **Multiple sources**: Index local files, websites, or table data
|
|
11
|
+
- **Semantic search**: Find relevant information based on meaning
|
|
12
|
+
- **Auto-chunking**: Documents are automatically split for optimal retrieval
|
|
13
|
+
|
|
14
|
+
### File Location
|
|
15
|
+
|
|
16
|
+
- **Location**: `src/knowledge/*.ts`
|
|
17
|
+
- **Auto-registration**: Knowledge bases are automatically available to AI
|
|
18
|
+
|
|
19
|
+
## Creating Knowledge Bases
|
|
20
|
+
|
|
21
|
+
### Basic Structure
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { Knowledge, DataSource } from "@botpress/runtime";
|
|
25
|
+
|
|
26
|
+
// Define a data source
|
|
27
|
+
const docsSource = DataSource.Directory.fromPath("src/knowledge/docs", {
|
|
28
|
+
id: "docs",
|
|
29
|
+
filter: (path) => path.endsWith(".md") || path.endsWith(".pdf"),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Create knowledge base
|
|
33
|
+
export const DocsKnowledgeBase = new Knowledge({
|
|
34
|
+
name: "docsKB",
|
|
35
|
+
description: "Documentation knowledge base",
|
|
36
|
+
sources: [docsSource],
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Data Source Types
|
|
41
|
+
|
|
42
|
+
### 1. Local Files (Directory)
|
|
43
|
+
|
|
44
|
+
Index local markdown, PDF, and text files:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const docsSource = DataSource.Directory.fromPath("src/knowledge", {
|
|
48
|
+
id: "docs",
|
|
49
|
+
|
|
50
|
+
// Filter specific file types
|
|
51
|
+
filter: (path) => {
|
|
52
|
+
return (
|
|
53
|
+
path.endsWith(".md") || path.endsWith(".pdf") || path.endsWith(".txt")
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Note**: Local file sources are for development only and won't work in production.
|
|
60
|
+
|
|
61
|
+
### 2. Website Crawling
|
|
62
|
+
|
|
63
|
+
Index websites via sitemap or direct URLs:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// From sitemap
|
|
67
|
+
const websiteSource = DataSource.Website.fromSitemap(
|
|
68
|
+
"https://docs.example.com/sitemap.xml",
|
|
69
|
+
{
|
|
70
|
+
id: "website",
|
|
71
|
+
maxPages: 500, // Maximum pages to crawl (1-50000)
|
|
72
|
+
maxDepth: 3, // Maximum crawl depth (1-20)
|
|
73
|
+
fetch: "node:fetch", // Optional: 'node:fetch' or 'integration:browser'
|
|
74
|
+
|
|
75
|
+
// Filter pages
|
|
76
|
+
filter: (context) => {
|
|
77
|
+
// Skip archive pages
|
|
78
|
+
if (context.url.includes("/archive/")) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
// Only include documentation pages
|
|
82
|
+
return context.url.includes("/docs/");
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// From direct URLs
|
|
88
|
+
const urlsSource = DataSource.Website.fromUrls(
|
|
89
|
+
[
|
|
90
|
+
"https://example.com/page1",
|
|
91
|
+
"https://example.com/page2",
|
|
92
|
+
"https://example.com/page3",
|
|
93
|
+
],
|
|
94
|
+
{
|
|
95
|
+
id: "specific_pages",
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// From llms.txt (AI-friendly site manifest)
|
|
100
|
+
const llmsTxtSource = DataSource.Website.fromLlmsTxt(
|
|
101
|
+
"https://example.com/llms.txt",
|
|
102
|
+
{
|
|
103
|
+
id: "llms_txt",
|
|
104
|
+
maxPages: 100,
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Table-Based
|
|
110
|
+
|
|
111
|
+
Table-backed knowledge sources are not fully implemented yet. The shape below is useful as a forward-looking pattern, but today you should treat it as experimental and prefer directory- or website-backed sources for production workflows.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { FAQTable } from "../tables/FAQ";
|
|
115
|
+
|
|
116
|
+
const tableSource = DataSource.Table.fromTable(FAQTable, {
|
|
117
|
+
id: "faq_kb",
|
|
118
|
+
|
|
119
|
+
// Transform row data into searchable text
|
|
120
|
+
transform: ({ row }) => {
|
|
121
|
+
return `Question: ${row.question}
|
|
122
|
+
|
|
123
|
+
Answer: ${row.answer}
|
|
124
|
+
|
|
125
|
+
Category: ${row.category}
|
|
126
|
+
Tags: ${row.tags.join(", ")}`;
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
// Optional: Filter rows
|
|
130
|
+
filter: ({ row }) => {
|
|
131
|
+
return row.published === true;
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 4. Multiple Sources
|
|
137
|
+
|
|
138
|
+
Combine different source types:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
export const CombinedKnowledgeBase = new Knowledge({
|
|
142
|
+
name: "combinedKB",
|
|
143
|
+
description: "Knowledge from multiple sources",
|
|
144
|
+
sources: [
|
|
145
|
+
// Local documentation
|
|
146
|
+
DataSource.Directory.fromPath("src/knowledge/docs", {
|
|
147
|
+
id: "local_docs",
|
|
148
|
+
}),
|
|
149
|
+
|
|
150
|
+
// Website documentation
|
|
151
|
+
DataSource.Website.fromSitemap("https://docs.example.com/sitemap.xml", {
|
|
152
|
+
id: "online_docs",
|
|
153
|
+
maxPages: 100,
|
|
154
|
+
}),
|
|
155
|
+
|
|
156
|
+
// FAQ from database
|
|
157
|
+
DataSource.Table.fromTable(FAQTable, {
|
|
158
|
+
id: "faq",
|
|
159
|
+
transform: ({ row }) => `Q: ${row.question}\nA: ${row.answer}`,
|
|
160
|
+
}),
|
|
161
|
+
],
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Using Knowledge Bases
|
|
166
|
+
|
|
167
|
+
### In Conversations
|
|
168
|
+
|
|
169
|
+
Provide knowledge bases to AI during execution:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { Conversation } from "@botpress/runtime";
|
|
173
|
+
import { DocsKnowledgeBase, FAQKnowledgeBase } from "../knowledge";
|
|
174
|
+
|
|
175
|
+
export const Chat = new Conversation({
|
|
176
|
+
channel: "chat.channel",
|
|
177
|
+
|
|
178
|
+
async handler({ execute }) {
|
|
179
|
+
await execute({
|
|
180
|
+
instructions:
|
|
181
|
+
"You are a helpful assistant. Use the provided knowledge to answer questions accurately.",
|
|
182
|
+
|
|
183
|
+
// Add knowledge bases
|
|
184
|
+
knowledge: [DocsKnowledgeBase, FAQKnowledgeBase],
|
|
185
|
+
|
|
186
|
+
// Optional: Add tools that can search knowledge
|
|
187
|
+
tools: [searchTool],
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### In Workflows
|
|
194
|
+
|
|
195
|
+
Knowledge bases work the same in workflows:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { Workflow } from "@botpress/runtime";
|
|
199
|
+
import { DocsKnowledgeBase } from "../knowledge";
|
|
200
|
+
|
|
201
|
+
export const ResearchWorkflow = new Workflow({
|
|
202
|
+
name: "research",
|
|
203
|
+
|
|
204
|
+
handler: async ({ input, execute }) => {
|
|
205
|
+
const result = await execute({
|
|
206
|
+
instructions: `Research the topic: ${input.topic}`,
|
|
207
|
+
knowledge: [DocsKnowledgeBase],
|
|
208
|
+
model: "openai:gpt-4o",
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return { research: result };
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Manual Search
|
|
217
|
+
|
|
218
|
+
Search knowledge bases programmatically:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { context } from "@botpress/runtime";
|
|
222
|
+
import { DocsKnowledgeBase } from "../knowledge";
|
|
223
|
+
|
|
224
|
+
export const searchAction = new Action({
|
|
225
|
+
name: "searchDocs",
|
|
226
|
+
input: z.object({ query: z.string() }),
|
|
227
|
+
|
|
228
|
+
async handler({ input }) {
|
|
229
|
+
const client = context.get("client");
|
|
230
|
+
|
|
231
|
+
// Search knowledge base
|
|
232
|
+
const { passages } = await client.searchFiles({
|
|
233
|
+
query: input.query,
|
|
234
|
+
tags: {
|
|
235
|
+
source: "knowledge-base",
|
|
236
|
+
kbName: [DocsKnowledgeBase.name],
|
|
237
|
+
},
|
|
238
|
+
limit: 5,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
results: passages.map((p) => ({
|
|
243
|
+
content: p.content,
|
|
244
|
+
score: p.score,
|
|
245
|
+
source: p.file.key,
|
|
246
|
+
})),
|
|
247
|
+
};
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Syncing Knowledge Bases
|
|
253
|
+
|
|
254
|
+
As of ADK 1.9+, knowledge bases are synced using the `adk kb` command, which runs automatically during `adk dev` and `adk deploy`.
|
|
255
|
+
|
|
256
|
+
### CLI Sync (Recommended)
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Interactive KB management
|
|
260
|
+
adk kb
|
|
261
|
+
|
|
262
|
+
# Non-interactive sync
|
|
263
|
+
adk kb sync -y
|
|
264
|
+
|
|
265
|
+
# Check sync status
|
|
266
|
+
adk kb status
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
The KB sync:
|
|
270
|
+
|
|
271
|
+
1. Detects all knowledge bases in your project
|
|
272
|
+
2. Identifies sources (directories, websites, tables)
|
|
273
|
+
3. Computes file hashes to detect changes
|
|
274
|
+
4. Syncs only changed content to Botpress Cloud
|
|
275
|
+
5. Handles orphaned sources (sources removed from code)
|
|
276
|
+
|
|
277
|
+
### Automatic Sync
|
|
278
|
+
|
|
279
|
+
KB sync runs automatically during:
|
|
280
|
+
|
|
281
|
+
- `adk dev` - Syncs on startup and file changes
|
|
282
|
+
- `adk deploy` - Syncs before deployment
|
|
283
|
+
|
|
284
|
+
## Refreshing Knowledge Bases
|
|
285
|
+
|
|
286
|
+
Refresh knowledge bases programmatically:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// Smart refresh - only changed files (uses SHA256 hashing)
|
|
290
|
+
await MyKnowledgeBase.refresh();
|
|
291
|
+
|
|
292
|
+
// Force refresh - re-indexes everything
|
|
293
|
+
await MyKnowledgeBase.refresh({ force: true });
|
|
294
|
+
|
|
295
|
+
// Refresh specific source
|
|
296
|
+
await MyKnowledgeBase.refreshSource("docs");
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
For scheduled or triggered refresh, use the same refresh methods in workflows, actions, or conversation handlers.
|
|
300
|
+
|
|
301
|
+
## Citations and References
|
|
302
|
+
|
|
303
|
+
Track knowledge sources used in responses:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
const citations = context.get("citations");
|
|
307
|
+
|
|
308
|
+
// Register source when using knowledge passage
|
|
309
|
+
const { tag } = citations.registerSource({
|
|
310
|
+
file: passage.file.key,
|
|
311
|
+
title: passage.file.tags.title,
|
|
312
|
+
url: passage.file.tags.url,
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// Include citation tag in content
|
|
316
|
+
const citedContent = `<${tag}>${passage.content}</${tag}>`;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
For complete citation implementation examples, see the autonomous execution documentation.
|
|
320
|
+
|
|
321
|
+
## Advanced Patterns
|
|
322
|
+
|
|
323
|
+
### Dynamic Knowledge Sources
|
|
324
|
+
|
|
325
|
+
Select knowledge bases based on user context:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
// Select knowledge based on user department
|
|
329
|
+
const knowledgeBases = [GeneralKB];
|
|
330
|
+
|
|
331
|
+
if (user.department === "engineering") {
|
|
332
|
+
knowledgeBases.push(EngineeringKB, TechnicalDocsKB);
|
|
333
|
+
} else if (user.department === "sales") {
|
|
334
|
+
knowledgeBases.push(SalesKB, ProductKB);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Pass to execute()
|
|
338
|
+
await execute({
|
|
339
|
+
instructions: "Answer based on department-specific knowledge",
|
|
340
|
+
knowledge: knowledgeBases,
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Content Transformation
|
|
345
|
+
|
|
346
|
+
Enhance content with metadata before indexing (Table and Website sources support transform):
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
// Table source with transformation
|
|
350
|
+
const docsTableSource = DataSource.Table.fromTable(DocsTable, {
|
|
351
|
+
id: "docs_table",
|
|
352
|
+
|
|
353
|
+
// Filter specific rows
|
|
354
|
+
filter: ({ row }) => {
|
|
355
|
+
return row.status === "published" && !row.deprecated;
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
// Transform row data into searchable text with metadata
|
|
359
|
+
transform: ({ row }) => {
|
|
360
|
+
return `
|
|
361
|
+
Title: ${row.title}
|
|
362
|
+
Category: ${row.category}
|
|
363
|
+
Tags: ${row.tags.join(", ")}
|
|
364
|
+
Author: ${row.author}
|
|
365
|
+
|
|
366
|
+
${row.content}`;
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Note**: Directory sources only support `filter`, not `transform`. Use Table or Website sources for content transformation.
|
|
372
|
+
|
|
373
|
+
### Multi-Language Support
|
|
374
|
+
|
|
375
|
+
Create separate knowledge bases per language:
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
export const EnglishKB = new Knowledge({
|
|
379
|
+
name: "englishKB",
|
|
380
|
+
sources: [DataSource.Directory.fromPath("src/knowledge/en", { id: "docs_en" })],
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
export const SpanishKB = new Knowledge({
|
|
384
|
+
name: "spanishKB",
|
|
385
|
+
sources: [DataSource.Directory.fromPath("src/knowledge/es", { id: "docs_es" })],
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// Select based on user language
|
|
389
|
+
const kb = userLanguage === "es" ? SpanishKB : EnglishKB;
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Best Practices
|
|
393
|
+
|
|
394
|
+
### 1. Organize Content Logically
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
src/knowledge/
|
|
398
|
+
├── docs/
|
|
399
|
+
│ ├── getting-started/
|
|
400
|
+
│ ├── api-reference/
|
|
401
|
+
│ └── tutorials/
|
|
402
|
+
├── policies/
|
|
403
|
+
│ ├── privacy.md
|
|
404
|
+
│ └── terms.md
|
|
405
|
+
└── faqs/
|
|
406
|
+
├── technical.md
|
|
407
|
+
└── billing.md
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### 2. Use Clear Naming
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// ✅ Good
|
|
414
|
+
export const TechnicalDocsKB = new Knowledge({ name: "technicalDocs" });
|
|
415
|
+
export const CustomerFAQKB = new Knowledge({ name: "customerFAQ" });
|
|
416
|
+
|
|
417
|
+
// ❌ Bad
|
|
418
|
+
export const KB1 = new Knowledge({ name: "kb1" });
|
|
419
|
+
export const Stuff = new Knowledge({ name: "stuff" });
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### 3. Refresh Frequently-Changing Content
|
|
423
|
+
|
|
424
|
+
Use `adk kb sync` during development, or call `refresh()` programmatically for dynamic content.
|
|
425
|
+
|
|
426
|
+
### 4. Structure Content for Search
|
|
427
|
+
|
|
428
|
+
Add summaries, keywords, and clear headings to improve retrieval quality.
|
|
429
|
+
|
|
430
|
+
### 5. Monitor Search Performance
|
|
431
|
+
|
|
432
|
+
Track search metrics (query, result count, duration) to identify slow queries or poor results.
|
|
433
|
+
|
|
434
|
+
## Troubleshooting
|
|
435
|
+
|
|
436
|
+
### Common Issues
|
|
437
|
+
|
|
438
|
+
1. **Knowledge not found by AI**
|
|
439
|
+
- Verify knowledge base is included in `execute()` call
|
|
440
|
+
- Check that content has been indexed (`refresh()`)
|
|
441
|
+
- Ensure file types are supported
|
|
442
|
+
|
|
443
|
+
2. **Poor search results**
|
|
444
|
+
- Review content structure and formatting
|
|
445
|
+
- Add metadata and keywords
|
|
446
|
+
- Adjust the `factor` parameter for ranking
|
|
447
|
+
|
|
448
|
+
3. **Refresh not working**
|
|
449
|
+
- Check file permissions
|
|
450
|
+
- Verify source paths are correct
|
|
451
|
+
- Look for errors in transform functions
|
|
452
|
+
|
|
453
|
+
4. **Large files causing issues**
|
|
454
|
+
- Files are automatically chunked, but very large files may need manual splitting
|
|
455
|
+
- Consider breaking into smaller documents
|
|
456
|
+
- Use filtering to exclude unnecessary content
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# LLM Behavior Debugging
|
|
2
|
+
|
|
3
|
+
When the bot's code runs fine but the LLM makes bad decisions — wrong tools, fabricated data, refusals, or loops. These issues live in the model's reasoning, not in your runtime code.
|
|
4
|
+
|
|
5
|
+
Always use `adk traces --format json` to inspect `think` and `tool_call` spans.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Wrong Tool Selected
|
|
10
|
+
|
|
11
|
+
**Symptom:** The model picks a different tool than expected for the user's request.
|
|
12
|
+
|
|
13
|
+
**How to diagnose:**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
adk traces --format json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
1. Find the `think` span before the `tool_call` — this shows the model's reasoning
|
|
20
|
+
2. Compare the tool it chose vs the tool you expected
|
|
21
|
+
3. Read both tools' `description` fields — is the wrong tool's description a better match for the input?
|
|
22
|
+
|
|
23
|
+
**Common causes:**
|
|
24
|
+
|
|
25
|
+
- Tool descriptions are too similar or ambiguous
|
|
26
|
+
- The correct tool's description doesn't clearly cover the use case
|
|
27
|
+
- Too many tools available — the model gets confused with a large tool set
|
|
28
|
+
|
|
29
|
+
**Fixes:**
|
|
30
|
+
|
|
31
|
+
- **Sharpen descriptions:** Make each tool's purpose unambiguous. Include what the tool does NOT do.
|
|
32
|
+
- **Add negative examples:** "Do NOT use this tool for X — use Y instead."
|
|
33
|
+
- **Reduce tool count:** If tools are rarely used, consider consolidating or removing them
|
|
34
|
+
- **Last resort, use `confirm: true`:** Require user confirmation before executing, giving the user a chance to correct
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 2. Hallucinated Parameters
|
|
39
|
+
|
|
40
|
+
**Symptom:** The model invokes the right tool but fills in parameter values that the user never provided.
|
|
41
|
+
|
|
42
|
+
**How to diagnose:**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
adk traces --format json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Check the `tool_call` span's `input` field against what the user actually said.
|
|
49
|
+
|
|
50
|
+
**Common causes:**
|
|
51
|
+
|
|
52
|
+
- Input schema is too loose (e.g., free-form `z.string()` where `z.enum()` would be better)
|
|
53
|
+
- No validation in the handler — the hallucinated value passes through
|
|
54
|
+
- The model infers values from context that don't exist
|
|
55
|
+
|
|
56
|
+
**Fixes:**
|
|
57
|
+
|
|
58
|
+
- **Tighten input schemas:** Use `z.enum()` for known values, add `.describe()` to clarify what each field expects
|
|
59
|
+
- **Add handler validation:** Check that input values make sense before using them
|
|
60
|
+
- **Last resort, require confirmation:** Set `confirm: true` on the tool so the user sees parameters before execution
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 3. Refusal
|
|
65
|
+
|
|
66
|
+
**Symptom:** The model refuses to perform an action, saying it can't or shouldn't do something.
|
|
67
|
+
|
|
68
|
+
**How to diagnose:**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
adk traces --format json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Check `think` spans for safety-related reasoning. The model may cite content policy, uncertainty, or ethical concerns.
|
|
75
|
+
|
|
76
|
+
**Common causes:**
|
|
77
|
+
|
|
78
|
+
- The system prompt or instructions don't explicitly authorize the action
|
|
79
|
+
- The tool description sounds potentially harmful or sensitive
|
|
80
|
+
- The user's request is ambiguous and the model errs on the side of caution
|
|
81
|
+
|
|
82
|
+
**Fixes:**
|
|
83
|
+
|
|
84
|
+
- **Update instructions:** Explicitly authorize the actions in your conversation's `instructions` field
|
|
85
|
+
- **Soften tool descriptions:** Remove language that sounds risky (e.g., "delete all" → "remove selected")
|
|
86
|
+
- **Check `confirm` settings:** If `confirm: true` is set, the model knows the user will approve — make sure instructions reflect this
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 4. Token Limit Issues
|
|
91
|
+
|
|
92
|
+
**Symptom:** The model's responses are truncated, it loses context from earlier in the conversation, or it starts repeating itself.
|
|
93
|
+
|
|
94
|
+
**How to diagnose:**
|
|
95
|
+
|
|
96
|
+
- Long conversations with many turns
|
|
97
|
+
- Large tool outputs filling the context window
|
|
98
|
+
- `adk traces --format json` may show degraded reasoning in later `think` spans
|
|
99
|
+
|
|
100
|
+
**Common causes:**
|
|
101
|
+
|
|
102
|
+
- Conversation history is too long — no pruning or summarization
|
|
103
|
+
- Tool outputs are large (e.g., full database dumps, long API responses)
|
|
104
|
+
- Model configuration doesn't match the conversation's needs
|
|
105
|
+
|
|
106
|
+
**Fixes:**
|
|
107
|
+
|
|
108
|
+
- **Check model configuration:** Verify model settings in `agent.config.ts` — consider using a model with a larger context window
|
|
109
|
+
- **Trim tool outputs:** Return only what the model needs, not everything
|
|
110
|
+
- **Summarize long conversations:** Use Zai to summarize earlier turns before they fill the window
|
|
111
|
+
- **Use `maxIterations`:** Set a reasonable limit on agent iterations to prevent runaway conversations
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 5. Poor Extraction Quality
|
|
116
|
+
|
|
117
|
+
**Symptom:** Using `adk.zai.extract()` or similar `zai` operations returns incorrect or incomplete structured data.
|
|
118
|
+
|
|
119
|
+
**Common causes:**
|
|
120
|
+
|
|
121
|
+
- Schema descriptions are vague — the model doesn't know what each field means
|
|
122
|
+
- Input text is ambiguous or poorly formatted
|
|
123
|
+
- Wrong model for the task — some models extract better than others
|
|
124
|
+
|
|
125
|
+
**Fixes:**
|
|
126
|
+
|
|
127
|
+
- **Improve schema descriptions:** Add `.describe()` to every field with clear, specific descriptions
|
|
128
|
+
- **Provide examples:** Show the model what good output looks like
|
|
129
|
+
- **Try a different model:** Some models handle extraction better; check model configuration
|
|
130
|
+
- **Pre-process input:** Clean up or normalize the text before extraction
|
|
131
|
+
- See the **Edge Cases & Gotchas** section in [zai-agent-reference.md](../../adk/references/zai-agent-reference.md) for common pitfalls like hallucinated fields and chunk-window issues
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 6. Looping
|
|
136
|
+
|
|
137
|
+
**Symptom:** The model calls the same tool repeatedly, or cycles between tools without making progress.
|
|
138
|
+
|
|
139
|
+
**How to diagnose:**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
adk traces --format json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Look for repeated `tool_call` spans with the same `tool_name` in sequence.
|
|
146
|
+
|
|
147
|
+
**Common causes:**
|
|
148
|
+
|
|
149
|
+
- Tool output doesn't clearly indicate success or completion — the model retries
|
|
150
|
+
- Instructions are ambiguous about when to stop
|
|
151
|
+
- The tool fails silently (returns empty/null) and the model keeps trying
|
|
152
|
+
- No iteration limit set
|
|
153
|
+
|
|
154
|
+
**Fixes:**
|
|
155
|
+
|
|
156
|
+
- **Improve tool output clarity:** Return clear success/failure messages that tell the model it's done
|
|
157
|
+
- **Add `onBeforeTool` guardrail:** Detect repeated calls and abort
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Create per-conversation to avoid leaking state across turns
|
|
161
|
+
const makeLoopGuard = () => {
|
|
162
|
+
const seen = new Set<string>();
|
|
163
|
+
const onBeforeTool: Autonomous.Hooks["onBeforeTool"] = async ({ tool, input, controller }) => {
|
|
164
|
+
const key = `${tool.name}:${JSON.stringify(input)}`;
|
|
165
|
+
if (seen.has(key)) {
|
|
166
|
+
controller.abort("Already called this tool with these parameters");
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
seen.add(key);
|
|
170
|
+
};
|
|
171
|
+
return { onBeforeTool };
|
|
172
|
+
};
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- **Set `maxIterations`:** Limit how many tool calls the agent can make per turn
|
|
176
|
+
- **Check instructions:** Add explicit stopping criteria ("after completing X, respond to the user")
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 7. Reading Model Reasoning
|
|
181
|
+
|
|
182
|
+
The `think` span type captures the model's internal reasoning before it acts. This is the most valuable debugging tool for LLM behavior issues.
|
|
183
|
+
|
|
184
|
+
**How to access:**
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Via CLI
|
|
188
|
+
adk traces --format json
|
|
189
|
+
# Look for spans with type "think" — the "content" field has the reasoning
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Via `onTrace` hook in code:**
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const onTrace: Autonomous.Hooks["onTrace"] = ({ trace }) => {
|
|
196
|
+
if (trace.type === "think") {
|
|
197
|
+
console.debug(`[MODEL REASONING] ${trace.content}`);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**What to look for:**
|
|
203
|
+
|
|
204
|
+
- Does the model correctly understand the user's intent?
|
|
205
|
+
- Does it consider the right tools?
|
|
206
|
+
- Does it have accurate context about the conversation state?
|
|
207
|
+
- Is it making assumptions that aren't supported by the input?
|
|
208
|
+
|
|
209
|
+
If the reasoning is wrong, the fix is usually in the instructions, tool descriptions, or the information available to the model — not in the code.
|