Skip to content

Commit 5e3694c

Browse files
committed
feat(docs): add documentation for Agent framework and update code examples
- Added a new document for the Agent framework under `development/call-core-services/agent.md`, detailing how to create and invoke Agent executors with different modes (`tool-calling` and `react`) - Updated existing documents to reflect changes in API usage patterns: - Modified language model and embedding model creation methods to use asynchronous calls and ref-based access (`model.value`) - Replaced outdated `parseRawModelName` import path and usage with updated version - Updated references to `PlatformService` methods such as `getAllModels` to `listAllModels` - Enhanced example snippets with `twoslash` syntax highlighting and clearer annotations - Extended supported languages in VitePress configuration to include bash, shell, and lua - Added sidebar navigation entry for the new Agent documentation page
1 parent 68d711e commit 5e3694c

File tree

8 files changed

+603
-155
lines changed

8 files changed

+603
-155
lines changed

docs/.vitepress/config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export default defineConfig({
114114
},
115115
codeTransformers: [transformerTwoslash()],
116116
// Explicitly load these languages for types hightlighting
117-
languages: ["js", "jsx", "ts", "tsx"],
117+
languages: ["js", "jsx", "ts", "tsx", 'bash', 'shell', 'lua'],
118118
},
119119
vite: {
120120
ssr: {
@@ -522,6 +522,10 @@ function sidebarDevelopment(): DefaultTheme.SidebarItem[] {
522522
text: "模型工具",
523523
link: "/development/call-core-services/model-tool",
524524
},
525+
{
526+
text: "Agent",
527+
link: "/development/call-core-services/agent",
528+
},
525529
],
526530
},
527531
{
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# Agent
2+
3+
ChatLuna 提供了 Agent 的简易框架,可以让模型自主选择和调用工具。
4+
5+
## 创建 Agent Executor
6+
7+
使用 `createAgentExecutor` 函数创建 Agent 执行器:
8+
9+
```ts twoslash
10+
// @noImplicitAny: false
11+
// @strictNullChecks: false
12+
import { Context, Schema } from 'koishi'
13+
14+
const ctx = new Context()
15+
16+
// ---cut---
17+
import type {} from "koishi-plugin-chatluna/services/chat";
18+
import { createAgentExecutor, createToolsRef } from 'koishi-plugin-chatluna/llm-core/agent'
19+
import { ChatLunaChatPrompt } from 'koishi-plugin-chatluna/llm-core/chain/prompt'
20+
import type { ChatLunaTool } from 'koishi-plugin-chatluna/llm-core/platform/types'
21+
import { computed } from 'koishi-plugin-chatluna'
22+
23+
const modelRef = await ctx.chatluna.createChatModel("openai/gpt-5-nano")
24+
const embeddingsRef = await ctx.chatluna.createEmbeddings("openai/text-embedding-3-small")
25+
26+
const enabledTools = ['web-search', 'web-browser']
27+
const toolsRef = computed(() =>
28+
enabledTools.map(
29+
(toolName) => ctx.chatluna.platform.getTool(toolName) satisfies ChatLunaTool
30+
)
31+
)
32+
33+
const toolsRefCreated = createToolsRef({
34+
tools: toolsRef,
35+
embeddings: embeddingsRef.value
36+
})
37+
38+
const prompt = new ChatLunaChatPrompt({
39+
preset: ctx.chatluna.preset.getPreset('sydney'),
40+
tokenCounter: (text) => modelRef.value.getNumTokens(text),
41+
promptRenderService: ctx.chatluna.promptRenderer,
42+
sendTokenLimit: modelRef.value.getModelMaxContextSize()
43+
})
44+
45+
const executorRef = createAgentExecutor({
46+
llm: modelRef,
47+
tools: toolsRefCreated.tools,
48+
prompt: prompt,
49+
agentMode: 'tool-calling',
50+
returnIntermediateSteps: true,
51+
handleParsingErrors: true
52+
})
53+
```
54+
55+
<br>
56+
57+
`createAgentExecutor` 接受以下参数:
58+
59+
- `llm`: 语言模型的计算引用
60+
- `tools`: 工具列表的计算引用
61+
- `prompt`: 聊天提示词对象
62+
- `agentMode`: Agent 模式,可选 `'tool-calling'``'react'`
63+
- `returnIntermediateSteps`: 是否返回中间步骤
64+
- `handleParsingErrors`: 是否处理解析错误
65+
- `instructions`: ReAct 模式下的额外指令 (可选)
66+
67+
## 调用 Agent
68+
69+
创建 Agent Executor 后,可以通过 `invoke` 方法调用:
70+
71+
```ts twoslash
72+
// @noImplicitAny: false
73+
// @strictNullChecks: false
74+
// @noErrors
75+
import { Context, Schema } from 'koishi'
76+
import { HumanMessage, AIMessageChunk } from '@langchain/core/messages'
77+
import { createAgentExecutor, createToolsRef } from 'koishi-plugin-chatluna/llm-core/agent'
78+
79+
const ctx = new Context()
80+
let executor: ReturnType<typeof createAgentExecutor>
81+
82+
// ---cut---
83+
const response = await executor.value.invoke({
84+
input: new HumanMessage("搜索 OpenAI 的最新新闻"),
85+
chat_history: [],
86+
variables: {}
87+
})
88+
89+
const message = new AIMessage(response['output'])
90+
91+
```
92+
93+
<br>
94+
95+
调用后返回的结果包含:
96+
97+
- `output`: Agent 的最终输出
98+
- `intermediateSteps`: 中间步骤 (如果 `returnIntermediateSteps``true`)
99+
100+
## Agent 模式
101+
102+
ChatLuna 支持两种 Agent 模式:
103+
104+
### tool-calling 模式
105+
106+
使用模型的原生工具调用能力,适用于支持 Tool Calling 的模型 (如 GPT-5, Claude 等)。
107+
108+
```ts twoslash
109+
// @noImplicitAny: false
110+
// @strictNullChecks: false
111+
// @noErrors
112+
import { createAgentExecutor } from 'koishi-plugin-chatluna/llm-core/agent'
113+
114+
const modelRef = await ctx.chatluna.createChatModel("openai/gpt-5-nano")
115+
const embeddingsRef = await ctx.chatluna.createEmbeddings("openai/text-embedding-3-small")
116+
117+
const enabledTools = ['web-search', 'web-browser']
118+
const toolsRef = computed(() =>
119+
enabledTools.map(
120+
(toolName) => ctx.chatluna.platform.getTool(toolName) satisfies ChatLunaTool
121+
)
122+
)
123+
124+
const toolsRefCreated = createToolsRef({
125+
tools: toolsRef,
126+
embeddings: embeddingsRef.value
127+
})
128+
129+
const prompt = new ChatLunaChatPrompt({
130+
preset: ctx.chatluna.preset.getPreset('sydney'),
131+
tokenCounter: (text) => modelRef.value.getNumTokens(text),
132+
promptRenderService: ctx.chatluna.promptRenderer,
133+
sendTokenLimit: modelRef.value.getModelMaxContextSize()
134+
})
135+
136+
// ---cut---
137+
const executorToolCallingRef = createAgentExecutor({
138+
llm: modelRef,
139+
tools: toolsRefCreated.tools,
140+
prompt,
141+
agentMode: 'tool-calling',
142+
returnIntermediateSteps: true
143+
})
144+
```
145+
146+
### react 模式
147+
148+
使用 ReAct (Reasoning and Acting) 模式,通过提示词引导模型进行推理和行动。
149+
150+
适用于不支持原生工具调用的模型。
151+
152+
```ts twoslash
153+
// @noImplicitAny: false
154+
// @strictNullChecks: false
155+
// @noErrors
156+
import { createAgentExecutor } from 'koishi-plugin-chatluna/llm-core/agent'
157+
import { computed } from 'koishi-plugin-chatluna'
158+
159+
const modelRef = await ctx.chatluna.createChatModel("openai/gpt-5-nano")
160+
const embeddingsRef = await ctx.chatluna.createEmbeddings("openai/text-embedding-3-small")
161+
162+
const enabledTools = ['web-search', 'web-browser']
163+
const toolsRef = computed(() =>
164+
enabledTools.map(
165+
(toolName) => ctx.chatluna.platform.getTool(toolName) satisfies ChatLunaTool
166+
)
167+
)
168+
169+
const toolsRefCreated = createToolsRef({
170+
tools: toolsRef,
171+
embeddings: embeddingsRef.value
172+
})
173+
174+
const prompt = new ChatLunaChatPrompt({
175+
preset: ctx.chatluna.preset.getPreset('sydney'),
176+
tokenCounter: (text) => modelRef.value.getNumTokens(text),
177+
promptRenderService: ctx.chatluna.promptRenderer,
178+
sendTokenLimit: modelRef.value.getModelMaxContextSize()
179+
})
180+
181+
// ---cut---
182+
const executorReactRef = createAgentExecutor({
183+
llm: modelRef,
184+
tools: toolsRefCreated.tools,
185+
prompt,
186+
agentMode: 'react',
187+
handleParsingErrors: true,
188+
instructions: computed(() => undefined)
189+
})
190+
```
191+
192+
## 创建工具引用
193+
194+
使用 `createToolsRef` 函数创建响应式的工具引用。
195+
196+
工具引用配合 Agent 执行器的引用,可以实现工具的动态选择和 Agent 执行器的动态重建。
197+
198+
```ts twoslash
199+
// @noImplicitAny: false
200+
// @strictNullChecks: false
201+
import { Context, Schema } from 'koishi'
202+
203+
const ctx = new Context()
204+
let session: Session
205+
206+
// ---cut---
207+
import type {} from "koishi-plugin-chatluna/services/chat";
208+
import { createToolsRef } from 'koishi-plugin-chatluna/llm-core/agent'
209+
import { computed } from 'koishi-plugin-chatluna'
210+
import type { ChatLunaTool } from 'koishi-plugin-chatluna/llm-core/platform/types'
211+
import { HumanMessage } from '@langchain/core/messages'
212+
213+
import { Session } from 'koishi'
214+
215+
const embeddingsRef = await ctx.chatluna.createEmbeddings("openai/text-embedding-3-small")
216+
217+
// 创建指定工具的引用
218+
/* const toolsRef = computed(() => {
219+
const searchTool = ctx.chatluna.platform.getTool('web-search')
220+
const browserTool = ctx.chatluna.platform.getTool('web-browser')
221+
return [searchTool, browserTool]
222+
}) */
223+
224+
// 创建全部工具的引用
225+
const toolsNameRef = await ctx.chatluna.platform.getTools()
226+
const toolsRef = computed(() => {
227+
return toolsNameRef.value.map((toolName) => {
228+
return ctx.chatluna.platform.getTool(toolName) satisfies ChatLunaTool
229+
})
230+
})
231+
232+
const toolsRefCreated = createToolsRef({
233+
tools: toolsRef,
234+
embeddings: embeddingsRef.value
235+
})
236+
237+
238+
const messages = [new HumanMessage("你好")]
239+
240+
toolsRefCreated.update(session, messages)
241+
```
242+
243+
<br>
244+
245+
`createToolsRef` 会根据工具的 `selector``authorization` 方法,自动筛选出当前对话历史下可用的工具。
246+
247+
调用 `update` 方法可以更新工具列表。

docs/development/call-core-services/embedding-model.md

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,53 +6,99 @@ ChatLuna 也能聚合和调用各种嵌入模型。
66

77
使用 `chatluna` 服务中的 `createEmbeddings` 方法来创建一个 `Embeddings` 实例。
88

9-
```typescript
9+
```ts twoslash
10+
// @noImplicitAny: false
11+
// @strictNullChecks: false
12+
import { Context, Schema } from 'koishi'
13+
14+
const ctx = new Context()
15+
16+
// ---cut---
1017
import type {} from "koishi-plugin-chatluna/services/chat";
1118

12-
// platform, model
13-
const model = ctx.chatluna.createEmbeddings("openai", "text-embedding-3-small")
19+
const modelRef = await ctx.chatluna.createEmbeddings("openai/text-embedding-3-small")
20+
21+
const vector = await modelRef.value.embedQuery("你好,世界!")
22+
// ^?
1423

15-
const vector = await model.embedQuery("你好,世界!")
1624

1725
console.log(vector)
1826
```
1927

20-
返回的模型继承自 [`Embeddings`](https://v03.api.js.langchain.com/classes/_langchain_core.embeddings.Embeddings.html)并和 LangChain 的其他 API 无缝衔接。
28+
返回的模型继承自 [`Embeddings`](https://v03.api.js.langchain.com/classes/_langchain_core.embeddings.Embeddings.html),并和 LangChain 的其他 API 无缝衔接。
2129

2230
## 获取可用的模型
2331

2432
在 ChatLuna 中,实际掌握各类模型和平台的是 `PlatformService` 类。
2533

26-
如果你需要获取当前平台下可用的嵌入模型列表,可以调用 `PlatformService``getAllModels` 方法。
34+
如果你需要获取全部可用的嵌入模型列表,可以调用 `PlatformService``listAllModels` 方法。
35+
36+
```ts twoslash
37+
// @noImplicitAny: false
38+
// @strictNullChecks: false
39+
import { Context, Schema } from 'koishi'
40+
41+
const ctx = new Context()
42+
43+
// ---cut---
44+
import type {} from "koishi-plugin-chatluna/services/chat";
45+
import { ModelType } from 'koishi-plugin-chatluna/llm-core/platform/types'
46+
47+
const modelsRef = ctx.chatluna.platform.listAllModels(ModelType.embeddings)
48+
const models = modelsRef.value
49+
// ^?
50+
```
51+
52+
<br>
53+
54+
`ModelType` 是一个枚举类型,定义了模型类型:
2755

28-
```typescript
56+
```ts twoslash
57+
// @noImplicitAny: false
58+
// @strictNullChecks: false
59+
// @noErrors
60+
import { Context, Schema } from 'koishi'
61+
const ctx = new Context()
62+
import type {} from "koishi-plugin-chatluna/services/chat";
2963
import { ModelType } from 'koishi-plugin-chatluna/llm-core/platform/types'
64+
type Prettify<T> = never | { [K in keyof T]: T[K] };
3065

31-
const models = ctx.chatluna.platform.getAllModels(ModelType.embedding)
66+
// ---cut---
67+
type PureModelType = Prettify<typeof ModelType>
68+
// ^?
3269
```
3370
34-
`ModelType` 是一个枚举类型,定义了模型类型。目前支持的模型类型有:
71+
<br><br><br><br><br><br>
72+
73+
目前支持的模型类型有:
3574
36-
- `llm`大语言模型
37-
- `embedding`嵌入模型
38-
- `all`所有模型
75+
- `llm`:大语言模型
76+
- `embedding`:嵌入模型
77+
- `all`:所有模型
3978
4079
## 从用户配置中创建
4180
4281
ChatLuna 的主插件中允许用户设置 [`defaultEmbeddings`](../../guide/useful-configurations.md#defaultembeddings) 配置项,用于指定默认的嵌入模型。
4382
4483
开发者也可以直接使用这个配置项指定的嵌入模型来创建嵌入模型实例。
4584
46-
```typescript
85+
```ts twoslash
86+
// @noImplicitAny: false
87+
// @strictNullChecks: false
88+
import { Context, Schema } from 'koishi'
89+
90+
const ctx = new Context()
91+
92+
// ---cut---
4793
import type {} from "koishi-plugin-chatluna/services/chat";
48-
import { parseRawModelName } from 'koishi-plugin-chatluna/llm-core/utils/model'
94+
import { parseRawModelName } from 'koishi-plugin-chatluna/llm-core/utils/count_tokens'
4995

50-
const [embeddingsPlatform, embeddingsModel] = parseRawModelName(ctx.chatluna.config.defaultEmbeddings)
51-
const embeddings = ctx.chatluna.createEmbeddings(embeddingsPlatform, embeddingsModel)
96+
const embeddings = await ctx.chatluna.createEmbeddings(ctx.chatluna.config.defaultEmbeddings)
97+
// ^?
5298
```
5399

54100
## 获取详细模型信息
55101

56-
可参考 [大语言模型](./language-model.md#获取详细模型信息) 中的 `获取详细模型信息` 部分。
102+
可参考 [大语言模型](./language-model.md#获取指定模型的信息) 中的 `获取指定模型的信息` 部分。
57103

58104
这里不再赘述。

0 commit comments

Comments
 (0)