#直接工具
session.tool(name, args)(以及 glob、grep、readFile 等类型化辅助方法)会直接运行宿主工具,循环中不发起任何模型调用。它们适用于测试、迁移以及宿主驱动的工作流——你需要确定性结果,而不是一次智能体回合。
直接调用是宿主控制面调用:会话视宿主为已批准这些调用,因此 permissionPolicy 和确认提示
都不适用。调用前请先执行你的产品授权逻辑;如果某个由宿主协调的调用仍需经过会话的权限与
确认关卡,请改用 governedTool / governed_tool / GovernedTool。
use a3s_code_core::Agent;use serde_json::{json, Value};use std::collections::HashSet;#[tokio::main]async fn main() -> a3s_code_core::Result<()> {let agent = Agent::new("agent.acl").await?;let session = agent.session_builder(".").build().await?;let allowed = HashSet::from(["glob", "grep", "read", "generate_object"]);let check = |name: &str| -> a3s_code_core::Result<()> {allowed.contains(name).then_some(()).ok_or_else(|| {a3s_code_core::CodeError::Security(format!("此处不允许直接调用工具:{name}"))})};check("glob")?;let files = session.glob("**/*.rs").await?;println!("glob 找到 {} 个 Rust 文件", files.len());check("grep")?;let matches = session.grep("Agent::new").await?;println!("grep:{}", matches.lines().last().unwrap_or_default());check("read")?;let readme = session.read_file("README.md").await?;println!("README 大小为 {} 字节", readme.len());let raw = session.tool("read", json!({ "file_path": "Cargo.toml" })).await?;println!("通过 tool() 读取了 {} 字节", raw.output.len());println!("会话暴露了 {} 个工具", session.tool_definitions().len());check("generate_object")?;let structured = session.tool("generate_object",json!({"schema": {"type": "object","required": ["count", "language"],"properties": {"count": { "type": "integer" },"language": { "type": "string" }}},"prompt": "这个项目中有多少个 Rust 文件?","schema_name": "file_stats"}),).await?;if structured.exit_code != 0 {return Err(a3s_code_core::CodeError::Tool {tool: "generate_object".into(),message: structured.output,});}let generated: Value = serde_json::from_str(&structured.output)?;println!("结构化输出:{}", generated["object"]);session.close().await;agent.close().await;Ok(())}
import { Agent } from '@a3s-lab/code';const agent = await Agent.create('agent.acl');const session = await agent.sessionAsync('.');const allowedDirectTools = new Set(['glob', 'grep', 'read', 'generate_object']);function assertDirectToolAllowed(name: string) {if (!allowedDirectTools.has(name)) {throw new Error(`direct tool not allowed here: ${name}`);}}// Glob:按模式列出文件assertDirectToolAllowed('glob');const files = await session.glob('**/*.ts');console.log(`glob 找到 ${files.length} 个 TypeScript 文件`);// Grep:搜索文件内容assertDirectToolAllowed('grep');const matches = await session.grep('Agent.create');console.log('grep:', matches.trimEnd().split('\n').at(-1));// 读取文件assertDirectToolAllowed('read');const readme = await session.readFile('README.md');console.log(`README 大小为 ${readme.length} 字节`);// 按名称直接调用工具assertDirectToolAllowed('read');const raw = await session.tool('read', { file_path: 'package.json' });console.log(`通过 tool() 读取 package.json:${raw.output.length} 字节`);// 查看可用的工具模式const schemas = session.toolDefinitions();console.log(`会话暴露了 ${schemas.length} 个工具`);// 结构化输出:生成通过模式校验的 JSON 对象assertDirectToolAllowed('generate_object');const structured = await session.tool('generate_object', {schema: {type: 'object',required: ['count', 'language'],properties: {count: { type: 'integer' },language: { type: 'string' },},},prompt: '这个项目中有多少个 TypeScript 文件?',schema_name: 'file_stats',});if (structured.exitCode !== 0) {throw new Error(structured.output);}console.log('结构化输出:', JSON.parse(structured.output).object);await session.closeAsync();await agent.close();
import jsonfrom a3s_code import Agentagent = Agent.create("agent.acl")session = agent.session('.')ALLOWED_DIRECT_TOOLS = {'glob', 'grep', 'read', 'generate_object'}def assert_direct_tool_allowed(name: str) -> None:if name not in ALLOWED_DIRECT_TOOLS:raise RuntimeError(f'direct tool not allowed here: {name}')# Glob:按模式列出文件assert_direct_tool_allowed('glob')files = session.glob('**/*.py')print(f'glob 找到 {len(files)} 个 Python 文件')# Grep:搜索文件内容assert_direct_tool_allowed('grep')matches = session.grep('Agent.create')print('grep:', matches.splitlines()[-1])# 读取文件assert_direct_tool_allowed('read')readme = session.read_file('README.md')print(f'README 大小为 {len(readme)} 字节')# 按名称直接调用工具assert_direct_tool_allowed('read')raw = session.tool('read', {'file_path': 'pyproject.toml'})print(f'通过 tool() 读取 pyproject.toml:{len(raw.output)} 字节')# 查看可用的工具模式schemas = session.tool_definitions()print(f'会话暴露了 {len(schemas)} 个工具')# 结构化输出:生成通过模式校验的 JSON 对象assert_direct_tool_allowed('generate_object')structured = session.tool('generate_object', {'schema': {'type': 'object','required': ['count', 'language'],'properties': {'count': {'type': 'integer'},'language': {'type': 'string'},},},'prompt': '这个项目中有多少个 Python 文件?','schema_name': 'file_stats',})if structured.exit_code != 0:raise RuntimeError(structured.output)print('结构化输出:', json.loads(structured.output)['object'])session.close()agent.close()
package mainimport ("context""encoding/json""fmt""log""strings"code "github.com/A3S-Lab/Code/sdk/go/v9")func must[T any](value T, err error) T {if err != nil {log.Fatal(err)}return value}func main() {ctx := context.Background()agent := must(code.Create(ctx, "agent.acl"))defer agent.Close(context.Background())session := must(agent.Session(ctx, ".", nil))defer session.Close(context.Background())files := must(session.Glob(ctx, "**/*.go"))fmt.Printf("glob 找到 %d 个 Go 文件\n", len(files))matches := must(session.Grep(ctx, "code.Create"))grepLines := strings.Split(strings.TrimSpace(matches), "\n")fmt.Println("grep:", grepLines[len(grepLines)-1])readme := must(session.ReadFile(ctx, "README.md", nil))fmt.Printf("README 大小为 %d 字节\n", len(readme))raw := must(session.Tool(ctx, "read", map[string]any{"file_path": "go.mod",}))fmt.Printf("通过 Tool() 读取 go.mod:%d 字节\n", len(raw.Output))schemas := must(session.ToolDefinitions(ctx))fmt.Printf("Session 提供 %d 个工具\n", len(schemas))structured := must(session.Tool(ctx, "generate_object", map[string]any{"schema": map[string]any{"type": "object","required": []string{"count", "language"},"properties": map[string]any{"count": map[string]any{"type": "integer"},"language": map[string]any{"type": "string"},},},"prompt": "这个项目中有多少个 Go 文件?","schema_name": "file_stats",}))if structured.ExitCode != 0 {log.Fatal(structured.Output)}var generated struct {Object map[string]any `json:"object"`}if err := json.Unmarshal([]byte(structured.Output), &generated); err != nil {log.Fatal(err)}fmt.Println("结构化输出:", generated.Object)}
直接工具在 session 工作区下执行,应视为宿主侧的特权操作。大多数调用(read、glob、grep)是纯确定性的;generate_object 是个例外——它仍会调用模型来填充经过 schema 校验的 JSON 对象,但由你显式驱动,而非通过自由形式的智能体回合。
grep / Grep 以 grep 模式运行 search 工具。它返回匹配的行,末尾附一行
N match(es) in M file(s) 汇总;没有匹配时返回 No matches found for pattern: ...。
示例打印的就是最后这一行。
readFile / read_file / ReadFile 返回 read 工具的视图:每行都带有右对齐的行号和一个
制表符前缀,长文件末尾还会附带续读提示。解析文件内容前请先去掉该前缀。
可运行版本位于 sdk/node/examples/basic/test_generate_object.ts
(Python:sdk/python/examples/test_generate_object.py)。Go 的直接
工具契约由 sdk/go/session_test.go 覆盖。