Max Lin

agent 就是
一个 while 循环
An agent is a while loop around one HTTP call

循环里只有一次模型调用。demo-agent 用 TypeScript 从零写这个循环,不用框架,一层一个文件。这是一个学习用的代码库,还在写:模型层写好了,循环和工具还没开始,现在还不能运行。demo-agent writes that loop from scratch in TypeScript: no framework, one file per layer. It's a learning codebase and a work in progress. The model layer is written; the loop and tools haven't started, so it doesn't run yet.

在 GitHub 上查看源码View the source on GitHub MIT 开源,Node 24+MIT, Node 24 or later
index.ts入口Entry point还没写Not written
agent.ts循环The loop还没写Not written
llm.ts模型层Model layer已写好Written
模型接口Model APIOpenAI 或任何兼容接口OpenAI or any compatible endpoint
tools/工具Tools还没写Not written
types.ts各层共用的类型Types every layer sharesMessage · CompletionRequest · ToolCall · CompletionResult已写好Written


      

写到哪了Where it stands

这个项目用来想清楚 agent 到底该怎么写,所以不引框架:框架替你回答的,正是这里要自己回答的问题。代码还没对真实模型跑过,类型也还没编译过。The project exists to work out how an agent should actually be built, so it imports no framework: a framework answers exactly the question this is here to answer. Nothing has been run against a real model yet, and the types have not been compiled.

一个运行时依赖One runtime dependency
只有官方的 openai SDK。The official openai SDK, nothing else.
不给 temperature 默认值No default temperature
推理模型会用 400 拒绝不等于 1 的 temperature,所以采样参数只在你传了才发。Reasoning models reject a temperature other than 1 with a 400, so sampling knobs are sent only when you pass them.
参数保持原样Arguments stay raw
工具调用的 arguments 是原始 JSON 字符串,模型写坏了怎么办由工具层决定。A tool call's arguments stay a raw JSON string; what to do with broken JSON is the tool layer's call.
任何兼容接口Any compatible endpoint
OpenRouter、DeepSeek、vLLM、Ollama,指过去就行。OpenRouter, DeepSeek, vLLM, Ollama: point baseURL at it.
平台Platform
Node.js
要求Requires
Node 24 或更高;pnpm(版本由 packageManager 固定);一个支持 OpenAI Chat Completions 格式的接口的 API Key。目前还不能运行:入口 index.ts 尚未编写。Node 24 or later; pnpm (pinned through packageManager); an API key for any service speaking the OpenAI Chat Completions format. Not runnable yet: the index.ts entry point has not been written.
许可证License
MIT

常见问题Questions

怎么不用 LangChain,用 TypeScript 自己写一个 AI agent?How do I build an AI agent in TypeScript without LangChain?

demo-agent 就是这样写的:模型层 llm.ts 直接用官方 openai SDK 调 Chat Completions,返回内容、工具调用和 token 用量;agent 循环(agent.ts)会是围绕这次调用的一个 while 循环,单独成一个文件。目前模型层已写好,循环还没开始。demo-agent is built that way: the model layer, llm.ts, calls Chat Completions through the official openai SDK and returns content, tool calls and token usage; the agent loop, agent.ts, will be a single-file while loop around that call. The model layer is written; the loop is not started yet.

现在能运行吗?Can I run it yet?

还不能。pnpm start 指向的 index.ts 还不存在,代码也还没对真实模型跑过。现在可以读 llm.ts 和 types.ts,看模型层是怎么写的。Not yet. pnpm start points at index.ts, which does not exist, and nothing has been run against a real model. For now, llm.ts and types.ts show how the model layer is written.

能用 DeepSeek、OpenRouter 或本地 Ollama 吗?Can I use DeepSeek, OpenRouter or a local Ollama model?

模型层用 OpenAI Chat Completions 协议,createLLM 接受 baseURL 参数,指向任何实现了这个协议的接口即可。目前还没有对任何真实接口验证过。The model layer speaks OpenAI Chat Completions and createLLM takes a baseURL, so any endpoint implementing that protocol can be used. It has not been checked against a live endpoint yet.

为什么调用推理模型时不能设 temperature?Why does a reasoning model reject my temperature setting?

推理模型会用 400 拒绝显式设置的非 1 temperature。所以 llm.ts 不给任何采样参数设默认值,只在调用方明确传入时才发送。Reasoning models reject an explicit temperature other than 1 with a 400. That is why llm.ts never defaults any sampling parameter and only sends one when the caller passes it.

工具调用之后为什么下一轮报 400?Why do I get a 400 on the turn after a tool call?

带 tool_calls 的 assistant 消息必须原样放回历史,而且其中每一个调用都要有自己对应的 tool 回复。少了任何一条,下一轮请求就会被拒。The assistant message carrying tool_calls must go back into history verbatim, and every call it made needs its own tool reply. Missing either one gets the next request rejected.

用什么许可证?What license is it under?

MIT。可以自由使用、修改和分发,包括商用,保留版权声明即可。MIT. You can use, change and distribute it, commercially or not, as long as the copyright notice is kept.

获取帮助Get help

发邮件到Email hi@max1874.com,或在 , or open an issue on GitHub 提 issue。写上版本和运行环境,能更快定位问题。. Include the version and your environment so the problem is easier to find.