Local Agent
Agent 构造参数
详细说明本地 Agent 的 id、path、instruction、prepare_session、env、tools 和 plugins 参数
Agent 构造参数
本地 Agent 的构造方式:
new Agent({
id,
path,
prepare_session,
env,
instruction,
tools,
shell,
plugins,
Session,
})id
agent 的稳定标识。
它会影响 SDK session 落盘路径:
<projectRoot>/.downcity/agents/<agentId>/...推荐:
- 稳定
- 可 URL 编码
- 不要随便改
因为它直接决定了 session 落盘目录分区。
path
当前 agent 绑定的项目根目录。
SDK 会基于它:
- 读取项目
.env - 组织会话落盘目录
如果 path 给错,后面很多行为都会变得不符合预期,因为 Agent 会在错误上下文里读取配置和写数据。
instruction
调用方传入的本地 SDK Agent 静态基础指令。
new Agent({
id: "repo-helper",
path: "/path/to/project",
instruction: [
"你是一个简洁的代码助手。",
"解释代码时优先给出明确文件引用。",
],
});关键点:
instruction是静态的,应该保持缓存友好- SDK 不会对它做动态变量渲染
- SDK 不读取项目 prompt 配置文件
- 如果省略
instruction,SDK 会使用包内最小 core instruction 作为 fallback
宿主需要额外基础指令时,应通过 instruction 显式传入。
prepare_session
Session 每次执行前调用的宿主准备钩子。
new Agent({
id: "repo-helper",
path: "/path/to/project",
prepare_session: async (session) => {
await session.set({ model: openai.responses("gpt-5") });
},
});关键点:
- SDK 不负责选择、保存或恢复模型 ID
- 宿主先创建
LanguageModel,再通过钩子注入 - 钩子每个 turn 执行前调用,宿主配置可在下一轮生效
- 该钩子也可以准备其他宿主级运行时依赖
env
这个 agent 可见的环境变量快照。
new Agent({
id: "repo-helper",
path: "/path/to/project",
env: {
OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? "",
},
});关键点:
- SDK 会先采用显式传入的
env,再由项目.env覆盖同名值 - SDK 不再区分 global env 和 agent env
- 如果宿主需要合并多层 env,应先在外部合并,再把最终结果传给
env - 这些值会参与配置解析与运行时上下文装配,但不会自动回写系统环境变量
运行时更新 env
构造 agent 之后,你也可以在运行期增量更新或整体替换 configured env:
const agent = new Agent({ id, path, env: { FOO: "1" } });
agent.getEnv(); // => { FOO: "1" }
agent.patchEnv({ BAR: "2" }); // 增量合并
agent.patchEnv({ FOO: null }); // null 表示删除
agent.setEnv({ ONLY: "ok" }); // 整体覆盖关键点:
getEnv()返回的是浅拷贝快照,修改它不会影响 agent 真实状态patchEnv()中null/undefined表示删除该 key,其余值会强制转字符串setEnv()会先清空当前 env,再写入新值,仍然保持原引用不变- 已有 Session 会在下一个 Session step 检查点统一提交 Agent instruction、env 与 plugin 修改
- 正在进行的 provider 请求及其工具调用继续使用当前 step 已生效的 env
- 如果当前 Session turn 没有后续 step,排队中的修改会在下一个 Session turn 开始时提交
- 配置真正生效时,Session timeline 会写入 completed action message
- 运行时变更只活在内存,不会回写项目
.env或系统环境变量
tools
agent 级默认工具集合。
关键点:
- 它属于 agent 级,不是 session 级
- 当前 agent 创建出来的 session 会直接复用这份工具集合
这很适合“多个 session 共用一套默认工具能力”的场景。
shell
详细配置参见 Shell 与沙箱。
可选的内建 shell 能力。
import { Agent } from "@downcity/agent";
import { Shell } from "@downcity/shell";
const agent = new Agent({
id: "repo-helper",
path: "/path/to/project",
shell: new Shell(),
});关键点:
- Shell 不是 plugin
- Agent 会从 Shell 实例挂载
shell_exec、shell_session、grep、find、read、write和edit - session 与 turn 上下文由 Agent 内部自动接线
- 审批归属具体 Session,使用
session.approvals()、session.resolve_approval(...)和session.set_approval_mode(...) - 文件和搜索工具固定限制在 Agent 项目根目录内,不提供 unrestricted 模式
plugins
这里接收的是已经实例化好的 BasePlugin 对象。
例如:
import { Agent } from "@downcity/agent";
import { SkillPlugin, WebPlugin } from "@downcity/plugins";
const agent = new Agent({
id: "repo-helper",
path: "/path/to/project",
tools: {},
plugins: [new SkillPlugin(), new WebPlugin()],
});SDK 会为当前 Agent 创建独立的 plugin registry。
关键点:
- 应该传
new SkillPlugin()这类实例,而不是原始 plugin 定义对象 - 它不会默认注册全部内建 plugin
- 它不会复用全局 runtime 的 plugin manager
- 同名 plugin 被重复注册时会直接报错
agent.plugins与AgentContext.plugins会使用这份 registry- 如果你想一次性注入整套内建 plugin,可以从
@downcity/plugins传入plugins: createBuiltinPlugins()
Session
本地 session 的高级自定义类。
当你希望替换本地 session 实现,或者在 Session 层注入自定义 Composer 时使用它。Agent 只负责用这个类创建和恢复 session,不理解 Composer 的具体策略。
import {
Agent,
Session,
type SessionOptions,
type SessionSystemComposer,
} from "@downcity/agent";
const systemComposer: SessionSystemComposer = {
name: "custom_system",
async resolve() {
return [{ role: "system", content: "始终简洁回答。" }];
},
};
class CustomSession extends Session {
constructor(options: SessionOptions) {
super({
...options,
composers: {
systemComposer,
},
});
}
}
const agent = new Agent({
id: "repo-helper",
path: "/path/to/project",
Session: CustomSession,
});关键点:
- 传入的是 class,不是已经创建好的 session 实例
- 这样
Agent可以按不同sessionId创建多个 session - Composer 自定义留在自定义 Session 类内部
RemoteAgent不支持本地 Session 类,因为它只是远程 runtime 的访问器