#loop() 🧵

1 messages · Page 1 of 1 (latest)

empty marlin
#

@cosmic orchid you mentioned you had an idea to maybe bring loop back? Tell me more 🙂

cosmic orchid
#

Oh, yeah I think it's still useful. Well, kind of. It at least does something.

Take this example:

    return dag.Llm(dagger.LlmOpts{Model: m.Model}).
        SetContainer("ctr", dag.Container()).
        WithPrompt("set up $ctr for PHP 7 development").
        Loop().
        WithPrompt("now install nano").
        Loop().
        WithPrompt("undo that and install vim instead").
        Loop().
        GetContainer("ctr")

If you remove the Loop() calls it just sends all of the prompts at once, instead of doing them in sequence, so the model sees everything and behaves differently than if you wait after each one.

I'm not sure if you'd want this for non-test code though. And this could be using Sync() instead but then I'd have to break the chain and make the code ugly.

empty marlin
#

But isn't Sync() the same thing?

#

Or you're saying, Loop() doesn't unlazily. It lazily requests an agentic loop to be done at that point in the chain

cosmic orchid
empty marlin
#

But, how does that play with GetContainer() in your example?

cosmic orchid
#

but i don't feel too strongly about this, like arguably the above code should actually Sync() and somehow assert what it expects from the reply or the state

empty marlin
#

Currently GetContainer() forces sync. Will it also force loop?

cosmic orchid
#

because right now when it messes up it just moves on to the next prompt like nothing happens lol

empty marlin
#

The current behavior is that this will work:

return dag.LLM().SetContainer().WithPrompt().GetContainer()

Also identical behavior to:

return dag.LLM().WithPrompt().SetContainer().GetContainer()
cosmic orchid
#

instead of "do this" <loop> "then that" <loop> "then that" <loop> it turns into "do all these things, which somewhat contradict each other and dont make sense anymore" <loop>

empty marlin
#

I see. Already possible with Sync() but like you said, less practical because of error checking

#

Should we remove sync() completely? and replace it with loop?

cosmic orchid
#

no Sync is still useful because you still need that 'returns a scalar ID that gets rehydrated into an Object' trick to force something to actually happen

#

and the CLI automatically calls it (like all other Syncers)

empty marlin
#

note that I wasn't able to use the real Syncer mechanism, because its implementation is tied to llb state

#

so it's a handrolled Sync() which has its own weird relationship to laziness

#

Ie. at the moment if I call LLM.Sync() directly, I can/must error check

#

But if I call LLM.GetContainer() (which calls sync()` I don't

#

I actually have no idea what happens if the underlying container binding is still lazy, then I call GetContainer(), it gets unlazied by nested sync(), and returns an error. What happens to my error-less GetContainer() outer call?

cosmic orchid
cosmic orchid
leaden grove
#

Can I suggest Turn instead of Loop?
I believe the term "turn" is more commonly used for LLMs.

empty marlin
#

first time I ever hear that term!

#

But admitedly I am an AI noob 😛

leaden grove
#

I think "turns" are usually used for AI dialogues/conversations
But I did see "turn" but didn't ever see "loop" in the context of LLMs

empty marlin
#

yeah "loop" is emerging as a short for "agentic loop"

#

only makes sense in the specific context of tool calling

#

since it's literally a loop of round-trips with the LLM endpoint until it stops calling tools (or we stop waiting)